new style api
This commit is contained in:
+219
-188
@@ -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
|
||||
|
||||
@
|
||||
|
||||
|
||||
Reference in New Issue
Block a user