]> cgit.babelmonkeys.de Git - adhocweb.git/blob - js/main.js
Prepare for moving adhoc code into a separate file
[adhocweb.git] / js / main.js
1 var BOSH_SERVICE = 'http://localhost:5280/http-bind/';
2 var show_log = true;
3
4 Strophe.addNamespace("ADHOC", "http://jabber.org/protocol/commands");
5
6 var localJID = null;
7 var connection   = null;
8 var adhoc_status = {
9     sessionid: null,
10     cmdNode: null,
11     queryJID: null
12 };
13
14 function log(msg) {
15     var entry = $('<div></div>').append(document.createTextNode(msg));
16     $('#log').append(entry);
17 }
18
19 function rawInput(data) {
20     log('RECV: ' + data);
21 }
22
23 function rawOutput(data) {
24     log('SENT: ' + data);
25 }
26
27 function onConnect(status) {
28     if (status == Strophe.Status.CONNECTING) {
29         log('Strophe is connecting.');
30     } else if (status == Strophe.Status.CONNFAIL) {
31         log('Strophe failed to connect.');
32         showConnect();
33     } else if (status == Strophe.Status.DISCONNECTING) {
34         log('Strophe is disconnecting.');
35     } else if (status == Strophe.Status.DISCONNECTED) {
36         log('Strophe is disconnected.');
37         showConnect();
38     } else if (status == Strophe.Status.AUTHFAIL) {
39         log('Authentication failed');
40         if (connection) {
41             connection.disconnect();
42         }
43     } else if (status == Strophe.Status.CONNECTED) {
44         log('Strophe is connected.');
45         adhoc_status.queryJID = connection.domain;
46         $('#queryJID').val(adhoc_status.queryJID);
47         $('#query').show();
48         checkFeatures("#output");
49     }
50 }
51
52 function addNote(elem, text, type) {
53     if (!type) {
54        type = "info";
55     }
56     text = text.replace(/\n/g, "<br/>");
57     $(elem).append("<p class='" + type + "Note'>" + text + "</p>");
58 }
59
60 function addForm(elem, x) {
61     var form = $("<form action='#'/>");
62     form.submit(function(event) {
63         executeCommand("execute", serializeToDataform('form'), function(e) { displayResult(elem, e) });
64         event.preventDefault();
65     });
66     var fieldset = $("<fieldset/>");
67     form.append(fieldset);
68     if ($(x).find("title").length > 0)
69         $("<legend/>").text($(x).find("title").text()).appendTo(fieldset);
70     if ($(x).find("instructions").length > 0)
71         $("<p/>").text($(x).find("instructions").text()).appendTo(fieldset);
72     $(x).find("field").each(function() {
73         var item = null;
74         var type = $(this).attr("type");
75         if($(this).attr("label")) {
76             $("<label/>").text($(this).attr("label")).attr("for", $(this).attr("var")).appendTo(fieldset);
77             $("<br/>").appendTo(fieldset);
78         }
79         switch(type) {
80         case "hidden":
81             item = $("<input type='hidden'/>");
82             break;
83         case "boolean":
84             item = $("<input type='checkbox'/>");
85             break;
86         case "text-multi":
87             item = $("<textarea rows='10' cols='70'/>");
88             break;
89         case "text-single":
90             item = $("<input type='text'/>");
91             break;
92         case "fixed":
93             item = $("<input type='text'/>").attr("readonly",true);
94             break;
95         case "jid-multi":
96             item = $("<textarea rows='10' cols='70'/>");
97             break;
98         case "jid-single":
99             item = $("<input type='text'/>");
100             break;
101         case "list-multi":
102             item = $("<select multiple='multiple'/>");
103             $(this).find("option").each(function() {
104                 $("<option/>").val($(this).find("value").text()).text($(this).attr("label")).appendTo(item);
105             });
106             break;
107         case "list-single":
108             item = $("<select/>");
109             $(this).find("option").each(function() {
110                 $("<option/>").val($(this).find("value").text()).text($(this).attr("label")).appendTo(item);
111             });
112             break;
113         case "text-private":
114             item = $("<input type='password'/>");
115             break;
116         default:
117             item = $("<input/>");
118         }
119         item.addClass("df-item");
120         if ($(this).find("value").length > 0) {
121             var value = null;
122             if ((type == "text-multi") || (type == "jid-multi")) {
123                 value = "";
124                 $(this).find("value").each(function() {
125                     value = value + $(this).text() + "\n";
126                 });
127                 item.val(value);
128             } else if (type == "list-multi") {
129                 $(this).children("value").each(function() {
130                     item.children('option[value="' + $(this).text() + '"]').each(function() {
131                         $(this).attr("selected", "selected");
132                     });
133                 });
134             } else {
135                 item.val($(this).find("value").text());
136             }
137         }
138         if ($(x).attr("type") == "result")
139             item.attr("readonly", true);
140         if ($(this).attr("var")) {
141             item.attr("name", $(this).attr("var"));
142             item.attr("id", $(this).attr("var"));
143         }
144         fieldset.append(item);
145         if (type != "hidden")
146             fieldset.append("<br/>");
147     });
148     $(elem).append(form);
149 }
150
151 function serializeToDataform(form) {
152     st = $build("x", {"xmlns": "jabber:x:data", "type": "submit"});
153     $(form).find(".df-item").each(function(){
154         st.c("field", {"var": $(this).attr("name")});
155         if (this.nodeName.toLowerCase() == "select" && this.multiple) {
156             for (var i = 0; i < this.options.length; i++)
157                 if (this.options[i].selected)
158                     st.c("value").t(this.options[i].text).up();
159         } else if (this.nodeName.toLowerCase() == "textarea") {
160             var sp_value = this.value.split(/\r?\n|\r/g);
161             for(var i = 0; i < sp_value.length; i++)
162                 st.c("value").t(sp_value[i]).up();
163         } else if (this.nodeName.toLowerCase() == "input" && this.type == "checkbox") {
164             if (this.checked) {
165                 st.c("value").t("1");
166             } else {
167                 st.c("value").t("0");
168             }
169         } else {
170             // if this has value then
171             st.c("value").t($(this).val()).up();
172         }
173         st.up();
174     });
175     st.up();
176     return st.tree();
177 }
178
179 function displayResult(elem, result) {
180     var status = $(result).find("command").attr("status");
181     var kinds = {'prev': 'Prev', 'next': 'Next', 'complete': 'Complete'};
182
183     $(elem).empty();
184     $(result).find("command > *").each(function(index, e) {
185         if ($(e).is("note")) {
186             addNote(elem, $(e).text(), $(e).attr("type"));
187         } else if ($(e).is("x[xmlns=jabber:x:data]")) {
188             addForm(elem, e);
189         }
190     });
191     if (status == "executing") {
192         for (kind in kinds) {
193             input = $("<input type='button' disabled='disabled' value='" + kinds[kind] + "'/>").click(function() {
194                 if (kind == 'prev')
195                     executeCommand(kind, false, function(e) { displayResult(elem, e) });
196                 else
197                     executeCommand(kind, serializeToDataform('form'), function(e) { displayResult(elem, e) });
198             });
199             if ($(result).find('actions ' + kind).length > 0)
200                 input.removeAttr("disabled");
201             $(elem).append(input);
202         }
203
204         $("<input type='button' id='executeButton' value='Execute'/>").click(function() {
205             executeCommand("execute", serializeToDataform('form'), function(e) { displayResult(elem, e) });
206         }).appendTo(elem);
207
208         $("<input type='button' value='Cancel'/>").click(function() {
209             cancelCommand(function(e) { displayResult(elem, e) });
210         }).appendTo(elem);
211     } else {
212         input = $("<input type='button' value='Start over'/>").bind("click", function() {
213             $(elem).empty();
214             adhoc_status.sessionid = null;
215             adhoc_status.cmdNode = null;
216             getCommandNodes(elem);
217         });
218         $(elem).append(input);
219     }
220 }
221
222 function runCommand(item, callback) {
223     adhoc_status.cmdNode = $(item).attr("id"); // Save node of executed command (in global var)
224     executeCommand("execute", false, function(result) {
225         adhoc_status.sessionid = $(result).find("command").attr("sessionid");
226         callback(result);
227     });
228 }
229
230 function executeCommand(type, childs, callback) {
231     if (adhoc_status.sessionid)
232         var execIQ = $iq({ type: "set", to: adhoc_status.queryJID, id: connection.getUniqueId() })
233             .c("command", { xmlns: Strophe.NS.ADHOC, node: adhoc_status.cmdNode, sessionid: adhoc_status.sessionid, action: type });
234     else
235         var execIQ = $iq({ type: "set", to: adhoc_status.queryJID, id: connection.getUniqueId() })
236             .c("command", { xmlns: Strophe.NS.ADHOC, node: adhoc_status.cmdNode, action: type });
237     if (childs)
238         execIQ.cnode(childs);
239         connection.sendIQ(execIQ, callback);
240 }
241
242 function cancelCommand(callback) {
243     executeCommand("cancel", false, callback);
244     adhoc_status.cmdNode = null
245     adhoc_status.sessionid = null;
246 }
247
248 function getCommandNodes(elem) {
249     var nodesIQ = $iq({ type: "get", to: adhoc_status.queryJID, id: connection.getUniqueId() }).c("query", {xmlns: Strophe.NS.DISCO_ITEMS, node: Strophe.NS.ADHOC});
250     connection.sendIQ(nodesIQ, function(result) {
251         var items = $("<ul></ul>");
252         $(elem).append(items);
253         $(result).find("item").each(function(index, e) {
254             $("<li></li>").append($("<a href='#' id='" + $(e).attr("node") + "'>" + $(e).attr("name") + "</a>").click(function (event) {
255                 runCommand(this, function (result) { displayResult(elem, result); });
256                 event.preventDefault();
257             })).appendTo(items);
258         });
259     });
260 }
261
262 function checkFeatures(elem) {
263     if (adhoc_status.sessionid)
264         cancelCommand();
265     featureIQ = $iq({ type: "get", to: adhoc_status.queryJID, id: connection.getUniqueId() }).c("query", {xmlns: Strophe.NS.DISCO_INFO});
266     $(elem).empty();
267     connection.sendIQ(featureIQ,
268         function(result) { /* Callback */
269             if ($(result).find("feature[var='" + Strophe.NS.ADHOC + "']").length > 0) {
270                 getCommandNodes(elem);
271             } else {
272                 $(elem).append("<p>" + adhoc_status.queryJID + " does NOT support AdHoc commands</p>");
273             }
274         },
275         function(result) { /* Errback */
276             $(elem).append("<p>Couldn't get list of supported features</p>");
277         }
278     );
279 }
280
281 function showConnect() {
282     var jid = $('#jid');
283     var pass = $('#pass');
284     var button = $('#connect').get(0);        
285
286     button.value = 'connect';
287     $('#query').hide();
288     pass.show();
289     jid.show();
290     $('#cred label').show();
291     $('#cred br').show();
292     $('#output').empty();
293 }
294
295 function showDisconnect() {
296     var jid = $('#jid');
297     var pass = $('#pass');
298     var button = $('#connect').get(0);        
299
300     button.value = 'disconnect';
301     pass.hide();
302     jid.hide();
303     $('#cred label').hide();
304     $('#cred br').hide();
305 }
306
307 $(document).ready(function () {
308     connection = new Strophe.Connection(BOSH_SERVICE);
309     if (show_log) {
310         $('#log_container').show();
311         connection.rawInput = rawInput;
312         connection.rawOutput = rawOutput;
313     }
314
315     $("#log_toggle").click(function () {
316         $("#log").toggle();
317       });
318
319     $('#cred').bind('submit', function (event) {
320         var button = $('#connect').get(0);
321         var jid = $('#jid');
322         var pass = $('#pass');        
323         localJID = jid.get(0).value;
324
325         if (button.value == 'connect') {
326             showDisconnect();
327             $('#log').empty();
328             connection.connect(localJID,
329                pass.get(0).value,
330                onConnect);
331         } else {
332             connection.disconnect();
333         }
334         event.preventDefault();
335     });
336
337     $('#queryForm').bind('submit', function (event) {
338         adhoc_status.queryJID = $('#queryJID').val();
339         checkFeatures("#output");
340         event.preventDefault();
341     });
342 });
343
344 window.onunload = window.onbeforeunload = function() {
345     if (connection) {
346         connection.disconnect();
347     }
348 }