diff --git a/CHANGELOG.md b/CHANGELOG.md
index efeee0ac..ee58b64b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,16 +1,24 @@
# Strophe.js Change Log
-## Version 1.1.4 - Unreleased
+## Version 1.2.0 - 2015-02-21
* Add bower package manager support.
* Add commandline testing support via qunit-phantomjs-runner
* Add integrated testing via TravisCI.
+* Fix Websocket connections now use the current XMPP-over-WebSockets RFC
* #25 Item-not-found-error caused by long term request.
+* #29 Add support for the Asynchronous Module Definition (AMD) and require.js
* #30 Base64 encoding problem in some older browsers.
* #45 Move xhlr plugin to strophejs-plugins repo.
+* #60 Fixed deletion of handlers in websocket connections
* #62 Add `xmlunescape` method.
+* #67 Use correct Content-Type in BOSH
* #70 `_onDisconnectTimeout` never tiggers because maxRetries is undefined.
+* #71 switched to case sensitive handling of XML elements
* #73 `getElementsByTagName` problem with namespaced elements.
+* #76 respect "Invalid SID" message
+* #79 connect.pause work correctly again
* #90 The queue data was not reset in .reset() method.
+* #104 Websocket connections with MongooseIM work now
## Version 1.1.3 - 2014-01-20
* Fix SCRAM-SHA1 auth now works for multiple connections at the same time
diff --git a/Gruntfile.js b/Gruntfile.js
index 943895bf..d0bd4fb9 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -39,6 +39,7 @@ module.exports = function(grunt){
}
}
},
+
concat: {
dist: {
src: ['src/wrap_header.js', 'src/base64.js', 'src/sha1.js', 'src/md5.js', 'src/polyfills.js', 'src/core.js', 'src/bosh.js', 'src/websocket.js', 'src/wrap_footer.js'],
@@ -138,4 +139,20 @@ module.exports = function(grunt){
grunt.registerTask("release", ["default", "doc", "copy:prepare-release", "shell:tar", "shell:zip"]);
grunt.registerTask("all", ["release", "clean"]);
grunt.registerTask("test", ["connect", "qunit"]);
+
+ grunt.registerTask('almond', 'Create an almond build with r.js', function () {
+ var done = this.async();
+ require('child_process').exec(
+ './node_modules/requirejs/bin/r.js -o build.js optimize=none out=strophe.almond.js',
+ function (err, stdout, stderr) {
+ if (err) {
+ grunt.log.write('build failed with error code '+err.code);
+ grunt.log.write(stderr);
+ }
+ grunt.log.write(stdout);
+ done();
+ }
+ );
+ grunt.task.run('uglify');
+ });
};
diff --git a/Makefile b/Makefile
index e9693d18..7b545cea 100644
--- a/Makefile
+++ b/Makefile
@@ -47,21 +47,16 @@ release:
@@echo "Release created."
@@echo
-check:: stamp-bower
+check::
+ make stamp-bower
$(PHANTOMJS) node_modules/qunit-phantomjs-runner/runner-list.js tests/strophe.html
clean:
- rm -f stamp-npm stamp-bower
- rm -rf node_modules bower_components
- @@echo "Cleaning" node_modules "..."
- @@rm -rf node_modules
- @@echo "Cleaning" $(STROPHE) "..."
+ @@rm -f stamp-npm stamp-bower
+ @@rm -rf node_modules bower_components
@@rm -f $(STROPHE)
- @@echo "Cleaning" $(STROPHE_MIN) "..."
@@rm -f $(STROPHE_MIN)
- @@echo "Cleaning minified plugins..."
@@rm -f $(PLUGIN_FILES_MIN)
- @@echo "Cleaning documentation..."
@@rm -rf $(NDPROJ_DIR) $(DOC_DIR) $(DOC_TEMP)
@@echo "Done."
@@echo
diff --git a/README.md b/README.md
index 3710d8b3..76f393c4 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,11 @@
-# Strophe.js
+# Strophe.js
[](https://travis-ci.org/strophe/strophejs)
Strophe.js is a JavaScript library for speaking XMPP via BOSH
([XEP 124](http://xmpp.org/extensions/xep-0124.html)
and [XEP 206](http://xmpp.org/extensions/xep-0206.html)) and WebSockets
-(draft-ietf-xmpp-websocket-00).
+([RFC 7395](http://tools.ietf.org/html/rfc7395)).
Its primary purpose is to enable web-based, real-time XMPP applications that
run in any browser.
diff --git a/bower.json b/bower.json
index 8ba5e205..804ec536 100644
--- a/bower.json
+++ b/bower.json
@@ -25,11 +25,9 @@
"release_checklist.txt",
"Makefile",
"Gruntfile.js",
- "component.json",
"contrib",
"examples",
"tests",
- "plugins",
"src"
],
"dependencies": {
@@ -37,6 +35,7 @@
"sinon-qunit": "~2.0.0",
"qunit": "~1.16.0",
"jquery": "1.11.0",
- "requirejs": "~2.1.15"
+ "requirejs": "~2.1.15",
+ "almond": "~0.3.0"
}
}
diff --git a/build.js b/build.js
new file mode 100644
index 00000000..8334c59c
--- /dev/null
+++ b/build.js
@@ -0,0 +1,7 @@
+({
+ baseUrl: ".",
+ name: "bower_components/almond/almond.js",
+ out: "strophe.js",
+ include: ['main'],
+ mainConfigFile: 'main.js'
+})
diff --git a/examples/amd.html b/examples/amd.html
new file mode 100644
index 00000000..f7c08fbe
--- /dev/null
+++ b/examples/amd.html
@@ -0,0 +1,21 @@
+
+
+
+ Strophe.js AMD Example
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/basic.js b/examples/basic.js
index a128e3d7..6b0d1dd3 100644
--- a/examples/basic.js
+++ b/examples/basic.js
@@ -1,4 +1,4 @@
-var BOSH_SERVICE = 'http://bosh.metajack.im:5280/xmpp-httpbind'
+var BOSH_SERVICE = 'http://bosh.metajack.im:5280/xmpp-httpbind';
var connection = null;
function log(msg)
@@ -52,4 +52,4 @@ $(document).ready(function () {
connection.disconnect();
}
});
-});
\ No newline at end of file
+});
diff --git a/examples/main.js b/examples/main.js
new file mode 100644
index 00000000..6ac8b1c8
--- /dev/null
+++ b/examples/main.js
@@ -0,0 +1,59 @@
+config.baseUrl = '../';
+require.config(config);
+if (typeof(require) === 'function') {
+ require(["jquery", "strophe", ], function($, wrapper) {
+ Strophe = wrapper.Strophe;
+
+ var BOSH_SERVICE = 'http://bosh.metajack.im:5280/xmpp-httpbind';
+ var connection = null;
+
+ function log(msg) {
+ $('#log').append('').append(document.createTextNode(msg));
+ }
+
+ function rawInput(data) {
+ log('RECV: ' + data);
+ }
+
+ function rawOutput(data) {
+ log('SENT: ' + data);
+ }
+
+ function onConnect(status) {
+ if (status == Strophe.Status.CONNECTING) {
+ log('Strophe is connecting.');
+ } else if (status == Strophe.Status.CONNFAIL) {
+ log('Strophe failed to connect.');
+ $('#connect').get(0).value = 'connect';
+ } else if (status == Strophe.Status.DISCONNECTING) {
+ log('Strophe is disconnecting.');
+ } else if (status == Strophe.Status.DISCONNECTED) {
+ log('Strophe is disconnected.');
+ $('#connect').get(0).value = 'connect';
+ } else if (status == Strophe.Status.CONNECTED) {
+ log('Strophe is connected.');
+ connection.disconnect();
+ }
+ }
+
+ $(document).ready(function () {
+ connection = new Strophe.Connection(BOSH_SERVICE);
+ connection.rawInput = rawInput;
+ connection.rawOutput = rawOutput;
+ $('#connect').bind('click', function () {
+ var button = $('#connect').get(0);
+ if (button.value == 'connect') {
+ button.value = 'disconnect';
+ connection.connect(
+ $('#jid').get(0).value,
+ $('#pass').get(0).value,
+ onConnect
+ );
+ } else {
+ button.value = 'connect';
+ connection.disconnect();
+ }
+ });
+ });
+ });
+}
diff --git a/main.js b/main.js
new file mode 100644
index 00000000..158c61ef
--- /dev/null
+++ b/main.js
@@ -0,0 +1,42 @@
+var config;
+if (typeof(require) === 'undefined') {
+ /* XXX: Hack to work around r.js's stupid parsing.
+ * We want to save the configuration in a variable so that we can reuse it in
+ * tests/main.js.
+ */
+ require = {
+ config: function (c) {
+ config = c;
+ }
+ };
+}
+
+require.config({
+ baseUrl: '.',
+ paths: {
+ // Strophe.js src files
+ "strophe-base64": "src/base64",
+ "strophe-bosh": "src/bosh",
+ "strophe-core": "src/core",
+ "strophe": "src/wrapper",
+ "strophe-md5": "src/md5",
+ "strophe-sha1": "src/sha1",
+ "strophe-websocket": "src/websocket",
+ "strophe-polyfill": "src/polyfills",
+
+ // Examples
+ "basic": "examples/basic",
+
+ // Tests
+ "jquery": "bower_components/jquery/dist/jquery",
+ "sinon": "bower_components/sinon/index",
+ "sinon-qunit": "bower_components/sinon-qunit/lib/sinon-qunit",
+ "tests": "tests/tests"
+ }
+});
+
+if (typeof(require) === 'function') {
+ require(["strophe"], function(Strophe) {
+ window.Strophe = Strophe;
+ });
+}
diff --git a/package.json b/package.json
index a5e59095..b5e5bac2 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "strophe.js",
"description": "Strophe.js is an XMPP library for JavaScript",
- "version": "1.1.4dev1",
+ "version": "1.2.0",
"homepage": "http://strophe.im/strophejs",
"repository": {
"type": "git",
@@ -30,7 +30,8 @@
"dodo",
"Lee Boynton (lboynton)",
"Theo Cushion (theozaurus)",
- "Brendon Crawford (brendoncrawford)"
+ "Brendon Crawford (brendoncrawford)",
+ "JC Brand (jcbrand)"
],
"licenses": [
"MIT"
@@ -62,12 +63,14 @@
"grunt-contrib-concat": "~0.3.0",
"grunt-contrib-connect": "^0.9.0",
"grunt-contrib-copy": "~0.5.0",
- "grunt-contrib-jshint": "~0.8.0",
+ "grunt-contrib-jshint": "~0.10.0",
"grunt-contrib-qunit": "^0.5.2",
+ "grunt-contrib-requirejs": "^0.4.4",
"grunt-contrib-uglify": "~0.2.7",
"grunt-contrib-watch": "~0.5.3",
"grunt-mkdir": "~0.1.1",
"grunt-natural-docs": "~0.1.1",
- "grunt-shell": "~0.6.1"
+ "grunt-shell": "~0.6.1",
+ "requirejs": "~2.1.15"
}
}
diff --git a/src/base64.js b/src/base64.js
index 39272b06..1fe7c7af 100644
--- a/src/base64.js
+++ b/src/base64.js
@@ -2,7 +2,17 @@
// public domain. It would be nice if you left this header intact.
// Base64 code from Tyler Akins -- http://rumkin.com
-var Base64 = (function () {
+(function (root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(function () {
+ return factory();
+ });
+ } else {
+ // Browser globals
+ root.Base64 = factory();
+ }
+}(this, function () {
var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
var obj = {
@@ -76,6 +86,5 @@ var Base64 = (function () {
return output;
}
};
-
return obj;
-})();
+}));
diff --git a/src/bosh.js b/src/bosh.js
index bbb726a2..264c5dcd 100644
--- a/src/bosh.js
+++ b/src/bosh.js
@@ -6,10 +6,22 @@
*/
/* jshint undef: true, unused: true:, noarg: true, latedef: true */
-/*global window, setTimeout, clearTimeout,
- XMLHttpRequest, ActiveXObject,
- Strophe, $build */
-
+/* global define, window, setTimeout, clearTimeout, XMLHttpRequest, ActiveXObject, Strophe, $build */
+
+(function (root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(['strophe-core'], function (core) {
+ return factory(
+ core.Strophe,
+ core.$build
+ );
+ });
+ } else {
+ // Browser globals
+ return factory(Strophe, $build);
+ }
+}(this, function (Strophe, $build) {
/** PrivateClass: Strophe.Request
* _Private_ helper class that provides a cross implementation abstraction
@@ -853,3 +865,5 @@ Strophe.Bosh.prototype = {
}
}
};
+return Strophe;
+}));
diff --git a/src/core.js b/src/core.js
index 9c1476f0..7d627393 100644
--- a/src/core.js
+++ b/src/core.js
@@ -6,30 +6,36 @@
*/
/* jshint undef: true, unused: true:, noarg: true, latedef: true */
-/*global document, window, setTimeout, clearTimeout, console,
- ActiveXObject, Base64, MD5, DOMParser */
-// from sha1.js
-/*global core_hmac_sha1, binb2str, str_hmac_sha1, str_sha1, b64_hmac_sha1*/
-
-/** File: strophe.js
- * A JavaScript library for XMPP BOSH/XMPP over Websocket.
- *
- * This is the JavaScript version of the Strophe library. Since JavaScript
- * had no facilities for persistent TCP connections, this library uses
- * Bidirectional-streams Over Synchronous HTTP (BOSH) to emulate
- * a persistent, stateful, two-way connection to an XMPP server. More
- * information on BOSH can be found in XEP 124.
- *
- * This version of Strophe also works with WebSockets.
- * For more information on XMPP-over WebSocket see this RFC draft:
- * http://tools.ietf.org/html/draft-ietf-xmpp-websocket-00
- */
-
-/* All of the Strophe globals are defined in this special function below so
- * that references to the globals become closures. This will ensure that
- * on page reload, these references will still be available to callbacks
- * that are still executing.
- */
+/*global define, document, window, setTimeout, clearTimeout, console, ActiveXObject, DOMParser */
+
+(function (root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define([
+ 'strophe-sha1',
+ 'strophe-base64',
+ 'strophe-md5',
+ "strophe-polyfill"
+ ], function () {
+ return factory.apply(this, arguments);
+ });
+ } else {
+ // Browser globals
+ var o = factory(root.SHA1, root.Base64, root.MD5);
+ window.Strophe = o.Strophe;
+ window.$build = o.$build;
+ window.$iq = o.$iq;
+ window.$msg = o.$msg;
+ window.$pres = o.$pres;
+ window.SHA1 = o.SHA1;
+ window.Base64 = o.Base64;
+ window.MD5 = o.MD5;
+ window.b64_hmac_sha1 = o.SHA1.b64_hmac_sha1;
+ window.b64_sha1 = o.SHA1.b64_sha1;
+ window.str_hmac_sha1 = o.SHA1.str_hmac_sha1;
+ window.str_sha1 = o.SHA1.str_sha1;
+ }
+}(this, function (SHA1, Base64, MD5) {
var Strophe;
@@ -45,6 +51,7 @@ var Strophe;
* A new Strophe.Builder object.
*/
function $build(name, attrs) { return new Strophe.Builder(name, attrs); }
+
/** Function: $msg
* Create a Strophe.Builder with a element as the root.
*
@@ -54,9 +61,8 @@ function $build(name, attrs) { return new Strophe.Builder(name, attrs); }
* Returns:
* A new Strophe.Builder object.
*/
-/* jshint ignore:start */
function $msg(attrs) { return new Strophe.Builder("message", attrs); }
-/* jshint ignore:end */
+
/** Function: $iq
* Create a Strophe.Builder with an element as the root.
*
@@ -67,6 +73,7 @@ function $msg(attrs) { return new Strophe.Builder("message", attrs); }
* A new Strophe.Builder object.
*/
function $iq(attrs) { return new Strophe.Builder("iq", attrs); }
+
/** Function: $pres
* Create a Strophe.Builder with a element as the root.
*
@@ -3156,26 +3163,26 @@ Strophe.SASLSHA1.prototype.onChallenge = function(connection, challenge, test_cn
salt = Base64.decode(salt);
salt += "\x00\x00\x00\x01";
- Hi = U_old = core_hmac_sha1(connection.pass, salt);
+ Hi = U_old = SHA1.core_hmac_sha1(connection.pass, salt);
for (i = 1; i < iter; i++) {
- U = core_hmac_sha1(connection.pass, binb2str(U_old));
+ U = SHA1.core_hmac_sha1(connection.pass, SHA1.binb2str(U_old));
for (k = 0; k < 5; k++) {
Hi[k] ^= U[k];
}
U_old = U;
}
- Hi = binb2str(Hi);
+ Hi = SHA1.binb2str(Hi);
- clientKey = core_hmac_sha1(Hi, "Client Key");
- serverKey = str_hmac_sha1(Hi, "Server Key");
- clientSignature = core_hmac_sha1(str_sha1(binb2str(clientKey)), authMessage);
- connection._sasl_data["server-signature"] = b64_hmac_sha1(serverKey, authMessage);
+ clientKey = SHA1.core_hmac_sha1(Hi, "Client Key");
+ serverKey = SHA1.str_hmac_sha1(Hi, "Server Key");
+ clientSignature = SHA1.core_hmac_sha1(SHA1.str_sha1(SHA1.binb2str(clientKey)), authMessage);
+ connection._sasl_data["server-signature"] = SHA1.b64_hmac_sha1(serverKey, authMessage);
for (k = 0; k < 5; k++) {
clientKey[k] ^= clientSignature[k];
}
- responseText += ",p=" + Base64.encode(binb2str(clientKey));
+ responseText += ",p=" + Base64.encode(SHA1.binb2str(clientKey));
return responseText;
}.bind(this);
@@ -3268,7 +3275,7 @@ Strophe.SASLMD5.prototype.onChallenge = function(connection, challenge, test_cno
this.onChallenge = function ()
{
- return "";
+ return "";
}.bind(this);
return responseText;
@@ -3276,3 +3283,14 @@ Strophe.SASLMD5.prototype.onChallenge = function(connection, challenge, test_cno
Strophe.Connection.prototype.mechanisms[Strophe.SASLMD5.prototype.name] = Strophe.SASLMD5;
+return {
+ Strophe: Strophe,
+ $build: $build,
+ $msg: $msg,
+ $iq: $iq,
+ $pres: $pres,
+ SHA1: SHA1,
+ Base64: Base64,
+ MD5: MD5,
+};
+}));
diff --git a/src/md5.js b/src/md5.js
index b752b449..9680c399 100644
--- a/src/md5.js
+++ b/src/md5.js
@@ -11,7 +11,17 @@
* Everything that isn't used by Strophe has been stripped here!
*/
-var MD5 = (function () {
+(function (root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(function () {
+ return factory();
+ });
+ } else {
+ // Browser globals
+ root.MD5 = factory();
+ }
+}(this, function (b) {
/*
* Add integers, wrapping at 2^32. This uses 16-bit operations internally
* to work around bugs in some JS interpreters.
@@ -187,7 +197,6 @@ var MD5 = (function () {
return [a, b, c, d];
};
-
var obj = {
/*
* These are the functions you'll usually want to call.
@@ -202,6 +211,5 @@ var MD5 = (function () {
return binl2str(core_md5(str2binl(s), s.length * 8));
}
};
-
return obj;
-})();
+}));
diff --git a/src/polyfills.js b/src/polyfills.js
index 0c023a56..d9e31088 100644
--- a/src/polyfills.js
+++ b/src/polyfills.js
@@ -7,12 +7,6 @@
/* jshint undef: true, unused: true:, noarg: true, latedef: true */
-/** File: polyfills.js
- * A JavaScript library for XMPP BOSH/XMPP over Websocket.
- *
- * This file contains some polyfills used by strophe.js
- */
-
/** PrivateFunction: Function.prototype.bind
* Bind a function to an instance.
*
diff --git a/src/sha1.js b/src/sha1.js
index e629c483..ef43a13c 100644
--- a/src/sha1.js
+++ b/src/sha1.js
@@ -7,16 +7,22 @@
* See http://pajhome.org.uk/crypt/md5 for details.
*/
+/* jshint undef: true, unused: true:, noarg: true, latedef: true */
+/* global define */
+
/* Some functions and variables have been stripped for use with Strophe */
-/*
- * These are the functions you'll usually want to call
- * They take string arguments and return either hex or base-64 encoded strings
- */
-function b64_sha1(s){return binb2b64(core_sha1(str2binb(s),s.length * 8));}
-function str_sha1(s){return binb2str(core_sha1(str2binb(s),s.length * 8));}
-function b64_hmac_sha1(key, data){ return binb2b64(core_hmac_sha1(key, data));}
-function str_hmac_sha1(key, data){ return binb2str(core_hmac_sha1(key, data));}
+(function (root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(function () {
+ return factory();
+ });
+ } else {
+ // Browser globals
+ root.SHA1 = factory();
+ }
+}(this, function () {
/*
* Calculate the SHA-1 of an array of big-endian words, and a bit length
@@ -174,3 +180,17 @@ function binb2b64(binarray)
}
return str;
}
+
+/*
+ * These are the functions you'll usually want to call
+ * They take string arguments and return either hex or base-64 encoded strings
+ */
+return {
+ b64_hmac_sha1: function (key, data){ return binb2b64(core_hmac_sha1(key, data)); },
+ b64_sha1: function (s) { return binb2b64(core_sha1(str2binb(s),s.length * 8)); },
+ binb2str: binb2str,
+ core_hmac_sha1: core_hmac_sha1,
+ str_hmac_sha1: function (key, data){ return binb2str(core_hmac_sha1(key, data)); },
+ str_sha1: function (s) { return binb2str(core_sha1(str2binb(s),s.length * 8)); },
+};
+}));
diff --git a/src/websocket.js b/src/websocket.js
index 4f5293e0..e424bb84 100644
--- a/src/websocket.js
+++ b/src/websocket.js
@@ -6,8 +6,22 @@
*/
/* jshint undef: true, unused: true:, noarg: true, latedef: true */
-/*global window, clearTimeout, WebSocket,
- DOMParser, Strophe, $build */
+/* global define, window, clearTimeout, WebSocket, DOMParser, Strophe, $build */
+
+(function (root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(['strophe-core'], function (core) {
+ return factory(
+ core.Strophe,
+ core.$build
+ );
+ });
+ } else {
+ // Browser globals
+ return factory(Strophe, $build);
+ }
+}(this, function (Strophe, $build) {
/** Class: Strophe.WebSocket
* _Private_ helper class that handles WebSocket Connections
@@ -508,3 +522,5 @@ Strophe.Websocket.prototype = {
this._conn._onIdle.bind(this._conn)();
}
};
+return Strophe;
+}));
diff --git a/src/wrap_header.js b/src/wrap_header.js
index f9d13449..4b400469 100644
--- a/src/wrap_header.js
+++ b/src/wrap_header.js
@@ -1,3 +1,17 @@
+/** File: strophe.js
+ * A JavaScript library for XMPP BOSH/XMPP over Websocket.
+ *
+ * This is the JavaScript version of the Strophe library. Since JavaScript
+ * had no facilities for persistent TCP connections, this library uses
+ * Bidirectional-streams Over Synchronous HTTP (BOSH) to emulate
+ * a persistent, stateful, two-way connection to an XMPP server. More
+ * information on BOSH can be found in XEP 124.
+ *
+ * This version of Strophe also works with WebSockets.
+ * For more information on XMPP-over WebSocket see this RFC:
+ * http://tools.ietf.org/html/rfc7395
+ */
+
/* All of the Strophe globals are defined in this special function below so
* that references to the globals become closures. This will ensure that
* on page reload, these references will still be available to callbacks
diff --git a/src/wrapper.js b/src/wrapper.js
new file mode 100644
index 00000000..1a7c1f7d
--- /dev/null
+++ b/src/wrapper.js
@@ -0,0 +1,7 @@
+define("strophe", [
+ "strophe-core",
+ "strophe-bosh",
+ "strophe-websocket"
+], function (wrapper) {
+ return wrapper;
+});
diff --git a/strophe.js b/strophe.js
index 117d8076..cfa3a723 100644
--- a/strophe.js
+++ b/strophe.js
@@ -1,3 +1,17 @@
+/** File: strophe.js
+ * A JavaScript library for XMPP BOSH/XMPP over Websocket.
+ *
+ * This is the JavaScript version of the Strophe library. Since JavaScript
+ * had no facilities for persistent TCP connections, this library uses
+ * Bidirectional-streams Over Synchronous HTTP (BOSH) to emulate
+ * a persistent, stateful, two-way connection to an XMPP server. More
+ * information on BOSH can be found in XEP 124.
+ *
+ * This version of Strophe also works with WebSockets.
+ * For more information on XMPP-over WebSocket see this RFC:
+ * http://tools.ietf.org/html/rfc7395
+ */
+
/* All of the Strophe globals are defined in this special function below so
* that references to the globals become closures. This will ensure that
* on page reload, these references will still be available to callbacks
@@ -12,7 +26,17 @@
// public domain. It would be nice if you left this header intact.
// Base64 code from Tyler Akins -- http://rumkin.com
-var Base64 = (function () {
+(function (root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(function () {
+ return factory();
+ });
+ } else {
+ // Browser globals
+ root.Base64 = factory();
+ }
+}(this, function () {
var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
var obj = {
@@ -86,9 +110,8 @@ var Base64 = (function () {
return output;
}
};
-
return obj;
-})();
+}));
/*
* A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
@@ -99,16 +122,22 @@ var Base64 = (function () {
* See http://pajhome.org.uk/crypt/md5 for details.
*/
+/* jshint undef: true, unused: true:, noarg: true, latedef: true */
+/* global define */
+
/* Some functions and variables have been stripped for use with Strophe */
-/*
- * These are the functions you'll usually want to call
- * They take string arguments and return either hex or base-64 encoded strings
- */
-function b64_sha1(s){return binb2b64(core_sha1(str2binb(s),s.length * 8));}
-function str_sha1(s){return binb2str(core_sha1(str2binb(s),s.length * 8));}
-function b64_hmac_sha1(key, data){ return binb2b64(core_hmac_sha1(key, data));}
-function str_hmac_sha1(key, data){ return binb2str(core_hmac_sha1(key, data));}
+(function (root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(function () {
+ return factory();
+ });
+ } else {
+ // Browser globals
+ root.SHA1 = factory();
+ }
+}(this, function () {
/*
* Calculate the SHA-1 of an array of big-endian words, and a bit length
@@ -267,6 +296,20 @@ function binb2b64(binarray)
return str;
}
+/*
+ * These are the functions you'll usually want to call
+ * They take string arguments and return either hex or base-64 encoded strings
+ */
+return {
+ b64_hmac_sha1: function (key, data){ return binb2b64(core_hmac_sha1(key, data)); },
+ b64_sha1: function (s) { return binb2b64(core_sha1(str2binb(s),s.length * 8)); },
+ binb2str: binb2str,
+ core_hmac_sha1: core_hmac_sha1,
+ str_hmac_sha1: function (key, data){ return binb2str(core_hmac_sha1(key, data)); },
+ str_sha1: function (s) { return binb2str(core_sha1(str2binb(s),s.length * 8)); },
+};
+}));
+
/*
* A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
* Digest Algorithm, as defined in RFC 1321.
@@ -280,7 +323,17 @@ function binb2b64(binarray)
* Everything that isn't used by Strophe has been stripped here!
*/
-var MD5 = (function () {
+(function (root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(function () {
+ return factory();
+ });
+ } else {
+ // Browser globals
+ root.MD5 = factory();
+ }
+}(this, function (b) {
/*
* Add integers, wrapping at 2^32. This uses 16-bit operations internally
* to work around bugs in some JS interpreters.
@@ -456,7 +509,6 @@ var MD5 = (function () {
return [a, b, c, d];
};
-
var obj = {
/*
* These are the functions you'll usually want to call.
@@ -471,9 +523,8 @@ var MD5 = (function () {
return binl2str(core_md5(str2binl(s), s.length * 8));
}
};
-
return obj;
-})();
+}));
/*
This program is distributed under the terms of the MIT license.
@@ -484,12 +535,6 @@ var MD5 = (function () {
/* jshint undef: true, unused: true:, noarg: true, latedef: true */
-/** File: polyfills.js
- * A JavaScript library for XMPP BOSH/XMPP over Websocket.
- *
- * This file contains some polyfills used by strophe.js
- */
-
/** PrivateFunction: Function.prototype.bind
* Bind a function to an instance.
*
@@ -580,30 +625,36 @@ if (!Array.prototype.indexOf)
*/
/* jshint undef: true, unused: true:, noarg: true, latedef: true */
-/*global document, window, setTimeout, clearTimeout, console,
- ActiveXObject, Base64, MD5, DOMParser */
-// from sha1.js
-/*global core_hmac_sha1, binb2str, str_hmac_sha1, str_sha1, b64_hmac_sha1*/
-
-/** File: strophe.js
- * A JavaScript library for XMPP BOSH/XMPP over Websocket.
- *
- * This is the JavaScript version of the Strophe library. Since JavaScript
- * had no facilities for persistent TCP connections, this library uses
- * Bidirectional-streams Over Synchronous HTTP (BOSH) to emulate
- * a persistent, stateful, two-way connection to an XMPP server. More
- * information on BOSH can be found in XEP 124.
- *
- * This version of Strophe also works with WebSockets.
- * For more information on XMPP-over WebSocket see this RFC draft:
- * http://tools.ietf.org/html/draft-ietf-xmpp-websocket-00
- */
-
-/* All of the Strophe globals are defined in this special function below so
- * that references to the globals become closures. This will ensure that
- * on page reload, these references will still be available to callbacks
- * that are still executing.
- */
+/*global define, document, window, setTimeout, clearTimeout, console, ActiveXObject, DOMParser */
+
+(function (root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define([
+ 'strophe-sha1',
+ 'strophe-base64',
+ 'strophe-md5',
+ "strophe-polyfill"
+ ], function () {
+ return factory.apply(this, arguments);
+ });
+ } else {
+ // Browser globals
+ var o = factory(root.SHA1, root.Base64, root.MD5);
+ window.Strophe = o.Strophe;
+ window.$build = o.$build;
+ window.$iq = o.$iq;
+ window.$msg = o.$msg;
+ window.$pres = o.$pres;
+ window.SHA1 = o.SHA1;
+ window.Base64 = o.Base64;
+ window.MD5 = o.MD5;
+ window.b64_hmac_sha1 = o.SHA1.b64_hmac_sha1;
+ window.b64_sha1 = o.SHA1.b64_sha1;
+ window.str_hmac_sha1 = o.SHA1.str_hmac_sha1;
+ window.str_sha1 = o.SHA1.str_sha1;
+ }
+}(this, function (SHA1, Base64, MD5) {
var Strophe;
@@ -619,6 +670,7 @@ var Strophe;
* A new Strophe.Builder object.
*/
function $build(name, attrs) { return new Strophe.Builder(name, attrs); }
+
/** Function: $msg
* Create a Strophe.Builder with a element as the root.
*
@@ -628,9 +680,8 @@ function $build(name, attrs) { return new Strophe.Builder(name, attrs); }
* Returns:
* A new Strophe.Builder object.
*/
-/* jshint ignore:start */
function $msg(attrs) { return new Strophe.Builder("message", attrs); }
-/* jshint ignore:end */
+
/** Function: $iq
* Create a Strophe.Builder with an element as the root.
*
@@ -641,6 +692,7 @@ function $msg(attrs) { return new Strophe.Builder("message", attrs); }
* A new Strophe.Builder object.
*/
function $iq(attrs) { return new Strophe.Builder("iq", attrs); }
+
/** Function: $pres
* Create a Strophe.Builder with a element as the root.
*
@@ -664,7 +716,7 @@ Strophe = {
* The version of the Strophe library. Unreleased builds will have
* a version of head-HASH where HASH is a partial revision.
*/
- VERSION: "1.1.4dev1",
+ VERSION: "1.2.0",
/** Constants: XMPP Namespace Constants
* Common namespace constants from the XMPP RFCs and XEPs.
@@ -3730,26 +3782,26 @@ Strophe.SASLSHA1.prototype.onChallenge = function(connection, challenge, test_cn
salt = Base64.decode(salt);
salt += "\x00\x00\x00\x01";
- Hi = U_old = core_hmac_sha1(connection.pass, salt);
+ Hi = U_old = SHA1.core_hmac_sha1(connection.pass, salt);
for (i = 1; i < iter; i++) {
- U = core_hmac_sha1(connection.pass, binb2str(U_old));
+ U = SHA1.core_hmac_sha1(connection.pass, SHA1.binb2str(U_old));
for (k = 0; k < 5; k++) {
Hi[k] ^= U[k];
}
U_old = U;
}
- Hi = binb2str(Hi);
+ Hi = SHA1.binb2str(Hi);
- clientKey = core_hmac_sha1(Hi, "Client Key");
- serverKey = str_hmac_sha1(Hi, "Server Key");
- clientSignature = core_hmac_sha1(str_sha1(binb2str(clientKey)), authMessage);
- connection._sasl_data["server-signature"] = b64_hmac_sha1(serverKey, authMessage);
+ clientKey = SHA1.core_hmac_sha1(Hi, "Client Key");
+ serverKey = SHA1.str_hmac_sha1(Hi, "Server Key");
+ clientSignature = SHA1.core_hmac_sha1(SHA1.str_sha1(SHA1.binb2str(clientKey)), authMessage);
+ connection._sasl_data["server-signature"] = SHA1.b64_hmac_sha1(serverKey, authMessage);
for (k = 0; k < 5; k++) {
clientKey[k] ^= clientSignature[k];
}
- responseText += ",p=" + Base64.encode(binb2str(clientKey));
+ responseText += ",p=" + Base64.encode(SHA1.binb2str(clientKey));
return responseText;
}.bind(this);
@@ -3842,7 +3894,7 @@ Strophe.SASLMD5.prototype.onChallenge = function(connection, challenge, test_cno
this.onChallenge = function ()
{
- return "";
+ return "";
}.bind(this);
return responseText;
@@ -3850,6 +3902,17 @@ Strophe.SASLMD5.prototype.onChallenge = function(connection, challenge, test_cno
Strophe.Connection.prototype.mechanisms[Strophe.SASLMD5.prototype.name] = Strophe.SASLMD5;
+return {
+ Strophe: Strophe,
+ $build: $build,
+ $msg: $msg,
+ $iq: $iq,
+ $pres: $pres,
+ SHA1: SHA1,
+ Base64: Base64,
+ MD5: MD5,
+};
+}));
/*
This program is distributed under the terms of the MIT license.
@@ -3859,10 +3922,22 @@ Strophe.Connection.prototype.mechanisms[Strophe.SASLMD5.prototype.name] = Stroph
*/
/* jshint undef: true, unused: true:, noarg: true, latedef: true */
-/*global window, setTimeout, clearTimeout,
- XMLHttpRequest, ActiveXObject,
- Strophe, $build */
-
+/* global define, window, setTimeout, clearTimeout, XMLHttpRequest, ActiveXObject, Strophe, $build */
+
+(function (root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(['strophe-core'], function (core) {
+ return factory(
+ core.Strophe,
+ core.$build
+ );
+ });
+ } else {
+ // Browser globals
+ return factory(Strophe, $build);
+ }
+}(this, function (Strophe, $build) {
/** PrivateClass: Strophe.Request
* _Private_ helper class that provides a cross implementation abstraction
@@ -4706,6 +4781,8 @@ Strophe.Bosh.prototype = {
}
}
};
+return Strophe;
+}));
/*
This program is distributed under the terms of the MIT license.
@@ -4715,8 +4792,22 @@ Strophe.Bosh.prototype = {
*/
/* jshint undef: true, unused: true:, noarg: true, latedef: true */
-/*global window, clearTimeout, WebSocket,
- DOMParser, Strophe, $build */
+/* global define, window, clearTimeout, WebSocket, DOMParser, Strophe, $build */
+
+(function (root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(['strophe-core'], function (core) {
+ return factory(
+ core.Strophe,
+ core.$build
+ );
+ });
+ } else {
+ // Browser globals
+ return factory(Strophe, $build);
+ }
+}(this, function (Strophe, $build) {
/** Class: Strophe.WebSocket
* _Private_ helper class that handles WebSocket Connections
@@ -5217,6 +5308,8 @@ Strophe.Websocket.prototype = {
this._conn._onIdle.bind(this._conn)();
}
};
+return Strophe;
+}));
/* jshint ignore:start */
if (callback) {
diff --git a/strophe.min.js b/strophe.min.js
new file mode 100644
index 00000000..255e8c0b
--- /dev/null
+++ b/strophe.min.js
@@ -0,0 +1,3 @@
+/*! strophe.js v1.2.0 - built on 21-02-2015 */
+!function(a){return function(a,b){"function"==typeof define&&define.amd?define(function(){return b()}):a.Base64=b()}(this,function(){var a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",b={encode:function(b){var c,d,e,f,g,h,i,j="",k=0;do c=b.charCodeAt(k++),d=b.charCodeAt(k++),e=b.charCodeAt(k++),f=c>>2,g=(3&c)<<4|d>>4,h=(15&d)<<2|e>>6,i=63&e,isNaN(d)?(g=(3&c)<<4,h=i=64):isNaN(e)&&(i=64),j=j+a.charAt(f)+a.charAt(g)+a.charAt(h)+a.charAt(i);while(k>4,d=(15&g)<<4|h>>2,e=(3&h)<<6|i,j+=String.fromCharCode(c),64!=h&&(j+=String.fromCharCode(d)),64!=i&&(j+=String.fromCharCode(e));while(k>5]|=128<<24-d%32,a[(d+64>>9<<4)+15]=d;var g,h,i,j,k,l,m,n,o=new Array(80),p=1732584193,q=-271733879,r=-1732584194,s=271733878,t=-1009589776;for(g=0;gh;h++)o[h]=16>h?a[g+h]:f(o[h-3]^o[h-8]^o[h-14]^o[h-16],1),i=e(e(f(p,5),b(h,q,r,s)),e(e(t,o[h]),c(h))),t=s,s=r,r=f(q,30),q=p,p=i;p=e(p,j),q=e(q,k),r=e(r,l),s=e(s,m),t=e(t,n)}return[p,q,r,s,t]}function b(a,b,c,d){return 20>a?b&c|~b&d:40>a?b^c^d:60>a?b&c|b&d|c&d:b^c^d}function c(a){return 20>a?1518500249:40>a?1859775393:60>a?-1894007588:-899497514}function d(b,c){var d=g(b);d.length>16&&(d=a(d,8*b.length));for(var e=new Array(16),f=new Array(16),h=0;16>h;h++)e[h]=909522486^d[h],f[h]=1549556828^d[h];var i=a(e.concat(g(c)),512+8*c.length);return a(f.concat(i),672)}function e(a,b){var c=(65535&a)+(65535&b),d=(a>>16)+(b>>16)+(c>>16);return d<<16|65535&c}function f(a,b){return a<>>32-b}function g(a){for(var b=[],c=255,d=0;d<8*a.length;d+=8)b[d>>5]|=(a.charCodeAt(d/8)&c)<<24-d%32;return b}function h(a){for(var b="",c=255,d=0;d<32*a.length;d+=8)b+=String.fromCharCode(a[d>>5]>>>24-d%32&c);return b}function i(a){for(var b,c,d="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",e="",f=0;f<4*a.length;f+=3)for(b=(a[f>>2]>>8*(3-f%4)&255)<<16|(a[f+1>>2]>>8*(3-(f+1)%4)&255)<<8|a[f+2>>2]>>8*(3-(f+2)%4)&255,c=0;4>c;c++)e+=8*f+6*c>32*a.length?"=":d.charAt(b>>6*(3-c)&63);return e}return{b64_hmac_sha1:function(a,b){return i(d(a,b))},b64_sha1:function(b){return i(a(g(b),8*b.length))},binb2str:h,core_hmac_sha1:d,str_hmac_sha1:function(a,b){return h(d(a,b))},str_sha1:function(b){return h(a(g(b),8*b.length))}}}),function(a,b){"function"==typeof define&&define.amd?define(function(){return b()}):a.MD5=b()}(this,function(){var a=function(a,b){var c=(65535&a)+(65535&b),d=(a>>16)+(b>>16)+(c>>16);return d<<16|65535&c},b=function(a,b){return a<>>32-b},c=function(a){for(var b=[],c=0;c<8*a.length;c+=8)b[c>>5]|=(255&a.charCodeAt(c/8))<>5]>>>c%32&255);return b},e=function(a){for(var b="0123456789abcdef",c="",d=0;d<4*a.length;d++)c+=b.charAt(a[d>>2]>>d%4*8+4&15)+b.charAt(a[d>>2]>>d%4*8&15);return c},f=function(c,d,e,f,g,h){return a(b(a(a(d,c),a(f,h)),g),e)},g=function(a,b,c,d,e,g,h){return f(b&c|~b&d,a,b,e,g,h)},h=function(a,b,c,d,e,g,h){return f(b&d|c&~d,a,b,e,g,h)},i=function(a,b,c,d,e,g,h){return f(b^c^d,a,b,e,g,h)},j=function(a,b,c,d,e,g,h){return f(c^(b|~d),a,b,e,g,h)},k=function(b,c){b[c>>5]|=128<>>9<<4)+14]=c;for(var d,e,f,k,l=1732584193,m=-271733879,n=-1732584194,o=271733878,p=0;pc?Math.ceil(c):Math.floor(c),0>c&&(c+=b);b>c;c++)if(c in this&&this[c]===a)return c;return-1}),function(a,b){if("function"==typeof define&&define.amd)define(["strophe-sha1","strophe-base64","strophe-md5","strophe-polyfill"],function(){return b.apply(this,arguments)});else{var c=b(a.SHA1,a.Base64,a.MD5);window.Strophe=c.Strophe,window.$build=c.$build,window.$iq=c.$iq,window.$msg=c.$msg,window.$pres=c.$pres,window.SHA1=c.SHA1,window.Base64=c.Base64,window.MD5=c.MD5,window.b64_hmac_sha1=c.SHA1.b64_hmac_sha1,window.b64_sha1=c.SHA1.b64_sha1,window.str_hmac_sha1=c.SHA1.str_hmac_sha1,window.str_sha1=c.SHA1.str_sha1}}(this,function(a,b,c){function d(a,b){return new h.Builder(a,b)}function e(a){return new h.Builder("message",a)}function f(a){return new h.Builder("iq",a)}function g(a){return new h.Builder("presence",a)}var h;return h={VERSION:"1.2.0",NS:{HTTPBIND:"http://jabber.org/protocol/httpbind",BOSH:"urn:xmpp:xbosh",CLIENT:"jabber:client",AUTH:"jabber:iq:auth",ROSTER:"jabber:iq:roster",PROFILE:"jabber:iq:profile",DISCO_INFO:"http://jabber.org/protocol/disco#info",DISCO_ITEMS:"http://jabber.org/protocol/disco#items",MUC:"http://jabber.org/protocol/muc",SASL:"urn:ietf:params:xml:ns:xmpp-sasl",STREAM:"http://etherx.jabber.org/streams",FRAMING:"urn:ietf:params:xml:ns:xmpp-framing",BIND:"urn:ietf:params:xml:ns:xmpp-bind",SESSION:"urn:ietf:params:xml:ns:xmpp-session",VERSION:"jabber:iq:version",STANZAS:"urn:ietf:params:xml:ns:xmpp-stanzas",XHTML_IM:"http://jabber.org/protocol/xhtml-im",XHTML:"http://www.w3.org/1999/xhtml"},XHTML:{tags:["a","blockquote","br","cite","em","img","li","ol","p","span","strong","ul","body"],attributes:{a:["href"],blockquote:["style"],br:[],cite:["style"],em:[],img:["src","alt","style","height","width"],li:["style"],ol:["style"],p:["style"],span:["style"],strong:[],ul:["style"],body:[]},css:["background-color","color","font-family","font-size","font-style","font-weight","margin-left","margin-right","text-align","text-decoration"],validTag:function(a){for(var b=0;b0)for(var c=0;c/g,">"),a=a.replace(/'/g,"'"),a=a.replace(/"/g,""")},xmlunescape:function(a){return a=a.replace(/\&/g,"&"),a=a.replace(/</g,"<"),a=a.replace(/>/g,">"),a=a.replace(/'/g,"'"),a=a.replace(/"/g,'"')},xmlTextNode:function(a){return h.xmlGenerator().createTextNode(a)},xmlHtmlNode:function(a){var b;if(window.DOMParser){var c=new DOMParser;b=c.parseFromString(a,"text/xml")}else b=new ActiveXObject("Microsoft.XMLDOM"),b.async="false",b.loadXML(a);return b},getText:function(a){if(!a)return null;var b="";0===a.childNodes.length&&a.nodeType==h.ElementType.TEXT&&(b+=a.nodeValue);for(var c=0;c0&&(g=i.join("; "),c.setAttribute(f,g))}else c.setAttribute(f,g);for(b=0;b/g,"\\3e").replace(/@/g,"\\40")},unescapeNode:function(a){return"string"!=typeof a?a:a.replace(/\\20/g," ").replace(/\\22/g,'"').replace(/\\26/g,"&").replace(/\\27/g,"'").replace(/\\2f/g,"/").replace(/\\3a/g,":").replace(/\\3c/g,"<").replace(/\\3e/g,">").replace(/\\40/g,"@").replace(/\\5c/g,"\\")},getNodeFromJid:function(a){return a.indexOf("@")<0?null:a.split("@")[0]},getDomainFromJid:function(a){var b=h.getBareJidFromJid(a);if(b.indexOf("@")<0)return b;var c=b.split("@");return c.splice(0,1),c.join("@")},getResourceFromJid:function(a){var b=a.split("/");return b.length<2?null:(b.splice(0,1),b.join("/"))},getBareJidFromJid:function(a){return a?a.split("/")[0]:null},log:function(){},debug:function(a){this.log(this.LogLevel.DEBUG,a)},info:function(a){this.log(this.LogLevel.INFO,a)},warn:function(a){this.log(this.LogLevel.WARN,a)},error:function(a){this.log(this.LogLevel.ERROR,a)},fatal:function(a){this.log(this.LogLevel.FATAL,a)},serialize:function(a){var b;if(!a)return null;"function"==typeof a.tree&&(a=a.tree());var c,d,e=a.nodeName;for(a.getAttribute("_realname")&&(e=a.getAttribute("_realname")),b="<"+e,c=0;c/g,">").replace(/0){for(b+=">",c=0;c"}b+=""+e+">"}else b+="/>";return b},_requestId:0,_connectionPlugins:{},addConnectionPlugin:function(a,b){h._connectionPlugins[a]=b}},h.Builder=function(a,b){("presence"==a||"message"==a||"iq"==a)&&(b&&!b.xmlns?b.xmlns=h.NS.CLIENT:b||(b={xmlns:h.NS.CLIENT})),this.nodeTree=h.xmlElement(a,b),this.node=this.nodeTree},h.Builder.prototype={tree:function(){return this.nodeTree},toString:function(){return h.serialize(this.nodeTree)},up:function(){return this.node=this.node.parentNode,this},attrs:function(a){for(var b in a)a.hasOwnProperty(b)&&this.node.setAttribute(b,a[b]);return this},c:function(a,b,c){var d=h.xmlElement(a,b,c);return this.node.appendChild(d),c||(this.node=d),this},cnode:function(a){var b,c=h.xmlGenerator();try{b=void 0!==c.importNode}catch(d){b=!1}var e=b?c.importNode(a,!0):h.copyElement(a);return this.node.appendChild(e),this.node=e,this},t:function(a){var b=h.xmlTextNode(a);return this.node.appendChild(b),this},h:function(a){var b=document.createElement("body");b.innerHTML=a;for(var c=h.createHtml(b);c.childNodes.length>0;)this.node.appendChild(c.childNodes[0]);return this}},h.Handler=function(a,b,c,d,e,f,g){this.handler=a,this.ns=b,this.name=c,this.type=d,this.id=e,this.options=g||{matchBare:!1},this.options.matchBare||(this.options.matchBare=!1),this.from=this.options.matchBare?f?h.getBareJidFromJid(f):null:f,this.user=!0},h.Handler.prototype={isMatch:function(a){var b,c=null;if(c=this.options.matchBare?h.getBareJidFromJid(a.getAttribute("from")):a.getAttribute("from"),b=!1,this.ns){var d=this;h.forEachChild(a,null,function(a){a.getAttribute("xmlns")==d.ns&&(b=!0)}),b=b||a.getAttribute("xmlns")==this.ns}else b=!0;var e=a.getAttribute("type");return!b||this.name&&!h.isTagEqual(a,this.name)||this.type&&(Array.isArray(this.type)?-1==this.type.indexOf(e):e!=this.type)||this.id&&a.getAttribute("id")!=this.id||this.from&&c!=this.from?!1:!0},run:function(a){var b=null;try{b=this.handler(a)}catch(c){throw c.sourceURL?h.fatal("error: "+this.handler+" "+c.sourceURL+":"+c.line+" - "+c.name+": "+c.message):c.fileName?("undefined"!=typeof console&&(console.trace(),console.error(this.handler," - error - ",c,c.message)),h.fatal("error: "+this.handler+" "+c.fileName+":"+c.lineNumber+" - "+c.name+": "+c.message)):h.fatal("error: "+c.message+"\n"+c.stack),c}return b},toString:function(){return"{Handler: "+this.handler+"("+this.name+","+this.id+","+this.ns+")}"}},h.TimedHandler=function(a,b){this.period=a,this.handler=b,this.lastCalled=(new Date).getTime(),this.user=!0},h.TimedHandler.prototype={run:function(){return this.lastCalled=(new Date).getTime(),this.handler()},reset:function(){this.lastCalled=(new Date).getTime()},toString:function(){return"{TimedHandler: "+this.handler+"("+this.period+")}"}},h.Connection=function(a,b){this.service=a,this.options=b||{};var c=this.options.protocol||"";this._proto=0===a.indexOf("ws:")||0===a.indexOf("wss:")||0===c.indexOf("ws")?new h.Websocket(this):new h.Bosh(this),this.jid="",this.domain=null,this.features=null,this._sasl_data={},this.do_session=!1,this.do_bind=!1,this.timedHandlers=[],this.handlers=[],this.removeTimeds=[],this.removeHandlers=[],this.addTimeds=[],this.addHandlers=[],this._authentication={},this._idleTimeout=null,this._disconnectTimeout=null,this.do_authentication=!0,this.authenticated=!1,this.disconnecting=!1,this.connected=!1,this.paused=!1,this._data=[],this._uniqueId=0,this._sasl_success_handler=null,this._sasl_failure_handler=null,this._sasl_challenge_handler=null,this.maxRetries=5,this._idleTimeout=setTimeout(this._onIdle.bind(this),100);for(var d in h._connectionPlugins)if(h._connectionPlugins.hasOwnProperty(d)){var e=h._connectionPlugins[d],f=function(){};f.prototype=e,this[d]=new f,this[d].init(this)}},h.Connection.prototype={reset:function(){this._proto._reset(),this.do_session=!1,this.do_bind=!1,this.timedHandlers=[],this.handlers=[],this.removeTimeds=[],this.removeHandlers=[],this.addTimeds=[],this.addHandlers=[],this._authentication={},this.authenticated=!1,this.disconnecting=!1,this.connected=!1,this._data=[],this._requests=[],this._uniqueId=0},pause:function(){this.paused=!0},resume:function(){this.paused=!1},getUniqueId:function(a){return"string"==typeof a||"number"==typeof a?++this._uniqueId+":"+a:++this._uniqueId+""},connect:function(a,b,c,d,e,f){this.jid=a,this.authzid=h.getBareJidFromJid(this.jid),this.authcid=h.getNodeFromJid(this.jid),this.pass=b,this.servtype="xmpp",this.connect_callback=c,this.disconnecting=!1,this.connected=!1,this.authenticated=!1,this.domain=h.getDomainFromJid(this.jid),this._changeConnectStatus(h.Status.CONNECTING,null),this._proto._connect(d,e,f)},attach:function(a,b,c,d,e,f,g){this._proto._attach(a,b,c,d,e,f,g)},xmlInput:function(){},xmlOutput:function(){},rawInput:function(){},rawOutput:function(){},send:function(a){if(null!==a){if("function"==typeof a.sort)for(var b=0;b=0&&this.addHandlers.splice(b,1)},disconnect:function(a){if(this._changeConnectStatus(h.Status.DISCONNECTING,a),h.info("Disconnect was called because: "+a),this.connected){var b=!1;this.disconnecting=!0,this.authenticated&&(b=g({xmlns:h.NS.CLIENT,type:"unavailable"})),this._disconnectTimeout=this._addSysTimedHandler(3e3,this._onDisconnectTimeout.bind(this)),this._proto._disconnect(b)}else h.info("Disconnect was called before Strophe connected to the server"),this._proto._abortAllRequests()},_changeConnectStatus:function(a,b){for(var c in h._connectionPlugins)if(h._connectionPlugins.hasOwnProperty(c)){var d=this[c];if(d.statusChanged)try{d.statusChanged(a,b)}catch(e){h.error(""+c+" plugin caused an exception changing status: "+e)}}if(this.connect_callback)try{this.connect_callback(a,b)}catch(f){h.error("User connection callback caused an exception: "+f)}},_doDisconnect:function(){"number"==typeof this._idleTimeout&&clearTimeout(this._idleTimeout),null!==this._disconnectTimeout&&(this.deleteTimedHandler(this._disconnectTimeout),this._disconnectTimeout=null),h.info("_doDisconnect was called"),this._proto._doDisconnect(),this.authenticated=!1,this.disconnecting=!1,this.handlers=[],this.timedHandlers=[],this.removeTimeds=[],this.removeHandlers=[],this.addTimeds=[],this.addHandlers=[],this._changeConnectStatus(h.Status.DISCONNECTED,null),this.connected=!1},_dataRecv:function(a,b){h.info("_dataRecv called");var c=this._proto._reqToData(a);if(null!==c){this.xmlInput!==h.Connection.prototype.xmlInput&&(c.nodeName===this._proto.strip&&c.childNodes.length?this.xmlInput(c.childNodes[0]):this.xmlInput(c)),this.rawInput!==h.Connection.prototype.rawInput&&(b?this.rawInput(b):this.rawInput(h.serialize(c)));for(var d,e;this.removeHandlers.length>0;)e=this.removeHandlers.pop(),d=this.handlers.indexOf(e),d>=0&&this.handlers.splice(d,1);for(;this.addHandlers.length>0;)this.handlers.push(this.addHandlers.pop());if(this.disconnecting&&this._proto._emptyQueue())return this._doDisconnect(),void 0;var f,g,i=c.getAttribute("type");if(null!==i&&"terminate"==i){if(this.disconnecting)return;return f=c.getAttribute("condition"),g=c.getElementsByTagName("conflict"),null!==f?("remote-stream-error"==f&&g.length>0&&(f="conflict"),this._changeConnectStatus(h.Status.CONNFAIL,f)):this._changeConnectStatus(h.Status.CONNFAIL,"unknown"),this._doDisconnect(),void 0}var j=this;h.forEachChild(c,null,function(a){var b,c;for(c=j.handlers,j.handlers=[],b=0;b0,j=d.getElementsByTagName("mechanism"),k=[],l=!1;if(!i)return this._proto._no_auth_received(b),void 0;if(j.length>0)for(f=0;f0,(l=this._authentication.legacy_auth||k.length>0)?(this.do_authentication!==!1&&this.authenticate(k),void 0):(this._proto._no_auth_received(b),void 0)}}},authenticate:function(a){var c;for(c=0;ca[e].prototype.priority&&(e=g);if(e!=c){var i=a[c];a[c]=a[e],a[e]=i}}var j=!1;for(c=0;c0&&(b="conflict"),this._changeConnectStatus(h.Status.AUTHFAIL,b),!1}var d,e=a.getElementsByTagName("bind");return e.length>0?(d=e[0].getElementsByTagName("jid"),d.length>0&&(this.jid=h.getText(d[0]),this.do_session?(this._addSysHandler(this._sasl_session_cb.bind(this),null,null,null,"_session_auth_2"),this.send(f({type:"set",id:"_session_auth_2"}).c("session",{xmlns:h.NS.SESSION}).tree())):(this.authenticated=!0,this._changeConnectStatus(h.Status.CONNECTED,null))),void 0):(h.info("SASL binding failed."),this._changeConnectStatus(h.Status.AUTHFAIL,null),!1)},_sasl_session_cb:function(a){if("result"==a.getAttribute("type"))this.authenticated=!0,this._changeConnectStatus(h.Status.CONNECTED,null);else if("error"==a.getAttribute("type"))return h.info("Session creation failed."),this._changeConnectStatus(h.Status.AUTHFAIL,null),!1;return!1},_sasl_failure_cb:function(){return this._sasl_success_handler&&(this.deleteHandler(this._sasl_success_handler),this._sasl_success_handler=null),this._sasl_challenge_handler&&(this.deleteHandler(this._sasl_challenge_handler),this._sasl_challenge_handler=null),this._sasl_mechanism&&this._sasl_mechanism.onFailure(),this._changeConnectStatus(h.Status.AUTHFAIL,null),!1},_auth2_cb:function(a){return"result"==a.getAttribute("type")?(this.authenticated=!0,this._changeConnectStatus(h.Status.CONNECTED,null)):"error"==a.getAttribute("type")&&(this._changeConnectStatus(h.Status.AUTHFAIL,null),this.disconnect("authentication failed")),!1},_addSysTimedHandler:function(a,b){var c=new h.TimedHandler(a,b);return c.user=!1,this.addTimeds.push(c),c},_addSysHandler:function(a,b,c,d,e){var f=new h.Handler(a,b,c,d,e);return f.user=!1,this.addHandlers.push(f),f},_onDisconnectTimeout:function(){return h.info("_onDisconnectTimeout was called"),this._proto._onDisconnectTimeout(),this._doDisconnect(),!1},_onIdle:function(){for(var a,b,c,d;this.addTimeds.length>0;)this.timedHandlers.push(this.addTimeds.pop());for(;this.removeTimeds.length>0;)b=this.removeTimeds.pop(),a=this.timedHandlers.indexOf(b),a>=0&&this.timedHandlers.splice(a,1);var e=(new Date).getTime();for(d=[],a=0;a=c-e?b.run()&&d.push(b):d.push(b));this.timedHandlers=d,clearTimeout(this._idleTimeout),this._proto._onIdle(),this.connected&&(this._idleTimeout=setTimeout(this._onIdle.bind(this),100))}},h.SASLMechanism=function(a,b,c){this.name=a,this.isClientFirst=b,this.priority=c},h.SASLMechanism.prototype={test:function(){return!0},onStart:function(a){this._connection=a},onChallenge:function(){throw new Error("You should implement challenge handling!")},onFailure:function(){this._connection=null},onSuccess:function(){this._connection=null}},h.SASLAnonymous=function(){},h.SASLAnonymous.prototype=new h.SASLMechanism("ANONYMOUS",!1,10),h.SASLAnonymous.test=function(a){return null===a.authcid},h.Connection.prototype.mechanisms[h.SASLAnonymous.prototype.name]=h.SASLAnonymous,h.SASLPlain=function(){},h.SASLPlain.prototype=new h.SASLMechanism("PLAIN",!0,20),h.SASLPlain.test=function(a){return null!==a.authcid},h.SASLPlain.prototype.onChallenge=function(a){var b=a.authzid;
+return b+="\x00",b+=a.authcid,b+="\x00",b+=a.pass},h.Connection.prototype.mechanisms[h.SASLPlain.prototype.name]=h.SASLPlain,h.SASLSHA1=function(){},h.SASLSHA1.prototype=new h.SASLMechanism("SCRAM-SHA-1",!0,40),h.SASLSHA1.test=function(a){return null!==a.authcid},h.SASLSHA1.prototype.onChallenge=function(d,e,f){var g=f||c.hexdigest(1234567890*Math.random()),h="n="+d.authcid;return h+=",r=",h+=g,d._sasl_data.cnonce=g,d._sasl_data["client-first-message-bare"]=h,h="n,,"+h,this.onChallenge=function(c,d){for(var e,f,g,h,i,j,k,l,m,n,o,p="c=biws,",q=c._sasl_data["client-first-message-bare"]+","+d+",",r=c._sasl_data.cnonce,s=/([a-z]+)=([^,]+)(,|$)/;d.match(s);){var t=d.match(s);switch(d=d.replace(t[0],""),t[1]){case"r":e=t[2];break;case"s":f=t[2];break;case"i":g=t[2]}}if(e.substr(0,r.length)!==r)return c._sasl_data={},c._sasl_failure_cb();for(p+="r="+e,q+=p,f=b.decode(f),f+="\x00\x00\x00",h=j=a.core_hmac_sha1(c.pass,f),k=1;g>k;k++){for(i=a.core_hmac_sha1(c.pass,a.binb2str(j)),l=0;5>l;l++)h[l]^=i[l];j=i}for(h=a.binb2str(h),m=a.core_hmac_sha1(h,"Client Key"),n=a.str_hmac_sha1(h,"Server Key"),o=a.core_hmac_sha1(a.str_sha1(a.binb2str(m)),q),c._sasl_data["server-signature"]=a.b64_hmac_sha1(n,q),l=0;5>l;l++)m[l]^=o[l];return p+=",p="+b.encode(a.binb2str(m))}.bind(this),h},h.Connection.prototype.mechanisms[h.SASLSHA1.prototype.name]=h.SASLSHA1,h.SASLMD5=function(){},h.SASLMD5.prototype=new h.SASLMechanism("DIGEST-MD5",!1,30),h.SASLMD5.test=function(a){return null!==a.authcid},h.SASLMD5.prototype._quote=function(a){return'"'+a.replace(/\\/g,"\\\\").replace(/"/g,'\\"')+'"'},h.SASLMD5.prototype.onChallenge=function(a,b,d){for(var e,f=/([a-z]+)=("[^"]+"|[^,"]+)(?:,|$)/,g=d||c.hexdigest(""+1234567890*Math.random()),h="",i=null,j="",k="";b.match(f);)switch(e=b.match(f),b=b.replace(e[0],""),e[2]=e[2].replace(/^"(.+)"$/,"$1"),e[1]){case"realm":h=e[2];break;case"nonce":j=e[2];break;case"qop":k=e[2];break;case"host":i=e[2]}var l=a.servtype+"/"+a.domain;null!==i&&(l=l+"/"+i);var m=c.hash(a.authcid+":"+h+":"+this._connection.pass)+":"+j+":"+g,n="AUTHENTICATE:"+l,o="";return o+="charset=utf-8,",o+="username="+this._quote(a.authcid)+",",o+="realm="+this._quote(h)+",",o+="nonce="+this._quote(j)+",",o+="nc=00000001,",o+="cnonce="+this._quote(g)+",",o+="digest-uri="+this._quote(l)+",",o+="response="+c.hexdigest(c.hexdigest(m)+":"+j+":00000001:"+g+":auth:"+c.hexdigest(n))+",",o+="qop=auth",this.onChallenge=function(){return""}.bind(this),o},h.Connection.prototype.mechanisms[h.SASLMD5.prototype.name]=h.SASLMD5,{Strophe:h,$build:d,$msg:e,$iq:f,$pres:g,SHA1:a,Base64:b,MD5:c}}),function(a,b){return"function"==typeof define&&define.amd?(define(["strophe-core"],function(a){return b(a.Strophe,a.$build)}),void 0):b(Strophe,$build)}(this,function(a,b){return a.Request=function(b,c,d,e){this.id=++a._requestId,this.xmlData=b,this.data=a.serialize(b),this.origFunc=c,this.func=c,this.rid=d,this.date=0/0,this.sends=e||0,this.abort=!1,this.dead=null,this.age=function(){if(!this.date)return 0;var a=new Date;return(a-this.date)/1e3},this.timeDead=function(){if(!this.dead)return 0;var a=new Date;return(a-this.dead)/1e3},this.xhr=this._newXHR()},a.Request.prototype={getResponse:function(){var b=null;if(this.xhr.responseXML&&this.xhr.responseXML.documentElement){if(b=this.xhr.responseXML.documentElement,"parsererror"==b.tagName)throw a.error("invalid response received"),a.error("responseText: "+this.xhr.responseText),a.error("responseXML: "+a.serialize(this.xhr.responseXML)),"parsererror"}else this.xhr.responseText&&(a.error("invalid response received"),a.error("responseText: "+this.xhr.responseText),a.error("responseXML: "+a.serialize(this.xhr.responseXML)));return b},_newXHR:function(){var a=null;return window.XMLHttpRequest?(a=new XMLHttpRequest,a.overrideMimeType&&a.overrideMimeType("text/xml; charset=utf-8")):window.ActiveXObject&&(a=new ActiveXObject("Microsoft.XMLHTTP")),a.onreadystatechange=this.func.bind(null,this),a}},a.Bosh=function(a){this._conn=a,this.rid=Math.floor(4294967295*Math.random()),this.sid=null,this.hold=1,this.wait=60,this.window=5,this.errors=0,this._requests=[]},a.Bosh.prototype={strip:null,_buildBody:function(){var c=b("body",{rid:this.rid++,xmlns:a.NS.HTTPBIND});return null!==this.sid&&c.attrs({sid:this.sid}),c},_reset:function(){this.rid=Math.floor(4294967295*Math.random()),this.sid=null,this.errors=0},_connect:function(b,c,d){this.wait=b||this.wait,this.hold=c||this.hold,this.errors=0;var e=this._buildBody().attrs({to:this._conn.domain,"xml:lang":"en",wait:this.wait,hold:this.hold,content:"text/xml; charset=utf-8",ver:"1.6","xmpp:version":"1.0","xmlns:xmpp":a.NS.BOSH});d&&e.attrs({route:d});var f=this._conn._connect_cb;this._requests.push(new a.Request(e.tree(),this._onRequestStateChange.bind(this,f.bind(this._conn)),e.tree().getAttribute("rid"))),this._throttledRequestHandler()},_attach:function(b,c,d,e,f,g,h){this._conn.jid=b,this.sid=c,this.rid=d,this._conn.connect_callback=e,this._conn.domain=a.getDomainFromJid(this._conn.jid),this._conn.authenticated=!0,this._conn.connected=!0,this.wait=f||this.wait,this.hold=g||this.hold,this.window=h||this.window,this._conn._changeConnectStatus(a.Status.ATTACHED,null)},_connect_cb:function(b){var c,d,e=b.getAttribute("type");if(null!==e&&"terminate"==e)return a.error("BOSH-Connection failed: "+c),c=b.getAttribute("condition"),d=b.getElementsByTagName("conflict"),null!==c?("remote-stream-error"==c&&d.length>0&&(c="conflict"),this._conn._changeConnectStatus(a.Status.CONNFAIL,c)):this._conn._changeConnectStatus(a.Status.CONNFAIL,"unknown"),this._conn._doDisconnect(),a.Status.CONNFAIL;this.sid||(this.sid=b.getAttribute("sid"));var f=b.getAttribute("requests");f&&(this.window=parseInt(f,10));var g=b.getAttribute("hold");g&&(this.hold=parseInt(g,10));var h=b.getAttribute("wait");h&&(this.wait=parseInt(h,10))},_disconnect:function(a){this._sendTerminate(a)},_doDisconnect:function(){this.sid=null,this.rid=Math.floor(4294967295*Math.random())},_emptyQueue:function(){return 0===this._requests.length},_hitError:function(b){this.errors++,a.warn("request errored, status: "+b+", number of errors: "+this.errors),this.errors>4&&this._conn._onDisconnectTimeout()},_no_auth_received:function(b){b=b?b.bind(this._conn):this._conn._connect_cb.bind(this._conn);var c=this._buildBody();this._requests.push(new a.Request(c.tree(),this._onRequestStateChange.bind(this,b.bind(this._conn)),c.tree().getAttribute("rid"))),this._throttledRequestHandler()},_onDisconnectTimeout:function(){this._abortAllRequests()},_abortAllRequests:function(){for(var a;this._requests.length>0;)a=this._requests.pop(),a.abort=!0,a.xhr.abort(),a.xhr.onreadystatechange=function(){}},_onIdle:function(){var b=this._conn._data;if(this._conn.authenticated&&0===this._requests.length&&0===b.length&&!this._conn.disconnecting&&(a.info("no requests during idle cycle, sending blank request"),b.push(null)),!this._conn.paused){if(this._requests.length<2&&b.length>0){for(var c=this._buildBody(),d=0;d0){var e=this._requests[0].age();null!==this._requests[0].dead&&this._requests[0].timeDead()>Math.floor(a.SECONDARY_TIMEOUT*this.wait)&&this._throttledRequestHandler(),e>Math.floor(a.TIMEOUT*this.wait)&&(a.warn("Request "+this._requests[0].id+" timed out, over "+Math.floor(a.TIMEOUT*this.wait)+" seconds since last activity"),this._throttledRequestHandler())}}},_onRequestStateChange:function(b,c){if(a.debug("request id "+c.id+"."+c.sends+" state changed to "+c.xhr.readyState),c.abort)return c.abort=!1,void 0;var d;if(4==c.xhr.readyState){d=0;try{d=c.xhr.status}catch(e){}if("undefined"==typeof d&&(d=0),this.disconnecting&&d>=400)return this._hitError(d),void 0;var f=this._requests[0]==c,g=this._requests[1]==c;(d>0&&500>d||c.sends>5)&&(this._removeRequest(c),a.debug("request id "+c.id+" should now be removed")),200==d?((g||f&&this._requests.length>0&&this._requests[0].age()>Math.floor(a.SECONDARY_TIMEOUT*this.wait))&&this._restartRequest(0),a.debug("request id "+c.id+"."+c.sends+" got 200"),b(c),this.errors=0):(a.error("request id "+c.id+"."+c.sends+" error "+d+" happened"),(0===d||d>=400&&600>d||d>=12e3)&&(this._hitError(d),d>=400&&500>d&&(this._conn._changeConnectStatus(a.Status.DISCONNECTING,null),this._conn._doDisconnect()))),d>0&&500>d||c.sends>5||this._throttledRequestHandler()}},_processRequest:function(b){var c=this,d=this._requests[b],e=-1;try{4==d.xhr.readyState&&(e=d.xhr.status)}catch(f){a.error("caught an error in _requests["+b+"], reqStatus: "+e)}if("undefined"==typeof e&&(e=-1),d.sends>this._conn.maxRetries)return this._conn._onDisconnectTimeout(),void 0;var g=d.age(),h=!isNaN(g)&&g>Math.floor(a.TIMEOUT*this.wait),i=null!==d.dead&&d.timeDead()>Math.floor(a.SECONDARY_TIMEOUT*this.wait),j=4==d.xhr.readyState&&(1>e||e>=500);if((h||i||j)&&(i&&a.error("Request "+this._requests[b].id+" timed out (secondary), restarting"),d.abort=!0,d.xhr.abort(),d.xhr.onreadystatechange=function(){},this._requests[b]=new a.Request(d.xmlData,d.origFunc,d.rid,d.sends),d=this._requests[b]),0===d.xhr.readyState){a.debug("request id "+d.id+"."+d.sends+" posting");try{d.xhr.open("POST",this._conn.service,this._conn.options.sync?!1:!0),d.xhr.setRequestHeader("Content-Type","text/xml; charset=utf-8")}catch(k){return a.error("XHR open failed."),this._conn.connected||this._conn._changeConnectStatus(a.Status.CONNFAIL,"bad-service"),this._conn.disconnect(),void 0}var l=function(){if(d.date=new Date,c._conn.options.customHeaders){var a=c._conn.options.customHeaders;for(var b in a)a.hasOwnProperty(b)&&d.xhr.setRequestHeader(b,a[b])}d.xhr.send(d.data)};if(d.sends>1){var m=1e3*Math.min(Math.floor(a.TIMEOUT*this.wait),Math.pow(d.sends,3));setTimeout(l,m)}else l();d.sends++,this._conn.xmlOutput!==a.Connection.prototype.xmlOutput&&(d.xmlData.nodeName===this.strip&&d.xmlData.childNodes.length?this._conn.xmlOutput(d.xmlData.childNodes[0]):this._conn.xmlOutput(d.xmlData)),this._conn.rawOutput!==a.Connection.prototype.rawOutput&&this._conn.rawOutput(d.data)}else a.debug("_processRequest: "+(0===b?"first":"second")+" request has readyState of "+d.xhr.readyState)},_removeRequest:function(b){a.debug("removing request");var c;for(c=this._requests.length-1;c>=0;c--)b==this._requests[c]&&this._requests.splice(c,1);b.xhr.onreadystatechange=function(){},this._throttledRequestHandler()},_restartRequest:function(a){var b=this._requests[a];null===b.dead&&(b.dead=new Date),this._processRequest(a)},_reqToData:function(a){try{return a.getResponse()}catch(b){if("parsererror"!=b)throw b;this._conn.disconnect("strophe-parsererror")}},_sendTerminate:function(b){a.info("_sendTerminate was called");var c=this._buildBody().attrs({type:"terminate"});b&&c.cnode(b.tree());var d=new a.Request(c.tree(),this._onRequestStateChange.bind(this,this._conn._dataRecv.bind(this._conn)),c.tree().getAttribute("rid"));this._requests.push(d),this._throttledRequestHandler()},_send:function(){clearTimeout(this._conn._idleTimeout),this._throttledRequestHandler(),this._conn._idleTimeout=setTimeout(this._conn._onIdle.bind(this._conn),100)},_sendRestart:function(){this._throttledRequestHandler(),clearTimeout(this._conn._idleTimeout)},_throttledRequestHandler:function(){this._requests?a.debug("_throttledRequestHandler called with "+this._requests.length+" requests"):a.debug("_throttledRequestHandler called with undefined requests"),this._requests&&0!==this._requests.length&&(this._requests.length>0&&this._processRequest(0),this._requests.length>1&&Math.abs(this._requests[0].rid-this._requests[1].rid)":d!==a.NS.FRAMING&&(c="Wrong xmlns in : "+d);var e=b.getAttribute("version");return"string"!=typeof e?c="Missing version in ":"1.0"!==e&&(c="Wrong version in : "+e),c?(this._conn._changeConnectStatus(a.Status.CONNFAIL,c),this._conn._doDisconnect(),!1):!0},_connect_cb_wrapper:function(b){if(0===b.data.indexOf("\s*)*/,"");if(""===c)return;var d=(new DOMParser).parseFromString(c,"text/xml").documentElement;this._conn.xmlInput(d),this._conn.rawInput(b.data),this._handleStreamStart(d)&&this._connect_cb(d)}else if(0===b.data.indexOf(" tag.")}}this._conn._doDisconnect()},_doDisconnect:function(){a.info("WebSockets _doDisconnect was called"),this._closeSocket()},_streamWrap:function(a){return""+a+""},_closeSocket:function(){if(this.socket)try{this.socket.close()}catch(a){}this.socket=null},_emptyQueue:function(){return!0},_onClose:function(){this._conn.connected&&!this._conn.disconnecting?(a.error("Websocket closed unexcectedly"),this._conn._doDisconnect()):a.info("Websocket closed")},_no_auth_received:function(b){a.error("Server did not send any auth methods"),this._conn._changeConnectStatus(a.Status.CONNFAIL,"Server did not send any auth methods"),b&&(b=b.bind(this._conn))(),this._conn._doDisconnect()},_onDisconnectTimeout:function(){},_abortAllRequests:function(){},_onError:function(b){a.error("Websocket error "+b),this._conn._changeConnectStatus(a.Status.CONNFAIL,"The WebSocket connection could not be established was disconnected."),this._disconnect()},_onIdle:function(){var b=this._conn._data;if(b.length>0&&!this._conn.paused){for(var c=0;c';if(b.data===e)return this._conn.rawInput(e),this._conn.xmlInput(b),this._conn.disconnecting||this._conn._doDisconnect(),void 0;if(0===b.data.search("
+