[cleanup] remove coffee script files

This commit is contained in:
caryoscelus 2022-05-31 13:32:47 +04:00
parent fee2a4f2c9
commit 574928e625
50 changed files with 0 additions and 4951 deletions

View file

@ -1,222 +0,0 @@
class ConfigStorage extends Class
constructor: (@config) ->
@items = []
@createSections()
@setValues(@config)
setValues: (values) ->
for section in @items
for item in section.items
if not values[item.key]
continue
item.value = @formatValue(values[item.key].value)
item.default = @formatValue(values[item.key].default)
item.pending = values[item.key].pending
values[item.key].item = item
formatValue: (value) ->
if not value
return false
else if typeof(value) == "object"
return value.join("\n")
else if typeof(value) == "number"
return value.toString()
else
return value
deformatValue: (value, type) ->
if type == "object" and typeof(value) == "string"
if not value.length
return value = null
else
return value.split("\n")
if type == "boolean" and not value
return false
else if type == "number"
if typeof(value) == "number"
return value.toString()
else if not value
return "0"
else
return value
else
return value
createSections: ->
# Web Interface
section = @createSection("Web Interface")
section.items.push
key: "open_browser"
title: "Open web browser on ZeroNet startup"
type: "checkbox"
# Network
section = @createSection("Network")
section.items.push
key: "offline"
title: "Offline mode"
type: "checkbox"
description: "Disable network communication."
section.items.push
key: "fileserver_ip_type"
title: "File server network"
type: "select"
options: [
{title: "IPv4", value: "ipv4"}
{title: "IPv6", value: "ipv6"}
{title: "Dual (IPv4 & IPv6)", value: "dual"}
]
description: "Accept incoming peers using IPv4 or IPv6 address. (default: dual)"
section.items.push
key: "fileserver_port"
title: "File server port"
type: "text"
valid_pattern: /[0-9]*/
description: "Other peers will use this port to reach your served sites. (default: randomize)"
section.items.push
key: "ip_external"
title: "File server external ip"
type: "textarea"
placeholder: "Detect automatically"
description: "Your file server is accessible on these ips. (default: detect automatically)"
section.items.push
title: "Tor"
key: "tor"
type: "select"
options: [
{title: "Disable", value: "disable"}
{title: "Enable", value: "enable"}
{title: "Always", value: "always"}
]
description: [
"Disable: Don't connect to peers on Tor network", h("br"),
"Enable: Only use Tor for Tor network peers", h("br"),
"Always: Use Tor for every connections to hide your IP address (slower)"
]
section.items.push
title: "Use Tor bridges"
key: "tor_use_bridges"
type: "checkbox"
description: "Use obfuscated bridge relays to avoid network level Tor block (even slower)"
isHidden: ->
return not Page.server_info.tor_has_meek_bridges
section.items.push
title: "Trackers"
key: "trackers"
type: "textarea"
description: "Discover new peers using these adresses"
section.items.push
title: "Trackers files"
key: "trackers_file"
type: "textarea"
description: "Load additional list of torrent trackers dynamically, from a file"
placeholder: "Eg.: {data_dir}/trackers.json"
value_pos: "fullwidth"
section.items.push
title: "Proxy for tracker connections"
key: "trackers_proxy"
type: "select"
options: [
{title: "Custom", value: ""}
{title: "Tor", value: "tor"}
{title: "Disable", value: "disable"}
]
isHidden: ->
Page.values["tor"] == "always"
section.items.push
title: "Custom socks proxy address for trackers"
key: "trackers_proxy"
type: "text"
placeholder: "Eg.: 127.0.0.1:1080"
value_pos: "fullwidth"
valid_pattern: /.+:[0-9]+/
isHidden: =>
Page.values["trackers_proxy"] in ["tor", "disable"]
# Performance
section = @createSection("Performance")
section.items.push
key: "log_level"
title: "Level of logging to file"
type: "select"
options: [
{title: "Everything", value: "DEBUG"}
{title: "Only important messages", value: "INFO"}
{title: "Only errors", value: "ERROR"}
]
section.items.push
key: "threads_fs_read"
title: "Threads for async file system reads"
type: "select"
options: [
{title: "Sync read", value: 0}
{title: "1 thread", value: 1}
{title: "2 threads", value: 2}
{title: "3 threads", value: 3}
{title: "4 threads", value: 4}
{title: "5 threads", value: 5}
{title: "10 threads", value: 10}
]
section.items.push
key: "threads_fs_write"
title: "Threads for async file system writes"
type: "select"
options: [
{title: "Sync write", value: 0}
{title: "1 thread", value: 1}
{title: "2 threads", value: 2}
{title: "3 threads", value: 3}
{title: "4 threads", value: 4}
{title: "5 threads", value: 5}
{title: "10 threads", value: 10}
]
section.items.push
key: "threads_crypt"
title: "Threads for cryptographic functions"
type: "select"
options: [
{title: "Sync execution", value: 0}
{title: "1 thread", value: 1}
{title: "2 threads", value: 2}
{title: "3 threads", value: 3}
{title: "4 threads", value: 4}
{title: "5 threads", value: 5}
{title: "10 threads", value: 10}
]
section.items.push
key: "threads_db"
title: "Threads for database operations"
type: "select"
options: [
{title: "Sync execution", value: 0}
{title: "1 thread", value: 1}
{title: "2 threads", value: 2}
{title: "3 threads", value: 3}
{title: "4 threads", value: 4}
{title: "5 threads", value: 5}
{title: "10 threads", value: 10}
]
createSection: (title) =>
section = {}
section.title = title
section.items = []
@items.push(section)
return section
window.ConfigStorage = ConfigStorage

