Wed, 24 Feb 2010 22:26:09 -0800
Making node-xml into a submodule. Gosh I hope I know what I'm doing.
12
1fe880c7383e
Add COPYING file, and add copyright header to xmpp.js reflecting the license
Matthew Wild <mwild1@gmail.com>
parents:
9
diff
changeset
|
1 | // xmpp.js - Server-side XMPP in Javascript |
1fe880c7383e
Add COPYING file, and add copyright header to xmpp.js reflecting the license
Matthew Wild <mwild1@gmail.com>
parents:
9
diff
changeset
|
2 | // (C) 2010 Matthew Wild |
1fe880c7383e
Add COPYING file, and add copyright header to xmpp.js reflecting the license
Matthew Wild <mwild1@gmail.com>
parents:
9
diff
changeset
|
3 | // This project is released under the MIT/X11 |
1fe880c7383e
Add COPYING file, and add copyright header to xmpp.js reflecting the license
Matthew Wild <mwild1@gmail.com>
parents:
9
diff
changeset
|
4 | // license. For more info see the COPYING file. |
1fe880c7383e
Add COPYING file, and add copyright header to xmpp.js reflecting the license
Matthew Wild <mwild1@gmail.com>
parents:
9
diff
changeset
|
5 | |
0 | 6 | // Node libs |
7 | var tcp = require("tcp"); | |
8 | ||
9 | // External libs | |
16
74a24eb1fb44
Making node-xml into a submodule. Gosh I hope I know what I'm doing.
zuwiki <zuwiki@gmail.com>
parents:
15
diff
changeset
|
10 | var xml = require("./node-xml/lib/node-xml"); |
0 | 11 | var sha1 = require("./sha1"); |
12 | ||
13 | // This lib | |
14 | var xmpp = exports; | |
15 | ||
16 | // Wraps a function so that its 'this' is always 'context' when called | |
17 | var recontext = function (context, f) { return function () { return f.apply(context, arguments); }; }; | |
18 | ||
19 | xmpp.xmlns = { | |
20 | streams: "http://etherx.jabber.org/streams", | |
14
aaad945d10ba
Adding node-xml.js by Rob Righter. Fixing up xmpp.js to work for me. Can't say exactly what all was wrong, other than apparent changes in the node.js TCP API.
zuwiki <zuwiki@gmail.com>
parents:
12
diff
changeset
|
21 | component_accept: "jabber:component:accept", |
aaad945d10ba
Adding node-xml.js by Rob Righter. Fixing up xmpp.js to work for me. Can't say exactly what all was wrong, other than apparent changes in the node.js TCP API.
zuwiki <zuwiki@gmail.com>
parents:
12
diff
changeset
|
22 | chatstates: "http://jabber.org/protocol/chatstates" |
0 | 23 | }; |
24 | ||
25 | xmpp.Status = { | |
26 | ERROR: 0, | |
27 | CONNECTING: 1, | |
28 | CONNFAIL: 2, | |
29 | AUTHENTICATING: 3, | |
30 | AUTHFAIL: 4, | |
31 | CONNECTED: 5, | |
32 | DISCONNECTED: 6, | |
33 | DISCONNECTING: 7, | |
34 | }; | |
35 | ||
36 | xmpp.LogLevel = { | |
37 | DEBUG: 0, | |
38 | INFO: 1, | |
39 | WARN: 2, | |
40 | ERROR: 3, | |
41 | FATAL: 4 | |
42 | }; | |
43 | /** XMPPStream: Takes a parser, eats bytes, fires callbacks on stream events **/ | |
44 | xmpp.Stream = function (callbacks) | |
45 | { | |
46 | this.callbacks = callbacks; | |
47 | var stream = this; | |
48 | var stanza; | |
49 | this.parser = new xml.SaxParser(function (cb) | |
50 | { | |
51 | cb.onStartElementNS(function (tagname, attr_arr, prefix, uri, namespaces) | |
52 | { | |
4
67b1d93509d3
Strip default stream namespace from stanza objects
Matthew Wild <mwild1@gmail.com>
parents:
3
diff
changeset
|
53 | var attr = {}; |
67b1d93509d3
Strip default stream namespace from stanza objects
Matthew Wild <mwild1@gmail.com>
parents:
3
diff
changeset
|
54 | if(uri != xmpp.xmlns.component_accept) |
67b1d93509d3
Strip default stream namespace from stanza objects
Matthew Wild <mwild1@gmail.com>
parents:
3
diff
changeset
|
55 | attr.xmlns = uri; |
0 | 56 | for(var i=0;i<attr_arr.length;i++) |
57 | attr[attr_arr[i][0]] = attr_arr[i][1]; | |
58 | for(var i=0;i<namespaces.length;i++) | |
59 | if(namespaces[i][0].length > 0) | |
60 | attr["xmlns:"+namespaces[i][0]] = namespaces[i][1]; | |
61 | if(!stanza) | |
62 | { | |
63 | if(stream.opened) | |
64 | stanza = xmpp.stanza(tagname, attr); | |
65 | else if(tagname == "stream" && uri == xmpp.xmlns.streams) | |
66 | { | |
67 | stream.opened = true; | |
68 | callbacks.opened(attr); | |
69 | } | |
70 | else | |
71 | { | |
72 | callbacks.error("no-stream"); | |
73 | } | |
74 | } | |
75 | else | |
76 | { | |
77 | stanza.c(tagname, attr); | |
78 | } | |
79 | ||
80 | }); | |
81 | ||
82 | cb.onEndElementNS(function(tagname) { | |
83 | if(stanza) | |
84 | if(stanza.last_node.length == 1) | |
85 | { | |
86 | callbacks.stanza(stanza); | |
87 | stanza = null; | |
88 | } | |
89 | else | |
90 | stanza.up(); | |
91 | else | |
92 | { | |
93 | stream.opened = false; | |
94 | callbacks.closed(); | |
95 | } | |
96 | }); | |
97 | ||
98 | cb.onCharacters(function(chars) { | |
99 | if(stanza) | |
100 | stanza.t(chars); | |
101 | }); | |
102 | }); | |
103 | ||
104 | this.data = function (data) | |
105 | { | |
106 | return this.parser.parseString(data); | |
107 | } | |
108 | ||
109 | return this; | |
110 | }; | |
111 | ||
112 | ||
113 | /** Connection: Takes host/port, manages stream **/ | |
114 | xmpp.Connection = function (host, port) | |
115 | { | |
116 | this.host = host || "localhost"; | |
117 | this.port = port || 5347; | |
118 | ||
119 | this.stream = new xmpp.Stream({ | |
120 | opened: recontext(this, this._stream_opened), | |
121 | stanza: recontext(this, this._handle_stanza), | |
122 | closed: recontext(this, this._stream_closed) | |
123 | }); | |
124 | ||
5 | 125 | this._uniqueId = 0; |
126 | ||
0 | 127 | return this; |
128 | }; | |
129 | ||
130 | exports.Connection.prototype = { | |
131 | connect: function (jid, pass, callback) | |
132 | { | |
133 | this.jid = jid; | |
134 | this.password = pass; | |
135 | this.connect_callback = callback; | |
136 | ||
137 | var conn = this; | |
15
b328899c936a
Cleaning up and documenting some changes.
zuwiki <zuwiki@gmail.com>
parents:
14
diff
changeset
|
138 | |
b328899c936a
Cleaning up and documenting some changes.
zuwiki <zuwiki@gmail.com>
parents:
14
diff
changeset
|
139 | // Note that tcp.createConnection also initiates the connection. |
b328899c936a
Cleaning up and documenting some changes.
zuwiki <zuwiki@gmail.com>
parents:
14
diff
changeset
|
140 | // This doesn't appear to create problems with adding listeners |
b328899c936a
Cleaning up and documenting some changes.
zuwiki <zuwiki@gmail.com>
parents:
14
diff
changeset
|
141 | // afterward, but should be kept in mind should any arise. |
14
aaad945d10ba
Adding node-xml.js by Rob Righter. Fixing up xmpp.js to work for me. Can't say exactly what all was wrong, other than apparent changes in the node.js TCP API.
zuwiki <zuwiki@gmail.com>
parents:
12
diff
changeset
|
142 | this.socket = tcp.createConnection(this.port, this.host) |
15
b328899c936a
Cleaning up and documenting some changes.
zuwiki <zuwiki@gmail.com>
parents:
14
diff
changeset
|
143 | |
0 | 144 | this.socket.addListener("connect", recontext(this, conn._socket_connected)); |
145 | this.socket.addListener("disconnect", recontext(this, conn._socket_disconnected)); | |
14
aaad945d10ba
Adding node-xml.js by Rob Righter. Fixing up xmpp.js to work for me. Can't say exactly what all was wrong, other than apparent changes in the node.js TCP API.
zuwiki <zuwiki@gmail.com>
parents:
12
diff
changeset
|
146 | this.socket.addListener("data", recontext(this, conn._socket_received)); |
0 | 147 | |
6 | 148 | this.handlers = []; |
149 | ||
0 | 150 | this._setStatus(xmpp.Status.CONNECTING); |
151 | }, | |
152 | ||
153 | send: function (data) | |
154 | { | |
155 | this.debug("SND: "+data); | |
14
aaad945d10ba
Adding node-xml.js by Rob Righter. Fixing up xmpp.js to work for me. Can't say exactly what all was wrong, other than apparent changes in the node.js TCP API.
zuwiki <zuwiki@gmail.com>
parents:
12
diff
changeset
|
156 | this.socket.write(data.toString()); |
0 | 157 | }, |
158 | ||
8 | 159 | sendIQ: function (iq, on_result, on_error) |
160 | { | |
161 | if(!iq.attr.id) | |
162 | iq.attr.id = this.getUniqueId(); | |
163 | this.addHandler(function (reply) { | |
164 | if(reply.attr.type == "result") | |
165 | return on_result(reply); | |
166 | elseif(on_error) | |
167 | return on_error(reply); | |
168 | return false; | |
169 | ||
170 | }, null, "iq", null, iq.attr.id); | |
171 | this.send(iq); | |
172 | }, | |
5 | 173 | |
6 | 174 | addHandler: function (handler, ns, name, type, id, from, options) |
175 | { | |
176 | return this.handlers.push({ | |
177 | callback: handler, | |
178 | xmlns: ns, | |
179 | name: name, | |
180 | type: type, | |
181 | id: id, | |
182 | from: from, | |
183 | matchBare: options && options.matchBare}); | |
184 | }, | |
185 | ||
5 | 186 | getUniqueId: function (suffix) |
187 | { | |
188 | return ++this._uniqueId + (suffix?(":"+suffix):""); | |
189 | }, | |
190 | ||
0 | 191 | // Update the status of the connection, call connect_callback |
192 | _setStatus: function (status, condition) | |
193 | { | |
194 | this.status = status; | |
195 | this.connect_callback(status, condition); | |
196 | }, | |
197 | ||
198 | // Socket listeners, called on TCP-level events | |
199 | _socket_connected: function () | |
200 | { | |
201 | this.info("CONNECTED."); | |
202 | this.send("<stream:stream xmlns='jabber:component:accept' xmlns:stream='http://etherx.jabber.org/streams' to='"+this.jid+"'>"); | |
203 | }, | |
204 | ||
205 | _socket_disconnected: function (had_error) | |
206 | { | |
207 | if(this.status == xmpp.Status.CONNECTING) | |
208 | this._setStatus(xmpp.Status.CONNFAIL); | |
209 | elseif(this.status == xmpp.Status.CONNECTED) | |
210 | this._setStatus(xmpp.Status.DISCONNECTED); | |
211 | this.info("DISCONNECTED."); | |
212 | }, | |
213 | ||
214 | _socket_received: function (data) | |
215 | { | |
216 | this.debug("RCV: "+data); | |
217 | // Push to parser | |
218 | this.stream.data(data); | |
219 | }, | |
220 | ||
221 | // Stream listeners, called on XMPP-level events | |
222 | _stream_opened: function (attr) | |
223 | { | |
224 | this.debug("STREAM: opened."); | |
225 | this._setStatus(xmpp.Status.AUTHENTICATING); | |
226 | var handshake = sha1.hex(attr.id + this.password); | |
227 | this.debug("Sending authentication token..."); | |
14
aaad945d10ba
Adding node-xml.js by Rob Righter. Fixing up xmpp.js to work for me. Can't say exactly what all was wrong, other than apparent changes in the node.js TCP API.
zuwiki <zuwiki@gmail.com>
parents:
12
diff
changeset
|
228 | this.debug("with id: '"+attr.id+"' and pass: '"+this.password+"'") |
0 | 229 | this.send("<handshake>"+handshake+"</handshake>"); |
230 | }, | |
231 | ||
232 | _handle_stanza: function (stanza) | |
233 | { | |
4
67b1d93509d3
Strip default stream namespace from stanza objects
Matthew Wild <mwild1@gmail.com>
parents:
3
diff
changeset
|
234 | if(!stanza.attr.xmlns) // Default namespace |
0 | 235 | { |
236 | if(stanza.name == "handshake") | |
237 | { | |
238 | this._setStatus(xmpp.Status.CONNECTED); | |
239 | } | |
240 | } | |
241 | this.debug("STANZA: "+stanza.toString()); | |
7
394b0c8cad04
Match and fire handler callbacks for incoming stanzas
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
242 | |
394b0c8cad04
Match and fire handler callbacks for incoming stanzas
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
243 | // Match and call handlers |
394b0c8cad04
Match and fire handler callbacks for incoming stanzas
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
244 | var removeHandlers = []; |
394b0c8cad04
Match and fire handler callbacks for incoming stanzas
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
245 | for(var i=0;i<this.handlers.length;i++) |
394b0c8cad04
Match and fire handler callbacks for incoming stanzas
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
246 | { |
394b0c8cad04
Match and fire handler callbacks for incoming stanzas
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
247 | var handler = this.handlers[i]; |
394b0c8cad04
Match and fire handler callbacks for incoming stanzas
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
248 | if( |
394b0c8cad04
Match and fire handler callbacks for incoming stanzas
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
249 | (!handler.name || handler.name == stanza.name) && |
394b0c8cad04
Match and fire handler callbacks for incoming stanzas
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
250 | (!handler.xmlns || (handler.xmlns == stanza.attr.xmlns |
394b0c8cad04
Match and fire handler callbacks for incoming stanzas
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
251 | || (stanza.tags[0] && handler.xmlns == stanza.tags[0].attr.xmlns))) && |
394b0c8cad04
Match and fire handler callbacks for incoming stanzas
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
252 | (!handler.type || handler.type == stanza.attr.type) && |
394b0c8cad04
Match and fire handler callbacks for incoming stanzas
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
253 | (!handler.id || handler.id == stanza.attr.id) && |
394b0c8cad04
Match and fire handler callbacks for incoming stanzas
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
254 | (!handler.from || (handler.from == (handler.matchBare?xmpp.getBareJID(stanza.attr.from):stanza.attr.from))) && |
394b0c8cad04
Match and fire handler callbacks for incoming stanzas
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
255 | (!handler.to || (handler.to == (handler.matchBare?xmpp.getBareJID(stanza.attr.to):stanza.attr.to))) |
394b0c8cad04
Match and fire handler callbacks for incoming stanzas
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
256 | ) |
394b0c8cad04
Match and fire handler callbacks for incoming stanzas
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
257 | { |
394b0c8cad04
Match and fire handler callbacks for incoming stanzas
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
258 | var ret = handler.callback(stanza); |
394b0c8cad04
Match and fire handler callbacks for incoming stanzas
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
259 | if(ret == false) |
394b0c8cad04
Match and fire handler callbacks for incoming stanzas
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
260 | removeHandlers.push(i); |
394b0c8cad04
Match and fire handler callbacks for incoming stanzas
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
261 | } |
394b0c8cad04
Match and fire handler callbacks for incoming stanzas
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
262 | } |
394b0c8cad04
Match and fire handler callbacks for incoming stanzas
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
263 | |
394b0c8cad04
Match and fire handler callbacks for incoming stanzas
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
264 | var adjust = 0; |
394b0c8cad04
Match and fire handler callbacks for incoming stanzas
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
265 | for(var i=0;i<removeHandlers.length;i++) |
394b0c8cad04
Match and fire handler callbacks for incoming stanzas
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
266 | this.handlers.splice(removeHandlers[i]-(adjust++), 1); |
0 | 267 | }, |
268 | ||
269 | _stream_closed: function () | |
270 | { | |
271 | this.debug("STREAM: closed."); | |
272 | this.socket.close(); | |
273 | if(this.status == xmpp.Status.CONNECTING) | |
274 | this._setStatus(xmpp.status.CONNFAIL); | |
275 | else | |
276 | this._setStatus(xmpp.Status.DISCONNECTED); | |
277 | }, | |
278 | ||
279 | _stream_error: function (condition) | |
280 | { | |
281 | this._setStatus(xmpp.Status.ERROR, condition); | |
282 | }, | |
283 | ||
284 | // Logging | |
285 | log: function (level, message) {}, | |
286 | debug: function (message) { return this.log(xmpp.LogLevel.DEBUG, message); }, | |
287 | info: function (message) { return this.log(xmpp.LogLevel.INFO , message); }, | |
288 | warn: function (message) { return this.log(xmpp.LogLevel.WARN , message); }, | |
289 | error: function (message) { return this.log(xmpp.LogLevel.ERROR, message); }, | |
290 | fatal: function (message) { return this.log(xmpp.LogLevel.FATAL, message); } | |
291 | ||
292 | }; | |
293 | ||
294 | function xmlescape(s) | |
295 | { | |
296 | return s.replace(/&/g, "&") | |
297 | .replace(/</g, "<") | |
298 | .replace(/>/g, ">") | |
1 | 299 | .replace(/\"/g, """) |
300 | .replace(/\'/g, "'"); | |
0 | 301 | } |
302 | ||
303 | /** StanzaBuilder: Helps create and manipulate XML snippets **/ | |
304 | xmpp.StanzaBuilder = function (name, attr) | |
305 | { | |
306 | this.name = name; | |
307 | this.attr = attr || {}; | |
308 | this.tags = []; | |
309 | this.children = []; | |
310 | this.last_node = [this]; | |
311 | return this; | |
312 | }; | |
313 | ||
314 | xmpp.StanzaBuilder.prototype = { | |
14
aaad945d10ba
Adding node-xml.js by Rob Righter. Fixing up xmpp.js to work for me. Can't say exactly what all was wrong, other than apparent changes in the node.js TCP API.
zuwiki <zuwiki@gmail.com>
parents:
12
diff
changeset
|
315 | s: function (name, attr) |
aaad945d10ba
Adding node-xml.js by Rob Righter. Fixing up xmpp.js to work for me. Can't say exactly what all was wrong, other than apparent changes in the node.js TCP API.
zuwiki <zuwiki@gmail.com>
parents:
12
diff
changeset
|
316 | { |
15
b328899c936a
Cleaning up and documenting some changes.
zuwiki <zuwiki@gmail.com>
parents:
14
diff
changeset
|
317 | // This function was created because c() doesn't seem to work for adding |
b328899c936a
Cleaning up and documenting some changes.
zuwiki <zuwiki@gmail.com>
parents:
14
diff
changeset
|
318 | // multiple children on the same level with each other. This is just a |
b328899c936a
Cleaning up and documenting some changes.
zuwiki <zuwiki@gmail.com>
parents:
14
diff
changeset
|
319 | // quick fix mostly to get chatstates working. |
14
aaad945d10ba
Adding node-xml.js by Rob Righter. Fixing up xmpp.js to work for me. Can't say exactly what all was wrong, other than apparent changes in the node.js TCP API.
zuwiki <zuwiki@gmail.com>
parents:
12
diff
changeset
|
320 | var s = new xmpp.StanzaBuilder(name, attr); |
aaad945d10ba
Adding node-xml.js by Rob Righter. Fixing up xmpp.js to work for me. Can't say exactly what all was wrong, other than apparent changes in the node.js TCP API.
zuwiki <zuwiki@gmail.com>
parents:
12
diff
changeset
|
321 | var parent = this; |
aaad945d10ba
Adding node-xml.js by Rob Righter. Fixing up xmpp.js to work for me. Can't say exactly what all was wrong, other than apparent changes in the node.js TCP API.
zuwiki <zuwiki@gmail.com>
parents:
12
diff
changeset
|
322 | parent.tags.push(s); |
aaad945d10ba
Adding node-xml.js by Rob Righter. Fixing up xmpp.js to work for me. Can't say exactly what all was wrong, other than apparent changes in the node.js TCP API.
zuwiki <zuwiki@gmail.com>
parents:
12
diff
changeset
|
323 | parent.children.push(s); |
aaad945d10ba
Adding node-xml.js by Rob Righter. Fixing up xmpp.js to work for me. Can't say exactly what all was wrong, other than apparent changes in the node.js TCP API.
zuwiki <zuwiki@gmail.com>
parents:
12
diff
changeset
|
324 | this.last_node.push(s); |
aaad945d10ba
Adding node-xml.js by Rob Righter. Fixing up xmpp.js to work for me. Can't say exactly what all was wrong, other than apparent changes in the node.js TCP API.
zuwiki <zuwiki@gmail.com>
parents:
12
diff
changeset
|
325 | return this |
aaad945d10ba
Adding node-xml.js by Rob Righter. Fixing up xmpp.js to work for me. Can't say exactly what all was wrong, other than apparent changes in the node.js TCP API.
zuwiki <zuwiki@gmail.com>
parents:
12
diff
changeset
|
326 | }, |
aaad945d10ba
Adding node-xml.js by Rob Righter. Fixing up xmpp.js to work for me. Can't say exactly what all was wrong, other than apparent changes in the node.js TCP API.
zuwiki <zuwiki@gmail.com>
parents:
12
diff
changeset
|
327 | |
0 | 328 | c: function (name, attr) |
329 | { | |
330 | var s = new xmpp.StanzaBuilder(name, attr); | |
331 | var parent = this.last_node[this.last_node.length-1]; | |
332 | parent.tags.push(s); | |
333 | parent.children.push(s); | |
334 | this.last_node.push(s); | |
335 | return this; | |
336 | }, | |
337 | ||
338 | t: function (text) | |
339 | { | |
340 | var parent = this.last_node[this.last_node.length-1]; | |
341 | parent.children.push(text); | |
342 | return this; | |
343 | }, | |
344 | ||
345 | up: function () | |
346 | { | |
347 | this.last_node.pop(); | |
348 | return this; | |
349 | }, | |
350 | ||
351 | toString: function (top_tag_only) | |
352 | { | |
353 | var buf = []; | |
354 | buf.push("<" + this.name); | |
355 | for(var attr in this.attr) | |
356 | { | |
357 | buf.push(" " + attr + "='" + xmlescape(this.attr[attr]) + "'"); | |
358 | } | |
359 | ||
360 | // Now add children if wanted | |
361 | if(top_tag_only) | |
362 | { | |
363 | buf.push(">"); | |
364 | } | |
365 | else if(this.children.length == 0) | |
366 | { | |
367 | buf.push("/>"); | |
368 | } | |
369 | else | |
370 | { | |
371 | buf.push(">"); | |
372 | for(var i = 0; i<this.children.length; i++) | |
373 | { | |
374 | var child = this.children[i]; | |
375 | if(typeof(child) == "string") | |
376 | buf.push(xmlescape(child)); | |
377 | else | |
378 | buf.push(child.toString()); | |
379 | } | |
380 | buf.push("</" + this.name + ">"); | |
381 | } | |
382 | return buf.join(""); | |
2
b88bcbbe08e1
Add stanza.getChild(name, xmlns) method to mirror Prosody's API
Matthew Wild <mwild1@gmail.com>
parents:
1
diff
changeset
|
383 | }, |
b88bcbbe08e1
Add stanza.getChild(name, xmlns) method to mirror Prosody's API
Matthew Wild <mwild1@gmail.com>
parents:
1
diff
changeset
|
384 | |
b88bcbbe08e1
Add stanza.getChild(name, xmlns) method to mirror Prosody's API
Matthew Wild <mwild1@gmail.com>
parents:
1
diff
changeset
|
385 | getChild: function (name, xmlns) { |
b88bcbbe08e1
Add stanza.getChild(name, xmlns) method to mirror Prosody's API
Matthew Wild <mwild1@gmail.com>
parents:
1
diff
changeset
|
386 | for(var i=0;i<this.tags.length;i++) |
b88bcbbe08e1
Add stanza.getChild(name, xmlns) method to mirror Prosody's API
Matthew Wild <mwild1@gmail.com>
parents:
1
diff
changeset
|
387 | { |
b88bcbbe08e1
Add stanza.getChild(name, xmlns) method to mirror Prosody's API
Matthew Wild <mwild1@gmail.com>
parents:
1
diff
changeset
|
388 | var child = this.tags[i]; |
b88bcbbe08e1
Add stanza.getChild(name, xmlns) method to mirror Prosody's API
Matthew Wild <mwild1@gmail.com>
parents:
1
diff
changeset
|
389 | if((!name || child.name == name) && (!xmlns || child.attr.xmlns == xmlns)) |
b88bcbbe08e1
Add stanza.getChild(name, xmlns) method to mirror Prosody's API
Matthew Wild <mwild1@gmail.com>
parents:
1
diff
changeset
|
390 | return child; |
b88bcbbe08e1
Add stanza.getChild(name, xmlns) method to mirror Prosody's API
Matthew Wild <mwild1@gmail.com>
parents:
1
diff
changeset
|
391 | } |
b88bcbbe08e1
Add stanza.getChild(name, xmlns) method to mirror Prosody's API
Matthew Wild <mwild1@gmail.com>
parents:
1
diff
changeset
|
392 | return null; |
b88bcbbe08e1
Add stanza.getChild(name, xmlns) method to mirror Prosody's API
Matthew Wild <mwild1@gmail.com>
parents:
1
diff
changeset
|
393 | }, |
3
2d83fe899f5f
Add stanza.getText() to retrieve all text nodes joined as a string
Matthew Wild <mwild1@gmail.com>
parents:
2
diff
changeset
|
394 | |
2d83fe899f5f
Add stanza.getText() to retrieve all text nodes joined as a string
Matthew Wild <mwild1@gmail.com>
parents:
2
diff
changeset
|
395 | getText: function () { |
2d83fe899f5f
Add stanza.getText() to retrieve all text nodes joined as a string
Matthew Wild <mwild1@gmail.com>
parents:
2
diff
changeset
|
396 | var buf = []; |
2d83fe899f5f
Add stanza.getText() to retrieve all text nodes joined as a string
Matthew Wild <mwild1@gmail.com>
parents:
2
diff
changeset
|
397 | for(var i=0;i<this.children.length;i++) |
2d83fe899f5f
Add stanza.getText() to retrieve all text nodes joined as a string
Matthew Wild <mwild1@gmail.com>
parents:
2
diff
changeset
|
398 | if(typeof(this.children[i]) == "string") |
2d83fe899f5f
Add stanza.getText() to retrieve all text nodes joined as a string
Matthew Wild <mwild1@gmail.com>
parents:
2
diff
changeset
|
399 | buf.push(this.children[i]); |
2d83fe899f5f
Add stanza.getText() to retrieve all text nodes joined as a string
Matthew Wild <mwild1@gmail.com>
parents:
2
diff
changeset
|
400 | return buf.join(""); |
9
c4ff2c2fea6d
Add stanza.getAttribute() method
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
401 | }, |
c4ff2c2fea6d
Add stanza.getAttribute() method
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
402 | |
c4ff2c2fea6d
Add stanza.getAttribute() method
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
403 | getAttribute: function (name) { |
c4ff2c2fea6d
Add stanza.getAttribute() method
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
404 | return this.attr[name] || null; |
0 | 405 | } |
406 | } | |
407 | ||
408 | xmpp.stanza = function (name, attr) | |
409 | { | |
410 | return new xmpp.StanzaBuilder(name, attr); | |
411 | } | |
412 | ||
413 | xmpp.message = function (attr) | |
414 | { | |
415 | return xmpp.stanza("message", attr); | |
416 | } | |
417 | ||
418 | xmpp.presence = function (attr) | |
419 | { | |
420 | return xmpp.stanza("presence", attr); | |
421 | } | |
422 | ||
423 | xmpp.iq = function (attr) | |
424 | { | |
425 | return xmpp.stanza("iq", attr); | |
426 | } |