xmppify 0.0.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/app/assets/javascripts/xmpp/index.js +0 -0
- data/app/assets/javascripts/xmpp/scripts/checkplayer.js +12 -0
- data/app/assets/javascripts/xmpp/scripts/crossdomain.xml +7 -0
- data/app/assets/javascripts/xmpp/scripts/flXHR.js +2 -0
- data/app/assets/javascripts/xmpp/scripts/flXHR.swf +0 -0
- data/app/assets/javascripts/xmpp/scripts/flXHR.vbs +44 -0
- data/app/assets/javascripts/xmpp/scripts/flensed.js +12 -0
- data/app/assets/javascripts/xmpp/scripts/strophe.flxhr.js +31 -0
- data/app/assets/javascripts/xmpp/scripts/strophe.js +3538 -0
- data/app/assets/javascripts/xmpp/scripts/swfobject.js +5 -0
- data/app/assets/javascripts/xmpp/scripts/updateplayer.swf +0 -0
- data/app/assets/javascripts/xmpp/scripts/xmpp.js.coffee +386 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/LICENSE.txt +19 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/README.markdown +95 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/archive/README.markdown +14 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/archive/iso8601_support.js +32 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/archive/strophe.archive.js +88 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/caps/README.markdown +53 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/caps/sha1.js +202 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/caps/strophe.CAPS.coffee +153 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/caps/strophe.CAPS.js +88 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/caps/strophe.caps.jsonly.js +240 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/chatstates/strophe.chatstates.js +80 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/cmds/README.markdown +47 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/cmds/spec/GetUrlComamndSpec.js +66 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/cmds/spec/strophe.cmds.spec.coffee +145 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/cmds/spec/support/jasmine.json +16 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/cmds/src/strophe.cmds.coffee +265 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/cmds/src/strophe.cmds.js +403 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/dataforms/README.markdown +82 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/dataforms/spec/strophe.x.coffee +715 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/dataforms/src/strophe.x.coffee +443 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/dataforms/src/strophe.x.js +854 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/.gitignore +1 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/README.markdown +0 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/convert.js +13 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/jasmine.json +11 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/lib/strophe.disco.js +137 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/public/javascript/strophe.disco.js +137 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/01_querying_information.xml +6 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/02_result_set_for_information_request.xml +22 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/03_target_entity_does_not_exist.xml +10 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/04_service_unavailable.xml +11 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/09_querying_specific_jid_and_node_combination.xml +7 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/10_jid_and_node_result.xml +12 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/11_requesting_all_items.xml +6 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/12_result_set_for_all_items.xml +23 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/13_empty_result_set.xml +7 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/17_service_returns_nodes.xml +16 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/18_requesting_further_nodes.xml +7 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/24_jid_and_node_error.xml +11 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/DiscoNodeSpec.js +50 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/SpecHelper.js +51 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/Stanzas.js +0 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/strophe.disco.spec.helper.js +54 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/strophe.disco.spec.js +0 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/support/jasmine.json +13 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/strophe.disco.js +232 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/epic/public/javascript/jquery.epic.js +61 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/epic/spec/SpecHelper.js +9 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/epic/spec/jquery.epic.js +39 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/epic/spec/support/jasmine.json +22 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/iexdomain/iexdomain.js +36 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/joap/README.markdown +117 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/joap/buster.js +23 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/joap/jid.coffee +64 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/joap/jid.js +92 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/joap/spec/browserSetup.coffee +1 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/joap/spec/jid.spec.coffee +96 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/joap/spec/strophe.joap.spec.coffee +461 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/joap/strophe.joap.coffee +304 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/joap/strophe.joap.js +522 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/mam/LICENSE.txt +19 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/mam/README.markdown +52 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/mam/strophe.mam.js +62 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/muc/LICENSE.txt +20 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/muc/strophe.muc.js +1003 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/ping/README.markdown +28 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/ping/strophe.ping.js +68 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/private/README.markdown +16 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/private/strophe.private.js +192 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/pubsub/strophe.pubsub.js +555 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/receipts/strophe.receipts.js +155 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/register/README.markdown +44 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/register/strophe.register.js +431 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/roster/public/javascript/strophe.roster.js +40 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/roster/spec/strophe.roster.spec.js +65 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/roster/spec/support/jasmine.json +15 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/roster/strophe.roster.js +438 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/rpc/.gitignore +6 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/rpc/README.md +113 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/rpc/buster.js +11 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/rpc/lib/strophe.js +4198 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/rpc/spec/strophe.rpc.spec.helper.js +38 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/rpc/spec/strophe.rpc.spec.js +262 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/rpc/strophe.rpc.js +464 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/rsm/strophe.rsm.js +52 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/serverdate/strophe.serverdate.js +58 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/vcard/examples/index.html +17 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/vcard/examples/strophevcard.js +0 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/vcard/strophe.vcard.coffee +44 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/vcard/strophe.vcard.js +66 -0
- data/app/assets/stylesheets/xmpp/index.css +0 -0
- data/app/controllers/omniauth_callbacks_controller.rb +15 -0
- data/app/controllers/ruby_bosh.rb +221 -0
- data/app/models/identity.rb +3 -0
- data/app/models/user.rb +40 -0
- data/bin/rails +8 -0
- data/db/migrate/20140329065635_create_users.rb +10 -0
- data/db/migrate/20140329070238_create_identities.rb +11 -0
- data/lib/xmppify/version.rb +3 -0
- data/lib/xmppify.rb +6 -0
- data/xmppify.gemspec +23 -0
- metadata +197 -0
@@ -0,0 +1,464 @@
|
|
1
|
+
/**
|
2
|
+
* This program is distributed under the terms of the MIT license.
|
3
|
+
*
|
4
|
+
* Copyright 2011 (c) Pierre Guilleminot <pierre.guilleminot@gmail.com>
|
5
|
+
*/
|
6
|
+
|
7
|
+
/**
|
8
|
+
* Jabber-RPC plugin (XEP-0009)
|
9
|
+
* Allow the management of RPC
|
10
|
+
*/
|
11
|
+
Strophe.addConnectionPlugin("rpc", {
|
12
|
+
|
13
|
+
_connection : undefined,
|
14
|
+
|
15
|
+
_whitelistEnabled : false,
|
16
|
+
|
17
|
+
jidWhiteList : [],
|
18
|
+
nodeWhiteList : [],
|
19
|
+
domainWhiteList : [],
|
20
|
+
|
21
|
+
/**
|
22
|
+
* Plugin init
|
23
|
+
*
|
24
|
+
* @param {Strophe.Connection} connection Strophe connection
|
25
|
+
*/
|
26
|
+
init: function(connection) {
|
27
|
+
|
28
|
+
this._connection = connection;
|
29
|
+
|
30
|
+
this._whitelistEnabled = false;
|
31
|
+
|
32
|
+
this.jidWhiteList = [];
|
33
|
+
this.nodeWhiteList = [];
|
34
|
+
this.domainWhiteList = [];
|
35
|
+
|
36
|
+
Strophe.addNamespace("RPC", "jabber:iq:rpc");
|
37
|
+
|
38
|
+
if (!connection.hasOwnProperty("disco")) {
|
39
|
+
Strophe.warn("You need the discovery plugin " +
|
40
|
+
"to have Jabber-RPC fully implemented.");
|
41
|
+
}
|
42
|
+
else {
|
43
|
+
this._connection.disco.addIdentity("automation", "rpc");
|
44
|
+
this._connection.disco.addFeature(Strophe.NS.RPC);
|
45
|
+
}
|
46
|
+
},
|
47
|
+
|
48
|
+
/**
|
49
|
+
* Add a jid or an array of jids to
|
50
|
+
* the whitelist.
|
51
|
+
* It's possible to use wildecards for the domain
|
52
|
+
* or the node. ie:
|
53
|
+
* *@*
|
54
|
+
* myname@*
|
55
|
+
* *@jabber.org
|
56
|
+
*
|
57
|
+
* @param {String|Array} jid
|
58
|
+
*/
|
59
|
+
addJidToWhiteList: function(jids) {
|
60
|
+
if (typeof(jids.sort) !== "function") {
|
61
|
+
jids = [jids];
|
62
|
+
}
|
63
|
+
|
64
|
+
for (var i = 0; i < jids.length; i++) {
|
65
|
+
var jid = jids[i];
|
66
|
+
|
67
|
+
if (jid === "*@*") {
|
68
|
+
this._whitelistEnabled = false;
|
69
|
+
return;
|
70
|
+
}
|
71
|
+
|
72
|
+
var node = Strophe.getNodeFromJid(jid);
|
73
|
+
var domain = Strophe.getDomainFromJid(jid);
|
74
|
+
if (jid) {
|
75
|
+
if (node === "*") {
|
76
|
+
this.domainWhiteList.push(domain);
|
77
|
+
} else if (domain === "*") {
|
78
|
+
this.nodeWhiteList.push(node);
|
79
|
+
} else {
|
80
|
+
this.jidWhiteList.push(jid);
|
81
|
+
}
|
82
|
+
this._whitelistEnabled = true;
|
83
|
+
}
|
84
|
+
}
|
85
|
+
},
|
86
|
+
|
87
|
+
/**
|
88
|
+
* Helper to filter out Jid outside of the whitelists
|
89
|
+
*
|
90
|
+
* @param {String} jid Jid to test
|
91
|
+
* @return {Boolean}
|
92
|
+
*/
|
93
|
+
_jidInWhitelist: function(jid) {
|
94
|
+
if (!this._whitelistEnabled)
|
95
|
+
return true;
|
96
|
+
|
97
|
+
if (jid === this._connection.jid)
|
98
|
+
return true;
|
99
|
+
|
100
|
+
return (
|
101
|
+
this.domainWhiteList.indexOf(Strophe.getDomainFromJid(jid)) !== -1 ||
|
102
|
+
this.nodeWhiteList.indexOf(Strophe.getNodeFromJid(jid)) !== -1 ||
|
103
|
+
this.jidWhiteList.indexOf(jid) !== -1
|
104
|
+
);
|
105
|
+
},
|
106
|
+
|
107
|
+
/**
|
108
|
+
* Send a request message
|
109
|
+
*
|
110
|
+
* @param {Object} id ID of the request
|
111
|
+
* @param {String} to JID of the recipient
|
112
|
+
* @param {String} method name of the method
|
113
|
+
* @param {Array} params Array of parameters
|
114
|
+
*/
|
115
|
+
sendRequest: function(id, to, method, params) {
|
116
|
+
params = (typeof(params.sort) === "function") ? params : [params];
|
117
|
+
|
118
|
+
var element = new Strophe.Builder("methodCall")
|
119
|
+
.c("methodName").t(method)
|
120
|
+
.up()
|
121
|
+
.c("params");
|
122
|
+
|
123
|
+
for (var i = 0; i < params.length; i++) {
|
124
|
+
element.c("param")
|
125
|
+
.cnode(this._convertToXML(params[i]))
|
126
|
+
.up().up();
|
127
|
+
}
|
128
|
+
|
129
|
+
this.sendXMLElement(id, to, "set", element.tree());
|
130
|
+
},
|
131
|
+
|
132
|
+
/**
|
133
|
+
* Send a response message
|
134
|
+
*
|
135
|
+
* @param {String} id ID of the request
|
136
|
+
* @param {String} to JID of the recipient
|
137
|
+
* @param {Object} result Result of the function call
|
138
|
+
*/
|
139
|
+
sendResponse: function(id, to, result) {
|
140
|
+
var element = new Strophe.Builder("methodResponse")
|
141
|
+
.c("params")
|
142
|
+
.c("param")
|
143
|
+
.cnode(this._convertToXML(result));
|
144
|
+
|
145
|
+
this.sendXMLElement(id, to, "result", element.tree());
|
146
|
+
},
|
147
|
+
|
148
|
+
/**
|
149
|
+
* Send an error response (or fault)
|
150
|
+
*
|
151
|
+
* @param {String} id ID of the faulted request
|
152
|
+
* @param {String} to JID of the recipient
|
153
|
+
* @param {Number} code Code of the error
|
154
|
+
* @param {String} message Error message
|
155
|
+
*/
|
156
|
+
sendError: function(id, to, code, message) {
|
157
|
+
if (isNaN(code)) {
|
158
|
+
Strophe.error(code + " is not a number");
|
159
|
+
return;
|
160
|
+
}
|
161
|
+
|
162
|
+
var element = new Strophe.Builder("methodResponse")
|
163
|
+
.c("fault")
|
164
|
+
.cnode(this._convertToXML({
|
165
|
+
faultCode: code,
|
166
|
+
faultString: String(message)
|
167
|
+
}));
|
168
|
+
|
169
|
+
this.sendXMLElement(id, to, "result", element.tree());
|
170
|
+
},
|
171
|
+
|
172
|
+
/**
|
173
|
+
* Send a XMLElement as the request
|
174
|
+
* Does not check whether it is properly formed or not
|
175
|
+
*
|
176
|
+
* @param {String} id ID of the request or response
|
177
|
+
* @param {String} to JID of the recipient
|
178
|
+
* @param {String} type Type of the request ('set' for a request and 'result' for a response)
|
179
|
+
* @param {Element} element The XMLElement to send
|
180
|
+
*/
|
181
|
+
sendXMLElement: function(id, to, type, element) {
|
182
|
+
if (typeof element.tree === 'function') {
|
183
|
+
element = element.tree();
|
184
|
+
}
|
185
|
+
|
186
|
+
var iq = $iq({type: type, id: id, from: this._connection.jid, to: to})
|
187
|
+
.c("query", {xmlns: Strophe.NS.RPC})
|
188
|
+
.cnode(element);
|
189
|
+
|
190
|
+
this._connection.send(iq.tree());
|
191
|
+
},
|
192
|
+
|
193
|
+
_sendForbiddenAccess: function(id, to) {
|
194
|
+
var iq = $iq({type: "error", id: id, from: this._connection.jid, to: to})
|
195
|
+
.c("error", {code: 403, type: "auth"})
|
196
|
+
.c("forbidden", {xmlns: Strophe.NS.STANZAS});
|
197
|
+
|
198
|
+
this._connection.send(iq.tree());
|
199
|
+
},
|
200
|
+
|
201
|
+
/**
|
202
|
+
* Add a request and response handlers
|
203
|
+
*
|
204
|
+
* @param {Function} request_h Request handler
|
205
|
+
* @param {Function} response_h Response handler
|
206
|
+
* @param {Object} context Context of the handlers
|
207
|
+
*/
|
208
|
+
addHandlers: function(request_h, response_h, context) {
|
209
|
+
this.addRequestHandler(request_h, context);
|
210
|
+
this.addResponseHandler(response_h, context);
|
211
|
+
},
|
212
|
+
|
213
|
+
/**
|
214
|
+
* Add a request handler
|
215
|
+
* called every time a request is received
|
216
|
+
*
|
217
|
+
* @param {Function} handler The handler function
|
218
|
+
* @param {Object} context Context of the handler
|
219
|
+
*/
|
220
|
+
addRequestHandler: function(handler, context) {
|
221
|
+
this._connection.addHandler(this._filteredRequestHandler(handler, context), Strophe.NS.RPC, "iq", "set");
|
222
|
+
},
|
223
|
+
|
224
|
+
/**
|
225
|
+
* Add a response handler
|
226
|
+
* called every time a response is received
|
227
|
+
*
|
228
|
+
* @param {Function} handler The handler function called every time a response is received
|
229
|
+
* @param {Object} context Context of the handler
|
230
|
+
*/
|
231
|
+
addResponseHandler: function(handler, context) {
|
232
|
+
this._connection.addHandler(this._filteredResponseHandler(handler, context), Strophe.NS.RPC, "iq", "result");
|
233
|
+
},
|
234
|
+
|
235
|
+
/**
|
236
|
+
* Add a raw XML handler for every RPC message incoming
|
237
|
+
* @param {Function} handler The handler function called every time a rpc is received
|
238
|
+
* @param {Object} context Context of the handler
|
239
|
+
*/
|
240
|
+
addXMLHandler: function(handler, context) {
|
241
|
+
this._connection.addHandler(this._filteredHandler(handler, context), Strophe.NS.RPC, "iq");
|
242
|
+
},
|
243
|
+
|
244
|
+
_filter: function(xml) {
|
245
|
+
var from = xml.getAttribute("from");
|
246
|
+
if (!this._jidInWhitelist(from)) {
|
247
|
+
this._sendForbiddenAccess(xml.getAttribute("id"), from);
|
248
|
+
return false;
|
249
|
+
}
|
250
|
+
return true;
|
251
|
+
},
|
252
|
+
|
253
|
+
_filteredHandler: function(handler, context) {
|
254
|
+
context = context || this;
|
255
|
+
var self = this;
|
256
|
+
return function(xml) {
|
257
|
+
if (self._filter(xml)) {
|
258
|
+
return handler.apply(context, arguments);
|
259
|
+
}
|
260
|
+
return true;
|
261
|
+
};
|
262
|
+
},
|
263
|
+
|
264
|
+
_filteredResponseHandler: function(handler, context) {
|
265
|
+
context = context || this;
|
266
|
+
var self = this;
|
267
|
+
return function(xml) {
|
268
|
+
if (self._filter(xml)) {
|
269
|
+
var rpc = self._parseResponseMessage(xml);
|
270
|
+
if (rpc.result || rpc.result === null)
|
271
|
+
return handler.call(context, rpc.id, rpc.from, rpc.result, false);
|
272
|
+
else if (rpc.fault || rpc.fault === null)
|
273
|
+
return handler.call(context, rpc.id, rpc.from, rpc.fault, true);
|
274
|
+
}
|
275
|
+
return true;
|
276
|
+
};
|
277
|
+
},
|
278
|
+
|
279
|
+
_filteredRequestHandler: function(handler, context) {
|
280
|
+
context = context || this;
|
281
|
+
var self = this;
|
282
|
+
return function(xml) {
|
283
|
+
if (self._filter(xml)) {
|
284
|
+
var rpc = self._parseRequestMessage(xml);
|
285
|
+
return handler.call(context, rpc.id, rpc.from, rpc.method, rpc.params);
|
286
|
+
}
|
287
|
+
return true;
|
288
|
+
};
|
289
|
+
},
|
290
|
+
|
291
|
+
/**
|
292
|
+
* Helper to transform a Javascript object
|
293
|
+
* into its XML representation as described in
|
294
|
+
* the XML-RPC spec
|
295
|
+
*
|
296
|
+
* @param {Object} obj The object to convert
|
297
|
+
* @return {Element} A <value> element
|
298
|
+
*/
|
299
|
+
_convertToXML: function(obj) {
|
300
|
+
var key;
|
301
|
+
|
302
|
+
var xml = new Strophe.Builder("value");
|
303
|
+
var type = new RegExp("function (.*?)\\(\\) \\{.*").exec(obj.constructor.toString())[1];
|
304
|
+
|
305
|
+
switch (type) {
|
306
|
+
case "Number":
|
307
|
+
// Numbers can only be sent as integers or doubles.
|
308
|
+
var number = (Math.floor(obj) !== obj) ? "double" : "i4";
|
309
|
+
xml.c(number).t(obj.toString());
|
310
|
+
break;
|
311
|
+
case "String":
|
312
|
+
xml.c("string").t(obj);
|
313
|
+
break;
|
314
|
+
case "Boolean":
|
315
|
+
xml.c("boolean").t((obj*1).toString());
|
316
|
+
break;
|
317
|
+
case "Object":
|
318
|
+
xml.c("struct");
|
319
|
+
for (key in obj) {
|
320
|
+
if (obj.hasOwnProperty(key) && typeof(obj[key]) !== "function") {
|
321
|
+
xml.c("member").c("name").t(key);
|
322
|
+
xml.up().cnode(this._convertToXML(obj[key]));
|
323
|
+
xml.up().up();
|
324
|
+
}
|
325
|
+
}
|
326
|
+
break;
|
327
|
+
case "Date":
|
328
|
+
var datetext = obj.getFullYear() +
|
329
|
+
this._padNumber(obj.getMonth()+1) +
|
330
|
+
this._padNumber(obj.getDate()) + "T" +
|
331
|
+
this._padNumber(obj.getHours()) + ":" +
|
332
|
+
this._padNumber(obj.getMinutes()) + ":" +
|
333
|
+
this._padNumber(obj.getSeconds());
|
334
|
+
xml.c("dateTime.iso8601").t(datetext);
|
335
|
+
break;
|
336
|
+
case "Array":
|
337
|
+
xml.c("array").c("data");
|
338
|
+
for (key in obj) {
|
339
|
+
if (obj.hasOwnProperty(key) && typeof(obj[key]) !== "function") {
|
340
|
+
xml.cnode(this._convertToXML(obj[key]));
|
341
|
+
xml.up();
|
342
|
+
}
|
343
|
+
}
|
344
|
+
break;
|
345
|
+
default:
|
346
|
+
break;
|
347
|
+
}
|
348
|
+
|
349
|
+
return xml.tree();
|
350
|
+
},
|
351
|
+
|
352
|
+
_padNumber: function(num) {
|
353
|
+
if (num < 10) {
|
354
|
+
num = "0" + num;
|
355
|
+
}
|
356
|
+
return num;
|
357
|
+
},
|
358
|
+
|
359
|
+
_parseRequestMessage: function(iq) {
|
360
|
+
var rpc = {};
|
361
|
+
rpc.from = iq.getAttribute("from");
|
362
|
+
rpc.id = iq.getAttribute("id") || null;
|
363
|
+
|
364
|
+
// Method name
|
365
|
+
var method = iq.getElementsByTagName("methodName")[0];
|
366
|
+
rpc.method = method ? method.textContent : null;
|
367
|
+
|
368
|
+
// Parameters
|
369
|
+
rpc.params = null;
|
370
|
+
try {
|
371
|
+
var params = iq.getElementsByTagName("params")[0]
|
372
|
+
.childNodes;
|
373
|
+
if (params && params.length > 0) {
|
374
|
+
rpc.params = [];
|
375
|
+
for (var i = 0; i < params.length; i++) {
|
376
|
+
rpc.params.push(this._convertFromXML(params[i].firstChild));
|
377
|
+
}
|
378
|
+
}
|
379
|
+
} catch(e) {
|
380
|
+
rpc.params = null;
|
381
|
+
}
|
382
|
+
return rpc;
|
383
|
+
},
|
384
|
+
|
385
|
+
_parseResponseMessage: function(iq) {
|
386
|
+
var rpc = {};
|
387
|
+
rpc.from = iq.getAttribute("from");
|
388
|
+
rpc.id = iq.getAttribute("id") || null;
|
389
|
+
|
390
|
+
try {
|
391
|
+
var result = iq.getElementsByTagName("methodResponse")[0].firstChild;
|
392
|
+
|
393
|
+
// Response
|
394
|
+
var tag = result.tagName;
|
395
|
+
if (tag === "params") {
|
396
|
+
rpc.result = this._convertFromXML(result.firstChild.firstChild);
|
397
|
+
}
|
398
|
+
// Error
|
399
|
+
else if (tag === "fault") {
|
400
|
+
rpc.fault = this._convertFromXML(result.firstChild);
|
401
|
+
}
|
402
|
+
} catch(e) {
|
403
|
+
rpc.result = null;
|
404
|
+
}
|
405
|
+
return rpc;
|
406
|
+
},
|
407
|
+
|
408
|
+
_convertFromXML: function(obj) {
|
409
|
+
if (!obj)
|
410
|
+
return null;
|
411
|
+
|
412
|
+
var data;
|
413
|
+
var tag = obj.tagName.toLowerCase();
|
414
|
+
|
415
|
+
try {
|
416
|
+
switch (tag) {
|
417
|
+
case "value":
|
418
|
+
return this._convertFromXML(obj.firstChild);
|
419
|
+
case "double":
|
420
|
+
case "i4":
|
421
|
+
case "int":
|
422
|
+
var number = obj.textContent;
|
423
|
+
data = number * 1;
|
424
|
+
break;
|
425
|
+
case "boolean":
|
426
|
+
var bool = obj.textContent;
|
427
|
+
data = (bool === "1" || bool === "true") ? true : false;
|
428
|
+
break;
|
429
|
+
case "datetime.iso8601":
|
430
|
+
var date = obj.textContent;
|
431
|
+
data = new Date();
|
432
|
+
data.setFullYear(date.substring(0,4), date.substring(4,6) - 1, date.substring(6,8));
|
433
|
+
data.setHours(date.substring(9,11), date.substring(12,14), date.substring(15,17));
|
434
|
+
break;
|
435
|
+
case "array":
|
436
|
+
data = [];
|
437
|
+
var datatag = obj.firstChild;
|
438
|
+
for (var k = 0; k < datatag.childNodes.length; k++) {
|
439
|
+
var value = datatag.childNodes[k];
|
440
|
+
data.push(this._convertFromXML(value.firstChild));
|
441
|
+
}
|
442
|
+
break;
|
443
|
+
case "struct":
|
444
|
+
data = {};
|
445
|
+
for (var j = 0; j < obj.childNodes.length; j++) {
|
446
|
+
var membername = obj.childNodes[j].getElementsByTagName("name")[0].textContent;
|
447
|
+
var membervalue = obj.childNodes[j].getElementsByTagName("value")[0].firstChild;
|
448
|
+
data[membername] = membervalue ? this._convertFromXML(membervalue) : null;
|
449
|
+
}
|
450
|
+
break;
|
451
|
+
case "string":
|
452
|
+
data = obj.textContent;
|
453
|
+
break;
|
454
|
+
default:
|
455
|
+
data = null;
|
456
|
+
break;
|
457
|
+
}
|
458
|
+
} catch(e) {
|
459
|
+
data = null;
|
460
|
+
}
|
461
|
+
return data;
|
462
|
+
}
|
463
|
+
|
464
|
+
});
|
@@ -0,0 +1,52 @@
|
|
1
|
+
// http://xmpp.org/extensions/xep-0059.html
|
2
|
+
|
3
|
+
Strophe.addNamespace('RSM', 'http://jabber.org/protocol/rsm');
|
4
|
+
|
5
|
+
Strophe.RSM = function(options) {
|
6
|
+
this.attribs = ['max', 'first', 'last', 'after', 'before', 'index', 'count'];
|
7
|
+
|
8
|
+
if (typeof options.xml != 'undefined') {
|
9
|
+
this.fromXMLElement(options.xml);
|
10
|
+
} else {
|
11
|
+
for (var ii = 0; ii < this.attribs.length; ii++) {
|
12
|
+
var attrib = this.attribs[ii];
|
13
|
+
this[attrib] = options[attrib];
|
14
|
+
}
|
15
|
+
}
|
16
|
+
};
|
17
|
+
|
18
|
+
Strophe.RSM.prototype = {
|
19
|
+
toXML: function() {
|
20
|
+
var xml = $build('set', {xmlns: Strophe.NS.RSM});
|
21
|
+
for (var ii = 0; ii < this.attribs.length; ii++) {
|
22
|
+
var attrib = this.attribs[ii];
|
23
|
+
if (typeof this[attrib] != 'undefined') {
|
24
|
+
xml = xml.c(attrib).t(this[attrib].toString()).up();
|
25
|
+
}
|
26
|
+
}
|
27
|
+
return xml.tree();
|
28
|
+
},
|
29
|
+
|
30
|
+
next: function(max) {
|
31
|
+
var newSet = new Strophe.RSM({max: max, after: this.last});
|
32
|
+
return newSet;
|
33
|
+
},
|
34
|
+
|
35
|
+
previous: function(max) {
|
36
|
+
var newSet = new Strophe.RSM({max: max, before: this.first});
|
37
|
+
return newSet;
|
38
|
+
},
|
39
|
+
|
40
|
+
fromXMLElement: function(xmlElement) {
|
41
|
+
for (var ii = 0; ii < this.attribs.length; ii++) {
|
42
|
+
var attrib = this.attribs[ii];
|
43
|
+
var elem = xmlElement.getElementsByTagName(attrib)[0];
|
44
|
+
if (typeof elem != 'undefined' && elem !== null) {
|
45
|
+
this[attrib] = Strophe.getText(elem);
|
46
|
+
if (attrib == 'first') {
|
47
|
+
this.index = elem.getAttribute('index');
|
48
|
+
}
|
49
|
+
}
|
50
|
+
}
|
51
|
+
}
|
52
|
+
};
|
@@ -0,0 +1,58 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
/* serverdate plugin
|
4
|
+
**
|
5
|
+
** This plugin syncs a local clock to the servers using the response header
|
6
|
+
** on the BOSH connection
|
7
|
+
**
|
8
|
+
*/
|
9
|
+
|
10
|
+
var ServerDate = function(){
|
11
|
+
if( arguments.length === 0 ){
|
12
|
+
return new Date( new Date().valueOf() + ServerDate.skew );
|
13
|
+
}
|
14
|
+
else if ( arguments.length === 1 ){
|
15
|
+
// Covers case where a string is passed in
|
16
|
+
return new Date( arguments[0] );
|
17
|
+
}
|
18
|
+
else {
|
19
|
+
return new Date( Date.UTC.apply( null, arguments ) + ((new Date()).getTimezoneOffset() * 60000) );
|
20
|
+
}
|
21
|
+
};
|
22
|
+
ServerDate.parse = Date.parse;
|
23
|
+
ServerDate.UTC = Date.UTC;
|
24
|
+
ServerDate.now = function(){ return (new ServerDate()).valueOf(); };
|
25
|
+
ServerDate.skew = 0;
|
26
|
+
|
27
|
+
Strophe.addConnectionPlugin('serverdate', {
|
28
|
+
init: function(connection){
|
29
|
+
Strophe.Request.prototype._newXHR = function () {
|
30
|
+
var xhr = null;
|
31
|
+
if (window.XMLHttpRequest) {
|
32
|
+
xhr = new XMLHttpRequest();
|
33
|
+
if (xhr.overrideMimeType) {
|
34
|
+
xhr.overrideMimeType("text/xml");
|
35
|
+
}
|
36
|
+
} else if (window.ActiveXObject) {
|
37
|
+
xhr = new ActiveXObject("Microsoft.XMLHTTP");
|
38
|
+
}
|
39
|
+
|
40
|
+
var handler = this.func.prependArg(this);
|
41
|
+
|
42
|
+
xhr.onreadystatechange = function(){
|
43
|
+
if(this.readyState == 2){
|
44
|
+
var header = this.getResponseHeader('Date');
|
45
|
+
var server_date = new Date(header);
|
46
|
+
if ( header && server_date != 'Invalid Date' ){
|
47
|
+
system_date = new Date();
|
48
|
+
skew_ms = server_date - system_date;
|
49
|
+
ServerDate.skew = skew_ms;
|
50
|
+
}
|
51
|
+
}
|
52
|
+
handler();
|
53
|
+
};
|
54
|
+
|
55
|
+
return xhr;
|
56
|
+
};
|
57
|
+
}
|
58
|
+
});
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
5
|
+
|
6
|
+
<title>Strophe Vcard Example</title>
|
7
|
+
<!-- Load jQuery -->
|
8
|
+
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.js"></script>
|
9
|
+
|
10
|
+
<script src="../../strophe.min.js"></script>
|
11
|
+
<script src="../strophe.vcard.js"></script>
|
12
|
+
<script src="strophevcard.js"></script>
|
13
|
+
</head>
|
14
|
+
<body class='avatar'>
|
15
|
+
<canvas id='example' width='100' height='100'></canvas>
|
16
|
+
</body>
|
17
|
+
</html>
|
File without changes
|
@@ -0,0 +1,44 @@
|
|
1
|
+
###
|
2
|
+
Plugin to implement the vCard extension.
|
3
|
+
http://xmpp.org/extensions/xep-0054.html
|
4
|
+
|
5
|
+
Author: Nathan Zorn (nathan.zorn@gmail.com)
|
6
|
+
CoffeeScript port: Andreas Guth (guth@dbis.rwth-aachen.de)
|
7
|
+
|
8
|
+
###
|
9
|
+
### jslint configuration: ###
|
10
|
+
### global document, window, setTimeout, clearTimeout, console,
|
11
|
+
XMLHttpRequest, ActiveXObject,
|
12
|
+
Base64, MD5,
|
13
|
+
Strophe, $build, $msg, $iq, $pres
|
14
|
+
###
|
15
|
+
buildIq = (type, jid, vCardEl) ->
|
16
|
+
iq = $iq if jid then type:type, to:jid else type:type
|
17
|
+
iq.c "vCard", xmlns:Strophe.NS.VCARD
|
18
|
+
iq.cnode vCardEl if vCardEl
|
19
|
+
iq
|
20
|
+
|
21
|
+
Strophe.addConnectionPlugin 'vcard',
|
22
|
+
_connection: null
|
23
|
+
# Called by Strophe.Connection constructor
|
24
|
+
init: (conn) ->
|
25
|
+
this._connection = conn
|
26
|
+
Strophe.addNamespace 'VCARD', 'vcard-temp'
|
27
|
+
|
28
|
+
###Function
|
29
|
+
Retrieve a vCard for a JID/Entity
|
30
|
+
Parameters:
|
31
|
+
(Function) handler_cb - The callback function used to handle the request.
|
32
|
+
(String) jid - optional - The name of the entity to request the vCard
|
33
|
+
If no jid is given, this function retrieves the current user's vcard.
|
34
|
+
###
|
35
|
+
get: (handler_cb, jid, error_cb) ->
|
36
|
+
iq = buildIq "get", jid
|
37
|
+
this._connection.sendIQ iq, handler_cb, error_cb
|
38
|
+
|
39
|
+
### Function
|
40
|
+
Set an entity's vCard.
|
41
|
+
###
|
42
|
+
set: (handler_cb, vCardEl, jid, error_cb) ->
|
43
|
+
iq = buildIq "set", jid, vCardEl
|
44
|
+
this._connection.sendIQ iq, handler_cb, error_cb
|
@@ -0,0 +1,66 @@
|
|
1
|
+
// Generated by CoffeeScript 1.3.3
|
2
|
+
/*
|
3
|
+
Plugin to implement the vCard extension.
|
4
|
+
http://xmpp.org/extensions/xep-0054.html
|
5
|
+
|
6
|
+
Author: Nathan Zorn (nathan.zorn@gmail.com)
|
7
|
+
CoffeeScript port: Andreas Guth (guth@dbis.rwth-aachen.de)
|
8
|
+
*/
|
9
|
+
|
10
|
+
/* jslint configuration:
|
11
|
+
*/
|
12
|
+
|
13
|
+
/* global document, window, setTimeout, clearTimeout, console,
|
14
|
+
XMLHttpRequest, ActiveXObject,
|
15
|
+
Base64, MD5,
|
16
|
+
Strophe, $build, $msg, $iq, $pres
|
17
|
+
*/
|
18
|
+
|
19
|
+
var buildIq;
|
20
|
+
|
21
|
+
buildIq = function(type, jid, vCardEl) {
|
22
|
+
var iq;
|
23
|
+
iq = $iq(jid ? {
|
24
|
+
type: type,
|
25
|
+
to: jid
|
26
|
+
} : {
|
27
|
+
type: type
|
28
|
+
});
|
29
|
+
iq.c("vCard", {
|
30
|
+
xmlns: Strophe.NS.VCARD
|
31
|
+
});
|
32
|
+
if (vCardEl) {
|
33
|
+
iq.cnode(vCardEl);
|
34
|
+
}
|
35
|
+
return iq;
|
36
|
+
};
|
37
|
+
|
38
|
+
Strophe.addConnectionPlugin('vcard', {
|
39
|
+
_connection: null,
|
40
|
+
init: function(conn) {
|
41
|
+
this._connection = conn;
|
42
|
+
return Strophe.addNamespace('VCARD', 'vcard-temp');
|
43
|
+
},
|
44
|
+
/*Function
|
45
|
+
Retrieve a vCard for a JID/Entity
|
46
|
+
Parameters:
|
47
|
+
(Function) handler_cb - The callback function used to handle the request.
|
48
|
+
(String) jid - optional - The name of the entity to request the vCard
|
49
|
+
If no jid is given, this function retrieves the current user's vcard.
|
50
|
+
*/
|
51
|
+
|
52
|
+
get: function(handler_cb, jid, error_cb) {
|
53
|
+
var iq;
|
54
|
+
iq = buildIq("get", jid);
|
55
|
+
return this._connection.sendIQ(iq, handler_cb, error_cb);
|
56
|
+
},
|
57
|
+
/* Function
|
58
|
+
Set an entity's vCard.
|
59
|
+
*/
|
60
|
+
|
61
|
+
set: function(handler_cb, vCardEl, jid, error_cb) {
|
62
|
+
var iq;
|
63
|
+
iq = buildIq("set", jid, vCardEl);
|
64
|
+
return this._connection.sendIQ(iq, handler_cb, error_rb);
|
65
|
+
}
|
66
|
+
});
|
File without changes
|