ZeroFrame.coffee 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. class ZeroFrame extends Class
  2. constructor: (url) ->
  3. @url = url
  4. @waiting_cb = {}
  5. @history_state = {}
  6. @wrapper_nonce = document.location.href.replace(/.*wrapper_nonce=([A-Za-z0-9]+).*/, "$1")
  7. @connect()
  8. @next_message_id = 1
  9. @init()
  10. init: ->
  11. @
  12. connect: ->
  13. @target = window.parent
  14. window.addEventListener("message", @onMessage, false)
  15. @cmd("innerReady")
  16. # Save scrollTop
  17. window.addEventListener "beforeunload", (e) =>
  18. @log "Save scrollTop", window.pageYOffset
  19. @history_state["scrollTop"] = window.pageYOffset
  20. @cmd "wrapperReplaceState", [@history_state, null]
  21. # Restore scrollTop
  22. @cmd "wrapperGetState", [], (state) =>
  23. @handleState(state)
  24. handleState: (state) ->
  25. @history_state = state if state?
  26. @log "Restore scrollTop", state, window.pageYOffset
  27. if window.pageYOffset == 0 and state
  28. window.scroll(window.pageXOffset, state.scrollTop)
  29. onMessage: (e) =>
  30. message = e.data
  31. cmd = message.cmd
  32. if cmd == "response"
  33. if @waiting_cb[message.to]?
  34. @waiting_cb[message.to](message.result)
  35. else
  36. @log "Websocket callback not found:", message
  37. else if cmd == "wrapperReady" # Wrapper inited later
  38. @cmd("innerReady")
  39. else if cmd == "ping"
  40. @response message.id, "pong"
  41. else if cmd == "wrapperOpenedWebsocket"
  42. @onOpenWebsocket()
  43. else if cmd == "wrapperClosedWebsocket"
  44. @onCloseWebsocket()
  45. else if cmd == "wrapperPopState"
  46. @handleState(message.params.state)
  47. @onRequest cmd, message.params
  48. else
  49. @onRequest cmd, message.params
  50. onRequest: (cmd, message) =>
  51. @log "Unknown request", message
  52. response: (to, result) ->
  53. @send {"cmd": "response", "to": to, "result": result}
  54. cmd: (cmd, params={}, cb=null) ->
  55. @send {"cmd": cmd, "params": params}, cb
  56. cmdp: (cmd, params={}) ->
  57. p = new Promise()
  58. @send {"cmd": cmd, "params": params}, (res) ->
  59. p.resolve(res)
  60. return p
  61. send: (message, cb=null) ->
  62. message.wrapper_nonce = @wrapper_nonce
  63. message.id = @next_message_id
  64. @next_message_id += 1
  65. @target.postMessage(message, "*")
  66. if cb
  67. @waiting_cb[message.id] = cb
  68. onOpenWebsocket: =>
  69. @log "Websocket open"
  70. onCloseWebsocket: =>
  71. @log "Websocket close"
  72. window.ZeroFrame = ZeroFrame