class Wrapper constructor: (ws_url) -> @log "Created!" @loading = new Loading(@) @notifications = new Notifications($(".notifications")) @infopanel = new Infopanel($(".infopanel")) @infopanel.onClosed = => @ws.cmd("siteSetSettingsValue", ["modified_files_notification", false]) @infopanel.onOpened = => @ws.cmd("siteSetSettingsValue", ["modified_files_notification", true]) @fixbutton = new Fixbutton() window.addEventListener("message", @onMessageInner, false) @inner = document.getElementById("inner-iframe").contentWindow @ws = new ZeroWebsocket(ws_url) @ws.next_message_id = 1000000 # Avoid messageid collision :) @ws.onOpen = @onOpenWebsocket @ws.onClose = @onCloseWebsocket @ws.onMessage = @onMessageWebsocket @ws.connect() @ws_error = null # Ws error message @next_cmd_message_id = -1 @site_info = null # Hold latest site info @server_info = null # Hold latest server info @event_site_info = $.Deferred() # Event when site_info received @inner_loaded = false # If iframe loaded or not @inner_ready = false # Inner frame ready to receive messages @wrapperWsInited = false # Wrapper notified on websocket open @site_error = null # Latest failed file download @address = null @opener_tested = false @announcer_line = null @web_notifications = {} @is_title_changed = false @allowed_event_constructors = [window.MouseEvent, window.KeyboardEvent, window.PointerEvent] # Allowed event constructors window.onload = @onPageLoad # On iframe loaded window.onhashchange = (e) => # On hash change @log "Hashchange", window.location.hash if window.location.hash src = $("#inner-iframe").attr("src").replace(/#.*/, "")+window.location.hash $("#inner-iframe").attr("src", src) window.onpopstate = (e) => @sendInner {"cmd": "wrapperPopState", "params": {"href": document.location.href, "state": e.state}} $("#inner-iframe").focus() verifyEvent: (allowed_target, e) => if not e.originalEvent.isTrusted throw "Event not trusted" if e.originalEvent.constructor not in @allowed_event_constructors throw "Invalid event constructor: #{e.constructor} not in #{JSON.stringify(@allowed_event_constructors)}" if e.originalEvent.currentTarget != allowed_target[0] throw "Invalid event target: #{e.originalEvent.currentTarget} != #{allowed_target[0]}" # Incoming message from UiServer websocket onMessageWebsocket: (e) => message = JSON.parse(e.data) @handleMessageWebsocket(message) handleMessageWebsocket: (message) => cmd = message.cmd if cmd == "response" if @ws.waiting_cb[message.to]? # We are waiting for response @ws.waiting_cb[message.to](message.result) else @sendInner message # Pass message to inner frame else if cmd == "notification" # Display notification type = message.params[0] id = "notification-ws-#{message.id}" if "-" in message.params[0] # - in first param: message id defined [id, type] = message.params[0].split("-") @notifications.add(id, type, message.params[1], message.params[2]) else if cmd == "progress" # Display notification @actionProgress(message) else if cmd == "prompt" # Prompt input @displayPrompt message.params[0], message.params[1], message.params[2], message.params[3], (res) => @ws.response message.id, res else if cmd == "confirm" # Confirm action @displayConfirm message.params[0], message.params[1], (res) => @ws.response message.id, res else if cmd == "setSiteInfo" @sendInner message # Pass to inner frame if message.params.address == @address # Current page @setSiteInfo message.params @updateProgress message.params else if cmd == "setAnnouncerInfo" @sendInner message # Pass to inner frame if message.params.address == @address # Current page @setAnnouncerInfo message.params @updateProgress message.params else if cmd == "error" @notifications.add("notification-#{message.id}", "error", message.params, 0) else if cmd == "updating" # Close connection @log "Updating: Closing websocket" @ws.ws.close() @ws.onCloseWebsocket(null, 4000) else if cmd == "redirect" window.top.location = message.params else if cmd == "injectHtml" $("body").append(message.params) else if cmd == "injectScript" script_tag = $("