| 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
 |