View file

@ -1,124 +0,0 @@
class ConfigView extends Class
constructor: () ->
@
render: ->
@config_storage.items.map @renderSection
renderSection: (section) =>
h("div.section", {key: section.title}, [
h("h2", section.title),
h("div.config-items", section.items.map @renderSectionItem)
])
handleResetClick: (e) =>
node = e.currentTarget
config_key = node.attributes.config_key.value
default_value = node.attributes.default_value?.value
Page.cmd "wrapperConfirm", ["Reset #{config_key} value?", "Reset to default"], (res) =>
if (res)
@values[config_key] = default_value
Page.projector.scheduleRender()
renderSectionItem: (item) =>
value_pos = item.value_pos
if item.type == "textarea"
value_pos ?= "fullwidth"
else
value_pos ?= "right"
value_changed = @config_storage.formatValue(@values[item.key]) != item.value
value_default = @config_storage.formatValue(@values[item.key]) == item.default
if item.key in ["open_browser", "fileserver_port"] # Value default for some settings makes no sense
value_default = true
marker_title = "Changed from default value: #{item.default} -> #{@values[item.key]}"
if item.pending
marker_title += " (change pending until client restart)"
if item.isHidden?()
return null
h("div.config-item", {key: item.title, enterAnimation: Animation.slideDown, exitAnimation: Animation.slideUpInout}, [
h("div.title", [
h("h3", item.title),
h("div.description", item.description)
])
h("div.value.value-#{value_pos}",
if item.type == "select"
@renderValueSelect(item)
else if item.type == "checkbox"
@renderValueCheckbox(item)
else if item.type == "textarea"
@renderValueTextarea(item)
else
@renderValueText(item)
h("a.marker", {
href: "#Reset", title: marker_title,
onclick: @handleResetClick, config_key: item.key, default_value: item.default,
classes: {default: value_default, changed: value_changed, visible: not value_default or value_changed or item.pending, pending: item.pending}
}, "\u2022")
)
])
# Values
handleInputChange: (e) =>
node = e.target
config_key = node.attributes.config_key.value
@values[config_key] = node.value
Page.projector.scheduleRender()
handleCheckboxChange: (e) =>
node = e.currentTarget
config_key = node.attributes.config_key.value
value = not node.classList.contains("checked")
@values[config_key] = value
Page.projector.scheduleRender()
renderValueText: (item) =>
value = @values[item.key]
if not value
value = ""
h("input.input-#{item.type}", {type: item.type, config_key: item.key, value: value, placeholder: item.placeholder, oninput: @handleInputChange})
autosizeTextarea: (e) =>
if e.currentTarget
# @handleInputChange(e)
node = e.currentTarget
else
node = e
height_before = node.style.height
if height_before
node.style.height = "0px"
h = node.offsetHeight
scrollh = node.scrollHeight + 20
if scrollh > h
node.style.height = scrollh + "px"
else
node.style.height = height_before
renderValueTextarea: (item) =>
value = @values[item.key]
if not value
value = ""
h("textarea.input-#{item.type}.input-text",{
type: item.type, config_key: item.key, oninput: @handleInputChange, afterCreate: @autosizeTextarea,
updateAnimation: @autosizeTextarea, value: value, placeholder: item.placeholder
})
renderValueCheckbox: (item) =>
if @values[item.key] and @values[item.key] != "False"
checked = true
else
checked = false
h("div.checkbox", {onclick: @handleCheckboxChange, config_key: item.key, classes: {checked: checked}}, h("div.checkbox-skin"))
renderValueSelect: (item) =>
h("select.input-select", {config_key: item.key, oninput: @handleInputChange},
item.options.map (option) =>
h("option", {selected: option.value.toString() == @values[item.key], value: option.value}, option.title)
)
window.ConfigView = ConfigView

