adapter.native.coffee |
|
---|---|
|
|
Native Opentip AdapterUse this adapter if you don't use a framework like jQuery and you don't really care about oldschool browser compatibility. |
class Adapter
name: "native"
|
Invoke callback as soon as dom is ready Source: https://github.com/dperini/ContentLoaded/blob/master/src/contentloaded.js |
domReady: (callback) ->
done = no
top = true
win = window
doc = document
return callback() if doc.readyState in [ "complete", "loaded" ]
root = doc.documentElement
add = (if doc.addEventListener then "addEventListener" else "attachEvent")
rem = (if doc.addEventListener then "removeEventListener" else "detachEvent")
pre = (if doc.addEventListener then "" else "on")
init = (e) ->
return if e.type is "readystatechange" and doc.readyState isnt "complete"
(if e.type is "load" then win else doc)[rem] pre + e.type, init, false
unless done
done = yes
callback()
poll = ->
try
root.doScroll "left"
catch e
setTimeout poll, 50
return
init "poll"
unless doc.readyState is "complete"
if doc.createEventObject and root.doScroll
try
top = not win.frameElement
poll() if top
doc[add] pre + "DOMContentLoaded", init, false
doc[add] pre + "readystatechange", init, false
win[add] pre + "load", init, false
|
DOM |
|
Create the HTML passed as string |
create: (htmlString) ->
div = document.createElement "div"
div.innerHTML = htmlString
@wrap div.childNodes
|
Element handling |
|
Wrap the element in the framework |
wrap: (element) ->
if element instanceof NodeList
element = (el for el in element)
else if element not instanceof Array
element = [ element ]
element
|
Returns the unwrapped element |
unwrap: (element) -> @wrap(element)[0]
|
Returns the tag name of the element |
tagName: (element) -> @unwrap(element).tagName
|
Returns or sets the given attribute of element |
attr: (element, attr, value) ->
if arguments.length == 3
@unwrap(element).setAttribute attr, value
else
@unwrap(element).getAttribute? attr
lastDataId = 0
dataValues = { }
|
Returns or sets the given data of element |
data: (element, name, value) ->
dataId = @attr element, "data-id"
unless dataId
dataId = ++lastDataId
@attr element, "data-id", dataId
dataValues[dataId] = { }
if arguments.length == 3
|
Setter |
dataValues[dataId][name] = value
else
value = dataValues[dataId][name]
return value if value?
value = @attr element, "data-#{Opentip::dasherize name}"
if value
dataValues[dataId][name] = value
return value
|
Finds elements by selector |
find: (element, selector) -> @unwrap(element).querySelector selector
|
Finds all elements by selector |
findAll: (element, selector) -> @unwrap(element).querySelectorAll selector
|
Updates the content of the element |
update: (element, content, escape) ->
element = @unwrap element
if escape
element.innerHTML = "" # Clearing the content
element.appendChild document.createTextNode content
else
element.innerHTML = content
|
Appends given child to element |
append: (element, child) ->
unwrappedChild = @unwrap child
unwrappedElement = @unwrap element
unwrappedElement.appendChild unwrappedChild
|
Add a class |
addClass: (element, className) -> @unwrap(element).classList.add className
|
Remove a class |
removeClass: (element, className) -> @unwrap(element).classList.remove className
|
Set given css properties |
css: (element, properties) ->
element = @unwrap @wrap element
for own key, value of properties
element.style[key] = value
|
Returns an object with given dimensions |
dimensions: (element) ->
element = @unwrap @wrap element
dimensions =
width: element.offsetWidth
height: element.offsetHeight
unless dimensions.width and dimensions.height
|
The element is probably invisible. So make it visible |
revert =
position: element.style.position || ''
visibility: element.style.visibility || ''
display: element.style.display || ''
@css element,
position: "absolute"
visibility: "hidden"
display: "block"
dimensions =
width: element.offsetWidth
height: element.offsetHeight
@css element, revert
dimensions
|
Returns the scroll offsets of current document |
scrollOffset: ->
[
window.pageXOffset or document.documentElement.scrollLeft or document.body.scrollLeft
window.pageYOffset or document.documentElement.scrollTop or document.body.scrollTop
]
|
Returns the dimensions of the viewport (currently visible browser area) |
viewportDimensions: ->
{
width: document.documentElement.clientWidth
height: document.documentElement.clientHeight
}
|
Returns an object with x and y |
mousePosition: (e) ->
pos = x: 0, y: 0
e ?= window.event
return unless e?
if e.pageX or e.pageY
pos.x = e.pageX
pos.y = e.pageY
else if e.clientX or e.clientY
pos.x = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft
pos.y = e.clientY + document.body.scrollTop + document.documentElement.scrollTop
pos
|
Returns the offset of the element |
offset: (element) ->
element = @unwrap element
offset = {
top: element.offsetTop
left: element.offsetLeft
}
while element = element.offsetParent
offset.top += element.offsetTop
offset.left += element.offsetLeft
if element != document.body
offset.top -= element.scrollTop
offset.left -= element.scrollLeft
offset
|
Observe given eventName |
observe: (element, eventName, observer) -> @unwrap(element).addEventListener eventName, observer
|
Stop observing event |
stopObserving: (element, eventName, observer) -> @unwrap(element).removeEventListener eventName, observer
|
Perform an AJAX request and call the appropriate callbacks. |
ajax: (options) ->
throw new Error "No url provided" unless options.url?
if window.XMLHttpRequest
|
Mozilla, Safari, ... |
request = new XMLHttpRequest
else if window.ActiveXObject
|
IE |
try
request = new ActiveXObject "Msxml2.XMLHTTP"
catch e
try
request = new ActiveXObject "Microsoft.XMLHTTP"
catch e
throw new Error "Can't create XMLHttpRequest" unless request
request.onreadystatechange = ->
if request.readyState == 4
try
if request.status == 200
options.onSuccess? request.responseText
else
options.onError? "Server responded with status #{request.status}"
catch e
options.onError? e.message
options.onComplete?()
request.open options.method?.toUpperCase() ? "GET", options.url
request.send()
|
Utility functions |
|
Creates a shallow copy of the object |
clone: (object) ->
newObject = { }
for own key, val of object
newObject[key] = val
newObject
|
Copies all properties from sources to target |
extend: (target, sources...) ->
for source in sources
for own key, val of source
target[key] = val
target
|
Add the adapter to the list |
Opentip.addAdapter new Adapter
|