Jump To …
adapter.ender.coffee adapter.jquery.coffee adapter.native.coffee adapter.prototype.coffee opentip.coffee

# adapter.native.coffee

¶

¶

# Native Opentip Adapter

Use 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