View file

@ -1,129 +0,0 @@
window.h = maquette.h
class UiConfig extends ZeroFrame
init: ->
@save_visible = true
@config = null # Setting currently set on the server
@values = null # Entered values on the page
@config_view = new ConfigView()
window.onbeforeunload = =>
if @getValuesChanged().length > 0
return true
else
return null
onOpenWebsocket: =>
@cmd("wrapperSetTitle", "Config - ZeroNet")
@cmd "serverInfo", {}, (server_info) =>
@server_info = server_info
@restart_loading = false
@updateConfig()
updateConfig: (cb) =>
@cmd "configList", [], (res) =>
@config = res
@values = {}
@config_storage = new ConfigStorage(@config)
@config_view.values = @values
@config_view.config_storage = @config_storage
for key, item of res
value = item.value
@values[key] = @config_storage.formatValue(value)
@projector.scheduleRender()
cb?()
createProjector: =>
@projector = maquette.createProjector()
@projector.replace($("#content"), @render)
@projector.replace($("#bottom-save"), @renderBottomSave)
@projector.replace($("#bottom-restart"), @renderBottomRestart)
getValuesChanged: =>
values_changed = []
for key, value of @values
if @config_storage.formatValue(value) != @config_storage.formatValue(@config[key]?.value)
values_changed.push({key: key, value: value})
return values_changed
getValuesPending: =>
values_pending = []
for key, item of @config
if item.pending
values_pending.push(key)
return values_pending
saveValues: (cb) =>
changed_values = @getValuesChanged()
for item, i in changed_values
last = i == changed_values.length - 1
value = @config_storage.deformatValue(item.value, typeof(@config[item.key].default))
default_value = @config_storage.deformatValue(@config[item.key].default, typeof(@config[item.key].default))
value_same_as_default = JSON.stringify(default_value) == JSON.stringify(value)
if @config[item.key].item.valid_pattern and not @config[item.key].item.isHidden?()
match = value.match(@config[item.key].item.valid_pattern)
if not match or match[0] != value
message = "Invalid value of #{@config[item.key].item.title}: #{value} (does not matches #{@config[item.key].item.valid_pattern})"
Page.cmd("wrapperNotification", ["error", message])
cb(false)
break
if value_same_as_default
value = null
@saveValue(item.key, value, if last then cb else null)
saveValue: (key, value, cb) =>
if key == "open_browser"
if value
value = "default_browser"
else
value = "False"
Page.cmd "configSet", [key, value], (res) =>
if res != "ok"
Page.cmd "wrapperNotification", ["error", res.error]
cb?(true)
render: =>
if not @config
return h("div.content")
h("div.content", [
@config_view.render()
])
handleSaveClick: =>
@save_loading = true
@logStart "Save"
@saveValues (success) =>
@save_loading = false
@logEnd "Save"
if success
@updateConfig()
Page.projector.scheduleRender()
return false
renderBottomSave: =>
values_changed = @getValuesChanged()
h("div.bottom.bottom-save", {classes: {visible: values_changed.length}}, h("div.bottom-content", [
h("div.title", "#{values_changed.length} configuration item value changed"),
h("a.button.button-submit.button-save", {href: "#Save", classes: {loading: @save_loading}, onclick: @handleSaveClick}, "Save settings")
]))
handleRestartClick: =>
@restart_loading = true
Page.cmd("serverShutdown", {restart: true})
Page.projector.scheduleRender()
return false
renderBottomRestart: =>
values_pending = @getValuesPending()
values_changed = @getValuesChanged()
h("div.bottom.bottom-restart", {classes: {visible: values_pending.length and not values_changed.length}}, h("div.bottom-content", [
h("div.title", "Some changed settings requires restart"),
h("a.button.button-submit.button-restart", {href: "#Restart", classes: {loading: @restart_loading}, onclick: @handleRestartClick}, "Restart ZeroNet client")
]))
window.Page = new UiConfig()
window.Page.createProjector()

