[cleanup] remove coffee script files
This commit is contained in:
parent
fee2a4f2c9
commit
574928e625
50 changed files with 0 additions and 4951 deletions
|
@ -1,32 +0,0 @@
|
|||
class Fixbutton
|
||||
constructor: ->
|
||||
@dragging = false
|
||||
$(".fixbutton-bg").on "mouseover", ->
|
||||
$(".fixbutton-bg").stop().animate({"scale": 0.7}, 800, "easeOutElastic")
|
||||
$(".fixbutton-burger").stop().animate({"opacity": 1.5, "left": 0}, 800, "easeOutElastic")
|
||||
$(".fixbutton-text").stop().animate({"opacity": 0, "left": 20}, 300, "easeOutCubic")
|
||||
|
||||
$(".fixbutton-bg").on "mouseout", ->
|
||||
if $(".fixbutton").hasClass("dragging")
|
||||
return true
|
||||
$(".fixbutton-bg").stop().animate({"scale": 0.6}, 300, "easeOutCubic")
|
||||
$(".fixbutton-burger").stop().animate({"opacity": 0, "left": -20}, 300, "easeOutCubic")
|
||||
$(".fixbutton-text").stop().animate({"opacity": 0.9, "left": 0}, 300, "easeOutBack")
|
||||
|
||||
|
||||
###$(".fixbutton-bg").on "click", ->
|
||||
return false
|
||||
###
|
||||
|
||||
$(".fixbutton-bg").on "mousedown", ->
|
||||
# $(".fixbutton-burger").stop().animate({"scale": 0.7, "left": 0}, 300, "easeOutCubic")
|
||||
#$("#inner-iframe").toggleClass("back")
|
||||
#$(".wrapper-iframe").stop().animate({"scale": 0.9}, 600, "easeOutCubic")
|
||||
#$("body").addClass("back")
|
||||
|
||||
$(".fixbutton-bg").on "mouseup", ->
|
||||
# $(".fixbutton-burger").stop().animate({"scale": 1, "left": 0}, 600, "easeOutElastic")
|
||||
|
||||
|
||||
|
||||
window.Fixbutton = Fixbutton
|
|
@ -1,57 +0,0 @@
|
|||
class Infopanel
|
||||
constructor: (@elem) ->
|
||||
@visible = false
|
||||
|
||||
show: (closed=false) =>
|
||||
@elem.parent().addClass("visible")
|
||||
if closed
|
||||
@close()
|
||||
else
|
||||
@open()
|
||||
|
||||
unfold: =>
|
||||
@elem.toggleClass("unfolded")
|
||||
return false
|
||||
|
||||
updateEvents: =>
|
||||
@elem.off("click")
|
||||
@elem.find(".close").off("click")
|
||||
@elem.find(".line").off("click")
|
||||
|
||||
@elem.find(".line").on("click", @unfold)
|
||||
|
||||
if @elem.hasClass("closed")
|
||||
@elem.on "click", =>
|
||||
@onOpened()
|
||||
@open()
|
||||
else
|
||||
@elem.find(".close").on "click", =>
|
||||
@onClosed()
|
||||
@close()
|
||||
|
||||
hide: =>
|
||||
@elem.parent().removeClass("visible")
|
||||
|
||||
close: =>
|
||||
@elem.addClass("closed")
|
||||
@updateEvents()
|
||||
return false
|
||||
|
||||
open: =>
|
||||
@elem.removeClass("closed")
|
||||
@updateEvents()
|
||||
return false
|
||||
|
||||
setTitle: (line1, line2) =>
|
||||
@elem.find(".line-1").text(line1)
|
||||
@elem.find(".line-2").text(line2)
|
||||
|
||||
setClosedNum: (num) =>
|
||||
@elem.find(".closed-num").text(num)
|
||||
|
||||
setAction: (title, func) =>
|
||||
@elem.find(".button").text(title).off("click").on("click", func)
|
||||
|
||||
|
||||
|
||||
window.Infopanel = Infopanel
|
|
@ -1,91 +0,0 @@
|
|||
class Loading
|
||||
constructor: (@wrapper) ->
|
||||
if window.show_loadingscreen then @showScreen()
|
||||
@timer_hide = null
|
||||
@timer_set = null
|
||||
|
||||
setProgress: (percent) ->
|
||||
if @timer_hide
|
||||
clearInterval @timer_hide
|
||||
@timer_set = RateLimit 500, ->
|
||||
$(".progressbar").css("transform": "scaleX(#{parseInt(percent*100)/100})").css("opacity", "1").css("display", "block")
|
||||
|
||||
hideProgress: ->
|
||||
@log "hideProgress"
|
||||
if @timer_set
|
||||
clearInterval @timer_set
|
||||
@timer_hide = setTimeout ( =>
|
||||
$(".progressbar").css("transform": "scaleX(1)").css("opacity", "0").hideLater(1000)
|
||||
), 300
|
||||
|
||||
|
||||
showScreen: ->
|
||||
$(".loadingscreen").css("display", "block").addClassLater("ready")
|
||||
@screen_visible = true
|
||||
@printLine " Connecting..."
|
||||
|
||||
|
||||
showTooLarge: (site_info) ->
|
||||
@log "Displaying large site confirmation"
|
||||
if $(".console .button-setlimit").length == 0 # Not displaying it yet
|
||||
line = @printLine("Site size: <b>#{parseInt(site_info.settings.size/1024/1024)}MB</b> is larger than default allowed #{parseInt(site_info.size_limit)}MB", "warning")
|
||||
button = $("<a href='#Set+limit' class='button button-setlimit'>" + "Open site and set size limit to #{site_info.next_size_limit}MB" + "</a>")
|
||||
button.on "click", =>
|
||||
button.addClass("loading")
|
||||
return @wrapper.setSizeLimit(site_info.next_size_limit)
|
||||
line.after(button)
|
||||
setTimeout (=>
|
||||
@printLine('Ready.')
|
||||
), 100
|
||||
|
||||
showTrackerTorBridge: (server_info) ->
|
||||
if $(".console .button-settrackerbridge").length == 0 and not server_info.tor_use_meek_bridges
|
||||
line = @printLine("Tracker connection error detected.", "error")
|
||||
button = $("<a href='#Enable+Tor+bridges' class='button button-settrackerbridge'>" + "Use Tor meek bridges for tracker connections" + "</a>")
|
||||
button.on "click", =>
|
||||
button.addClass("loading")
|
||||
@wrapper.ws.cmd "configSet", ["tor_use_bridges", ""]
|
||||
@wrapper.ws.cmd "configSet", ["trackers_proxy", "tor"]
|
||||
@wrapper.ws.cmd "siteUpdate", {address: @wrapper.site_info.address, announce: true}
|
||||
@wrapper.reloadIframe()
|
||||
return false
|
||||
line.after(button)
|
||||
if not server_info.tor_has_meek_bridges
|
||||
button.addClass("disabled")
|
||||
@printLine("No meek bridge support in your client, please <a href='https://github.com/HelloZeroNet/ZeroNet#how-to-join'>download the latest bundle</a>.", "warning")
|
||||
|
||||
# We dont need loadingscreen anymore
|
||||
hideScreen: ->
|
||||
@log "hideScreen"
|
||||
if not $(".loadingscreen").hasClass("done") # Only if its not animating already
|
||||
if @screen_visible # Hide with animate
|
||||
$(".loadingscreen").addClass("done").removeLater(2000)
|
||||
else # Not visible, just remove
|
||||
$(".loadingscreen").remove()
|
||||
@screen_visible = false
|
||||
|
||||
|
||||
# Append text to last line of loadingscreen
|
||||
print: (text, type="normal") ->
|
||||
if not @screen_visible then return false
|
||||
$(".loadingscreen .console .cursor").remove() # Remove previous cursor
|
||||
last_line = $(".loadingscreen .console .console-line:last-child")
|
||||
if type == "error" then text = "<span class='console-error'>#{text}</span>"
|
||||
last_line.html(last_line.html()+text)
|
||||
|
||||
|
||||
# Add line to loading screen
|
||||
printLine: (text, type="normal") ->
|
||||
if not @screen_visible then return false
|
||||
$(".loadingscreen .console .cursor").remove() # Remove previous cursor
|
||||
if type == "error" then text = "<span class='console-error'>#{text}</span>" else text = text+"<span class='cursor'> </span>"
|
||||
|
||||
line = $("<div class='console-line'>#{text}</div>").appendTo(".loadingscreen .console")
|
||||
if type == "warning" then line.addClass("console-warning")
|
||||
return line
|
||||
|
||||
log: (args...) ->
|
||||
console.log "[Loading]", args...
|
||||
|
||||
|
||||
window.Loading = Loading
|
|
@ -1,89 +0,0 @@
|
|||
class Notifications
|
||||
constructor: (@elem) ->
|
||||
@
|
||||
|
||||
test: ->
|
||||
setTimeout (=>
|
||||
@add("connection", "error", "Connection lost to <b>UiServer</b> on <b>localhost</b>!")
|
||||
@add("message-Anyone", "info", "New from <b>Anyone</b>.")
|
||||
), 1000
|
||||
setTimeout (=>
|
||||
@add("connection", "done", "<b>UiServer</b> connection recovered.", 5000)
|
||||
), 3000
|
||||
|
||||
|
||||
add: (id, type, body, timeout=0) ->
|
||||
id = id.replace /[^A-Za-z0-9-]/g, ""
|
||||
# Close notifications with same id
|
||||
for elem in $(".notification-#{id}")
|
||||
@close $(elem)
|
||||
|
||||
# Create element
|
||||
elem = $(".notification.template", @elem).clone().removeClass("template")
|
||||
elem.addClass("notification-#{type}").addClass("notification-#{id}")
|
||||
if type == "progress"
|
||||
elem.addClass("notification-done")
|
||||
|
||||
# Update text
|
||||
if type == "error"
|
||||
$(".notification-icon", elem).html("!")
|
||||
else if type == "done"
|
||||
$(".notification-icon", elem).html("<div class='icon-success'></div>")
|
||||
else if type == "progress"
|
||||
$(".notification-icon", elem).html("<div class='icon-success'></div>")
|
||||
else if type == "ask"
|
||||
$(".notification-icon", elem).html("?")
|
||||
else
|
||||
$(".notification-icon", elem).html("i")
|
||||
|
||||
if typeof(body) == "string"
|
||||
$(".body", elem).html("<div class='message'><span class='multiline'>"+body+"</span></div>")
|
||||
else
|
||||
$(".body", elem).html("").append(body)
|
||||
|
||||
elem.appendTo(@elem)
|
||||
|
||||
# Timeout
|
||||
if timeout
|
||||
$(".close", elem).remove() # No need of close button
|
||||
setTimeout (=>
|
||||
@close elem
|
||||
), timeout
|
||||
|
||||
# Animate
|
||||
width = Math.min(elem.outerWidth() + 50, 580)
|
||||
if not timeout then width += 20 # Add space for close button
|
||||
if elem.outerHeight() > 55 then elem.addClass("long")
|
||||
elem.css({"width": "50px", "transform": "scale(0.01)"})
|
||||
elem.animate({"scale": 1}, 800, "easeOutElastic")
|
||||
elem.animate({"width": width}, 700, "easeInOutCubic")
|
||||
$(".body", elem).css("width": (width - 50))
|
||||
$(".body", elem).cssLater("box-shadow", "0px 0px 5px rgba(0,0,0,0.1)", 1000)
|
||||
|
||||
# Close button or Confirm button
|
||||
$(".close, .button", elem).on "click", =>
|
||||
@close elem
|
||||
return false
|
||||
|
||||
# Select list
|
||||
$(".select", elem).on "click", =>
|
||||
@close elem
|
||||
|
||||
# Input enter
|
||||
$("input", elem).on "keyup", (e) =>
|
||||
if e.keyCode == 13
|
||||
@close elem
|
||||
|
||||
return elem
|
||||
|
||||
|
||||
close: (elem) ->
|
||||
elem.stop().animate {"width": 0, "opacity": 0}, 700, "easeInOutCubic"
|
||||
elem.slideUp 300, (-> elem.remove())
|
||||
|
||||
|
||||
log: (args...) ->
|
||||
console.log "[Notifications]", args...
|
||||
|
||||
|
||||
window.Notifications = Notifications
|
|
@ -1,714 +0,0 @@
|
|||
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 = $("<script>")
|
||||
script_tag.attr("nonce", @script_nonce)
|
||||
script_tag.html(message.params)
|
||||
document.head.appendChild(script_tag[0])
|
||||
else
|
||||
@sendInner message # Pass message to inner frame
|
||||
|
||||
# Incoming message from inner frame
|
||||
onMessageInner: (e) =>
|
||||
# No nonce security enabled, test if window opener present
|
||||
if not window.postmessage_nonce_security and @opener_tested == false
|
||||
if window.opener and window.opener != window
|
||||
@log "Opener present", window.opener
|
||||
@displayOpenerDialog()
|
||||
return false
|
||||
else
|
||||
@opener_tested = true
|
||||
|
||||
message = e.data
|
||||
# Invalid message (probably not for us)
|
||||
if not message.cmd
|
||||
@log "Invalid message:", message
|
||||
return false
|
||||
|
||||
# Test nonce security to avoid third-party messages
|
||||
if window.postmessage_nonce_security and message.wrapper_nonce != window.wrapper_nonce
|
||||
@log "Message nonce error:", message.wrapper_nonce, '!=', window.wrapper_nonce
|
||||
return
|
||||
|
||||
@handleMessage message
|
||||
|
||||
cmd: (cmd, params={}, cb=null) =>
|
||||
message = {}
|
||||
message.cmd = cmd
|
||||
message.params = params
|
||||
message.id = @next_cmd_message_id
|
||||
if cb
|
||||
@ws.waiting_cb[message.id] = cb
|
||||
@next_cmd_message_id -= 1
|
||||
|
||||
@handleMessage(message)
|
||||
|
||||
handleMessage: (message) =>
|
||||
cmd = message.cmd
|
||||
if cmd == "innerReady"
|
||||
@inner_ready = true
|
||||
if @ws.ws.readyState == 1 and not @wrapperWsInited # If ws already opened
|
||||
@sendInner {"cmd": "wrapperOpenedWebsocket"}
|
||||
@wrapperWsInited = true
|
||||
else if cmd == "innerLoaded" or cmd == "wrapperInnerLoaded"
|
||||
if window.location.hash
|
||||
$("#inner-iframe")[0].src += window.location.hash # Hash tag
|
||||
@log "Added hash to location", $("#inner-iframe")[0].src
|
||||
else if cmd == "wrapperNotification" # Display notification
|
||||
@actionNotification(message)
|
||||
else if cmd == "wrapperConfirm" # Display confirm message
|
||||
@actionConfirm(message)
|
||||
else if cmd == "wrapperPrompt" # Prompt input
|
||||
@actionPrompt(message)
|
||||
else if cmd == "wrapperProgress" # Progress bar
|
||||
@actionProgress(message)
|
||||
else if cmd == "wrapperSetViewport" # Set the viewport
|
||||
@actionSetViewport(message)
|
||||
else if cmd == "wrapperSetTitle"
|
||||
@log "wrapperSetTitle", message.params
|
||||
$("head title").text(message.params)
|
||||
@is_title_changed = true
|
||||
else if cmd == "wrapperReload" # Reload current page
|
||||
@actionReload(message)
|
||||
else if cmd == "wrapperGetLocalStorage"
|
||||
@actionGetLocalStorage(message)
|
||||
else if cmd == "wrapperSetLocalStorage"
|
||||
@actionSetLocalStorage(message)
|
||||
else if cmd == "wrapperPushState"
|
||||
query = @toRelativeQuery(message.params[2])
|
||||
window.history.pushState(message.params[0], message.params[1], query)
|
||||
else if cmd == "wrapperReplaceState"
|
||||
query = @toRelativeQuery(message.params[2])
|
||||
window.history.replaceState(message.params[0], message.params[1], query)
|
||||
else if cmd == "wrapperGetState"
|
||||
@sendInner {"cmd": "response", "to": message.id, "result": window.history.state}
|
||||
else if cmd == "wrapperGetAjaxKey"
|
||||
@sendInner {"cmd": "response", "to": message.id, "result": window.ajax_key}
|
||||
else if cmd == "wrapperOpenWindow"
|
||||
@actionOpenWindow(message.params)
|
||||
else if cmd == "wrapperPermissionAdd"
|
||||
@actionPermissionAdd(message)
|
||||
else if cmd == "wrapperRequestFullscreen"
|
||||
@actionRequestFullscreen()
|
||||
else if cmd == "wrapperWebNotification"
|
||||
@actionWebNotification(message)
|
||||
else if cmd == "wrapperCloseWebNotification"
|
||||
@actionCloseWebNotification(message)
|
||||
else # Send to websocket
|
||||
if message.id < 1000000
|
||||
if message.cmd == "fileWrite" and not @modified_panel_updater_timer and site_info?.settings?.own
|
||||
@modified_panel_updater_timer = setTimeout ( => @updateModifiedPanel(); @modified_panel_updater_timer = null ), 1000
|
||||
@ws.send(message) # Pass message to websocket
|
||||
else
|
||||
@log "Invalid inner message id"
|
||||
|
||||
toRelativeQuery: (query=null) ->
|
||||
if query == null
|
||||
query = window.location.search
|
||||
back = window.location.pathname
|
||||
if back.match /^\/[^\/]+$/ # Add / after site address if called without it
|
||||
back += "/"
|
||||
if query.startsWith("#")
|
||||
back = query
|
||||
else if query.replace("?", "")
|
||||
back += "?"+query.replace("?", "")
|
||||
return back
|
||||
|
||||
|
||||
displayOpenerDialog: ->
|
||||
elem = $("<div class='opener-overlay'><div class='dialog'>You have opened this page by clicking on a link. Please, confirm if you want to load this site.<a href='?' target='_blank' class='button'>Open site</a></div></div>")
|
||||
elem.find('a').on "click", ->
|
||||
window.open("?", "_blank")
|
||||
window.close()
|
||||
return false
|
||||
$("body").prepend(elem)
|
||||
|
||||
# - Actions -
|
||||
|
||||
actionOpenWindow: (params) ->
|
||||
if typeof(params) == "string"
|
||||
w = window.open()
|
||||
w.opener = null
|
||||
w.location = params
|
||||
else
|
||||
w = window.open(null, params[1], params[2])
|
||||
w.opener = null
|
||||
w.location = params[0]
|
||||
|
||||
actionRequestFullscreen: ->
|
||||
elem = document.getElementById("inner-iframe")
|
||||
request_fullscreen = elem.requestFullScreen || elem.webkitRequestFullscreen || elem.mozRequestFullScreen || elem.msRequestFullScreen
|
||||
request_fullscreen.call(elem)
|
||||
|
||||
actionWebNotification: (message) ->
|
||||
$.when(@event_site_info).done =>
|
||||
# Check that the wrapper may send notifications
|
||||
if Notification.permission == "granted"
|
||||
@displayWebNotification message
|
||||
else if Notification.permission == "denied"
|
||||
res = {"error": "Web notifications are disabled by the user"}
|
||||
@sendInner {"cmd": "response", "to": message.id, "result": res}
|
||||
else
|
||||
Notification.requestPermission().then (permission) =>
|
||||
if permission == "granted"
|
||||
@displayWebNotification message
|
||||
|
||||
actionCloseWebNotification: (message) ->
|
||||
$.when(@event_site_info).done =>
|
||||
id = message.params[0]
|
||||
@web_notifications[id].close()
|
||||
|
||||
displayWebNotification: (message) ->
|
||||
title = message.params[0]
|
||||
id = message.params[1]
|
||||
options = message.params[2]
|
||||
notification = new Notification(title, options)
|
||||
@web_notifications[id] = notification
|
||||
notification.onshow = () =>
|
||||
@sendInner {"cmd": "response", "to": message.id, "result": "ok"}
|
||||
notification.onclick = (e) =>
|
||||
if not options.focus_tab
|
||||
e.preventDefault()
|
||||
@sendInner {"cmd": "webNotificationClick", "params": {"id": id}}
|
||||
notification.onclose = () =>
|
||||
@sendInner {"cmd": "webNotificationClose", "params": {"id": id}}
|
||||
delete @web_notifications[id]
|
||||
|
||||
actionPermissionAdd: (message) ->
|
||||
permission = message.params
|
||||
$.when(@event_site_info).done =>
|
||||
if permission in @site_info.settings.permissions
|
||||
return false
|
||||
@ws.cmd "permissionDetails", permission, (permission_details) =>
|
||||
@displayConfirm "This site requests permission:" + " <b>#{@toHtmlSafe(permission)}</b>" + "<br><small style='color: #4F4F4F'>#{permission_details}</small>", "Grant", =>
|
||||
@ws.cmd "permissionAdd", permission, (res) =>
|
||||
@sendInner {"cmd": "response", "to": message.id, "result": res}
|
||||
|
||||
actionNotification: (message) ->
|
||||
message.params = @toHtmlSafe(message.params) # Escape html
|
||||
body = $("<span class='message'>"+message.params[1]+"</span>")
|
||||
@notifications.add("notification-#{message.id}", message.params[0], body, message.params[2])
|
||||
|
||||
displayConfirm: (body, captions, cb) ->
|
||||
body = $("<span class='message-outer'><span class='message'>"+body+"</span></span>")
|
||||
buttons = $("<span class='buttons'></span>")
|
||||
if captions not instanceof Array then captions = [captions] # Convert to list if necessary
|
||||
for caption, i in captions
|
||||
button = $("<a></a>", {href: "#" + caption, class: "button button-confirm button-#{caption} button-#{i+1}", "data-value": i + 1}) # Add confirm button
|
||||
button.text(caption)
|
||||
((button) =>
|
||||
button.on "click", (e) =>
|
||||
@verifyEvent button, e
|
||||
cb(parseInt(e.currentTarget.dataset.value))
|
||||
return false
|
||||
)(button)
|
||||
buttons.append(button)
|
||||
body.append(buttons)
|
||||
@notifications.add("notification-#{caption}", "ask", body)
|
||||
|
||||
buttons.first().focus()
|
||||
$(".notification").scrollLeft(0)
|
||||
|
||||
|
||||
actionConfirm: (message, cb=false) ->
|
||||
message.params = @toHtmlSafe(message.params) # Escape html
|
||||
if message.params[1] then caption = message.params[1] else caption = "ok"
|
||||
@displayConfirm message.params[0], caption, (res) =>
|
||||
@sendInner {"cmd": "response", "to": message.id, "result": res} # Response to confirm
|
||||
return false
|
||||
|
||||
|
||||
displayPrompt: (message, type, caption, placeholder, cb) ->
|
||||
body = $("<span class='message'></span>").html(message)
|
||||
placeholder ?= ""
|
||||
|
||||
input = $("<input/>", {type: type, class: "input button-#{type}", placeholder: placeholder}) # Add input
|
||||
input.on "keyup", (e) => # Send on enter
|
||||
@verifyEvent input, e
|
||||
if e.keyCode == 13
|
||||
cb input.val() # Response to confirm
|
||||
body.append(input)
|
||||
|
||||
button = $("<a></a>", {href: "#" + caption, class: "button button-#{caption}"}).text(caption) # Add confirm button
|
||||
button.on "click", (e) => # Response on button click
|
||||
@verifyEvent button, e
|
||||
cb input.val()
|
||||
return false
|
||||
body.append(button)
|
||||
|
||||
@notifications.add("notification-#{message.id}", "ask", body)
|
||||
|
||||
input.focus()
|
||||
$(".notification").scrollLeft(0)
|
||||
|
||||
|
||||
actionPrompt: (message) ->
|
||||
message.params = @toHtmlSafe(message.params) # Escape html
|
||||
if message.params[1] then type = message.params[1] else type = "text"
|
||||
caption = if message.params[2] then message.params[2] else "OK"
|
||||
if message.params[3]?
|
||||
placeholder = message.params[3]
|
||||
else
|
||||
placeholder = ""
|
||||
|
||||
@displayPrompt message.params[0], type, caption, placeholder, (res) =>
|
||||
@sendInner {"cmd": "response", "to": message.id, "result": res} # Response to confirm
|
||||
|
||||
displayProgress: (type, body, percent) ->
|
||||
percent = Math.min(100, percent)/100
|
||||
offset = 75-(percent*75)
|
||||
circle = """
|
||||
<div class="circle"><svg class="circle-svg" width="30" height="30" viewport="0 0 30 30" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle r="12" cx="15" cy="15" fill="transparent" class="circle-bg"></circle>
|
||||
<circle r="12" cx="15" cy="15" fill="transparent" class="circle-fg" style="stroke-dashoffset: #{offset}"></circle>
|
||||
</svg></div>
|
||||
"""
|
||||
body = "<span class='message'>"+body+"</span>" + circle
|
||||
elem = $(".notification-#{type}")
|
||||
if elem.length
|
||||
width = $(".body .message", elem).outerWidth()
|
||||
$(".body .message", elem).html(body)
|
||||
if $(".body .message", elem).css("width") == ""
|
||||
$(".body .message", elem).css("width", width)
|
||||
$(".body .circle-fg", elem).css("stroke-dashoffset", offset)
|
||||
else
|
||||
elem = @notifications.add(type, "progress", $(body))
|
||||
if percent > 0
|
||||
$(".body .circle-bg", elem).css {"animation-play-state": "paused", "stroke-dasharray": "180px"}
|
||||
|
||||
if $(".notification-icon", elem).data("done")
|
||||
return false
|
||||
else if percent >= 1 # Done
|
||||
$(".circle-fg", elem).css("transition", "all 0.3s ease-in-out")
|
||||
setTimeout (->
|
||||
$(".notification-icon", elem).css {transform: "scale(1)", opacity: 1}
|
||||
$(".notification-icon .icon-success", elem).css {transform: "rotate(45deg) scale(1)"}
|
||||
), 300
|
||||
setTimeout (=>
|
||||
@notifications.close elem
|
||||
), 3000
|
||||
$(".notification-icon", elem).data("done", true)
|
||||
else if percent < 0 # Error
|
||||
$(".body .circle-fg", elem).css("stroke", "#ec6f47").css("transition", "transition: all 0.3s ease-in-out")
|
||||
setTimeout (=>
|
||||
$(".notification-icon", elem).css {transform: "scale(1)", opacity: 1}
|
||||
elem.removeClass("notification-done").addClass("notification-error")
|
||||
$(".notification-icon .icon-success", elem).removeClass("icon-success").html("!")
|
||||
), 300
|
||||
$(".notification-icon", elem).data("done", true)
|
||||
|
||||
|
||||
actionProgress: (message) ->
|
||||
message.params = @toHtmlSafe(message.params) # Escape html
|
||||
@displayProgress(message.params[0], message.params[1], message.params[2])
|
||||
|
||||
actionSetViewport: (message) ->
|
||||
@log "actionSetViewport", message
|
||||
if $("#viewport").length > 0
|
||||
$("#viewport").attr("content", @toHtmlSafe message.params)
|
||||
else
|
||||
$('<meta name="viewport" id="viewport">').attr("content", @toHtmlSafe message.params).appendTo("head")
|
||||
|
||||
actionReload: (message) ->
|
||||
@reload(message.params[0])
|
||||
|
||||
reload: (url_post="") ->
|
||||
@log "Reload"
|
||||
current_url = window.location.toString().replace(/#.*/g, "")
|
||||
if url_post
|
||||
if current_url.indexOf("?") > 0
|
||||
window.location = current_url + "&" + url_post
|
||||
else
|
||||
window.location = current_url + "?" + url_post
|
||||
else
|
||||
window.location.reload()
|
||||
|
||||
|
||||
actionGetLocalStorage: (message) ->
|
||||
$.when(@event_site_info).done =>
|
||||
data = localStorage.getItem "site.#{@site_info.address}.#{@site_info.auth_address}"
|
||||
if not data # Migrate from non auth_address based local storage
|
||||
data = localStorage.getItem "site.#{@site_info.address}"
|
||||
if data
|
||||
localStorage.setItem "site.#{@site_info.address}.#{@site_info.auth_address}", data
|
||||
localStorage.removeItem "site.#{@site_info.address}"
|
||||
@log "Migrated LocalStorage from global to auth_address based"
|
||||
if data then data = JSON.parse(data)
|
||||
@sendInner {"cmd": "response", "to": message.id, "result": data}
|
||||
|
||||
|
||||
actionSetLocalStorage: (message) ->
|
||||
$.when(@event_site_info).done =>
|
||||
back = localStorage.setItem "site.#{@site_info.address}.#{@site_info.auth_address}", JSON.stringify(message.params)
|
||||
@sendInner {"cmd": "response", "to": message.id, "result": back}
|
||||
|
||||
|
||||
# EOF actions
|
||||
|
||||
|
||||
onOpenWebsocket: (e) =>
|
||||
if window.show_loadingscreen # Get info on modifications
|
||||
@ws.cmd "channelJoin", {"channels": ["siteChanged", "serverChanged", "announcerChanged"]}
|
||||
else
|
||||
@ws.cmd "channelJoin", {"channels": ["siteChanged", "serverChanged"]}
|
||||
if not @wrapperWsInited and @inner_ready
|
||||
@sendInner {"cmd": "wrapperOpenedWebsocket"} # Send to inner frame
|
||||
@wrapperWsInited = true
|
||||
if window.show_loadingscreen
|
||||
@ws.cmd "serverInfo", [], (server_info) =>
|
||||
@server_info = server_info
|
||||
|
||||
@ws.cmd "announcerInfo", [], (announcer_info) =>
|
||||
@setAnnouncerInfo(announcer_info)
|
||||
|
||||
if @inner_loaded # Update site info
|
||||
@reloadSiteInfo()
|
||||
|
||||
# If inner frame not loaded for 2 sec show peer informations on loading screen by loading site info
|
||||
setTimeout (=>
|
||||
if not @site_info then @reloadSiteInfo()
|
||||
), 2000
|
||||
|
||||
if @ws_error
|
||||
@notifications.add("connection", "done", "Connection with <b>UiServer Websocket</b> recovered.", 6000)
|
||||
@ws_error = null
|
||||
|
||||
|
||||
onCloseWebsocket: (e) =>
|
||||
@wrapperWsInited = false
|
||||
setTimeout (=> # Wait a bit, maybe its page closing
|
||||
@sendInner {"cmd": "wrapperClosedWebsocket"} # Send to inner frame
|
||||
if e and e.code == 1000 and e.wasClean == false # Server error please reload page
|
||||
@ws_error = @notifications.add("connection", "error", "UiServer Websocket error, please reload the page.")
|
||||
else if e and e.code == 1001 and e.wasClean == true # Navigating to other page
|
||||
return
|
||||
else if not @ws_error
|
||||
@ws_error = @notifications.add("connection", "error", "Connection with <b>UiServer Websocket</b> was lost. Reconnecting...")
|
||||
), 1000
|
||||
|
||||
|
||||
# Iframe loaded
|
||||
onPageLoad: (e) =>
|
||||
@log "onPageLoad"
|
||||
@inner_loaded = true
|
||||
if not @inner_ready then @sendInner {"cmd": "wrapperReady"} # Inner frame loaded before wrapper
|
||||
#if not @site_error then @loading.hideScreen() # Hide loading screen
|
||||
if @ws.ws.readyState == 1 and not @site_info # Ws opened
|
||||
@reloadSiteInfo()
|
||||
else if @site_info and @site_info.content?.title? and not @is_title_changed
|
||||
window.document.title = @site_info.content.title + " - ZeroNet"
|
||||
@log "Setting title to", window.document.title
|
||||
|
||||
onWrapperLoad: =>
|
||||
@script_nonce = window.script_nonce
|
||||
@wrapper_key = window.wrapper_key
|
||||
# Cleanup secret variables
|
||||
delete window.wrapper
|
||||
delete window.wrapper_key
|
||||
delete window.script_nonce
|
||||
$("#script_init").remove()
|
||||
|
||||
# Send message to innerframe
|
||||
sendInner: (message) ->
|
||||
@inner.postMessage(message, '*')
|
||||
|
||||
|
||||
# Get site info from UiServer
|
||||
reloadSiteInfo: ->
|
||||
if @loading.screen_visible # Loading screen visible
|
||||
params = {"file_status": window.file_inner_path} # Query the current required file status
|
||||
else
|
||||
params = {}
|
||||
|
||||
@ws.cmd "siteInfo", params, (site_info) =>
|
||||
@address = site_info.address
|
||||
@setSiteInfo site_info
|
||||
|
||||
if site_info.settings.size > site_info.size_limit * 1024 * 1024 and not @loading.screen_visible # Site size too large and not displaying it yet
|
||||
@displayConfirm "Site is larger than allowed: #{(site_info.settings.size/1024/1024).toFixed(1)}MB/#{site_info.size_limit}MB", "Set limit to #{site_info.next_size_limit}MB", =>
|
||||
@ws.cmd "siteSetLimit", [site_info.next_size_limit], (res) =>
|
||||
if res == "ok"
|
||||
@notifications.add("size_limit", "done", "Site storage limit modified!", 5000)
|
||||
|
||||
if site_info.content?.title? and not @is_title_changed
|
||||
window.document.title = site_info.content.title + " - ZeroNet"
|
||||
@log "Setting title to", window.document.title
|
||||
|
||||
|
||||
# Got setSiteInfo from websocket UiServer
|
||||
setSiteInfo: (site_info) ->
|
||||
if site_info.event? # If loading screen visible add event to it
|
||||
# File started downloading
|
||||
if site_info.event[0] == "file_added" and site_info.bad_files
|
||||
@loading.printLine("#{site_info.bad_files} files needs to be downloaded")
|
||||
# File finished downloading
|
||||
else if site_info.event[0] == "file_done"
|
||||
@loading.printLine("#{site_info.event[1]} downloaded")
|
||||
if site_info.event[1] == window.file_inner_path # File downloaded we currently on
|
||||
@loading.hideScreen()
|
||||
if not @site_info then @reloadSiteInfo()
|
||||
if site_info.content and not @is_title_changed
|
||||
window.document.title = site_info.content.title + " - ZeroNet"
|
||||
@log "Required file #{window.file_inner_path} done, setting title to", window.document.title
|
||||
if not window.show_loadingscreen
|
||||
@notifications.add("modified", "info", "New version of this page has just released.<br>Reload to see the modified content.")
|
||||
# File failed downloading
|
||||
else if site_info.event[0] == "file_failed"
|
||||
@site_error = site_info.event[1]
|
||||
if site_info.settings.size > site_info.size_limit*1024*1024 # Site size too large and not displaying it yet
|
||||
@loading.showTooLarge(site_info)
|
||||
|
||||
else
|
||||
@loading.printLine("#{site_info.event[1]} download failed", "error")
|
||||
# New peers found
|
||||
else if site_info.event[0] == "peers_added"
|
||||
@loading.printLine("Peers found: #{site_info.peers}")
|
||||
|
||||
if @loading.screen_visible and not @site_info # First site info display current peers
|
||||
if site_info.peers > 1
|
||||
@loading.printLine "Peers found: #{site_info.peers}"
|
||||
else
|
||||
@site_error = "No peers found"
|
||||
@loading.printLine "No peers found"
|
||||
|
||||
if not @site_info and not @loading.screen_visible and $("#inner-iframe").attr("src").replace("?wrapper=False", "").replace(/\?wrapper_nonce=[A-Za-z0-9]+/, "").indexOf("?") == -1 # First site info and we are on mainpage (does not have other parameter thatn wrapper)
|
||||
if site_info.size_limit*1.1 < site_info.next_size_limit # Need upgrade soon
|
||||
@displayConfirm "Running out of size limit (#{(site_info.settings.size/1024/1024).toFixed(1)}MB/#{site_info.size_limit}MB)", "Set limit to #{site_info.next_size_limit}MB", =>
|
||||
@ws.cmd "siteSetLimit", [site_info.next_size_limit], (res) =>
|
||||
if res == "ok"
|
||||
@notifications.add("size_limit", "done", "Site storage limit modified!", 5000)
|
||||
return false
|
||||
|
||||
if @loading.screen_visible and @inner_loaded and site_info.settings.size < site_info.size_limit * 1024 * 1024 and site_info.settings.size > 0 # Loading screen still visible, but inner loaded
|
||||
@log "Loading screen visible, but inner loaded"
|
||||
@loading.hideScreen()
|
||||
|
||||
if site_info?.settings?.own and site_info?.settings?.modified != @site_info?.settings?.modified
|
||||
@updateModifiedPanel()
|
||||
|
||||
if @loading.screen_visible and site_info.settings.size > site_info.size_limit * 1024 * 1024
|
||||
@log "Site too large"
|
||||
@loading.showTooLarge(site_info)
|
||||
|
||||
@site_info = site_info
|
||||
@event_site_info.resolve()
|
||||
|
||||
siteSign: (inner_path, cb) =>
|
||||
if @site_info.privatekey
|
||||
# Privatekey stored in users.json
|
||||
@infopanel.elem.find(".button").addClass("loading")
|
||||
@ws.cmd "siteSign", {privatekey: "stored", inner_path: inner_path, update_changed_files: true}, (res) =>
|
||||
if res == "ok"
|
||||
cb?(true)
|
||||
else
|
||||
cb?(false)
|
||||
@infopanel.elem.find(".button").removeClass("loading")
|
||||
else
|
||||
# Ask the user for privatekey
|
||||
@displayPrompt "Enter your private key:", "password", "Sign", "", (privatekey) => # Prompt the private key
|
||||
@infopanel.elem.find(".button").addClass("loading")
|
||||
@ws.cmd "siteSign", {privatekey: privatekey, inner_path: inner_path, update_changed_files: true}, (res) =>
|
||||
if res == "ok"
|
||||
cb?(true)
|
||||
else
|
||||
cb?(false)
|
||||
@infopanel.elem.find(".button").removeClass("loading")
|
||||
|
||||
sitePublish: (inner_path) =>
|
||||
@ws.cmd "sitePublish", {"inner_path": inner_path, "sign": false}
|
||||
|
||||
updateModifiedPanel: =>
|
||||
@ws.cmd "siteListModifiedFiles", [], (res) =>
|
||||
num = res.modified_files?.length
|
||||
if num > 0
|
||||
closed = @site_info.settings.modified_files_notification == false
|
||||
@infopanel.show(closed)
|
||||
else
|
||||
@infopanel.hide()
|
||||
|
||||
if num > 0
|
||||
@infopanel.setTitle(
|
||||
"#{res.modified_files.length} modified file#{if num > 1 then 's' else ''}",
|
||||
res.modified_files.join(", ")
|
||||
)
|
||||
@infopanel.setClosedNum(num)
|
||||
@infopanel.setAction "Sign & Publish", =>
|
||||
@siteSign "content.json", (res) =>
|
||||
if (res)
|
||||
@notifications.add "sign", "done", "content.json Signed!", 5000
|
||||
@sitePublish("content.json")
|
||||
return false
|
||||
@log "siteListModifiedFiles", num, res
|
||||
|
||||
setAnnouncerInfo: (announcer_info) ->
|
||||
status_db = {announcing: [], error: [], announced: []}
|
||||
for key, val of announcer_info.stats
|
||||
if val.status
|
||||
status_db[val.status].push(val)
|
||||
status_line = "Trackers announcing: #{status_db.announcing.length}, error: #{status_db.error.length}, done: #{status_db.announced.length}"
|
||||
if @announcer_line
|
||||
@announcer_line.text(status_line)
|
||||
else
|
||||
@announcer_line = @loading.printLine(status_line)
|
||||
|
||||
if status_db.error.length > (status_db.announced.length + status_db.announcing.length) and status_db.announced.length < 3
|
||||
@loading.showTrackerTorBridge(@server_info)
|
||||
|
||||
updateProgress: (site_info) ->
|
||||
if site_info.tasks > 0 and site_info.started_task_num > 0
|
||||
@loading.setProgress 1-(Math.max(site_info.tasks, site_info.bad_files) / site_info.started_task_num)
|
||||
else
|
||||
@loading.hideProgress()
|
||||
|
||||
|
||||
toHtmlSafe: (values) ->
|
||||
if values not instanceof Array then values = [values] # Convert to array if its not
|
||||
for value, i in values
|
||||
if value instanceof Array
|
||||
value = @toHtmlSafe(value)
|
||||
else
|
||||
value = String(value).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''') # Escape dangerous characters
|
||||
value = value.replace(/<([\/]{0,1}(br|b|u|i|small))>/g, "<$1>") # Unescape b, i, u, br tags
|
||||
values[i] = value
|
||||
return values
|
||||
|
||||
|
||||
setSizeLimit: (size_limit, reload=true) =>
|
||||
@log "setSizeLimit: #{size_limit}, reload: #{reload}"
|
||||
@inner_loaded = false # Inner frame not loaded, just a 404 page displayed
|
||||
@ws.cmd "siteSetLimit", [size_limit], (res) =>
|
||||
if res != "ok"
|
||||
return false
|
||||
@loading.printLine res
|
||||
@inner_loaded = false
|
||||
if reload then @reloadIframe()
|
||||
return false
|
||||
|
||||
reloadIframe: =>
|
||||
src = $("iframe").attr("src")
|
||||
@ws.cmd "serverGetWrapperNonce", [], (wrapper_nonce) =>
|
||||
src = src.replace(/wrapper_nonce=[A-Za-z0-9]+/, "wrapper_nonce=" + wrapper_nonce)
|
||||
@log "Reloading iframe using url", src
|
||||
$("iframe").attr "src", src
|
||||
|
||||
log: (args...) ->
|
||||
console.log "[Wrapper]", args...
|
||||
|
||||
origin = window.server_url or window.location.href.replace(/(\:\/\/.*?)\/.*/, "$1")
|
||||
|
||||
if origin.indexOf("https:") == 0
|
||||
proto = { ws: 'wss', http: 'https' }
|
||||
else
|
||||
proto = { ws: 'ws', http: 'http' }
|
||||
|
||||
ws_url = proto.ws + ":" + origin.replace(proto.http+":", "") + "/ZeroNet-Internal/Websocket?wrapper_key=" + window.wrapper_key
|
||||
|
||||
window.wrapper = new Wrapper(ws_url)
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
class WrapperZeroFrame
|
||||
constructor: (wrapper) ->
|
||||
@wrapperCmd = wrapper.cmd
|
||||
@wrapperResponse = wrapper.ws.response
|
||||
console.log "WrapperZeroFrame", wrapper
|
||||
|
||||
cmd: (cmd, params={}, cb=null) =>
|
||||
@wrapperCmd(cmd, params, cb)
|
||||
|
||||
response: (to, result) =>
|
||||
@wrapperResponse(to, result)
|
||||
|
||||
isProxyRequest: ->
|
||||
return window.location.pathname == "/"
|
||||
|
||||
certSelectGotoSite: (elem) =>
|
||||
href = $(elem).attr("href")
|
||||
if @isProxyRequest() # Fix for proxy request
|
||||
$(elem).attr("href", "http://zero#{href}")
|
||||
|
||||
|
||||
window.zeroframe = new WrapperZeroFrame(window.wrapper)
|
|
@ -1,49 +0,0 @@
|
|||
DARK = "(prefers-color-scheme: dark)"
|
||||
LIGHT = "(prefers-color-scheme: light)"
|
||||
|
||||
mqDark = window.matchMedia(DARK)
|
||||
mqLight = window.matchMedia(LIGHT)
|
||||
|
||||
|
||||
changeColorScheme = (theme) ->
|
||||
zeroframe.cmd "userGetGlobalSettings", [], (user_settings) ->
|
||||
if user_settings.theme != theme
|
||||
user_settings.theme = theme
|
||||
zeroframe.cmd "userSetGlobalSettings", [user_settings], (status) ->
|
||||
if status == "ok"
|
||||
location.reload()
|
||||
return
|
||||
return
|
||||
return
|
||||
|
||||
|
||||
displayNotification = ({matches, media}) ->
|
||||
if !matches
|
||||
return
|
||||
|
||||
zeroframe.cmd "siteInfo", [], (site_info) ->
|
||||
if "ADMIN" in site_info.settings.permissions
|
||||
zeroframe.cmd "wrapperNotification", ["info", "Your system's theme has been changed.<br>Please reload site to use it."]
|
||||
else
|
||||
zeroframe.cmd "wrapperNotification", ["info", "Your system's theme has been changed.<br>Please open ZeroHello to use it."]
|
||||
return
|
||||
return
|
||||
|
||||
|
||||
detectColorScheme = ->
|
||||
if mqDark.matches
|
||||
changeColorScheme("dark")
|
||||
else if mqLight.matches
|
||||
changeColorScheme("light")
|
||||
|
||||
mqDark.addListener(displayNotification)
|
||||
mqLight.addListener(displayNotification)
|
||||
|
||||
return
|
||||
|
||||
|
||||
zeroframe.cmd "userGetGlobalSettings", [], (user_settings) ->
|
||||
if user_settings.use_system_theme == true
|
||||
detectColorScheme()
|
||||
|
||||
return
|
|
@ -1,14 +0,0 @@
|
|||
limits = {}
|
||||
call_after_interval = {}
|
||||
window.RateLimit = (interval, fn) ->
|
||||
if not limits[fn]
|
||||
call_after_interval[fn] = false
|
||||
fn() # First call is not delayed
|
||||
limits[fn] = setTimeout (->
|
||||
if call_after_interval[fn]
|
||||
fn()
|
||||
delete limits[fn]
|
||||
delete call_after_interval[fn]
|
||||
), interval
|
||||
else # Called within iterval, delay the call
|
||||
call_after_interval[fn] = true
|
|
@ -1 +0,0 @@
|
|||
window._ = (s) -> return s
|
|
@ -1,95 +0,0 @@
|
|||
class ZeroWebsocket
|
||||
constructor: (url) ->
|
||||
@url = url
|
||||
@next_message_id = 1
|
||||
@waiting_cb = {}
|
||||
@init()
|
||||
|
||||
|
||||
init: ->
|
||||
@
|
||||
|
||||
|
||||
connect: ->
|
||||
@ws = new WebSocket(@url)
|
||||
@ws.onmessage = @onMessage
|
||||
@ws.onopen = @onOpenWebsocket
|
||||
@ws.onerror = @onErrorWebsocket
|
||||
@ws.onclose = @onCloseWebsocket
|
||||
@connected = false
|
||||
@message_queue = []
|
||||
|
||||
|
||||
onMessage: (e) =>
|
||||
message = JSON.parse(e.data)
|
||||
cmd = message.cmd
|
||||
if cmd == "response"
|
||||
if @waiting_cb[message.to]?
|
||||
@waiting_cb[message.to](message.result)
|
||||
else
|
||||
@log "Websocket callback not found:", message
|
||||
else if cmd == "ping"
|
||||
@response message.id, "pong"
|
||||
else
|
||||
@route cmd, message
|
||||
|
||||
route: (cmd, message) =>
|
||||
@log "Unknown command", message
|
||||
|
||||
|
||||
response: (to, result) =>
|
||||
@send {"cmd": "response", "to": to, "result": result}
|
||||
|
||||
|
||||
cmd: (cmd, params={}, cb=null) ->
|
||||
@send {"cmd": cmd, "params": params}, cb
|
||||
|
||||
|
||||
send: (message, cb=null) ->
|
||||
if not message.id?
|
||||
message.id = @next_message_id
|
||||
@next_message_id += 1
|
||||
if @connected
|
||||
@ws.send(JSON.stringify(message))
|
||||
else
|
||||
@log "Not connected, adding message to queue"
|
||||
@message_queue.push(message)
|
||||
if cb
|
||||
@waiting_cb[message.id] = cb
|
||||
|
||||
|
||||
log: (args...) =>
|
||||
console.log "[ZeroWebsocket]", args...
|
||||
|
||||
|
||||
onOpenWebsocket: (e) =>
|
||||
@log "Open"
|
||||
@connected = true
|
||||
|
||||
# Process messages sent before websocket opened
|
||||
for message in @message_queue
|
||||
@ws.send(JSON.stringify(message))
|
||||
@message_queue = []
|
||||
|
||||
if @onOpen? then @onOpen(e)
|
||||
|
||||
|
||||
onErrorWebsocket: (e) =>
|
||||
@log "Error", e
|
||||
if @onError? then @onError(e)
|
||||
|
||||
|
||||
onCloseWebsocket: (e, reconnect=10000) =>
|
||||
@log "Closed", e
|
||||
@connected = false
|
||||
if e and e.code == 1000 and e.wasClean == false
|
||||
@log "Server error, please reload the page", e.wasClean
|
||||
else # Connection error
|
||||
setTimeout (=>
|
||||
@log "Reconnecting..."
|
||||
@connect()
|
||||
), reconnect
|
||||
if @onClose? then @onClose(e)
|
||||
|
||||
|
||||
window.ZeroWebsocket = ZeroWebsocket
|
|
@ -1,36 +0,0 @@
|
|||
jQuery.fn.readdClass = (class_name) ->
|
||||
elem = @
|
||||
elem.removeClass class_name
|
||||
setTimeout ( ->
|
||||
elem.addClass class_name
|
||||
), 1
|
||||
return @
|
||||
|
||||
jQuery.fn.removeLater = (time = 500) ->
|
||||
elem = @
|
||||
setTimeout ( ->
|
||||
elem.remove()
|
||||
), time
|
||||
return @
|
||||
|
||||
jQuery.fn.hideLater = (time = 500) ->
|
||||
elem = @
|
||||
setTimeout ( ->
|
||||
if elem.css("opacity") == 0
|
||||
elem.css("display", "none")
|
||||
), time
|
||||
return @
|
||||
|
||||
jQuery.fn.addClassLater = (class_name, time = 5) ->
|
||||
elem = @
|
||||
setTimeout ( ->
|
||||
elem.addClass(class_name)
|
||||
), time
|
||||
return @
|
||||
|
||||
jQuery.fn.cssLater = (name, val, time = 500) ->
|
||||
elem = @
|
||||
setTimeout ( ->
|
||||
elem.css name, val
|
||||
), time
|
||||
return @
|
Loading…
Add table
Add a link
Reference in a new issue