coffeescript-ui
Version:
Coffeescript User Interface System
278 lines (234 loc) • 5.92 kB
text/coffeescript
###
* coffeescript-ui - Coffeescript User Interface System (CUI)
* Copyright (c) 2013 - 2016 Programmfabrik GmbH
* MIT Licence
* https://github.com/programmfabrik/coffeescript-ui, http://www.coffeescript-ui.org
###
class CUI.XHR extends CUI.Element
getGroup: ->
"Core"
initOpts: ->
super()
method:
mandatory: true
default: "GET"
check: ["GET", "POST", "PUT", "DELETE", "OPTIONS"]
url:
mandatory: true
check: String
check: (v) ->
v.trim().length > 0
user:
check: String
password:
check: String
responseType:
mandatory: true
default: "json"
check: ["", "text", "json", "blob", "arraybuffer"]
timeout:
check: (v) ->
v >= 0
form:
check: "PlainObject"
url_data:
check: "PlainObject"
body: {}
json_data: {} # can be anything
json_pretty:
default: false
check: (v) ->
v == false or v == true or CUI.util.isString(v)
headers:
mandatory: true
default: {}
check: "PlainObject"
withCredentials:
mandatory: true
default: false
check: Boolean
@
:
0: "UNSENT"
1: "OPENED"
2: "HEADERS_RECEIVED"
3: "LOADING"
4: "DONE"
:
"-1": "abort"
"-2": "timeout"
"-3": "network_failure"
readOpts: ->
super()
= new XMLHttpRequest()
.withCredentials =
# console.debug "XHR.readOpts", @
= []
= {}
for k, v of
[k.toLowerCase()] = v
if
if not .method
= "POST"
if
= CUI.appendToUrl(, )
else
=
set = 0
if
set = set + 1
if
set = set + 1
if ['content-type'] == undefined
['content-type'] = 'application/json; charset=utf-8'
if
set = set + 1
CUI.util.assert(set <= 1, "new CUI.XHR", "opts.form, opts.json_data, opts.body are mutually exclusive.")
@
# type: xhr / upload
__registerEvents: (type) ->
keys = [
"loadStart"
"progress"
"abort"
"error"
"load"
"loadend"
"timeout"
]
if type == "upload"
xhr = .upload
else
keys.push("readyStateChange")
xhr =
for k in keys
fn = "__"+type+"_"+k
if not @[fn]
continue
do (fn, k) =>
# console.debug "register", type, k, fn
xhr.addEventListener k.toLowerCase(), (ev) =>
# console.debug ev.type, type # , ev
@[fn](ev)
@
__setStatus: () ->
.CUI_status =
.CUI_statusText =
__download_abort: ->
# console.warn("Aborted:", , @)
__download_timeout: ->
# console.warn("Timeout:", , @)
__download_loadend: ->
# console.info("Loadend:", , , )
if
.resolve(, , )
else
if not and not
# check ready states if we can determine a pseudo status
console.debug("XHR.__download_loadend", )
.reject(, , )
@
__download_readyStateChange: ->
CUI.util.pushOntoArray(, )
__progress: (ev, type) ->
if == "DONE"
return
loaded = ev.loaded
total = ev.total
if ev.lengthComputable
percent = Math.floor(loaded / total * 100)
else
percent = -1
.notify(type, loaded, total, percent)
@
__upload_progress: (ev) ->
__download_progress: (ev) ->
abort: ->
.abort()
isSuccess: ->
if .startsWith("file:///") and .join(",") == "UNSENT,OPENED,HEADERS_RECEIVED,LOADING,DONE"
true
else
.status >= 200 and .status < 300 or .status == 304
status: ->
if < 0
else
.status
statusText: ->
if < 0
CUI.XHR.statusText[+""]
else
.statusText
response: ->
if == "json" and .responseType == ""
# Internet Explorer needs some help here
try
res = JSON.parse(.response)
catch e
res = .response
else
res = .response
if == "json"
# be more compatible with jQuery
.responseJSON = res
res
start: ->
.open(, , true, , )
for k, v of
.setRequestHeader(k, v)
.responseType =
.timeout =
# console.debug "URL:", .responseType, , ,
if
data = new FormData()
for k, v of
data.append(k, v)
send_data = data
# let the browser set the content-type
else if
if
if == true
send_data = JSON.stringify(, null, "\t")
else
send_data = JSON.stringify(, null, )
else
send_data = JSON.stringify()
else if
send_data =
else
send_data = undefined
= new CUI.Deferred()
.send(send_data)
# console.debug ,
.promise()
getXHR: ->
getAllResponseHeaders: ->
headers = []
for header in .getAllResponseHeaders().split("\r\n")
if header.trim().length == 0
continue
headers.push(header)
headers
getResponseHeaders: ->
map = {}
for header in
match = header.match(/^(.*?): (.*)$/)
key = match[1].toLowerCase()
if not map[key]
map[key] = []
map[key].push(match[2])
map
getResponseHeader: (key) ->
[key.toLowerCase()]?[0]
readyState: ->
CUI.XHR.readyStates[.readyState]