View file

@ -1,23 +0,0 @@
class Class
trace: true
log: (args...) ->
return unless @trace
return if typeof console is 'undefined'
args.unshift("[#{@.constructor.name}]")
console.log(args...)
@
logStart: (name, args...) ->
return unless @trace
@logtimers or= {}
@logtimers[name] = +(new Date)
@log "#{name}", args..., "(started)" if args.length > 0
@
logEnd: (name, args...) ->
ms = +(new Date)-@logtimers[name]
@log "#{name}", args..., "(Done in #{ms}ms)"
@
window.Class = Class

View file

@ -1,74 +0,0 @@
# From: http://dev.bizo.com/2011/12/promises-in-javascriptcoffeescript.html
class Promise
@when: (tasks...) ->
num_uncompleted = tasks.length
args = new Array(num_uncompleted)
promise = new Promise()
for task, task_id in tasks
((task_id) ->
task.then(() ->
args[task_id] = Array.prototype.slice.call(arguments)
num_uncompleted--
promise.complete.apply(promise, args) if num_uncompleted == 0
)
)(task_id)
return promise
constructor: ->
@resolved = false
@end_promise = null
@result = null
@callbacks = []
resolve: ->
if @resolved
return false
@resolved = true
@data = arguments
if not arguments.length
@data = [true]
@result = @data[0]
for callback in @callbacks
back = callback.apply callback, @data
if @end_promise
@end_promise.resolve(back)
fail: ->
@resolve(false)
then: (callback) ->
if @resolved == true
callback.apply callback, @data
return
@callbacks.push callback
@end_promise = new Promise()
window.Promise = Promise
###
s = Date.now()
log = (text) ->
console.log Date.now()-s, Array.prototype.slice.call(arguments).join(", ")
log "Started"
cmd = (query) ->
p = new Promise()
setTimeout ( ->
p.resolve query+" Result"
), 100
return p
back = cmd("SELECT * FROM message").then (res) ->
log res
return "Return from query"
.then (res) ->
log "Back then", res
log "Query started", back
###

View file

@ -1,8 +0,0 @@
String::startsWith = (s) -> @[...s.length] is s
String::endsWith = (s) -> s is '' or @[-s.length..] is s
String::repeat = (count) -> new Array( count + 1 ).join(@)
window.isEmpty = (obj) ->
for key of obj
return false
return true

View file

