Move Strophe.addNamespace call to adhoc.js
[adhocweb.git] / js / adhoc.js
1 Strophe.addNamespace("ADHOC", "http://jabber.org/protocol/commands");
2
3 var Adhoc = {
4     status: {
5         sessionid: null,
6         cmdNode: null,
7         queryJID: null
8     },
9
10     addNote: function (elem, text, type) {
11         if (!type) {
12            type = "info";
13         }
14         text = text.replace(/\n/g, "<br/>");
15         $(elem).append("<p class='" + type + "Note'>" + text + "</p>");
16     },
17
18     addForm: function (elem, x) {
19         var form = $("<form action='#'/>");
20         form.submit(function(event) {
21             Adhoc.executeCommand("execute", Adhoc.serializeToDataform('form'),
22                 function(e) { Adhoc.displayResult(elem, e) });
23             event.preventDefault();
24         });
25         var fieldset = $("<fieldset/>");
26         form.append(fieldset);
27         if ($(x).find("title").length > 0)
28             $("<legend/>").text($(x).find("title").text()).appendTo(fieldset);
29         if ($(x).find("instructions").length > 0)
30             $("<p/>").text($(x).find("instructions").text()).appendTo(fieldset);
31         $(x).find("field").each(function() {
32             var item = null;
33             var type = $(this).attr("type");
34             if($(this).attr("label")) {
35                 $("<label/>").text($(this).attr("label")).attr("for", $(this).attr("var")).appendTo(fieldset);
36                 $("<br/>").appendTo(fieldset);
37             }
38             switch(type) {
39             case "hidden":
40                 item = $("<input type='hidden'/>");
41                 break;
42             case "boolean":
43                 item = $("<input type='checkbox'/>");
44                 break;
45             case "text-multi":
46                 item = $("<textarea rows='10' cols='70'/>");
47                 break;
48             case "text-single":
49                 item = $("<input type='text'/>");
50                 break;
51             case "fixed":
52                 item = $("<input type='text'/>").attr("readonly",true);
53                 break;
54             case "jid-multi":
55                 item = $("<textarea rows='10' cols='70'/>");
56                 break;
57             case "jid-single":
58                 item = $("<input type='text'/>");
59                 break;
60             case "list-multi":
61                 item = $("<select multiple='multiple'/>");
62                 $(this).find("option").each(function() {
63                     $("<option/>").val($(this).find("value").text()).text($(this).attr("label")).appendTo(item);
64                 });
65                 break;
66             case "list-single":
67                 item = $("<select/>");
68                 $(this).find("option").each(function() {
69                     $("<option/>").val($(this).find("value").text()).text($(this).attr("label")).appendTo(item);
70                 });
71                 break;
72             case "text-private":
73                 item = $("<input type='password'/>");
74                 break;
75             default:
76                 item = $("<input/>");
77             }
78             item.addClass("df-item");
79             if ($(this).find("value").length > 0) {
80                 var value = null;
81                 if ((type == "text-multi") || (type == "jid-multi")) {
82                     value = "";
83                     $(this).find("value").each(function() {
84                         value = value + $(this).text() + "\n";
85                     });
86                     item.val(value);
87                 } else if (type == "list-multi") {
88                     $(this).children("value").each(function() {
89                         item.children('option[value="' + $(this).text() + '"]').each(function() {
90                             $(this).attr("selected", "selected");
91                 });
92                     });
93                 } else {
94                     item.val($(this).find("value").text());
95                 }
96             }
97             if ($(x).attr("type") == "result")
98                 item.attr("readonly", true);
99             if ($(this).attr("var")) {
100                 item.attr("name", $(this).attr("var"));
101                 item.attr("id", $(this).attr("var"));
102             }
103             fieldset.append(item);
104             if (type != "hidden")
105                 fieldset.append("<br/>");
106         });
107         $(elem).append(form);
108     },
109
110     serializeToDataform: function (form) {
111         st = $build("x", {"xmlns": "jabber:x:data", "type": "submit"});
112         $(form).find(".df-item").each(function(){
113             st.c("field", {"var": $(this).attr("name")});
114             if (this.nodeName.toLowerCase() == "select" && this.multiple) {
115                 for (var i = 0; i < this.options.length; i++)
116                     if (this.options[i].selected)
117                         st.c("value").t(this.options[i].text).up();
118             } else if (this.nodeName.toLowerCase() == "textarea") {
119                 var sp_value = this.value.split(/\r?\n|\r/g);
120                 for(var i = 0; i < sp_value.length; i++)
121                     st.c("value").t(sp_value[i]).up();
122             } else if (this.nodeName.toLowerCase() == "input" && this.type == "checkbox") {
123                 if (this.checked) {
124                     st.c("value").t("1");
125                 } else {
126                     st.c("value").t("0");
127                 }
128             } else {
129                 // if this has value then
130                 st.c("value").t($(this).val()).up();
131             }
132             st.up();
133         });
134         st.up();
135         return st.tree();
136     },
137
138     displayResult: function (elem, result) {
139         var status = $(result).find("command").attr("status");
140         var kinds = {'prev': 'Prev', 'next': 'Next', 'complete': 'Complete'};
141
142         $(elem).empty();
143         $(result).find("command > *").each(function(index, e) {
144             if ($(e).is("note")) {
145                 Adhoc.addNote(elem, $(e).text(), $(e).attr("type"));
146             } else if ($(e).is("x[xmlns=jabber:x:data]")) {
147                 Adhoc.addForm(elem, e);
148             }
149         });
150         if (status == "executing") {
151             for (kind in kinds) {
152                 input = $("<input type='button' disabled='disabled' value='" + kinds[kind] + "'/>").click(function() {
153                     Adhoc.executeCommand(kind, (kind != 'prev') && Adhoc.serializeToDataform('form'), function(e) { Adhoc.displayResult(elem, e) });
154                 });
155                 if ($(result).find('actions ' + kind).length > 0)
156                     input.removeAttr("disabled");
157                 $(elem).append(input);
158             }
159
160             $("<input type='button' id='executeButton' value='Execute'/>").click(function() {
161                 Adhoc.executeCommand("execute", Adhoc.serializeToDataform('form'), function(e) { Adhoc.displayResult(elem, e) });
162             }).appendTo(elem);
163
164             $("<input type='button' value='Cancel'/>").click(function() {
165                 Adhoc.cancelCommand(function(e) { Adhoc.displayResult(elem, e) });
166             }).appendTo(elem);
167         } else {
168             input = $("<input type='button' value='Start over'/>").bind("click", function() {
169                 $(elem).empty();
170                 Adhoc.status.sessionid = null;
171                 Adhoc.status.cmdNode = null;
172                 Adhoc.getCommandNodes(elem);
173             });
174             $(elem).append(input);
175         }
176     },
177
178     runCommand: function (item, callback) {
179         Adhoc.status.cmdNode = $(item).attr("id"); // Save node of executed command (in global var)
180         Adhoc.executeCommand("execute", false, function(result) {
181             Adhoc.status.sessionid = $(result).find("command").attr("sessionid");
182             callback(result);
183         });
184     },
185
186     executeCommand: function (type, childs, callback) {
187         if (Adhoc.status.sessionid)
188             var execIQ = $iq({ type: "set", to: Adhoc.status.queryJID, id: connection.getUniqueId() })
189                 .c("command", { xmlns: Strophe.NS.ADHOC, node: Adhoc.status.cmdNode, sessionid: Adhoc.status.sessionid, action: type });
190         else
191             var execIQ = $iq({ type: "set", to: Adhoc.status.queryJID, id: connection.getUniqueId() })
192                 .c("command", { xmlns: Strophe.NS.ADHOC, node: Adhoc.status.cmdNode, action: type });
193         if (childs)
194             execIQ.cnode(childs);
195             connection.sendIQ(execIQ, callback);
196     },
197
198     cancelCommand: function (callback) {
199         Adhoc.executeCommand("cancel", false, callback);
200         Adhoc.status.cmdNode = null
201         Adhoc.status.sessionid = null;
202     },
203
204     getCommandNodes: function (elem) {
205         var nodesIQ = $iq({ type: "get", to: Adhoc.status.queryJID, id: connection.getUniqueId() }).c("query", {xmlns: Strophe.NS.DISCO_ITEMS, node: Strophe.NS.ADHOC});
206         connection.sendIQ(nodesIQ, function(result) {
207             var items = $("<ul></ul>");
208             $(elem).append(items);
209             $(result).find("item").each(function(index, e) {
210                 $("<li></li>").append($("<a href='#' id='" + $(e).attr("node") + "'>" + $(e).attr("name") + "</a>").click(function (event) {
211                     Adhoc.runCommand(this, function (result) { Adhoc.displayResult(elem, result); });
212                     event.preventDefault();
213                 })).appendTo(items);
214             });
215         });
216     },
217
218     checkFeatures: function (elem, jid) {
219         if (Adhoc.status.sessionid)
220             Adhoc.cancelCommand();
221         Adhoc.status.queryJID = jid;
222         var featureIQ = $iq({ type: "get", to: Adhoc.status.queryJID, id: connection.getUniqueId() }).c("query", {xmlns: Strophe.NS.DISCO_INFO});
223         $(elem).empty();
224         connection.sendIQ(featureIQ,
225             function(result) { /* Callback */
226                 if ($(result).find("feature[var='" + Strophe.NS.ADHOC + "']").length > 0) {
227                     Adhoc.getCommandNodes(elem);
228                 } else {
229                     $(elem).append("<p>" + Adhoc.status.queryJID + " does NOT support AdHoc commands</p>");
230                 }
231             },
232             function(result) { /* Errback */
233                 $(elem).append("<p>Couldn't get list of supported features</p>");
234             }
235         );
236     }
237
238 }