]> cgit.babelmonkeys.de Git - xmppchat.git/blob - js/main.js
Escape nicknames
[xmppchat.git] / js / main.js
1 var connection = null;
2 var nickname;
3
4 Strophe.addNamespace('TIME', "urn:xmpp:time");
5
6 function handleDisconnected() {
7         // Make things (in)visible
8         $('#login').show();
9         $('#chat').hide();
10         $('#roster').hide();
11         $('#entry').hide();
12 }
13
14 function handleError(error) {
15         alert("An error occured:" + error);
16         handleDisconnected();
17 }
18
19 function addBubble(nick) {
20         var id, div;
21         id = nick + 'Bubble';
22         if (!document.getElementById(id)) {
23                 div = '';
24                 div += '<div id="' + id + '" class="bubble" onmousedown="startDrag(this)" style="display: none">';
25                 div += '<a href="#" onclick="' +"$('#" + id + "').hide('slow')" + '">Close</a>';
26                 div += '<div id="' + id + 'Chat" class="bubbleChat"></div>';
27                 div += '<form id="' + id + 'Form" class="bubbleForm" onsubmit="return sendChatMessage(this,' + "'" + nick + "');" + '" action="#">';
28                 div += '<input type="text" name="text" id="' + id + 'Text" class="bubbleForm"/>';
29                 div += '</form>';
30                 div += '</div>';
31                 $('body').append(div);
32         }
33         $('#'+id).show('slow');
34 }
35
36 function handleMessage(msg) {
37         var html, sender, type, body, subject;
38         html = '';
39         sender = Strophe.getResourceFromJid(msg.getAttribute('from'));
40         if (sender) {
41                 sender = Strophe.xmlescape(sender);
42         } else {
43                 sender = false;
44         }
45         type = msg.getAttribute('type');
46         body = msg.getElementsByTagName('body')[0];
47         if (body) {
48                 body = Strophe.xmlescape(Strophe.getText(body));
49         } else {
50                 body = false;
51         }
52         subject = msg.getElementsByTagName('subject')[0];
53         if (subject) {
54                 subject = Strophe.xmlescape(Strophe.getText(subject));
55         } else {
56                 subject = false;
57         }
58
59         html += '<div class="msg">';
60         if (body) {
61                 if (sender) {
62                         if (body.search(/^\/me/) === 0) {
63                                 body = body.replace(/^\/me/, sender);
64                                 html += '<span class="sender">';
65                                 html += body;
66                                 html += '</span></div>';
67                         } else {
68                                 html += '<span class="sender">';
69                                 html += sender;
70                                 html += ':</span> ';
71                                 html += body + '</div>';
72                         }
73                 } else {
74                         html += '<span class="server">';
75                         html += body + '</span></div>';
76                 }
77         } else if (subject) {
78                 html += '<span class="server">';
79                 html += "The subject is: " + subject + '</span></div>';
80         } else {
81                 return true;
82         }
83
84         if (type == 'chat') {
85                 addBubble(sender);
86                 $('#' + sender + 'BubbleChat').append(html);
87                 document.getElementById(sender + 'BubbleChat').lastChild.scrollIntoView();
88         } else {
89                 $('#chat').append(html);
90                 document.getElementById('chat').lastChild.scrollIntoView();
91         }
92
93         return true;
94 }
95
96 function handlePresence(presence) {
97         var roster_list, nick, type, element;
98         if (Strophe.getBareJidFromJid(presence.getAttribute('from')) != room) {
99                 return true;
100         }
101         roster_list = document.getElementById('roster_list');
102         nick = Strophe.xmlescape(Strophe.getResourceFromJid(presence.getAttribute('from')));
103         type = presence.getAttribute('type');
104         if (type == 'unavailable') {
105                 element = document.getElementById(nick);
106                 roster_list.removeChild(element);
107                 $('#chat').append('<div class="msg"><span class="server">' + nick + ' left the groupchat</span></div>');
108         } else {
109                 roster_list.innerHTML += '<li id="' + nick + '" onclick="addBubble(' + "'" + nick + "')" + '" >' + nick + '</li>';
110                 $('#chat').append('<div class="msg"><span class="server">' + nick + ' joined the groupchat</span></div>');
111         }
112
113         return true;
114 }
115
116 function handleIQ(iq) {
117         var to, from, type, id, reply;
118         to = iq.getAttribute('to');
119         from = iq.getAttribute('from');
120         type = iq.getAttribute('type');
121         id = iq.getAttribute('id');
122
123         //FIXME: Clients SHOULD send the content of the original stanza back for analysis
124         reply = $iq({to: from, from: to, id: id, type: 'error'}).c('error', {type: 'cancel'}).c('feature-not-implemented', {xmlns: Strophe.NS.STANZAS});
125         connection.send(reply.tree());
126
127         return true;
128 }
129
130 function handleIqVersion(iq) {
131         var to, from, id, reply;
132         to = iq.getAttribute('to');
133         from = iq.getAttribute('from');
134         id = iq.getAttribute('id');
135
136         reply = $iq({type: 'result', to: from, from: to, id: id}).c('query', {xmlns: Strophe.NS.VERSION}).c('name').t('XMPPChat').up().c('version').t('git').up().c('os').t(navigator.userAgent);
137         connection.send(reply.tree());
138
139         return true;
140 }
141
142 function handleIqTime(iq) {
143         var now, to, from, id, year, month, day, hours, minutes, seconds, offsetHour, offsetMin, reply;
144         now = new Date();
145         to = iq.getAttribute('to');
146         from = iq.getAttribute('from');
147         id = iq.getAttribute('id');
148
149         year = now.getUTCFullYear();
150         month = now.getUTCMonth() + 1;
151         month = (month < 10) ? '0' + month : month;
152         day = now.getUTCDate();
153         day = (day < 10) ? '0' + day : day;
154         hours = now.getUTCHours();
155         hours = (hours < 10) ? '0' + hours : hours;
156         minutes = now.getUTCMinutes();
157         minutes = (minutes < 10) ? '0' + minutes : minutes;
158         seconds = now.getUTCSeconds();
159         seconds = (seconds < 10) ? '0' + seconds : seconds;
160         offsetMin = now.getTimezoneOffset() * (-1);
161         offsetHour = offsetMin / 60;
162         offsetHour = (offsetHour < 10) ? '0' + offsetHour : offsetHour;
163         offsetMin = offsetMin % 60;
164         offsetMin = (offsetMin < 0) ? (-1)*offsetMin : offsetMin;
165         offsetMin = (offsetMin < 10) ? '0' + offsetMin : offsetMin;
166
167         reply = $iq({type: 'result', from: to, to: from, id: id}).c('time', {xmlns: Strophe.NS.TIME}).c('utc').t(year + '-' + month + '-' + day + 'T' + hours + ':' + minutes + ':' + seconds + 'Z').up().c('tzo').t( ((offsetHour >= 0) ? '+':'') + offsetHour + ':' + offsetMin);
168
169         connection.send(reply.tree());
170
171         return true;
172 }
173
174 function sendMessage(aForm) {
175         var message;
176         if (aForm.text.value) {
177                 message = $msg({type: 'groupchat', to: room}).c('body').t(aForm.text.value);
178                 connection.send(message.tree());
179                 aForm.text.value = '';
180         }
181         return false;
182 }
183
184 function sendChatMessage(aForm, to) {
185         var body, message, html;
186         if (aForm.text.value) {
187                 body = aForm.text.value;
188                 message = $msg({type: 'chat', to: room + '/' + to}).c('body').t(body);
189                 connection.send(message.tree());
190                 aForm.text.value = '';
191                 html = '';
192                 html += '<div class="msg">';
193                 html += '<span class="sender">';
194                 html += nickname;
195                 html += ':</span> ';
196                 html += Strophe.xmlescape(body) + '</div>';
197                 document.getElementById(to + 'BubbleChat').innerHTML += html;
198                 document.getElementById(to + 'BubbleChat').lastChild.scrollIntoView();
199
200         }
201         return false;
202 }
203
204 function onConnect(status) {
205         if (status == Strophe.Status.CONNFAIL) {
206                 handleError('Failed to connect');
207         } else if (status == Strophe.Status.DISCONNECTED) {
208                 handleDisconnected();
209         } else if (status == Strophe.Status.CONNECTED) {
210                 // Add handlers connection.addHandler(callback, namespace, stanza_name, type, id, from, options)
211                 connection.addHandler(handleMessage, null, 'message');
212                 connection.addHandler(handlePresence, null, 'presence');
213                 connection.addHandler(handleIQ, null, 'iq');
214
215                 connection.addHandler(handleIqVersion, Strophe.NS.VERSION, 'iq');
216                 connection.addHandler(handleIqTime, Strophe.NS.TIME, 'iq');
217
218                 connection.send($pres().tree());
219                 connection.send($pres({to: room + '/' + nickname}).tree());
220
221                 // Make things (in)visible
222                 $('#login').hide();
223                 $('#chat').show();
224                 $('#roster').show();
225                 $('#entry').show();
226         }
227 }
228
229 function doLogin(aForm) {
230         if (!aForm.nickname.value) {
231                 return false;
232         }
233         try {
234                 connection = new Strophe.Connection(BOSH_LOCATION);
235                 connection.connect(jid, password, onConnect);
236
237                 nickname = aForm.nickname.value;
238         } catch (e) {
239                 alert(e);
240         } finally {
241                 return false;
242         }
243 }
244
245 function doDisconnect(aForm) {
246         if (connection) {
247                 connection.send($pres({to: room, type: 'unavailable'}).tree());
248                 connection.flush();
249                 connection.disconnect();
250                 connection = null;
251         }
252         return false;
253 }
254
255 var dragElement = null;
256 var mouseX = 0;
257 var mouseY = 0;
258 var offX = 0;
259 var offY = 0;
260
261 function startDrag(element) {
262         dragElement = element;
263         offX = mouseX - dragElement.offsetLeft;
264         offY = mouseY - dragElement.offsetTop;
265 }
266
267 function doDrag(eve) {
268         mouseX = eve.pageX;
269         mouseY = eve.pageY;
270
271         if (dragElement) {
272                 dragElement.style.left = (mouseX - offX) + 'px';
273                 dragElement.style.top = (mouseY - offY) + 'px';
274         }
275 }
276
277 function stopDrag(eve) {
278         dragElement = null;
279 }
280
281 window.onunload = window.onbeforeunload = doDisconnect;
282
283 window.onmousemove = doDrag;
284
285 window.onmouseup = stopDrag;