@ -1,138 +0,0 @@
class Animation
slideDown: (elem, props) ->
if elem.offsetTop > 2000
return
h = elem.offsetHeight
cstyle = window.getComputedStyle(elem)
margin_top = cstyle.marginTop
margin_bottom = cstyle.marginBottom
padding_top = cstyle.paddingTop
padding_bottom = cstyle.paddingBottom
transition = cstyle.transition
elem.style.boxSizing = "border-box"
elem.style.overflow = "hidden"
elem.style.transform = "scale(0.6)"
elem.style.opacity = "0"
elem.style.height = "0px"
elem.style.marginTop = "0px"
elem.style.marginBottom = "0px"
elem.style.paddingTop = "0px"
elem.style.paddingBottom = "0px"
elem.style.transition = "none"
setTimeout (->
elem.className += " animate-inout"
elem.style.height = h+"px"
elem.style.transform = "scale(1)"
elem.style.opacity = "1"
elem.style.marginTop = margin_top
elem.style.marginBottom = margin_bottom
elem.style.paddingTop = padding_top
elem.style.paddingBottom = padding_bottom
), 1
elem.addEventListener "transitionend", ->
elem.classList.remove("animate-inout")
elem.style.transition = elem.style.transform = elem.style.opacity = elem.style.height = null
elem.style.boxSizing = elem.style.marginTop = elem.style.marginBottom = null
elem.style.paddingTop = elem.style.paddingBottom = elem.style.overflow = null
elem.removeEventListener "transitionend", arguments.callee, false
slideUp: (elem, remove_func, props) ->
if elem.offsetTop > 1000
return remove_func()
elem.className += " animate-back"
elem.style.boxSizing = "border-box"
elem.style.height = elem.offsetHeight+"px"
elem.style.overflow = "hidden"
elem.style.transform = "scale(1)"
elem.style.opacity = "1"
elem.style.pointerEvents = "none"
setTimeout (->
elem.style.height = "0px"
elem.style.marginTop = "0px"
elem.style.marginBottom = "0px"
elem.style.paddingTop = "0px"
elem.style.paddingBottom = "0px"
elem.style.transform = "scale(0.8)"
elem.style.borderTopWidth = "0px"
elem.style.borderBottomWidth = "0px"
elem.style.opacity = "0"
), 1
elem.addEventListener "transitionend", (e) ->
if e.propertyName == "opacity" or e.elapsedTime >= 0.6
elem.removeEventListener "transitionend", arguments.callee, false
remove_func()
slideUpInout: (elem, remove_func, props) ->
elem.className += " animate-inout"
elem.style.boxSizing = "border-box"
elem.style.height = elem.offsetHeight+"px"
elem.style.overflow = "hidden"
elem.style.transform = "scale(1)"
elem.style.opacity = "1"
elem.style.pointerEvents = "none"
setTimeout (->
elem.style.height = "0px"
elem.style.marginTop = "0px"
elem.style.marginBottom = "0px"
elem.style.paddingTop = "0px"
elem.style.paddingBottom = "0px"
elem.style.transform = "scale(0.8)"
elem.style.borderTopWidth = "0px"
elem.style.borderBottomWidth = "0px"
elem.style.opacity = "0"
), 1
elem.addEventListener "transitionend", (e) ->
if e.propertyName == "opacity" or e.elapsedTime >= 0.6
elem.removeEventListener "transitionend", arguments.callee, false
remove_func()
showRight: (elem, props) ->
elem.className += " animate"
elem.style.opacity = 0
elem.style.transform = "TranslateX(-20px) Scale(1.01)"
setTimeout (->
elem.style.opacity = 1
elem.style.transform = "TranslateX(0px) Scale(1)"
), 1
elem.addEventListener "transitionend", ->
elem.classList.remove("animate")
elem.style.transform = elem.style.opacity = null
show: (elem, props) ->
delay = arguments[arguments.length-2]?.delay*1000 or 1
elem.style.opacity = 0
setTimeout (->
elem.className += " animate"
), 1
setTimeout (->
elem.style.opacity = 1
), delay
elem.addEventListener "transitionend", ->
elem.classList.remove("animate")
elem.style.opacity = null
elem.removeEventListener "transitionend", arguments.callee, false
hide: (elem, remove_func, props) ->
delay = arguments[arguments.length-2]?.delay*1000 or 1
elem.className += " animate"
setTimeout (->
elem.style.opacity = 0
), delay
elem.addEventListener "transitionend", (e) ->
if e.propertyName == "opacity"
remove_func()
addVisibleClass: (elem, props) ->
setTimeout ->
elem.classList.add("visible")
window.Animation = new Animation()

View file

@ -1,3 +0,0 @@
window.$ = (selector) ->
if selector.startsWith("#")
return document.getElementById(selector.replace("#", ""))

View file

@ -1,85 +0,0 @@
class ZeroFrame extends Class
constructor: (url) ->
@url = url
@waiting_cb = {}
@wrapper_nonce = document.location.href.replace(/.*wrapper_nonce=([A-Za-z0-9]+).*/, "$1")
@connect()
@next_message_id = 1
@history_state = {}
@init()
init: ->
@
connect: ->
@target = window.parent
window.addEventListener("message", @onMessage, false)
@cmd("innerReady")
# Save scrollTop
window.addEventListener "beforeunload", (e) =>
@log "save scrollTop", window.pageYOffset
@history_state["scrollTop"] = window.pageYOffset
@cmd "wrapperReplaceState", [@history_state, null]
# Restore scrollTop
@cmd "wrapperGetState", [], (state) =>
@history_state = state if state?
@log "restore scrollTop", state, window.pageYOffset
if window.pageYOffset == 0 and state
window.scroll(window.pageXOffset, state.scrollTop)
onMessage: (e) =>
message = 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 == "wrapperReady" # Wrapper inited later
@cmd("innerReady")
else if cmd == "ping"
@response message.id, "pong"
else if cmd == "wrapperOpenedWebsocket"
@onOpenWebsocket()
else if cmd == "wrapperClosedWebsocket"
@onCloseWebsocket()
else
@onRequest cmd, message.params
onRequest: (cmd, message) =>
@log "Unknown request", 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) ->
message.wrapper_nonce = @wrapper_nonce
message.id = @next_message_id
@next_message_id += 1
@target.postMessage(message, "*")
if cb
@waiting_cb[message.id] = cb
onOpenWebsocket: =>
@log "Websocket open"
onCloseWebsocket: =>
@log "Websocket close"
window.ZeroFrame = ZeroFrame