Menu.coffee 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. class Menu
  2. constructor: ->
  3. @visible = false
  4. @items = []
  5. @node = null
  6. show: =>
  7. window.visible_menu?.hide()
  8. @visible = true
  9. window.visible_menu = @
  10. hide: =>
  11. @visible = false
  12. toggle: =>
  13. if @visible
  14. @hide()
  15. else
  16. @show()
  17. Page.projector.scheduleRender()
  18. addItem: (title, cb, selected=false) ->
  19. @items.push([title, cb, selected])
  20. storeNode: (node) =>
  21. @node = node
  22. # Animate visible
  23. if @visible
  24. node.className = node.className.replace("visible", "")
  25. setTimeout (->
  26. node.className += " visible"
  27. ), 10
  28. handleClick: (e) =>
  29. keep_menu = false
  30. for item in @items
  31. [title, cb, selected] = item
  32. if title == e.target.textContent
  33. keep_menu = cb(item)
  34. if keep_menu != true
  35. @hide()
  36. return false
  37. renderItem: (item) =>
  38. [title, cb, selected] = item
  39. if typeof(selected) == "function"
  40. selected = selected()
  41. if title == "---"
  42. h("div.menu-item-separator")
  43. else
  44. if typeof(cb) == "string" # Url
  45. href = cb
  46. onclick = true
  47. else # Callback
  48. href = "#"+title
  49. onclick = @handleClick
  50. h("a.menu-item", {href: href, onclick: onclick, key: title, classes: {"selected": selected}}, [title])
  51. render: (class_name="") =>
  52. if @visible or @node
  53. h("div.menu#{class_name}", {classes: {"visible": @visible}, afterCreate: @storeNode}, @items.map(@renderItem))
  54. window.Menu = Menu
  55. # Hide menu on outside click
  56. document.body.addEventListener "mouseup", (e) ->
  57. if not window.visible_menu or not window.visible_menu.node
  58. return false
  59. if e.target != window.visible_menu.node.parentNode and e.target.parentNode != window.visible_menu.node and e.target.parentNode != window.visible_menu.node.parentNode and e.target.parentNode != window.visible_menu.node and e.target.parentNode.parentNode != window.visible_menu.node.parentNode
  60. window.visible_menu.hide()
  61. Page.projector.scheduleRender()