UNPKG

3.07 kBJavaScriptView Raw
1
2!function(window, document, xhr) {
3 var auth, hash, poll
4 , events = []
5
6 // JSON.parse and sessionStorage IE8
7
8 Object.each({ DELETE: "del", GET: 0, PATCH: 0, POST: 0, PUT:0 }, addMethod)
9
10 xhr.addMethod = addMethod
11 xhr.hello = hello
12
13 function hello(data, next) {
14 var put = {
15 a: nameStorage(window).a
16 }
17 if (!put.a) {
18 put.b = nameStorage(window.opener).a || sessionStorage.getItem("act")
19 put.c = document.referrer
20 }
21
22 xhr.put("/hello", function(err, json) {
23 auth = json && json.authorization
24 poll = json && json.user
25 if (json && json.a) {
26 nameStorage(window, {a: json.a})
27 hash = json.a
28 }
29 if (next) {
30 next(err, json)
31 }
32 setTimeout(xhrPoll, 1500)
33 onFocus()
34 }, Object.assign(put, data))
35 }
36
37 xhr.logout = function() {
38 xhr.del("/hello", function(err, json) {
39 authorization = null
40 location.reload()
41 })
42 }
43 /*, ws
44 try {
45 new WebSocket("ws" + location.protocol.slice(4) + "//" + location.host + "/events")
46 .addEventListener("open", function(ev) {
47 ws = this
48 ws.send(put)
49 })
50 } catch(e) {}
51 function wsReq(method, url, next, data) {
52 // Prior to version 11, Firefox only supported sending data as a string.
53 ws.send(JSON.stringify({method:method,url:url,data:data}))
54 }
55 */
56
57 El.on(window, "focus", onFocus)
58 El.on(window, "unload", function() {
59 xhr.unload = true
60 if (events.length) navigator.sendBeacon("/events", JSON.stringify(events))
61 })
62
63 function addMethod(name, method) {
64 xhr[name || method.toLowerCase()] = xhr[method] = xhrReq.bind(null, method)
65 }
66
67 function xhrReq(method, url, next, data) {
68 var req = xhr(method, url, function onResponse(err, txt) {
69 var body = (
70 req.getResponseHeader("Content-Type") == "application/json" ?
71 JSON.parse(txt) :
72 { message: txt, code: err }
73 )
74 if (next && next(err, body, req) === true) return
75 if (err) {
76 View.emit(
77 View._e["xhr:" + err] ? "xhr:" + err : "xhr:err",
78 body, method, url, data, onResponse, xhrSend
79 )
80 }
81 })
82 xhrSend(req, data)
83 return req
84 }
85
86 function xhrSend(req, data) {
87 if (auth) {
88 req.setRequestHeader("Authorization", auth)
89 }
90 if (data) {
91 req.setRequestHeader("Content-Type", "application/json")
92 }
93 req.send(data ? JSON.stringify(data) : null)
94 }
95
96 function xhrPoll() {
97 if (poll) {
98 xhr.post("/events", pollHandler, events.length > 0 ? events.splice(0) : null)
99 }
100 }
101
102 function pollHandler(err, res) {
103 var i = 0
104 , events = !err && (Array.isArray(res) ? res : res.events)
105 , len = events && events.length || 0
106
107 if (len) for (; i < len; ) {
108 try {
109 View.emit("event", events[i++])
110 } catch(e) {
111 console.error(e)
112 }
113 }
114
115 setTimeout(xhrPoll, err ? 6000 : 600)
116 }
117
118 function nameStorage(win, append) {
119 var data = {}
120 try {
121 // RE against XSS
122 data = JSON.parse(win.name.match(/^{[\w:"]*}$/)[0])
123 } catch(e) {}
124 if (append) {
125 win.name = JSON.stringify(Object.assign(data, append))
126 }
127 return data
128 }
129
130 function onFocus() {
131 if (hash && document.hasFocus()) {
132 sessionStorage.setItem("act", hash)
133 }
134 }
135}(this, document, xhr)
136