app/scripts/ui-lib/widgets/tooltip.coffee

Tooltip

The Tooltip class provides a tooltip widget.

author: Julien Ramboz version: 1.0 references: WAI-ARIA tooltip role, AOL's Tooltip style guide usage: Tooltip examples requires: Toggle

AMD loader

Try loading as AMD module or fall back to default loading

((widget) -> if typeof define is "function" and define.amd define ["jslib", "core", "widget", "toggle"], widget else widget @$, _, _.AbstractWidget, _.Toggle ) tooltip = ($, _, AbstractWidget, Toggle) -> "use strict"

Widget

The actual widget class

class Tooltip extends Toggle

Default options for the widget

@defaultOptions:
  • toggleHiddenClass: class added to hidden toggle
toggleHiddenClass: ""
  • toggleVisibleClass: class added to visible toggle
toggleVisibleClass: ""
  • paneHiddenClass: class added to hidden content
paneHiddenClass: "hidden"
  • paneVisibleClass: class added to visible content
paneVisibleClass: "focus"
  • event: the event to react to
event: "mouseenter.#{_.namespace}toggle mouseleave.#{_.namespace}toggle"
  • labelledby: element to use as the label if the toggle has no actual text
labelledby: ""
  • target: the target to use, specified as a selector
target: ""
  • tooltip: the tooltip to use
tooltip: ""
  • overlay: whether or not the targets are toggled in an overlay
overlay: false

Initialisation

Initializer function.

initialize: (options) -> @created = tooltip: false super options @hide()

Accessibility markup

Add aria attributes

aria: () -> super if @targets isnt @element @targets.attr "role", "tooltip" targetIds = "" @targets.each (i, target) => $target = $(target) if (not @element.attr("aria-describedby")) $parents = $target.parents("[role]") if (not target.id) hashString = $target.get(0).outerHTML if $parents.length hashString = $parents.get(0).outerHTML + hashString target.id = "tooltip-" + _.hash(hashString) targetIds += target.id + " " @element.attr("aria-describedby", $.trim(targetIds))

Event handling

Attach evenets to the widget

bindEvents: () -> @handleKeys(@element) if @options.event @element.on "#{@options.event}", (e) => if e.target.getAttribute("aria-disabled") is "true" return e.preventDefault() if @options.overlay is "true" or @options.overlay is true return if $("#overlay").attr("aria-hidden") is "false" e.preventDefault() return @show() if e.type is "mouseenter" return @hide() if e.type is "mouseout" @toggle(undefined, e)

Force activation on keyboard focus

@element.on "focus.#{_.namespace}tooltip", (e) => @show(e) if e.relatedTarget @element.on "blur.#{_.namespace}tooltip", (e) => @hide(e) if e.relatedTarget

Adjust target positions relative to the toggle

@element.on "afterToggle.#{_.namespace}tooltip", (e, options) => @targets.each (i, target) => $target = $(target) spacing = parseInt(@element.css("line-height"), 10) $target.attr("aria-hidden", options.visible) $target.css "left": @element.position().left + @element.width() "top": @element.position().top - spacing if i > 0 $target.css("top", parseInt($target.css("top"), 10) + @targets.eq(i-1).height() + spacing) if @options.overlay is "true" or @options.overlay is true @targets.on "beforeOverlay", (e, o) => @hide e if o.status is false

Structure discovery

Find the widget structure using the specified configuration

Targets

Find the targets of the tooltip, specified in one of the following ways:

  • using aria-describedby attribute (i.e. "id1")
  • using tooltip option content (i.e. "my tooltip text")
  • fall back to the predefined function
findTargets: () -> ariaTargets = @element.attr("aria-describedby")

Handle targets specified using the aria-controls attribute

if ariaTargets $("#"+ariaTargets.split(" ").join(",#"))

Handle targets specified using the tooltip option

else if @options.tooltip and not @targets @createTooltip().insertAfter(@element)

Handle targets specified using the data-target attribute

else super

Structure creation

Create elements required by the structure if they are not present

Tooltip element

createTooltip: () -> @created.tooltip = true $(document.createElement("span")).text(@options.tooltip)

Key handling

Handle escape key press

keyEscape: (e) -> @hide(e)

Cleanup

Cleanup the widget and remove remaining references

destructor: () -> @targets.remove() if @created.tooltip super()

Installation

Install the widget into the JS library

Tooltip.install("Tooltip", () -> $("[data-widget='tooltip']")["#{_.namespace}tooltip"]() )