Sun, 21 Feb 2010 15:25:11 -0800
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.
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 | |
10 | var xml = require("./node-xml"); | |
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); | |
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
|
65 | /* else if(tagname == "stream") */ |
0 | 66 | else if(tagname == "stream" && uri == xmpp.xmlns.streams) |
67 | { | |
68 | stream.opened = true; | |
69 | callbacks.opened(attr); | |
70 | } | |
71 | else | |
72 | { | |
73 | callbacks.error("no-stream"); | |
74 | } | |
75 | } | |
76 | else | |
77 | { | |
78 | stanza.c(tagname, attr); | |
79 | } | |
80 | ||
81 | }); | |
82 | ||
83 | cb.onEndElementNS(function(tagname) { | |
84 | if(stanza) | |
85 | if(stanza.last_node.length == 1) | |
86 | { | |
87 | callbacks.stanza(stanza); | |
88 | stanza = null; | |
89 | } | |
90 | else | |
91 | stanza.up(); | |
92 | else | |
93 | { | |
94 | stream.opened = false; | |
95 | callbacks.closed(); | |
96 | } | |
97 | }); | |
98 | ||
99 | cb.onCharacters(function(chars) { | |
100 | if(stanza) | |
101 | stanza.t(chars); | |
102 | }); | |
103 | }); | |
104 | ||
105 | this.data = function (data) | |
106 | { | |
107 | return this.parser.parseString(data); | |
108 | } | |
109 | ||
110 | return this; | |
111 | }; | |
112 | ||
113 | ||
114 | /** Connection: Takes host/port, manages stream **/ | |
115 | xmpp.Connection = function (host, port) | |
116 | { | |
117 | this.host = host || "localhost"; | |
118 | this.port = port || 5347; | |
119 | ||
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
|
120 | /** this.socket = tcp.createConnection(); |
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
|
121 | this.socket.close() **/ |
0 | 122 | |
123 | this.stream = new xmpp.Stream({ | |
124 | opened: recontext(this, this._stream_opened), | |
125 | stanza: recontext(this, this._handle_stanza), | |
126 | closed: recontext(this, this._stream_closed) | |
127 | }); | |
128 | ||
5 | 129 | this._uniqueId = 0; |
130 | ||
0 | 131 | return this; |
132 | }; | |
133 | ||
134 | exports.Connection.prototype = { | |
135 | connect: function (jid, pass, callback) | |
136 | { | |
137 | this.jid = jid; | |
138 | this.password = pass; | |
139 | this.connect_callback = callback; | |
140 | ||
141 | var conn = this; | |
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) |
0 | 143 | this.socket.addListener("connect", recontext(this, conn._socket_connected)); |
144 | 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
|
145 | this.socket.addListener("data", recontext(this, conn._socket_received)); |
0 | 146 | |
6 | 147 | this.handlers = []; |
148 | ||
0 | 149 | // Connect TCP socket |
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
|
150 | // this.socket.connect(this.port, this.host); |
0 | 151 | |
152 | this._setStatus(xmpp.Status.CONNECTING); | |
153 | }, | |
154 | ||
155 | send: function (data) | |
156 | { | |
157 | 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
|
158 | this.socket.write(data.toString()); |
0 | 159 | }, |
160 | ||
8 | 161 | sendIQ: function (iq, on_result, on_error) |
162 | { | |
163 | if(!iq.attr.id) | |
164 | iq.attr.id = this.getUniqueId(); | |
165 | this.addHandler(function (reply) { | |
166 | if(reply.attr.type == "result") | |
167 | return on_result(reply); | |
168 | elseif(on_error) | |
169 | return on_error(reply); | |
170 | return false; | |
171 | ||
172 | }, null, "iq", null, iq.attr.id); | |
173 | this.send(iq); | |
174 | }, | |
5 | 175 | |
6 | 176 | addHandler: function (handler, ns, name, type, id, from, options) |
177 | { | |
178 | return this.handlers.push({ | |
179 | callback: handler, | |
180 | xmlns: ns, | |
181 | name: name, | |
182 | type: type, | |
183 | id: id, | |
184 | from: from, | |
185 | matchBare: options && options.matchBare}); | |
186 | }, | |
187 | ||
5 | 188 | getUniqueId: function (suffix) |
189 | { | |
190 | return ++this._uniqueId + (suffix?(":"+suffix):""); | |
191 | }, | |
192 | ||
0 | 193 | // Update the status of the connection, call connect_callback |
194 | _setStatus: function (status, condition) | |
195 | { | |
196 | this.status = status; | |
197 | this.connect_callback(status, condition); | |
198 | }, | |
199 | ||
200 | // Socket listeners, called on TCP-level events | |
201 | _socket_connected: function () | |
202 | { | |
203 | this.info("CONNECTED."); | |
204 | this.send("<stream:stream xmlns='jabber:component:accept' xmlns:stream='http://etherx.jabber.org/streams' to='"+this.jid+"'>"); | |
205 | }, | |
206 | ||
207 | _socket_disconnected: function (had_error) | |
208 | { | |
209 | if(this.status == xmpp.Status.CONNECTING) | |
210 | this._setStatus(xmpp.Status.CONNFAIL); | |
211 | elseif(this.status == xmpp.Status.CONNECTED) | |
212 | this._setStatus(xmpp.Status.DISCONNECTED); | |
213 | this.info("DISCONNECTED."); | |
214 | }, | |
215 | ||
216 | _socket_received: function (data) | |
217 | { | |
218 | this.debug("RCV: "+data); | |
219 | // Push to parser | |
220 | this.stream.data(data); | |
221 | }, | |
222 | ||
223 | // Stream listeners, called on XMPP-level events | |
224 | _stream_opened: function (attr) | |
225 | { | |
226 | this.debug("STREAM: opened."); | |
227 | this._setStatus(xmpp.Status.AUTHENTICATING); | |
228 | var handshake = sha1.hex(attr.id + this.password); | |
229 | 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
|
230 | this.debug("with id: '"+attr.id+"' and pass: '"+this.password+"'") |
0 | 231 | this.send("<handshake>"+handshake+"</handshake>"); |
232 | }, | |
233 | ||
234 | _handle_stanza: function (stanza) | |
235 | { | |
4
67b1d93509d3
Strip default stream namespace from stanza objects
Matthew Wild <mwild1@gmail.com>
parents:
3
diff
changeset
|
236 | if(!stanza.attr.xmlns) // Default namespace |
0 | 237 | { |
238 | if(stanza.name == "handshake") | |
239 | { | |
240 | this._setStatus(xmpp.Status.CONNECTED); | |
241 | } | |
242 | } | |
243 | this.debug("STANZA: "+stanza.toString()); | |
7
394b0c8cad04
Match and fire handler callbacks for incoming stanzas
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
244 | |
394b0c8cad04
Match and fire handler callbacks for incoming stanzas
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
245 | // Match and call handlers |
394b0c8cad04
Match and fire handler callbacks for incoming stanzas
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
246 | var removeHandlers = []; |
394b0c8cad04
Match and fire handler callbacks for incoming stanzas
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
247 | 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
|
248 | { |
394b0c8cad04
Match and fire handler callbacks for incoming stanzas
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
249 | var handler = this.handlers[i]; |
394b0c8cad04
Match and fire handler callbacks for incoming stanzas
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
250 | if( |
394b0c8cad04
Match and fire handler callbacks for incoming stanzas
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
251 | (!handler.name || handler.name == stanza.name) && |
394b0c8cad04
Match and fire handler callbacks for incoming stanzas
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
252 | (!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
|
253 | || (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
|
254 | (!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
|
255 | (!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
|
256 | (!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
|
257 | (!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
|
258 | ) |
394b0c8cad04
Match and fire handler callbacks for incoming stanzas
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
259 | { |
394b0c8cad04
Match and fire handler callbacks for incoming stanzas
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
260 | var ret = handler.callback(stanza); |
394b0c8cad04
Match and fire handler callbacks for incoming stanzas
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
261 | if(ret == false) |
394b0c8cad04
Match and fire handler callbacks for incoming stanzas
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
262 | removeHandlers.push(i); |
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 | } |
394b0c8cad04
Match and fire handler callbacks for incoming stanzas
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
265 | |
394b0c8cad04
Match and fire handler callbacks for incoming stanzas
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
266 | var adjust = 0; |
394b0c8cad04
Match and fire handler callbacks for incoming stanzas
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
267 | 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
|
268 | this.handlers.splice(removeHandlers[i]-(adjust++), 1); |
0 | 269 | }, |
270 | ||
271 | _stream_closed: function () | |
272 | { | |
273 | this.debug("STREAM: closed."); | |
274 | this.socket.close(); | |
275 | if(this.status == xmpp.Status.CONNECTING) | |
276 | this._setStatus(xmpp.status.CONNFAIL); | |
277 | else | |
278 | this._setStatus(xmpp.Status.DISCONNECTED); | |
279 | }, | |
280 | ||
281 | _stream_error: function (condition) | |
282 | { | |
283 | this._setStatus(xmpp.Status.ERROR, condition); | |
284 | }, | |
285 | ||
286 | // Logging | |
287 | log: function (level, message) {}, | |
288 | debug: function (message) { return this.log(xmpp.LogLevel.DEBUG, message); }, | |
289 | info: function (message) { return this.log(xmpp.LogLevel.INFO , message); }, | |
290 | warn: function (message) { return this.log(xmpp.LogLevel.WARN , message); }, | |
291 | error: function (message) { return this.log(xmpp.LogLevel.ERROR, message); }, | |
292 | fatal: function (message) { return this.log(xmpp.LogLevel.FATAL, message); } | |
293 | ||
294 | }; | |
295 | ||
296 | function xmlescape(s) | |
297 | { | |
298 | return s.replace(/&/g, "&") | |
299 | .replace(/</g, "<") | |
300 | .replace(/>/g, ">") | |
1 | 301 | .replace(/\"/g, """) |
302 | .replace(/\'/g, "'"); | |
0 | 303 | } |
304 | ||
305 | /** StanzaBuilder: Helps create and manipulate XML snippets **/ | |
306 | xmpp.StanzaBuilder = function (name, attr) | |
307 | { | |
308 | this.name = name; | |
309 | this.attr = attr || {}; | |
310 | this.tags = []; | |
311 | this.children = []; | |
312 | this.last_node = [this]; | |
313 | return this; | |
314 | }; | |
315 | ||
316 | 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
|
317 | 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
|
318 | { |
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
|
319 | 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
|
320 | 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
|
321 | 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
|
322 | 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
|
323 | 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
|
324 | 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
|
325 | }, |
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 | |
0 | 327 | c: function (name, attr) |
328 | { | |
329 | var s = new xmpp.StanzaBuilder(name, attr); | |
330 | var parent = this.last_node[this.last_node.length-1]; | |
331 | parent.tags.push(s); | |
332 | parent.children.push(s); | |
333 | this.last_node.push(s); | |
334 | return this; | |
335 | }, | |
336 | ||
337 | t: function (text) | |
338 | { | |
339 | var parent = this.last_node[this.last_node.length-1]; | |
340 | parent.children.push(text); | |
341 | return this; | |
342 | }, | |
343 | ||
344 | up: function () | |
345 | { | |
346 | this.last_node.pop(); | |
347 | return this; | |
348 | }, | |
349 | ||
350 | toString: function (top_tag_only) | |
351 | { | |
352 | var buf = []; | |
353 | buf.push("<" + this.name); | |
354 | for(var attr in this.attr) | |
355 | { | |
356 | buf.push(" " + attr + "='" + xmlescape(this.attr[attr]) + "'"); | |
357 | } | |
358 | ||
359 | // Now add children if wanted | |
360 | if(top_tag_only) | |
361 | { | |
362 | buf.push(">"); | |
363 | } | |
364 | else if(this.children.length == 0) | |
365 | { | |
366 | buf.push("/>"); | |
367 | } | |
368 | else | |
369 | { | |
370 | buf.push(">"); | |
371 | for(var i = 0; i<this.children.length; i++) | |
372 | { | |
373 | var child = this.children[i]; | |
374 | if(typeof(child) == "string") | |
375 | buf.push(xmlescape(child)); | |
376 | else | |
377 | buf.push(child.toString()); | |
378 | } | |
379 | buf.push("</" + this.name + ">"); | |
380 | } | |
381 | 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
|
382 | }, |
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 | 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
|
385 | 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
|
386 | { |
b88bcbbe08e1
Add stanza.getChild(name, xmlns) method to mirror Prosody's API
Matthew Wild <mwild1@gmail.com>
parents:
1
diff
changeset
|
387 | 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
|
388 | 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
|
389 | return child; |
b88bcbbe08e1
Add stanza.getChild(name, xmlns) method to mirror Prosody's API
Matthew Wild <mwild1@gmail.com>
parents:
1
diff
changeset
|
390 | } |
b88bcbbe08e1
Add stanza.getChild(name, xmlns) method to mirror Prosody's API
Matthew Wild <mwild1@gmail.com>
parents:
1
diff
changeset
|
391 | return null; |
b88bcbbe08e1
Add stanza.getChild(name, xmlns) method to mirror Prosody's API
Matthew Wild <mwild1@gmail.com>
parents:
1
diff
changeset
|
392 | }, |
3
2d83fe899f5f
Add stanza.getText() to retrieve all text nodes joined as a string
Matthew Wild <mwild1@gmail.com>
parents:
2
diff
changeset
|
393 | |
2d83fe899f5f
Add stanza.getText() to retrieve all text nodes joined as a string
Matthew Wild <mwild1@gmail.com>
parents:
2
diff
changeset
|
394 | getText: function () { |
2d83fe899f5f
Add stanza.getText() to retrieve all text nodes joined as a string
Matthew Wild <mwild1@gmail.com>
parents:
2
diff
changeset
|
395 | var buf = []; |
2d83fe899f5f
Add stanza.getText() to retrieve all text nodes joined as a string
Matthew Wild <mwild1@gmail.com>
parents:
2
diff
changeset
|
396 | 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
|
397 | 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
|
398 | 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
|
399 | return buf.join(""); |
9
c4ff2c2fea6d
Add stanza.getAttribute() method
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
400 | }, |
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 | getAttribute: function (name) { |
c4ff2c2fea6d
Add stanza.getAttribute() method
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
403 | return this.attr[name] || null; |
0 | 404 | } |
405 | } | |
406 | ||
407 | xmpp.stanza = function (name, attr) | |
408 | { | |
409 | return new xmpp.StanzaBuilder(name, attr); | |
410 | } | |
411 | ||
412 | xmpp.message = function (attr) | |
413 | { | |
414 | return xmpp.stanza("message", attr); | |
415 | } | |
416 | ||
417 | xmpp.presence = function (attr) | |
418 | { | |
419 | return xmpp.stanza("presence", attr); | |
420 | } | |
421 | ||
422 | xmpp.iq = function (attr) | |
423 | { | |
424 | return xmpp.stanza("iq", attr); | |
425 | } |