Merge branch 'master' into otr
Conflicts: docs/doctrees/index.doctree docs/html/index.html docs/html/searchindex.js
This commit is contained in:
commit
104f905641
@ -2,5 +2,5 @@ language: node_js
|
||||
node_js:
|
||||
- "0.10"
|
||||
before_script:
|
||||
- "./node_modules/.bin/bower update"
|
||||
- "./node_modules/.bin/grunt fetch"
|
||||
script: grunt test
|
||||
|
@ -95,7 +95,7 @@ module.exports = function(grunt) {
|
||||
var done = this.async();
|
||||
var child_process = require('child_process');
|
||||
var exec = child_process.exec;
|
||||
exec('bower update && cd ./components/strophe && make normal',
|
||||
exec('./node_modules/.bin/bower update && cd ./components/strophe && make normal',
|
||||
function (err, stdout, stderr) {
|
||||
if (err) {
|
||||
grunt.log.write('build failed with error code '+err.code);
|
||||
@ -106,7 +106,7 @@ module.exports = function(grunt) {
|
||||
});
|
||||
});
|
||||
|
||||
grunt.registerTask('minify', 'Create a new release', ['requirejs', 'cssmin']);
|
||||
grunt.registerTask('minify', 'Create a new release', ['cssmin', 'requirejs']);
|
||||
|
||||
grunt.registerTask('check', 'Perform all checks (e.g. before releasing)', function () {
|
||||
grunt.task.run('jshint', 'test');
|
||||
|
@ -2,6 +2,9 @@
|
||||
converse.js
|
||||
===========
|
||||
|
||||
.. figure:: https://api.travis-ci.org/jcbrand/converse.js.png?branch=master
|
||||
:alt: Build Status
|
||||
|
||||
Converse.js_ is a web based `XMPP/Jabber`_ instant messaging client.
|
||||
|
||||
It enables you to add chat functionality to your website, independent of any
|
||||
|
194
converse.js
194
converse.js
@ -42,20 +42,40 @@
|
||||
}
|
||||
}(this, function ($, _, crypto, otr, console) {
|
||||
var converse = {};
|
||||
converse.initialize = function (settings) {
|
||||
converse.initialize = function (settings, callback) {
|
||||
// Default values
|
||||
var converse = this;
|
||||
this.animate = true;
|
||||
this.auto_list_rooms = false;
|
||||
this.auto_subscribe = false;
|
||||
this.bosh_service_url = ''; // The BOSH connection manager URL. Required if you are not prebinding.
|
||||
this.bosh_service_url = undefined; // The BOSH connection manager URL.
|
||||
this.debug = false;
|
||||
this.hide_muc_server = false;
|
||||
this.i18n = locales.en;
|
||||
this.prebind = false;
|
||||
this.show_controlbox_by_default = false;
|
||||
this.xhr_user_search = false;
|
||||
_.extend(this, settings);
|
||||
this.testing = false; // Exposes sensitive data for testing. Never set to true in production systems!
|
||||
this.callback = callback || function () {};
|
||||
|
||||
// Allow only the whitelisted settings attributes to be overwritten,
|
||||
// nothing else.
|
||||
whitelist = [
|
||||
'animate',
|
||||
'auto_list_rooms',
|
||||
'auto_subscribe',
|
||||
'bosh_service_url',
|
||||
'fullname',
|
||||
'debug',
|
||||
'hide_muc_server',
|
||||
'i18n',
|
||||
'prebind',
|
||||
'show_controlbox_by_default',
|
||||
'xhr_user_search',
|
||||
'connection',
|
||||
'testing'
|
||||
];
|
||||
_.extend(this, _.pick(settings, whitelist));
|
||||
|
||||
var __ = $.proxy(function (str) {
|
||||
var t = this.i18n.translate(str);
|
||||
@ -72,6 +92,49 @@
|
||||
return text.replace(re, '<a target="_blank" href="$1">$1</a>');
|
||||
};
|
||||
|
||||
this.giveFeedback = function (message, klass) {
|
||||
$('.conn-feedback').text(message);
|
||||
$('.conn-feedback').attr('class', 'conn-feedback');
|
||||
if (klass) {
|
||||
$('.conn-feedback').addClass(klass);
|
||||
}
|
||||
};
|
||||
|
||||
this.log = function (txt) {
|
||||
if (this.debug) {
|
||||
console.log(txt);
|
||||
}
|
||||
};
|
||||
|
||||
this.onConnect = function (status) {
|
||||
if (status === Strophe.Status.CONNECTED) {
|
||||
converse.log('Connected');
|
||||
converse.onConnected();
|
||||
} else if (status === Strophe.Status.DISCONNECTED) {
|
||||
if ($button) { $button.show().siblings('span').remove(); }
|
||||
converse.giveFeedback(__('Disconnected'), 'error');
|
||||
converse.connection.connect(connection.jid, connection.pass, converse.onConnect);
|
||||
} else if (status === Strophe.Status.Error) {
|
||||
if ($button) { $button.show().siblings('span').remove(); }
|
||||
converse.giveFeedback(__('Error'), 'error');
|
||||
} else if (status === Strophe.Status.CONNECTING) {
|
||||
converse.giveFeedback(__('Connecting'));
|
||||
} else if (status === Strophe.Status.CONNFAIL) {
|
||||
converse.chatboxesview.views.controlbox.trigger('connection-fail');
|
||||
converse.giveFeedback(__('Connection Failed'), 'error');
|
||||
} else if (status === Strophe.Status.AUTHENTICATING) {
|
||||
converse.giveFeedback(__('Authenticating'));
|
||||
} else if (status === Strophe.Status.AUTHFAIL) {
|
||||
converse.chatboxesview.views.controlbox.trigger('auth-fail');
|
||||
converse.giveFeedback(__('Authentication Failed'), 'error');
|
||||
} else if (status === Strophe.Status.DISCONNECTING) {
|
||||
converse.giveFeedback(__('Disconnecting'), 'error');
|
||||
} else if (status === Strophe.Status.ATTACHED) {
|
||||
converse.log('Attached');
|
||||
converse.onConnected();
|
||||
}
|
||||
};
|
||||
|
||||
this.toISOString = function (date) {
|
||||
var pad;
|
||||
if (typeof date.toISOString !== 'undefined') {
|
||||
@ -158,10 +221,10 @@
|
||||
.t('1');
|
||||
|
||||
converse.connection.sendIQ(iq,
|
||||
callback,
|
||||
function () {
|
||||
console.log('Error while retrieving collections');
|
||||
});
|
||||
callback,
|
||||
function () {
|
||||
converse.log('Error while retrieving collections');
|
||||
});
|
||||
};
|
||||
|
||||
this.collections.getLastMessages = function (jid, callback) {
|
||||
@ -556,7 +619,7 @@
|
||||
});
|
||||
}, this),
|
||||
$.proxy(function (stanza) {
|
||||
console.log("ChatBoxView.initialize: An error occured while fetching vcard");
|
||||
converse.log("ChatBoxView.initialize: An error occured while fetching vcard");
|
||||
}, this)
|
||||
);
|
||||
}
|
||||
@ -755,7 +818,7 @@
|
||||
this.addContact(jid, fullname);
|
||||
}, this),
|
||||
$.proxy(function (stanza) {
|
||||
console.log("An error occured while fetching vcard");
|
||||
converse.log("An error occured while fetching vcard");
|
||||
var jid = $(stanza).attr('from');
|
||||
this.addContact(jid, jid);
|
||||
}, this));
|
||||
@ -1002,7 +1065,7 @@
|
||||
}
|
||||
}
|
||||
if (!nick) { return; }
|
||||
chatroom = converse.chatboxes.createChatBox({
|
||||
chatroom = converse.chatboxesview.showChatBox({
|
||||
'id': jid,
|
||||
'jid': jid,
|
||||
'name': Strophe.unescapeNode(Strophe.getNodeFromJid(jid)),
|
||||
@ -1098,7 +1161,7 @@
|
||||
if ((!converse.prebind) && (!converse.connection)) {
|
||||
// Add login panel if the user still has to authenticate
|
||||
this.$el.html(this.template(this.model.toJSON()));
|
||||
this.loginpanel = new converse.LoginPanel({'$parent': this.$el.find('#controlbox-panes')});
|
||||
this.loginpanel = new converse.LoginPanel({'$parent': this.$el.find('#controlbox-panes'), 'model': this});
|
||||
this.loginpanel.render();
|
||||
} else if (!this.contactspanel) {
|
||||
this.$el.html(this.template(this.model.toJSON()));
|
||||
@ -1668,16 +1731,6 @@
|
||||
});
|
||||
},
|
||||
|
||||
createChatBox: function (attrs) {
|
||||
var chatbox = this.get(attrs.jid);
|
||||
if (chatbox) {
|
||||
chatbox.trigger('show');
|
||||
} else {
|
||||
chatbox = this.create(attrs);
|
||||
}
|
||||
return chatbox;
|
||||
},
|
||||
|
||||
messageReceived: function (message) {
|
||||
var partner_jid, $message = $(message),
|
||||
message_from = $message.attr('from');
|
||||
@ -1747,6 +1800,20 @@
|
||||
}
|
||||
}
|
||||
}, this);
|
||||
},
|
||||
|
||||
showChatBox: function (attrs) {
|
||||
var chatbox = this.model.get(attrs.jid);
|
||||
if (chatbox) {
|
||||
chatbox.trigger('show');
|
||||
} else {
|
||||
chatbox = this.model.create(attrs, {
|
||||
'error': function (model, response) {
|
||||
converse.log(response.responseText);
|
||||
}
|
||||
});
|
||||
}
|
||||
return chatbox;
|
||||
}
|
||||
});
|
||||
|
||||
@ -1780,7 +1847,7 @@
|
||||
|
||||
openChat: function (ev) {
|
||||
ev.preventDefault();
|
||||
converse.chatboxes.createChatBox({
|
||||
converse.chatboxesview.showChatBox({
|
||||
'id': this.model.get('jid'),
|
||||
'jid': this.model.get('jid'),
|
||||
'fullname': this.model.get('fullname'),
|
||||
@ -2122,7 +2189,7 @@
|
||||
});
|
||||
}, this),
|
||||
$.proxy(function (jid, fullname, img, img_type, url) {
|
||||
console.log("Error while retrieving vcard");
|
||||
converse.log("Error while retrieving vcard");
|
||||
this.add({jid: bare_jid, subscription: 'none', ask: 'request', fullname: jid, is_last: true});
|
||||
}, this)
|
||||
);
|
||||
@ -2544,44 +2611,26 @@
|
||||
'<input type="text" id="bosh_service_url">'),
|
||||
|
||||
connect: function ($form, jid, password) {
|
||||
var button = null,
|
||||
connection = new Strophe.Connection(converse.bosh_service_url);
|
||||
if ($form) {
|
||||
$button = $form.find('input[type=submit]');
|
||||
$button.hide().after('<span class="spinner login-submit"/>');
|
||||
$form.find('input[type=submit]').hide().after('<span class="spinner login-submit"/>');
|
||||
}
|
||||
converse.connection = new Strophe.Connection(converse.bosh_service_url);
|
||||
converse.connection.connect(jid, password, converse.onConnect);
|
||||
},
|
||||
|
||||
showConnectButton: function () {
|
||||
var $form = this.$el.find('#converse-login');
|
||||
var $button = $form.find('input[type=submit]')
|
||||
if ($button.length) {
|
||||
$button.show().siblings('span').remove();
|
||||
}
|
||||
connection.connect(jid, password, $.proxy(function (status, message) {
|
||||
if (status === Strophe.Status.CONNECTED) {
|
||||
console.log(__('Connected'));
|
||||
converse.onConnected(connection);
|
||||
} else if (status === Strophe.Status.DISCONNECTED) {
|
||||
if ($button) { $button.show().siblings('span').remove(); }
|
||||
converse.giveFeedback(__('Disconnected'), 'error');
|
||||
this.connect(null, connection.jid, connection.pass);
|
||||
} else if (status === Strophe.Status.Error) {
|
||||
if ($button) { $button.show().siblings('span').remove(); }
|
||||
converse.giveFeedback(__('Error'), 'error');
|
||||
} else if (status === Strophe.Status.CONNECTING) {
|
||||
converse.giveFeedback(__('Connecting'));
|
||||
} else if (status === Strophe.Status.CONNFAIL) {
|
||||
if ($button) { $button.show().siblings('span').remove(); }
|
||||
converse.giveFeedback(__('Connection Failed'), 'error');
|
||||
} else if (status === Strophe.Status.AUTHENTICATING) {
|
||||
converse.giveFeedback(__('Authenticating'));
|
||||
} else if (status === Strophe.Status.AUTHFAIL) {
|
||||
if ($button) { $button.show().siblings('span').remove(); }
|
||||
converse.giveFeedback(__('Authentication Failed'), 'error');
|
||||
} else if (status === Strophe.Status.DISCONNECTING) {
|
||||
converse.giveFeedback(__('Disconnecting'), 'error');
|
||||
} else if (status === Strophe.Status.ATTACHED) {
|
||||
console.log(__('Attached'));
|
||||
}
|
||||
}, this));
|
||||
},
|
||||
|
||||
initialize: function (cfg) {
|
||||
cfg.$parent.append(this.$el.html(this.template()));
|
||||
this.$tabs = cfg.$parent.parent().find('#controlbox-tabs');
|
||||
this.model.on('connection-fail', function () { this.showConnectButton(); }, this);
|
||||
this.model.on('auth-fail', function () { this.showConnectButton(); }, this);
|
||||
},
|
||||
|
||||
render: function () {
|
||||
@ -2655,14 +2704,6 @@
|
||||
}
|
||||
};
|
||||
|
||||
this.giveFeedback = function (message, klass) {
|
||||
$('.conn-feedback').text(message);
|
||||
$('.conn-feedback').attr('class', 'conn-feedback');
|
||||
if (klass) {
|
||||
$('.conn-feedback').addClass(klass);
|
||||
}
|
||||
};
|
||||
|
||||
this.initStatus = function (callback) {
|
||||
this.xmppstatus = new this.XMPPStatus();
|
||||
var id = hex_sha1('converse.xmppstatus-'+this.bare_jid);
|
||||
@ -2682,8 +2723,7 @@
|
||||
this.rosterview = new this.RosterView({'model':this.roster});
|
||||
}
|
||||
|
||||
this.onConnected = function (connection, callback) {
|
||||
this.connection = connection;
|
||||
this.onConnected = function () {
|
||||
if (this.debug) {
|
||||
this.connection.xmlInput = function (body) { console.log(body); };
|
||||
this.connection.xmlOutput = function (body) { console.log(body); };
|
||||
@ -2722,8 +2762,10 @@
|
||||
this.windowState = e.type;
|
||||
},this));
|
||||
this.giveFeedback(__('Online Contacts'));
|
||||
if (callback) {
|
||||
callback(this);
|
||||
if (this.testing) {
|
||||
this.callback(this);
|
||||
} else {
|
||||
this.callback();
|
||||
}
|
||||
}, this));
|
||||
};
|
||||
@ -2737,17 +2779,21 @@
|
||||
e.preventDefault(); this.toggleControlBox();
|
||||
}, this)
|
||||
);
|
||||
if (this.show_controlbox_by_default) {
|
||||
this.toggleControlBox();
|
||||
if ((this.prebind) && (!this.connection)) {
|
||||
if ((!this.jid) || (!this.sid) || (!this.rid) || (!this.bosh_service_url)) {
|
||||
this.log('If you set prebind=true, you MUST supply JID, RID and SID values');
|
||||
return;
|
||||
}
|
||||
this.connection = new Strophe.Connection(this.bosh_service_url);
|
||||
this.connection.attach(this.jid, this.sid, this.rid, this.onConnect);
|
||||
} else if (this.connection) {
|
||||
this.onConnected();
|
||||
}
|
||||
if (this.show_controlbox_by_default) { this.showControlBox(); }
|
||||
};
|
||||
return {
|
||||
'initialize': function (settings) {
|
||||
converse.initialize(settings);
|
||||
},
|
||||
'onConnected': function (connection, callback) {
|
||||
// onConnected can only be called after initialize has been called.
|
||||
converse.onConnected(connection, callback);
|
||||
'initialize': function (settings, callback) {
|
||||
converse.initialize(settings, callback);
|
||||
}
|
||||
};
|
||||
}));
|
||||
|
2
converse.min.js
vendored
2
converse.min.js
vendored
File diff suppressed because one or more lines are too long
Binary file not shown.
@ -188,15 +188,17 @@ Jack Moffitt has a great `blogpost`_ about this and even provides an `example Dj
|
||||
.. Note::
|
||||
If you want to enable single session support, make sure to pass **prebind: true**
|
||||
when you call **converse.initialize** (see ./index.html).
|
||||
Additionally you need to pass in valid **jid**, **sid**, **rid** and
|
||||
**bosh_service_url** values.
|
||||
|
||||
When you authenticate to the XMPP server on your backend, you'll receive two
|
||||
tokens, RID (request ID) and SID (session ID).
|
||||
|
||||
These tokens then need to be passed back to the javascript running in your
|
||||
browser, where you will need them attach to the existing session.
|
||||
browser, where you will need them to attach to the existing session.
|
||||
|
||||
You can embed the RID and SID tokens in your HTML markup or you can do an
|
||||
XMLHttpRequest call to you server and ask it to return them for you.
|
||||
XMLHttpRequest call to your server and ask it to return them for you.
|
||||
|
||||
Below is one example of how this could work. An Ajax call is made to the
|
||||
relative URL **/prebind** and it expects to receive JSON data back.
|
||||
@ -204,26 +206,19 @@ relative URL **/prebind** and it expects to receive JSON data back.
|
||||
::
|
||||
|
||||
$.getJSON('/prebind', function (data) {
|
||||
var connection = new Strophe.Connection(converse.bosh_service_url);
|
||||
connection.attach(data.jid, data.sid, data.rid, function (status) {
|
||||
if ((status === Strophe.Status.ATTACHED) || (status === Strophe.Status.CONNECTED)) {
|
||||
converse.onConnected(connection)
|
||||
}
|
||||
});
|
||||
}
|
||||
converse.initialize({
|
||||
prebind: true,
|
||||
bosh_service_url: data.bosh_service_url,
|
||||
jid: data.jid,
|
||||
sid: data.sid,
|
||||
rid: data.rid
|
||||
});
|
||||
);
|
||||
|
||||
**Here's what's happening:**
|
||||
|
||||
The JSON data contains the user's JID (jabber ID), RID and SID. The URL to the
|
||||
BOSH connection manager is already set as a configuration setting on the
|
||||
*converse* object (see ./main.js), so we can reuse it from there.
|
||||
|
||||
A new Strophe.Connection object is instantiated and then *attach* is called with
|
||||
the user's JID, the necessary tokens and a callback function.
|
||||
|
||||
In the callback function, you call *converse.onConnected* together with the
|
||||
connection object.
|
||||
The JSON data contains the user's JID (jabber ID), RID, SID and the URL to the
|
||||
BOSH connection manager.
|
||||
|
||||
|
||||
Facebook integration
|
||||
@ -471,22 +466,28 @@ If set to true, debugging output will be logged to the browser console.
|
||||
fullname
|
||||
--------
|
||||
|
||||
If you are using prebinding, you need to specify the fullname of the currently
|
||||
logged in user.
|
||||
If you are using prebinding, can specify the fullname of the currently
|
||||
logged in user, otherwise the user's vCard will be fetched.
|
||||
|
||||
hide_muc_server
|
||||
---------------
|
||||
|
||||
Default = False
|
||||
Default = false
|
||||
|
||||
Hide the ``server`` input field of the form inside the ``Room`` panel of the
|
||||
controlbox. Useful if you want to restrict users to a specific XMPP server of
|
||||
your choosing.
|
||||
|
||||
i18n
|
||||
----
|
||||
|
||||
Specify the locale/language. The language must be in the ``locales`` object. Refer to
|
||||
``./locale/locales.js`` to see which locales are supported.
|
||||
|
||||
prebind
|
||||
--------
|
||||
|
||||
Default = False
|
||||
Default = false
|
||||
|
||||
Use this option when you want to attach to an existing XMPP connection that was
|
||||
already authenticated (usually on the backend before page load).
|
||||
@ -494,26 +495,19 @@ already authenticated (usually on the backend before page load).
|
||||
This is useful when you don't want to render the login form on the chat control
|
||||
box with each page load.
|
||||
|
||||
When set to true, you'll need to make sure that the onConnected method is
|
||||
called, and passed to it a Strophe connection object.
|
||||
For prebinding to work, your backend server must authenticate for you, and
|
||||
then return a JID (jabber ID), SID (session ID) and RID (Request ID).
|
||||
|
||||
Besides requiring the back-end to authenticate you, you'll also
|
||||
have to write a Javascript snippet to attach to the set up connection::
|
||||
If you set ``prebind`` to ``true``, you have to make sure to also pass in these
|
||||
values as ``jid``, ``sid``, ``rid``.
|
||||
|
||||
$.JSON({
|
||||
'url': 'mysite.com/xmpp-authenticate',
|
||||
'success': function (data) {
|
||||
connection = new Strophe.Connection(bosh_service_url);
|
||||
connection.attach(data.jid, data.sid, data.rid, converse.onConnected);
|
||||
}
|
||||
Additionally, you have to specify ``bosh_service_url``.
|
||||
|
||||
The backend must authenticate for you, and then return a SID (session ID) and
|
||||
RID (Request ID), which you use when you attach to the connection.
|
||||
|
||||
show_controlbox_by_default
|
||||
--------------------------
|
||||
|
||||
Default = False
|
||||
Default = false
|
||||
|
||||
The "controlbox" refers to the special chatbox containing your contacts roster,
|
||||
status widget, chatrooms and other controls.
|
||||
@ -542,40 +536,27 @@ be used.
|
||||
Minification
|
||||
============
|
||||
|
||||
Minifying Javascript
|
||||
====================
|
||||
Minifying Javascript and CSS
|
||||
============================
|
||||
|
||||
Please make sure to read the section `Development`_ and that you have installed
|
||||
all development dependencies (long story short, you can run ``npm install``
|
||||
and then ``grunt fetch``).
|
||||
|
||||
We use `require.js`_ to keep track of *Converse.js* and its dependencies and to
|
||||
to bundle them together in a single minified file fit for deployment to a
|
||||
production site.
|
||||
|
||||
To use the require.js's optimization tool, you'll need Node and it's package
|
||||
manager, NPM.
|
||||
|
||||
You can then install install require.js for Node like so:
|
||||
To minify the Javascript and CSS, run the following command:
|
||||
|
||||
::
|
||||
|
||||
npm install requirejs
|
||||
|
||||
The minified javascript file is then created like this:
|
||||
|
||||
::
|
||||
|
||||
r.js -o build.js
|
||||
|
||||
You should now have a new minified file (the name which is specified in build.js).
|
||||
grunt minify
|
||||
|
||||
Javascript will be bundled and minified via `require.js`_'s optimization tool.
|
||||
You can `read more about require.js's optimizer here`_.
|
||||
|
||||
Minifying CSS
|
||||
=============
|
||||
|
||||
CSS can be minimized with Yahoo's yuicompressor tool:
|
||||
|
||||
::
|
||||
|
||||
yui-compressor --type=css converse.css -o converse.min.css
|
||||
CSS is minified via `cssmin <https://github.com/gruntjs/grunt-contrib-cssmin>`_.
|
||||
|
||||
|
||||
============
|
||||
|
@ -32,4 +32,11 @@ h1 a {
|
||||
|
||||
ul {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
tt.literal {
|
||||
color: #222;
|
||||
background-color: #fff;
|
||||
font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace;
|
||||
font-size: 14px;
|
||||
}
|
@ -102,16 +102,16 @@
|
||||
<li><a class="reference internal" href="#debug" id="id26">debug</a></li>
|
||||
<li><a class="reference internal" href="#fullname" id="id27">fullname</a></li>
|
||||
<li><a class="reference internal" href="#hide-muc-server" id="id28">hide_muc_server</a></li>
|
||||
<li><a class="reference internal" href="#prebind" id="id29">prebind</a></li>
|
||||
<li><a class="reference internal" href="#show-controlbox-by-default" id="id30">show_controlbox_by_default</a></li>
|
||||
<li><a class="reference internal" href="#xhr-user-search" id="id31">xhr_user_search</a></li>
|
||||
<li><a class="reference internal" href="#i18n" id="id29">i18n</a></li>
|
||||
<li><a class="reference internal" href="#prebind" id="id30">prebind</a></li>
|
||||
<li><a class="reference internal" href="#show-controlbox-by-default" id="id31">show_controlbox_by_default</a></li>
|
||||
<li><a class="reference internal" href="#xhr-user-search" id="id32">xhr_user_search</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#minification" id="id32">Minification</a><ul>
|
||||
<li><a class="reference internal" href="#minifying-javascript" id="id33">Minifying Javascript</a></li>
|
||||
<li><a class="reference internal" href="#minifying-css" id="id34">Minifying CSS</a></li>
|
||||
<li><a class="reference internal" href="#minification" id="id33">Minification</a><ul>
|
||||
<li><a class="reference internal" href="#minifying-javascript-and-css" id="id34">Minifying Javascript and CSS</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#translations" id="id35">Translations</a></li>
|
||||
@ -245,34 +245,31 @@ but this will require custom code on your server.</p>
|
||||
<div class="admonition note">
|
||||
<p class="first admonition-title">Note</p>
|
||||
<p class="last">If you want to enable single session support, make sure to pass <strong>prebind: true</strong>
|
||||
when you call <strong>converse.initialize</strong> (see ./index.html).</p>
|
||||
when you call <strong>converse.initialize</strong> (see ./index.html).
|
||||
Additionally you need to pass in valid <strong>jid</strong>, <strong>sid</strong>, <strong>rid</strong> and
|
||||
<strong>bosh_service_url</strong> values.</p>
|
||||
</div>
|
||||
<p>When you authenticate to the XMPP server on your backend, you’ll receive two
|
||||
tokens, RID (request ID) and SID (session ID).</p>
|
||||
<p>These tokens then need to be passed back to the javascript running in your
|
||||
browser, where you will need them attach to the existing session.</p>
|
||||
browser, where you will need them to attach to the existing session.</p>
|
||||
<p>You can embed the RID and SID tokens in your HTML markup or you can do an
|
||||
XMLHttpRequest call to you server and ask it to return them for you.</p>
|
||||
XMLHttpRequest call to your server and ask it to return them for you.</p>
|
||||
<p>Below is one example of how this could work. An Ajax call is made to the
|
||||
relative URL <strong>/prebind</strong> and it expects to receive JSON data back.</p>
|
||||
<div class="highlight-python"><pre>$.getJSON('/prebind', function (data) {
|
||||
var connection = new Strophe.Connection(converse.bosh_service_url);
|
||||
connection.attach(data.jid, data.sid, data.rid, function (status) {
|
||||
if ((status === Strophe.Status.ATTACHED) || (status === Strophe.Status.CONNECTED)) {
|
||||
converse.onConnected(connection)
|
||||
}
|
||||
});
|
||||
}
|
||||
converse.initialize({
|
||||
prebind: true,
|
||||
bosh_service_url: data.bosh_service_url,
|
||||
jid: data.jid,
|
||||
sid: data.sid,
|
||||
rid: data.rid
|
||||
});
|
||||
);</pre>
|
||||
</div>
|
||||
<p><strong>Here’s what’s happening:</strong></p>
|
||||
<p>The JSON data contains the user’s JID (jabber ID), RID and SID. The URL to the
|
||||
BOSH connection manager is already set as a configuration setting on the
|
||||
<em>converse</em> object (see ./main.js), so we can reuse it from there.</p>
|
||||
<p>A new Strophe.Connection object is instantiated and then <em>attach</em> is called with
|
||||
the user’s JID, the necessary tokens and a callback function.</p>
|
||||
<p>In the callback function, you call <em>converse.onConnected</em> together with the
|
||||
connection object.</p>
|
||||
<p>The JSON data contains the user’s JID (jabber ID), RID, SID and the URL to the
|
||||
BOSH connection manager.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="facebook-integration">
|
||||
@ -451,40 +448,37 @@ a middle man between HTTP and XMPP.</p>
|
||||
</div>
|
||||
<div class="section" id="fullname">
|
||||
<h3><a class="toc-backref" href="#id27">fullname</a><a class="headerlink" href="#fullname" title="Permalink to this headline">¶</a></h3>
|
||||
<p>If you are using prebinding, you need to specify the fullname of the currently
|
||||
logged in user.</p>
|
||||
<p>If you are using prebinding, can specify the fullname of the currently
|
||||
logged in user, otherwise the user’s vCard will be fetched.</p>
|
||||
</div>
|
||||
<div class="section" id="hide-muc-server">
|
||||
<h3><a class="toc-backref" href="#id28">hide_muc_server</a><a class="headerlink" href="#hide-muc-server" title="Permalink to this headline">¶</a></h3>
|
||||
<p>Default = False</p>
|
||||
<p>Default = false</p>
|
||||
<p>Hide the <tt class="docutils literal"><span class="pre">server</span></tt> input field of the form inside the <tt class="docutils literal"><span class="pre">Room</span></tt> panel of the
|
||||
controlbox. Useful if you want to restrict users to a specific XMPP server of
|
||||
your choosing.</p>
|
||||
</div>
|
||||
<div class="section" id="i18n">
|
||||
<h3><a class="toc-backref" href="#id29">i18n</a><a class="headerlink" href="#i18n" title="Permalink to this headline">¶</a></h3>
|
||||
<p>Specify the locale/language. The language must be in the <tt class="docutils literal"><span class="pre">locales</span></tt> object. Refer to
|
||||
<tt class="docutils literal"><span class="pre">./locale/locales.js</span></tt> to see which locales are supported.</p>
|
||||
</div>
|
||||
<div class="section" id="prebind">
|
||||
<h3><a class="toc-backref" href="#id29">prebind</a><a class="headerlink" href="#prebind" title="Permalink to this headline">¶</a></h3>
|
||||
<p>Default = False</p>
|
||||
<h3><a class="toc-backref" href="#id30">prebind</a><a class="headerlink" href="#prebind" title="Permalink to this headline">¶</a></h3>
|
||||
<p>Default = false</p>
|
||||
<p>Use this option when you want to attach to an existing XMPP connection that was
|
||||
already authenticated (usually on the backend before page load).</p>
|
||||
<p>This is useful when you don’t want to render the login form on the chat control
|
||||
box with each page load.</p>
|
||||
<p>When set to true, you’ll need to make sure that the onConnected method is
|
||||
called, and passed to it a Strophe connection object.</p>
|
||||
<p>Besides requiring the back-end to authenticate you, you’ll also
|
||||
have to write a Javascript snippet to attach to the set up connection:</p>
|
||||
<div class="highlight-python"><pre>$.JSON({
|
||||
'url': 'mysite.com/xmpp-authenticate',
|
||||
'success': function (data) {
|
||||
connection = new Strophe.Connection(bosh_service_url);
|
||||
connection.attach(data.jid, data.sid, data.rid, converse.onConnected);
|
||||
}</pre>
|
||||
</div>
|
||||
<p>The backend must authenticate for you, and then return a SID (session ID) and
|
||||
RID (Request ID), which you use when you attach to the connection.</p>
|
||||
<p>For prebinding to work, your backend server must authenticate for you, and
|
||||
then return a JID (jabber ID), SID (session ID) and RID (Request ID).</p>
|
||||
<p>If you set <tt class="docutils literal"><span class="pre">prebind</span></tt> to <tt class="docutils literal"><span class="pre">true</span></tt>, you have to make sure to also pass in these
|
||||
values as <tt class="docutils literal"><span class="pre">jid</span></tt>, <tt class="docutils literal"><span class="pre">sid</span></tt>, <tt class="docutils literal"><span class="pre">rid</span></tt>.</p>
|
||||
<p>Additionally, you have to specify <tt class="docutils literal"><span class="pre">bosh_service_url</span></tt>.</p>
|
||||
</div>
|
||||
<div class="section" id="show-controlbox-by-default">
|
||||
<h3><a class="toc-backref" href="#id30">show_controlbox_by_default</a><a class="headerlink" href="#show-controlbox-by-default" title="Permalink to this headline">¶</a></h3>
|
||||
<p>Default = False</p>
|
||||
<h3><a class="toc-backref" href="#id31">show_controlbox_by_default</a><a class="headerlink" href="#show-controlbox-by-default" title="Permalink to this headline">¶</a></h3>
|
||||
<p>Default = false</p>
|
||||
<p>The “controlbox” refers to the special chatbox containing your contacts roster,
|
||||
status widget, chatrooms and other controls.</p>
|
||||
<p>By default this box is hidden and can be toggled by clicking on any element in
|
||||
@ -493,7 +487,7 @@ the page with class <em>toggle-online-users</em>.</p>
|
||||
page load.</p>
|
||||
</div>
|
||||
<div class="section" id="xhr-user-search">
|
||||
<h3><a class="toc-backref" href="#id31">xhr_user_search</a><a class="headerlink" href="#xhr-user-search" title="Permalink to this headline">¶</a></h3>
|
||||
<h3><a class="toc-backref" href="#id32">xhr_user_search</a><a class="headerlink" href="#xhr-user-search" title="Permalink to this headline">¶</a></h3>
|
||||
<p>Default = False</p>
|
||||
<p>There are two ways to add users.</p>
|
||||
<ul class="simple">
|
||||
@ -506,28 +500,21 @@ be used.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="minification">
|
||||
<h1><a class="toc-backref" href="#id32">Minification</a><a class="headerlink" href="#minification" title="Permalink to this headline">¶</a></h1>
|
||||
<div class="section" id="minifying-javascript">
|
||||
<h2><a class="toc-backref" href="#id33">Minifying Javascript</a><a class="headerlink" href="#minifying-javascript" title="Permalink to this headline">¶</a></h2>
|
||||
<h1><a class="toc-backref" href="#id33">Minification</a><a class="headerlink" href="#minification" title="Permalink to this headline">¶</a></h1>
|
||||
<div class="section" id="minifying-javascript-and-css">
|
||||
<h2><a class="toc-backref" href="#id34">Minifying Javascript and CSS</a><a class="headerlink" href="#minifying-javascript-and-css" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Please make sure to read the section <a class="reference internal" href="#development">Development</a> and that you have installed
|
||||
all development dependencies (long story short, you can run <tt class="docutils literal"><span class="pre">npm</span> <span class="pre">install</span></tt>
|
||||
and then <tt class="docutils literal"><span class="pre">grunt</span> <span class="pre">fetch</span></tt>).</p>
|
||||
<p>We use <a class="reference external" href="http://requirejs.org">require.js</a> to keep track of <em>Converse.js</em> and its dependencies and to
|
||||
to bundle them together in a single minified file fit for deployment to a
|
||||
production site.</p>
|
||||
<p>To use the require.js’s optimization tool, you’ll need Node and it’s package
|
||||
manager, NPM.</p>
|
||||
<p>You can then install install require.js for Node like so:</p>
|
||||
<div class="highlight-python"><pre>npm install requirejs</pre>
|
||||
</div>
|
||||
<p>The minified javascript file is then created like this:</p>
|
||||
<div class="highlight-python"><pre>r.js -o build.js</pre>
|
||||
</div>
|
||||
<p>You should now have a new minified file (the name which is specified in build.js).</p>
|
||||
<p>You can <a class="reference external" href="http://requirejs.org/docs/optimization.html">read more about require.js’s optimizer here</a>.</p>
|
||||
</div>
|
||||
<div class="section" id="minifying-css">
|
||||
<h2><a class="toc-backref" href="#id34">Minifying CSS</a><a class="headerlink" href="#minifying-css" title="Permalink to this headline">¶</a></h2>
|
||||
<p>CSS can be minimized with Yahoo’s yuicompressor tool:</p>
|
||||
<div class="highlight-python"><pre>yui-compressor --type=css converse.css -o converse.min.css</pre>
|
||||
<p>To minify the Javascript and CSS, run the following command:</p>
|
||||
<div class="highlight-python"><pre>grunt minify</pre>
|
||||
</div>
|
||||
<p>Javascript will be bundled and minified via <a class="reference external" href="http://requirejs.org">require.js</a>‘s optimization tool.
|
||||
You can <a class="reference external" href="http://requirejs.org/docs/optimization.html">read more about require.js’s optimizer here</a>.</p>
|
||||
<p>CSS is minified via <a class="reference external" href="https://github.com/gruntjs/grunt-contrib-cssmin">cssmin</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="translations">
|
||||
|
File diff suppressed because one or more lines are too long
@ -188,15 +188,17 @@ Jack Moffitt has a great `blogpost`_ about this and even provides an `example Dj
|
||||
.. Note::
|
||||
If you want to enable single session support, make sure to pass **prebind: true**
|
||||
when you call **converse.initialize** (see ./index.html).
|
||||
Additionally you need to pass in valid **jid**, **sid**, **rid** and
|
||||
**bosh_service_url** values.
|
||||
|
||||
When you authenticate to the XMPP server on your backend, you'll receive two
|
||||
tokens, RID (request ID) and SID (session ID).
|
||||
|
||||
These tokens then need to be passed back to the javascript running in your
|
||||
browser, where you will need them attach to the existing session.
|
||||
browser, where you will need them to attach to the existing session.
|
||||
|
||||
You can embed the RID and SID tokens in your HTML markup or you can do an
|
||||
XMLHttpRequest call to you server and ask it to return them for you.
|
||||
XMLHttpRequest call to your server and ask it to return them for you.
|
||||
|
||||
Below is one example of how this could work. An Ajax call is made to the
|
||||
relative URL **/prebind** and it expects to receive JSON data back.
|
||||
@ -204,26 +206,19 @@ relative URL **/prebind** and it expects to receive JSON data back.
|
||||
::
|
||||
|
||||
$.getJSON('/prebind', function (data) {
|
||||
var connection = new Strophe.Connection(converse.bosh_service_url);
|
||||
connection.attach(data.jid, data.sid, data.rid, function (status) {
|
||||
if ((status === Strophe.Status.ATTACHED) || (status === Strophe.Status.CONNECTED)) {
|
||||
converse.onConnected(connection)
|
||||
}
|
||||
});
|
||||
}
|
||||
converse.initialize({
|
||||
prebind: true,
|
||||
bosh_service_url: data.bosh_service_url,
|
||||
jid: data.jid,
|
||||
sid: data.sid,
|
||||
rid: data.rid
|
||||
});
|
||||
);
|
||||
|
||||
**Here's what's happening:**
|
||||
|
||||
The JSON data contains the user's JID (jabber ID), RID and SID. The URL to the
|
||||
BOSH connection manager is already set as a configuration setting on the
|
||||
*converse* object (see ./main.js), so we can reuse it from there.
|
||||
|
||||
A new Strophe.Connection object is instantiated and then *attach* is called with
|
||||
the user's JID, the necessary tokens and a callback function.
|
||||
|
||||
In the callback function, you call *converse.onConnected* together with the
|
||||
connection object.
|
||||
The JSON data contains the user's JID (jabber ID), RID, SID and the URL to the
|
||||
BOSH connection manager.
|
||||
|
||||
|
||||
Facebook integration
|
||||
@ -471,22 +466,28 @@ If set to true, debugging output will be logged to the browser console.
|
||||
fullname
|
||||
--------
|
||||
|
||||
If you are using prebinding, you need to specify the fullname of the currently
|
||||
logged in user.
|
||||
If you are using prebinding, can specify the fullname of the currently
|
||||
logged in user, otherwise the user's vCard will be fetched.
|
||||
|
||||
hide_muc_server
|
||||
---------------
|
||||
|
||||
Default = False
|
||||
Default = false
|
||||
|
||||
Hide the ``server`` input field of the form inside the ``Room`` panel of the
|
||||
controlbox. Useful if you want to restrict users to a specific XMPP server of
|
||||
your choosing.
|
||||
|
||||
i18n
|
||||
----
|
||||
|
||||
Specify the locale/language. The language must be in the ``locales`` object. Refer to
|
||||
``./locale/locales.js`` to see which locales are supported.
|
||||
|
||||
prebind
|
||||
--------
|
||||
|
||||
Default = False
|
||||
Default = false
|
||||
|
||||
Use this option when you want to attach to an existing XMPP connection that was
|
||||
already authenticated (usually on the backend before page load).
|
||||
@ -494,26 +495,19 @@ already authenticated (usually on the backend before page load).
|
||||
This is useful when you don't want to render the login form on the chat control
|
||||
box with each page load.
|
||||
|
||||
When set to true, you'll need to make sure that the onConnected method is
|
||||
called, and passed to it a Strophe connection object.
|
||||
For prebinding to work, your backend server must authenticate for you, and
|
||||
then return a JID (jabber ID), SID (session ID) and RID (Request ID).
|
||||
|
||||
Besides requiring the back-end to authenticate you, you'll also
|
||||
have to write a Javascript snippet to attach to the set up connection::
|
||||
If you set ``prebind`` to ``true``, you have to make sure to also pass in these
|
||||
values as ``jid``, ``sid``, ``rid``.
|
||||
|
||||
$.JSON({
|
||||
'url': 'mysite.com/xmpp-authenticate',
|
||||
'success': function (data) {
|
||||
connection = new Strophe.Connection(bosh_service_url);
|
||||
connection.attach(data.jid, data.sid, data.rid, converse.onConnected);
|
||||
}
|
||||
Additionally, you have to specify ``bosh_service_url``.
|
||||
|
||||
The backend must authenticate for you, and then return a SID (session ID) and
|
||||
RID (Request ID), which you use when you attach to the connection.
|
||||
|
||||
show_controlbox_by_default
|
||||
--------------------------
|
||||
|
||||
Default = False
|
||||
Default = false
|
||||
|
||||
The "controlbox" refers to the special chatbox containing your contacts roster,
|
||||
status widget, chatrooms and other controls.
|
||||
@ -542,40 +536,27 @@ be used.
|
||||
Minification
|
||||
============
|
||||
|
||||
Minifying Javascript
|
||||
====================
|
||||
Minifying Javascript and CSS
|
||||
============================
|
||||
|
||||
Please make sure to read the section `Development`_ and that you have installed
|
||||
all development dependencies (long story short, you can run ``npm install``
|
||||
and then ``grunt fetch``).
|
||||
|
||||
We use `require.js`_ to keep track of *Converse.js* and its dependencies and to
|
||||
to bundle them together in a single minified file fit for deployment to a
|
||||
production site.
|
||||
|
||||
To use the require.js's optimization tool, you'll need Node and it's package
|
||||
manager, NPM.
|
||||
|
||||
You can then install install require.js for Node like so:
|
||||
To minify the Javascript and CSS, run the following command:
|
||||
|
||||
::
|
||||
|
||||
npm install requirejs
|
||||
|
||||
The minified javascript file is then created like this:
|
||||
|
||||
::
|
||||
|
||||
r.js -o build.js
|
||||
|
||||
You should now have a new minified file (the name which is specified in build.js).
|
||||
grunt minify
|
||||
|
||||
Javascript will be bundled and minified via `require.js`_'s optimization tool.
|
||||
You can `read more about require.js's optimizer here`_.
|
||||
|
||||
Minifying CSS
|
||||
=============
|
||||
|
||||
CSS can be minimized with Yahoo's yuicompressor tool:
|
||||
|
||||
::
|
||||
|
||||
yui-compressor --type=css converse.css -o converse.min.css
|
||||
CSS is minified via `cssmin <https://github.com/gruntjs/grunt-contrib-cssmin>`_.
|
||||
|
||||
|
||||
============
|
||||
|
@ -33,3 +33,10 @@ h1 a {
|
||||
ul {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
tt.literal {
|
||||
color: #222;
|
||||
background-color: #fff;
|
||||
font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
@ -167,7 +167,7 @@
|
||||
prebind: false,
|
||||
show_controlbox_by_default: true,
|
||||
xhr_user_search: false,
|
||||
debug: false
|
||||
debug: true
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
3
mock.js
3
mock.js
@ -23,7 +23,8 @@
|
||||
'unauthorize': function () {},
|
||||
'get': function () {},
|
||||
'subscribe': function () {},
|
||||
'registerCallback': function () {}
|
||||
'registerCallback': function () {},
|
||||
'remove': function (jid, callback) { callback(); }
|
||||
},
|
||||
'vcard': {
|
||||
'get': function (callback, jid) {
|
||||
|
21
mockup.html
21
mockup.html
@ -192,8 +192,9 @@
|
||||
<div class="chatbox" id="37c0c87392010303765fe36b05c0967d62c6b70f" style="opacity: 1; display: inline;">
|
||||
<div class="chat-head chat-head-chatbox">
|
||||
<a class="close-chatbox-button icon-close"></a>
|
||||
<a href="" target="_blank" class="user">
|
||||
<div class="chat-title">John Smit</div>
|
||||
<a href="http://opkode.com" target="_blank" class="user">
|
||||
<canvas height="35px" width="35px" class="avatar" style="background-color: black"></canvas>
|
||||
<div class="chat-title"> JC Brand </div>
|
||||
</a>
|
||||
<p class="user-custom-message"></p>
|
||||
<p></p>
|
||||
@ -203,6 +204,10 @@
|
||||
<span class="chat-message-me">19:39 me: </span>
|
||||
<span class="chat-message-content">Hello world</span>
|
||||
</div>
|
||||
<div class="chat-message ">
|
||||
<span class="chat-message-them">15:45 Benedict-John: </span>
|
||||
<span class="chat-message-content">Dagsê</span>
|
||||
</div>
|
||||
</div>
|
||||
<form class="sendXMPPMessage" action="" method="post">
|
||||
<textarea type="text" class="chat-textarea" placeholder="Personal message"></textarea>
|
||||
@ -213,7 +218,7 @@
|
||||
<div class="chat-head chat-head-chatroom">
|
||||
<a class="close-chatbox-button icon-close"></a>
|
||||
<a class="configure-chatroom-button icon-wrench" style=""></a>
|
||||
<div class="chat-title"> converse.js </div>
|
||||
<div class="chat-title"> Chatroom </div>
|
||||
<p class="chatroom-topic"></p>
|
||||
<p></p>
|
||||
</div>
|
||||
@ -222,8 +227,8 @@
|
||||
<div class="chat-content">
|
||||
<time class="chat-date" datetime="2013-06-04T00:00:00.000Z">Tue Jun 04 2013</time>
|
||||
<div class="chat-message ">
|
||||
<span class="chat-message-room">18:50 fires: </span>
|
||||
<span class="chat-message-content">explodingcoder: hi :)</span>
|
||||
<span class="chat-message-room">18:50 luke: </span>
|
||||
<span class="chat-message-content">leia: hi :)</span>
|
||||
</div>
|
||||
<div class="chat-message ">
|
||||
<span class="chat-message-me">19:40 me: </span>
|
||||
@ -238,8 +243,8 @@
|
||||
<div class="participants">
|
||||
<ul class="participant-list">
|
||||
<li class="participant" title="This user can send messages in this room">jabberthehut</li>
|
||||
<li class="participant" title="This user can send messages in this room">explodingcoder</li>
|
||||
<li class="moderator" title="This user is a moderator">jcbrand</li>
|
||||
<li class="participant" title="This user can send messages in this room">leia</li>
|
||||
<li class="moderator" title="This user is a moderator">luke</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@ -249,7 +254,7 @@
|
||||
<div class="chat-head chat-head-chatroom">
|
||||
<a class="close-chatbox-button icon-close"></a>
|
||||
<a class="configure-chatroom-button" style="display:none"> </a>
|
||||
<div class="chat-title"> problematic </div>
|
||||
<div class="chat-title"> Restricted Chatroom</div>
|
||||
<p class="chatroom-topic"></p>
|
||||
<p></p>
|
||||
</div>
|
||||
|
@ -16,7 +16,6 @@
|
||||
<script type="text/javascript" src="components/underscore/underscore.js"></script>
|
||||
<script type="text/javascript" src="components/backbone//backbone.js"></script>
|
||||
<script type="text/javascript" src="components/backbone.localStorage/backbone.localStorage.js"></script>
|
||||
<script type="text/javascript" src="components/sjcl/sjcl.js"></script>
|
||||
<script type="text/javascript" src="components/tinysort/src/jquery.tinysort.js"></script>
|
||||
<script type="text/javascript" src="components/jed/jed.js"></script>
|
||||
<script type="text/javascript" src="locale/en/LC_MESSAGES/en.js"></script>
|
||||
|
@ -135,7 +135,6 @@
|
||||
.c('not-authorized').attrs({xmlns:'urn:ietf:params:xml:ns:xmpp-stanzas'}).nodeTree;
|
||||
|
||||
var view = this.chatboxesview.views['problematic@muc.localhost'];
|
||||
spyOn(converse.connection.muc, 'removeRoom');
|
||||
spyOn(view, 'renderPasswordForm').andCallThrough();
|
||||
runs(function () {
|
||||
view.onChatRoomPresence(presence, {'nick': 'dummy'});
|
||||
@ -159,7 +158,6 @@
|
||||
.c('error').attrs({by:'coven@chat.shakespeare.lit', type:'auth'})
|
||||
.c('registration-required').attrs({xmlns:'urn:ietf:params:xml:ns:xmpp-stanzas'}).nodeTree;
|
||||
var view = this.chatboxesview.views['problematic@muc.localhost'];
|
||||
spyOn(converse.connection.muc, 'removeRoom');
|
||||
spyOn(view, 'showErrorMessage').andCallThrough();
|
||||
view.onChatRoomPresence(presence, {'nick': 'dummy'});
|
||||
expect(view.$el.find('.chat-body p').text()).toBe('You are not on the member list of this room');
|
||||
@ -175,7 +173,6 @@
|
||||
.c('error').attrs({by:'coven@chat.shakespeare.lit', type:'auth'})
|
||||
.c('forbidden').attrs({xmlns:'urn:ietf:params:xml:ns:xmpp-stanzas'}).nodeTree;
|
||||
var view = this.chatboxesview.views['problematic@muc.localhost'];
|
||||
spyOn(converse.connection.muc, 'removeRoom');
|
||||
spyOn(view, 'showErrorMessage').andCallThrough();
|
||||
view.onChatRoomPresence(presence, {'nick': 'dummy'});
|
||||
expect(view.$el.find('.chat-body p').text()).toBe('You have been banned from this room');
|
||||
@ -191,7 +188,6 @@
|
||||
.c('error').attrs({by:'coven@chat.shakespeare.lit', type:'modify'})
|
||||
.c('jid-malformed').attrs({xmlns:'urn:ietf:params:xml:ns:xmpp-stanzas'}).nodeTree;
|
||||
var view = this.chatboxesview.views['problematic@muc.localhost'];
|
||||
spyOn(converse.connection.muc, 'removeRoom');
|
||||
spyOn(view, 'showErrorMessage').andCallThrough();
|
||||
view.onChatRoomPresence(presence, {'nick': 'dummy'});
|
||||
expect(view.$el.find('.chat-body p').text()).toBe('No nickname was specified');
|
||||
@ -207,7 +203,6 @@
|
||||
.c('error').attrs({by:'coven@chat.shakespeare.lit', type:'cancel'})
|
||||
.c('not-allowed').attrs({xmlns:'urn:ietf:params:xml:ns:xmpp-stanzas'}).nodeTree;
|
||||
var view = this.chatboxesview.views['problematic@muc.localhost'];
|
||||
spyOn(converse.connection.muc, 'removeRoom');
|
||||
spyOn(view, 'showErrorMessage').andCallThrough();
|
||||
view.onChatRoomPresence(presence, {'nick': 'dummy'});
|
||||
expect(view.$el.find('.chat-body p').text()).toBe('You are not allowed to create new rooms');
|
||||
@ -223,7 +218,6 @@
|
||||
.c('error').attrs({by:'coven@chat.shakespeare.lit', type:'cancel'})
|
||||
.c('not-acceptable').attrs({xmlns:'urn:ietf:params:xml:ns:xmpp-stanzas'}).nodeTree;
|
||||
var view = this.chatboxesview.views['problematic@muc.localhost'];
|
||||
spyOn(converse.connection.muc, 'removeRoom');
|
||||
spyOn(view, 'showErrorMessage').andCallThrough();
|
||||
view.onChatRoomPresence(presence, {'nick': 'dummy'});
|
||||
expect(view.$el.find('.chat-body p').text()).toBe("Your nickname doesn't conform to this room's policies");
|
||||
@ -239,7 +233,6 @@
|
||||
.c('error').attrs({by:'coven@chat.shakespeare.lit', type:'cancel'})
|
||||
.c('conflict').attrs({xmlns:'urn:ietf:params:xml:ns:xmpp-stanzas'}).nodeTree;
|
||||
var view = this.chatboxesview.views['problematic@muc.localhost'];
|
||||
spyOn(converse.connection.muc, 'removeRoom');
|
||||
spyOn(view, 'showErrorMessage').andCallThrough();
|
||||
view.onChatRoomPresence(presence, {'nick': 'dummy'});
|
||||
expect(view.$el.find('.chat-body p').text()).toBe("Your nickname is already taken");
|
||||
@ -255,7 +248,6 @@
|
||||
.c('error').attrs({by:'coven@chat.shakespeare.lit', type:'cancel'})
|
||||
.c('item-not-found').attrs({xmlns:'urn:ietf:params:xml:ns:xmpp-stanzas'}).nodeTree;
|
||||
var view = this.chatboxesview.views['problematic@muc.localhost'];
|
||||
spyOn(converse.connection.muc, 'removeRoom');
|
||||
spyOn(view, 'showErrorMessage').andCallThrough();
|
||||
view.onChatRoomPresence(presence, {'nick': 'dummy'});
|
||||
expect(view.$el.find('.chat-body p').text()).toBe("This room does not (yet) exist");
|
||||
@ -271,7 +263,6 @@
|
||||
.c('error').attrs({by:'coven@chat.shakespeare.lit', type:'cancel'})
|
||||
.c('service-unavailable').attrs({xmlns:'urn:ietf:params:xml:ns:xmpp-stanzas'}).nodeTree;
|
||||
var view = this.chatboxesview.views['problematic@muc.localhost'];
|
||||
spyOn(converse.connection.muc, 'removeRoom');
|
||||
spyOn(view, 'showErrorMessage').andCallThrough();
|
||||
view.onChatRoomPresence(presence, {'nick': 'dummy'});
|
||||
expect(view.$el.find('.chat-body p').text()).toBe("This room has reached it's maximum number of occupants");
|
||||
|
@ -12,7 +12,7 @@
|
||||
'Louw Spekman', 'Mohamad Stet', 'Dominik Beyer'
|
||||
];
|
||||
var pend_names = [
|
||||
'Suleyman van Beusichem', 'Nicole Diederich', 'Nanja van Yperen'
|
||||
'Suleyman van Beusichem', 'Nanja van Yperen', 'Nicole Diederich'
|
||||
];
|
||||
var cur_names = [
|
||||
'Max Frankfurter', 'Candice van der Knijff', 'Irini Vlastuin', 'Rinse Sommer', 'Annegreet Gomez',
|
||||
@ -123,6 +123,48 @@
|
||||
expect(this.rosterview.$el.find('dt#pending-xmpp-contacts').css('display')).toEqual('none');
|
||||
}, converse));
|
||||
|
||||
it("can be added to the roster", $.proxy(function () {
|
||||
spyOn(this.rosterview, 'render').andCallThrough();
|
||||
spyOn(this.xmppstatus, 'sendPresence');
|
||||
this.roster.create({
|
||||
jid: pend_names[0].replace(' ','.').toLowerCase() + '@localhost',
|
||||
subscription: 'none',
|
||||
ask: 'subscribe',
|
||||
fullname: pend_names[0],
|
||||
is_last: true
|
||||
});
|
||||
expect(this.rosterview.$el.is(':visible')).toEqual(true);
|
||||
expect(this.xmppstatus.sendPresence).toHaveBeenCalled();
|
||||
expect(this.rosterview.render).toHaveBeenCalled();
|
||||
}, converse));
|
||||
|
||||
it("can be removed by the user", $.proxy(function () {
|
||||
var view = _.toArray(this.rosterview.rosteritemviews).pop();
|
||||
spyOn(window, 'confirm').andReturn(true);
|
||||
spyOn(this.connection.roster, 'remove').andCallThrough();
|
||||
spyOn(this.connection.roster, 'unauthorize');
|
||||
spyOn(this.rosterview.model, 'remove').andCallThrough();
|
||||
//spyOn(view, 'removeContact').andCallThrough();
|
||||
|
||||
runs($.proxy(function () {
|
||||
view.$el.find('.remove-xmpp-contact').click();
|
||||
}, converse));
|
||||
waits(500);
|
||||
runs($.proxy(function () {
|
||||
expect(window.confirm).toHaveBeenCalled();
|
||||
//expect(view.removeContact).toHaveBeenCalled();
|
||||
expect(this.connection.roster.remove).toHaveBeenCalled();
|
||||
expect(this.connection.roster.unauthorize).toHaveBeenCalled();
|
||||
expect(this.rosterview.model.remove).toHaveBeenCalled();
|
||||
// The element must now be detached from the DOM.
|
||||
expect(view.$el.closest('html').length).toBeFalsy();
|
||||
}, converse));
|
||||
}, converse));
|
||||
|
||||
it("will lose their own heading once the last one has been removed", $.proxy(function () {
|
||||
expect(this.rosterview.$el.find('dt#pending-xmpp-contacts').is(':visible')).toBeFalsy();
|
||||
}, converse));
|
||||
|
||||
it("can be added to the roster and they will be sorted alphabetically", $.proxy(function () {
|
||||
var i, t, is_last;
|
||||
spyOn(this.rosterview, 'render').andCallThrough();
|
||||
@ -136,13 +178,10 @@
|
||||
fullname: pend_names[i],
|
||||
is_last: is_last
|
||||
});
|
||||
// For performance reasons, the roster should only be shown once
|
||||
// the last contact has been added.
|
||||
if (is_last) {
|
||||
expect(this.rosterview.$el.is(':visible')).toEqual(true);
|
||||
expect(this.xmppstatus.sendPresence).toHaveBeenCalled();
|
||||
} else {
|
||||
expect(this.rosterview.$el.is(':visible')).toEqual(false);
|
||||
expect(this.xmppstatus.sendPresence).not.toHaveBeenCalled();
|
||||
}
|
||||
expect(this.rosterview.render).toHaveBeenCalled();
|
||||
// Check that they are sorted alphabetically
|
||||
@ -154,6 +193,7 @@
|
||||
it("will have their own heading once they have been added", $.proxy(function () {
|
||||
expect(this.rosterview.$el.find('dt#pending-xmpp-contacts').css('display')).toEqual('block');
|
||||
}, converse));
|
||||
|
||||
}, converse));
|
||||
|
||||
describe("Existing Contacts", $.proxy(function () {
|
||||
|
@ -68,37 +68,35 @@ require([
|
||||
prebind: false,
|
||||
xhr_user_search: false,
|
||||
auto_subscribe: false,
|
||||
animate: false
|
||||
animate: false,
|
||||
connection: mock_connection,
|
||||
testing: true
|
||||
}, function (converse) {
|
||||
window.converse = converse;
|
||||
require([
|
||||
"jasmine-console-reporter",
|
||||
"jasmine-junit-reporter",
|
||||
"spec/MainSpec",
|
||||
"spec/ChatRoomSpec"
|
||||
], function () {
|
||||
// Jasmine stuff
|
||||
var jasmineEnv = jasmine.getEnv();
|
||||
if (/PhantomJS/.test(navigator.userAgent)) {
|
||||
jasmineEnv.addReporter(new jasmine.TrivialReporter());
|
||||
jasmineEnv.addReporter(new jasmine.JUnitXmlReporter('./test-reports/'));
|
||||
jasmineEnv.addReporter(new jasmine.ConsoleReporter());
|
||||
jasmineEnv.updateInterval = 0;
|
||||
} else {
|
||||
var htmlReporter = new jasmine.HtmlReporter();
|
||||
jasmineEnv.addReporter(htmlReporter);
|
||||
jasmineEnv.addReporter(new jasmine.ConsoleReporter());
|
||||
jasmineEnv.specFilter = function(spec) {
|
||||
return htmlReporter.specFilter(spec);
|
||||
};
|
||||
jasmineEnv.updateInterval = 200;
|
||||
}
|
||||
jasmineEnv.execute();
|
||||
});
|
||||
});
|
||||
converse.onConnected(
|
||||
mock_connection,
|
||||
function (converse) {
|
||||
window.converse = converse;
|
||||
require([
|
||||
"jasmine-console-reporter",
|
||||
"jasmine-junit-reporter",
|
||||
"spec/MainSpec",
|
||||
"spec/ChatRoomSpec"
|
||||
], function () {
|
||||
// Jasmine stuff
|
||||
var jasmineEnv = jasmine.getEnv();
|
||||
if (/PhantomJS/.test(navigator.userAgent)) {
|
||||
jasmineEnv.addReporter(new jasmine.TrivialReporter());
|
||||
jasmineEnv.addReporter(new jasmine.JUnitXmlReporter('./test-reports/'));
|
||||
jasmineEnv.addReporter(new jasmine.ConsoleReporter());
|
||||
jasmineEnv.updateInterval = 0;
|
||||
} else {
|
||||
var htmlReporter = new jasmine.HtmlReporter();
|
||||
jasmineEnv.addReporter(htmlReporter);
|
||||
jasmineEnv.addReporter(new jasmine.ConsoleReporter());
|
||||
jasmineEnv.specFilter = function(spec) {
|
||||
return htmlReporter.specFilter(spec);
|
||||
};
|
||||
jasmineEnv.updateInterval = 200;
|
||||
}
|
||||
jasmineEnv.execute();
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user