Files
jquery-notify/src/notify.coffee
T

566 lines
16 KiB
CoffeeScript
Raw Normal View History

2013-04-04 13:13:08 +11:00
'use strict'
#plugin constants
pluginName = 'notify'
2013-06-04 17:01:03 +10:00
pluginClassName = pluginName+'js'
2013-04-04 13:13:08 +11:00
2013-06-03 12:28:03 +10:00
# ================================
# POSITIONING
# ================================
2013-05-30 16:35:16 +10:00
2013-06-02 23:19:34 +10:00
positions =
2013-05-30 16:35:16 +10:00
t: 'top'
m: 'middle'
b: 'bottom'
l: 'left'
c: 'center'
r: 'right'
2013-06-03 09:15:58 +10:00
hAligns = ['l','c','r']
vAligns = ['t','m','b']
2013-05-31 13:18:43 +10:00
mainPositions = ['t','b','l','r']
2013-05-29 16:59:19 +10:00
#positions mapped to opposites
2013-05-30 16:35:16 +10:00
opposites =
2013-05-29 16:59:19 +10:00
t: 'b'
m: null
b: 't'
l: 'r'
c: null
r: 'l'
2013-04-04 13:13:08 +11:00
2013-05-29 16:59:19 +10:00
parsePosition = (str) ->
pos = []
$.each str.split(/\W+/), (i,word) ->
2013-05-30 16:35:16 +10:00
w = word.toLowerCase().charAt(0)
pos.push w if positions[w]
2013-05-29 16:59:19 +10:00
pos
2013-06-03 12:28:03 +10:00
# ================================
# STYLES
# ================================
styles = {}
coreStyle =
name: 'core'
html: """
2013-06-04 17:01:03 +10:00
<div class="#{pluginClassName}-wrapper">
<div class="#{pluginClassName}-arrow"></div>
<div class="#{pluginClassName}-container"></div>
2013-06-03 12:28:03 +10:00
</div>
"""
2013-06-04 17:01:03 +10:00
# <div class="#{pluginClassName}Debug"></div>
2013-06-03 12:28:03 +10:00
2013-06-04 17:01:03 +10:00
# .#{pluginClassName}Debug {
2013-06-03 12:28:03 +10:00
# position: absolute;
# border: 3px solid red;
# height: 0;
# width: 0;
# }
css: """
2013-06-04 17:01:03 +10:00
.#{pluginClassName}-corner {
2013-06-03 12:28:03 +10:00
position: fixed;
top: 0;
right: 0;
margin: 5px;
z-index: 1050;
}
2013-06-04 17:01:03 +10:00
.#{pluginClassName}-corner .#{pluginClassName}-wrapper,
.#{pluginClassName}-corner .#{pluginClassName}-container {
2013-06-03 12:28:03 +10:00
position: relative;
display: block;
height: inherit;
width: inherit;
}
2013-06-04 17:01:03 +10:00
.#{pluginClassName}-wrapper {
2013-06-03 12:28:03 +10:00
z-index: 1;
position: absolute;
display: inline-block;
height: 0;
width: 0;
}
2013-06-04 17:01:03 +10:00
.#{pluginClassName}-container {
2013-06-03 12:28:03 +10:00
display: none;
z-index: 1;
position: absolute;
cursor: pointer;
}
2013-06-04 17:01:03 +10:00
.#{pluginClassName}-text {
2013-06-03 12:28:03 +10:00
position: relative;
}
2013-06-04 17:01:03 +10:00
.#{pluginClassName}-arrow {
2013-06-03 12:28:03 +10:00
position: absolute;
z-index: 2;
width: 0;
height: 0;
}
"""
defaultStyleName = "bootstrap"
defaultStyle =
html: """
<div>
<span data-notify-text></span>
</div>
"""
classes:
2013-06-04 17:01:03 +10:00
base:
"padding": "8px 15px 8px 14px"
"text-shadow": "0 1px 0 rgba(255, 255, 255, 0.5)"
"background-color": "#fcf8e3"
"border": "1px solid #fbeed5"
"border-radius": "4px"
"white-space": "nowrap"
#for background-image
"padding-left": "25px"
"background-repeat": "no-repeat"
"background-position": "3px 7px"
error:
"color": "#B94A48"
"background-color": "#F2DEDE"
"border-color": "#EED3D7"
"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=)"
success:
"color": "#468847"
"background-color": "#DFF0D8"
"border-color": "#D6E9C6"
"background-image": "url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAutJREFUeNq0lctPE0Ecx38zu/RFS1EryqtgJFA08YCiMZIAQQ4eRG8eDGdPJiYeTIwHTfwPiAcvXIwXLwoXPaDxkWgQ6islKlJLSQWLUraPLTv7Gme32zoF9KSTfLO7v53vZ3d/M7/fIth+IO6INt2jjoA7bjHCJoAlzCRw59YwHYjBnfMPqAKWQYKjGkfCJqAF0xwZjipQtA3MxeSG87VhOOYegVrUCy7UZM9S6TLIdAamySTclZdYhFhRHloGYg7mgZv1Zzztvgud7V1tbQ2twYA34LJmF4p5dXF1KTufnE+SxeJtuCZNsLDCQU0+RyKTF27Unw101l8e6hns3u0PBalORVVVkcaEKBJDgV3+cGM4tKKmI+ohlIGnygKX00rSBfszz/n2uXv81wd6+rt1orsZCHRdr1Imk2F2Kob3hutSxW8thsd8AXNaln9D7CTfA6O+0UgkMuwVvEFFUbbAcrkcTA8+AtOk8E6KiQiDmMFSDqZItAzEVQviRkdDdaFgPp8HSZKAEAL5Qh7Sq2lIJBJwv2scUqkUnKoZgNhcDKhKg5aH+1IkcouCAdFGAQsuWZYhOjwFHQ96oagWgRoUov1T9kRBEODAwxM2QtEUl+Wp+Ln9VRo6BcMw4ErHRYjH4/B26AlQoQQTRdHWwcd9AH57+UAXddvDD37DmrBBV34WfqiXPl61g+vr6xA9zsGeM9gOdsNXkgpEtTwVvwOklXLKm6+/p5ezwk4B+j6droBs2CsGa/gNs6RIxazl4Tc25mpTgw/apPR1LYlNRFAzgsOxkyXYLIM1V8NMwyAkJSctD1eGVKiq5wWjSPdjmeTkiKvVW4f2YPHWl3GAVq6ymcyCTgovM3FzyRiDe2TaKcEKsLpJvNHjZgPNqEtyi6mZIm4SRFyLMUsONSSdkPeFtY1n0mczoY3BHTLhwPRy9/lzcziCw9ACI+yql0VLzcGAZbYSM5CCSZg1/9oc/nn7+i8N9p/8An4JMADxhH+xHfuiKwAAAABJRU5ErkJggg==)"
info: {}
warn: {}
stylePrefixes =
"border-radius": ["-webkit-", "-moz-"]
2013-06-03 12:28:03 +10:00
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
2013-06-04 17:01:03 +10:00
$.each def.classes, (className, props) ->
cssText += ".#{pluginClassName}-#{def.name}-#{className} {\n"
$.each props, (name, val) ->
#vendor prefixes
if stylePrefixes[name]
$.each stylePrefixes[name], (i, prefix) ->
cssText += " #{prefix}#{name}: #{val};\n"
#add prop
cssText += " #{name}: #{val};\n"
cssText += "}\n"
2013-06-03 12:28:03 +10:00
if def.css
cssText += """
/* styles for #{def.name} */
#{def.css}
2013-04-04 13:48:42 +11:00
"""
2013-06-03 09:15:58 +10:00
2013-06-03 12:28:03 +10:00
return unless cssText
def.cssElem = insertCSS cssText
def.cssElem.attr('data-notify-style', def.name)
2013-06-03 09:15:58 +10:00
2013-06-03 12:28:03 +10:00
insertCSS = (cssText) ->
2013-06-04 17:01:03 +10:00
2013-06-03 12:28:03 +10:00
elem = createElem("style")
$("head").append elem
try
elem.html cssText
catch e #ie fix
elem[0].styleSheet.cssText = cssText
elem
2013-06-03 09:15:58 +10:00
2013-04-04 16:58:22 +11:00
2013-06-03 12:28:03 +10:00
# ================================
# OPTIONS
# ================================
2013-04-04 13:13:08 +11:00
#overridable options
pluginOptions =
2013-06-04 17:01:03 +10:00
autoHide: true
autoHideDelay: 5000
2013-05-31 13:18:43 +10:00
arrowShow: true
2013-04-04 13:13:08 +11:00
arrowSize: 5
2013-04-05 15:09:44 +11:00
position: 'bottom'
2013-04-04 13:48:42 +11:00
# Default style
2013-06-03 12:28:03 +10:00
style: 'bootstrap'
2013-06-04 17:01:03 +10:00
className: 'error'
2013-04-04 16:58:22 +11:00
showAnimation: 'slideDown'
2013-04-05 11:53:48 +11:00
showDuration: 400
2013-04-04 16:58:22 +11:00
hideAnimation: 'slideUp'
2013-04-05 11:53:48 +11:00
hideDuration: 200
2013-04-04 13:13:08 +11:00
# Gap between main and element
2013-05-31 13:18:43 +10:00
offsetY: 0
2013-04-05 11:53:48 +11:00
offsetX: 0
2013-04-04 13:13:08 +11:00
#TODO add z-index watches
#parents: { '.ui-dialog': 5001 }
2013-04-05 11:53:48 +11:00
inherit = (a, b) ->
F = () ->
F.prototype = a
$.extend true, new F(), b
2013-04-04 13:13:08 +11:00
2013-06-03 12:28:03 +10:00
options = (opts) ->
$.extend pluginOptions, opts
# ================================
# DOM MANIPULATION
# ================================
# plugin helpers
createElem = (tag) ->
$ "<#{tag}></#{tag}>"
2013-04-04 16:58:22 +11:00
# container for element-less notifications
2013-06-04 17:01:03 +10:00
cornerElem = createElem("div").addClass("#{pluginClassName}-corner")
2013-04-04 16:58:22 +11:00
#gets first on n radios, and gets the fancy stylised input for hidden inputs
2013-04-04 13:13:08 +11:00
getAnchorElement = (element) ->
#choose the first of n radios
if element.is('[type=radio]')
radios = element.parents('form:first').find('[type=radio]').filter (i, e) ->
$(e).attr('name') is element.attr('name')
element = radios.first()
#custom-styled inputs - find thier real element
element
2013-05-31 13:18:43 +10:00
incr = (obj, pos, val) ->
2013-05-30 16:35:16 +10:00
# console.log "incr ---- #{pos} #{val} (#{typeof val})"
if typeof val is 'string'
val = parseInt val, 10
else if typeof val isnt 'number'
return
return if isNaN val
2013-06-02 23:19:34 +10:00
opp = positions[opposites[pos.charAt(0)]]
2013-05-30 16:35:16 +10:00
temp = pos
#use the opposite if exists
if obj[opp] isnt `undefined`
pos = positions[opp.charAt(0)]
val *= -1
if obj[pos] is `undefined`
obj[pos] = val
else
obj[pos] += val
null
2013-05-31 13:18:43 +10:00
realign = (alignment, inner, outer) ->
return if alignment in ['l','t']
0
else if alignment in ['c','m']
outer/2 - inner/2
else if alignment in ['r','b']
outer - inner
throw "Invalid alignment"
2013-04-05 11:53:48 +11:00
2013-06-03 12:28:03 +10:00
# ================================
# NOTIFY CLASS
# ================================
2013-04-16 15:57:38 +10:00
2013-04-04 13:13:08 +11:00
#define plugin
2013-04-04 16:58:22 +11:00
class Notification
2013-06-02 23:19:34 +10:00
2013-04-04 13:13:08 +11:00
#setup instance variables
2013-04-04 16:58:22 +11:00
constructor: (elem, data, options) ->
2013-06-04 17:01:03 +10:00
options = {className: options} if typeof options is 'string'
2013-04-05 11:53:48 +11:00
@options = inherit pluginOptions, if $.isPlainObject(options) then options else {}
2013-04-04 13:48:42 +11:00
2013-04-04 16:58:22 +11:00
#load user html into @userContainer
2013-04-04 13:48:42 +11:00
@loadHTML()
2013-06-03 12:28:03 +10:00
@wrapper = $(coreStyle.html)
2013-06-04 17:01:03 +10:00
@wrapper.data pluginClassName, @
@arrow = @wrapper.find ".#{pluginClassName}-arrow"
@container = @wrapper.find ".#{pluginClassName}-container"
2013-04-04 14:02:55 +11:00
@container.append @userContainer
2013-04-04 13:13:08 +11:00
2013-04-04 16:58:22 +11:00
if elem and elem.length
@elementType = elem.attr('type')
@originalElement = elem
@elem = getAnchorElement(elem)
2013-06-04 17:01:03 +10:00
@elem.data pluginClassName, @
2013-04-04 16:58:22 +11:00
# add into dom above elem
@elem.before @wrapper
else
# @options.autoHide = true
@options.arrowShow = false
cornerElem.prepend @wrapper
2013-04-04 13:13:08 +11:00
2013-04-04 16:58:22 +11:00
@container.hide()
@run(data)
2013-04-04 13:13:08 +11:00
2013-04-11 17:22:27 +10:00
loadHTML: ->
style = @getStyle()
2013-04-04 14:02:55 +11:00
@userContainer = $(style.html)
2013-05-30 16:35:16 +10:00
@text = @userContainer.find '[data-notify-text]'
2013-04-04 13:48:42 +11:00
if @text.length is 0
2013-06-04 17:01:03 +10:00
@text = @userContainer.find '[data-notify-html]'
@rawText = true
if @text.length is 0
throw "style: '#{name}' HTML is missing a: 'data-notify-text' or 'data-notify-html' attribute"
@text.addClass "#{pluginClassName}-text"
2013-04-04 13:48:42 +11:00
2013-04-05 15:34:55 +11:00
show: (show, callback = $.noop) ->
2013-04-05 12:26:27 +11:00
2013-04-04 13:48:42 +11:00
hidden = @container.parent().parents(':hidden').length > 0
2013-06-02 23:19:34 +10:00
2013-04-05 12:26:27 +11:00
elems = @container.add @arrow
2013-04-05 15:34:55 +11:00
args = []
if hidden and show
fn = 'show'
else if hidden and not show
fn = 'hide'
else if not hidden and show
fn = @options.showAnimation
args.push @options.showDuration
else if not hidden and not show
fn = @options.hideAnimation
args.push @options.hideDuration
2013-05-31 13:18:43 +10:00
else
return callback()
2013-04-05 15:34:55 +11:00
args.push callback
2013-06-02 23:19:34 +10:00
elems[fn].apply elems, args
2013-04-04 13:13:08 +11:00
2013-04-05 11:53:48 +11:00
updatePosition: ->
return unless @elem
2013-05-30 16:35:16 +10:00
2013-05-31 13:18:43 +10:00
#grab some dimensions
elemPos = @elem.position()
elemH = @elem.outerHeight()
elemW = @elem.outerWidth()
2013-06-03 09:15:58 +10:00
elemIH = @elem.innerHeight()
elemIW = @elem.innerWidth()
2013-05-31 13:18:43 +10:00
wrapPos = @wrapper.position()
contH = @container.height()
contW = @container.width()
#get user defined position
2013-04-05 11:53:48 +11:00
position = @getPosition()
2013-06-03 12:28:03 +10:00
2013-05-31 13:18:43 +10:00
pMain = position[0]
pAlign = position[1]
pArrow = position[2] or pAlign
2013-05-30 16:35:16 +10:00
2013-04-05 11:53:48 +11:00
#start calculations
2013-05-31 13:18:43 +10:00
mainFull = positions[pMain]
opp = opposites[pMain]
oppFull = positions[opp]
#initial positioning
css = {}
2013-06-04 17:01:03 +10:00
css[oppFull] = if pMain is 'b'
elemH
else if pMain is 'r'
elemW
else
0
2013-04-05 11:53:48 +11:00
2013-05-31 13:18:43 +10:00
#correct for elem-wrapper offset
# unless navigator.userAgent.match /MSIE/
# incr css, 'top', (elemPos.top - wrapPos.top)
incr css, 'left', elemPos.left - wrapPos.left
2013-06-02 23:19:34 +10:00
2013-05-31 13:18:43 +10:00
#correct for left margin
margin = parseInt @elem.css("margin-left"), 10
incr css, 'left', margin if margin
#correct for inline top padding
if /^inline/.test @elem.css('display')
padding = parseInt @elem.css("padding-top"), 10
incr css, 'top', -padding if padding
#user defined offset
incr css, 'top', @options.offsetY
incr css, 'left', @options.offsetX
2013-04-05 11:53:48 +11:00
2013-06-03 12:28:03 +10:00
style = @getStyle()
# if style.css
2013-05-31 13:18:43 +10:00
#calculate arrow
if not @options.arrowShow
2013-04-05 11:53:48 +11:00
@arrow.hide()
2013-05-31 13:18:43 +10:00
else
2013-06-03 09:15:58 +10:00
arrowSize = @options.arrowSize
2013-05-31 13:18:43 +10:00
arrowCss = $.extend {}, css
2013-06-04 17:01:03 +10:00
arrowColor = @userContainer.css("border-color") or
@userContainer.css("background-color") or
'white'
2013-05-31 13:18:43 +10:00
#build arrow
for pos in mainPositions
posFull = positions[pos]
continue if pos is opp
2013-06-04 17:01:03 +10:00
color = if posFull is mainFull then arrowColor else 'transparent'
2013-06-03 09:15:58 +10:00
arrowCss["border-#{posFull}"] = "#{arrowSize}px solid #{color}"
2013-05-31 13:18:43 +10:00
#add some room for the arrow
2013-06-03 09:15:58 +10:00
incr css, positions[opp], arrowSize
2013-04-05 11:53:48 +11:00
2013-06-03 09:15:58 +10:00
incr arrowCss, positions[pAlign], arrowSize*2 if pAlign in mainPositions
#calculate container alignment
if pMain in vAligns
2013-05-31 13:18:43 +10:00
incr css, 'left', realign(pAlign, contW, elemW)
2013-06-03 09:15:58 +10:00
incr arrowCss, 'left', realign(pAlign, arrowSize, elemIW) if arrowCss
else if pMain in hAligns
2013-05-31 13:18:43 +10:00
incr css, 'top', realign(pAlign, contH, elemH)
2013-06-03 09:15:58 +10:00
incr arrowCss, 'top', realign(pAlign, arrowSize, elemIH) if arrowCss
2013-04-05 11:53:48 +11:00
2013-05-31 13:18:43 +10:00
css.display = 'block' if @container.is(":visible")
2013-06-04 17:01:03 +10:00
#apply css
2013-05-31 13:18:43 +10:00
@container.removeAttr('style').css css
2013-06-03 09:15:58 +10:00
@arrow.removeAttr('style').css(arrowCss) if arrowCss
2013-04-05 11:53:48 +11:00
getPosition: ->
2013-05-29 16:59:19 +10:00
text = @options.position
pos = parsePosition text
2013-06-03 09:15:58 +10:00
#validate position
2013-05-31 13:18:43 +10:00
pos[0] = 'b' if pos.length is 0
if pos[0] not in mainPositions
throw "Must be one of [#{mainPositions}]"
2013-06-03 12:28:03 +10:00
2013-06-03 09:15:58 +10:00
#validate alignment
2013-05-31 13:18:43 +10:00
if pos.length is 1 or
2013-06-03 09:15:58 +10:00
(pos[0] in vAligns and pos[1] not in hAligns) or
(pos[0] in hAligns and pos[1] not in vAligns)
pos[1] = if pos[0] in hAligns then 'm' else 'l'
2013-05-29 16:59:19 +10:00
unless @options.autoReposition
return pos
# if @elem.position().left + @elem.width() + @wrapper.width() < $(window).width()
# return 'right'
# return 'bottom'
throw "Not implemented"
2013-04-04 13:13:08 +11:00
2013-04-04 13:48:42 +11:00
getStyle: (name) ->
name = @options.style unless name
2013-04-05 11:53:48 +11:00
name = 'default' unless name
2013-06-03 12:28:03 +10:00
style = styles[name]
2013-06-04 17:01:03 +10:00
throw "Missing style: #{name}"unless style
2013-04-04 13:48:42 +11:00
style
2013-06-03 12:28:03 +10:00
updateStyleClasses: ->
2013-06-04 17:01:03 +10:00
classes = ['base']
2013-06-03 12:28:03 +10:00
2013-06-04 17:01:03 +10:00
if $.isArray @options.className
classes = classes.concat @options.className
else if @options.className
classes.push @options.className
2013-06-03 12:28:03 +10:00
style = @getStyle()
2013-06-04 17:01:03 +10:00
classes = $.map(classes, (n) -> "#{pluginClassName}-#{style.name}-#{n}").join ' '
2013-06-03 12:28:03 +10:00
2013-06-04 17:01:03 +10:00
@userContainer.attr 'class', classes
2013-06-03 12:28:03 +10:00
2013-04-05 11:53:48 +11:00
2013-04-04 13:13:08 +11:00
#run plugin
2013-04-04 16:58:22 +11:00
run: (data, options) ->
2013-04-04 13:13:08 +11:00
#update options
if $.isPlainObject(options)
2013-06-02 23:19:34 +10:00
$.extend @options, options
2013-04-04 13:13:08 +11:00
#shortcut special case
else if $.type(options) is 'string'
@options.color = options
2013-04-04 16:58:22 +11:00
if @container and not data
@show false #hide
2013-04-04 13:13:08 +11:00
return
2013-04-04 16:58:22 +11:00
else if not @container and not data
2013-04-04 13:13:08 +11:00
return
#update content
2013-04-04 16:58:22 +11:00
if $.type(data) is 'string'
@text.html data.replace('\n', '<br/>')
2013-04-04 13:13:08 +11:00
else
2013-04-04 16:58:22 +11:00
@text.empty().append(data)
2013-04-04 14:02:55 +11:00
2013-06-03 12:28:03 +10:00
#set styles
@updateStyleClasses()
#position
2013-04-05 11:53:48 +11:00
@updatePosition()
2013-04-04 13:13:08 +11:00
2013-04-04 16:58:22 +11:00
@show true
2013-04-04 13:13:08 +11:00
#autohide
2013-04-04 16:58:22 +11:00
if @options.autoHide
clearTimeout @autohideTimer
2013-05-31 13:18:43 +10:00
@autohideTimer = setTimeout =>
2013-04-04 16:58:22 +11:00
@show false
2013-04-04 13:13:08 +11:00
, @options.autoHideDelay
2013-04-05 15:34:55 +11:00
destroy: ->
@show false, =>
@wrapper.remove()
2013-06-03 12:28:03 +10:00
# ================================
# 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 ->
2013-06-04 17:01:03 +10:00
inst = getAnchorElement($(@)).data(pluginClassName)
2013-06-03 12:28:03 +10:00
if inst
inst.run data, options
else
new Notification $(@), data, options
@
#extra
$.extend $[pluginName], { options, addStyle }
2013-04-05 12:26:27 +11:00
#when ready
2013-04-04 13:13:08 +11:00
$ ->
2013-04-05 12:26:27 +11:00
#corner notification container
2013-04-04 16:58:22 +11:00
$("body").append cornerElem
#auto-detect bootstrap
$("link").each ->
src = $(@).attr 'href'
2013-04-05 12:26:27 +11:00
if src.match /bootstrap/
2013-04-05 11:53:48 +11:00
bootstrapDetected = true
2013-04-04 16:58:22 +11:00
return false
2013-04-05 12:26:27 +11:00
2013-06-03 12:28:03 +10:00
#insert default style
insertCSS(coreStyle.css).attr('data-notify-style', 'core')
#insert default style
$[pluginName].addStyle(defaultStyleName, defaultStyle)
2013-04-05 11:53:48 +11:00
2013-04-04 16:58:22 +11:00
#watch all notifications clicks
2013-06-04 17:01:03 +10:00
$(document).on 'click', ".#{pluginClassName}-wrapper", ->
inst = $(@).data pluginClassName
2013-04-05 15:34:55 +11:00
return unless inst
if inst.elem
inst.show false
else
inst.destroy()
2013-04-04 13:13:08 +11:00