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:
|
node_js:
|
||||||
- "0.10"
|
- "0.10"
|
||||||
before_script:
|
before_script:
|
||||||
- "./node_modules/.bin/bower update"
|
- "./node_modules/.bin/grunt fetch"
|
||||||
script: grunt test
|
script: grunt test
|
||||||
|
@ -95,7 +95,7 @@ module.exports = function(grunt) {
|
|||||||
var done = this.async();
|
var done = this.async();
|
||||||
var child_process = require('child_process');
|
var child_process = require('child_process');
|
||||||
var exec = child_process.exec;
|
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) {
|
function (err, stdout, stderr) {
|
||||||
if (err) {
|
if (err) {
|
||||||
grunt.log.write('build failed with error code '+err.code);
|
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.registerTask('check', 'Perform all checks (e.g. before releasing)', function () {
|
||||||
grunt.task.run('jshint', 'test');
|
grunt.task.run('jshint', 'test');
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
converse.js
|
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.
|
Converse.js_ is a web based `XMPP/Jabber`_ instant messaging client.
|
||||||
|
|
||||||
It enables you to add chat functionality to your website, independent of any
|
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) {
|
}(this, function ($, _, crypto, otr, console) {
|
||||||
var converse = {};
|
var converse = {};
|
||||||
converse.initialize = function (settings) {
|
converse.initialize = function (settings, callback) {
|
||||||
// Default values
|
// Default values
|
||||||
var converse = this;
|
var converse = this;
|
||||||
this.animate = true;
|
this.animate = true;
|
||||||
this.auto_list_rooms = false;
|
this.auto_list_rooms = false;
|
||||||
this.auto_subscribe = 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.debug = false;
|
||||||
this.hide_muc_server = false;
|
this.hide_muc_server = false;
|
||||||
this.i18n = locales.en;
|
this.i18n = locales.en;
|
||||||
this.prebind = false;
|
this.prebind = false;
|
||||||
this.show_controlbox_by_default = false;
|
this.show_controlbox_by_default = false;
|
||||||
this.xhr_user_search = 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 __ = $.proxy(function (str) {
|
||||||
var t = this.i18n.translate(str);
|
var t = this.i18n.translate(str);
|
||||||
@ -72,6 +92,49 @@
|
|||||||
return text.replace(re, '<a target="_blank" href="$1">$1</a>');
|
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) {
|
this.toISOString = function (date) {
|
||||||
var pad;
|
var pad;
|
||||||
if (typeof date.toISOString !== 'undefined') {
|
if (typeof date.toISOString !== 'undefined') {
|
||||||
@ -158,10 +221,10 @@
|
|||||||
.t('1');
|
.t('1');
|
||||||
|
|
||||||
converse.connection.sendIQ(iq,
|
converse.connection.sendIQ(iq,
|
||||||
callback,
|
callback,
|
||||||
function () {
|
function () {
|
||||||
console.log('Error while retrieving collections');
|
converse.log('Error while retrieving collections');
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
this.collections.getLastMessages = function (jid, callback) {
|
this.collections.getLastMessages = function (jid, callback) {
|
||||||
@ -556,7 +619,7 @@
|
|||||||
});
|
});
|
||||||
}, this),
|
}, this),
|
||||||
$.proxy(function (stanza) {
|
$.proxy(function (stanza) {
|
||||||
console.log("ChatBoxView.initialize: An error occured while fetching vcard");
|
converse.log("ChatBoxView.initialize: An error occured while fetching vcard");
|
||||||
}, this)
|
}, this)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -755,7 +818,7 @@
|
|||||||
this.addContact(jid, fullname);
|
this.addContact(jid, fullname);
|
||||||
}, this),
|
}, this),
|
||||||
$.proxy(function (stanza) {
|
$.proxy(function (stanza) {
|
||||||
console.log("An error occured while fetching vcard");
|
converse.log("An error occured while fetching vcard");
|
||||||
var jid = $(stanza).attr('from');
|
var jid = $(stanza).attr('from');
|
||||||
this.addContact(jid, jid);
|
this.addContact(jid, jid);
|
||||||
}, this));
|
}, this));
|
||||||
@ -1002,7 +1065,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!nick) { return; }
|
if (!nick) { return; }
|
||||||
chatroom = converse.chatboxes.createChatBox({
|
chatroom = converse.chatboxesview.showChatBox({
|
||||||
'id': jid,
|
'id': jid,
|
||||||
'jid': jid,
|
'jid': jid,
|
||||||
'name': Strophe.unescapeNode(Strophe.getNodeFromJid(jid)),
|
'name': Strophe.unescapeNode(Strophe.getNodeFromJid(jid)),
|
||||||
@ -1098,7 +1161,7 @@
|
|||||||
if ((!converse.prebind) && (!converse.connection)) {
|
if ((!converse.prebind) && (!converse.connection)) {
|
||||||
// Add login panel if the user still has to authenticate
|
// Add login panel if the user still has to authenticate
|
||||||
this.$el.html(this.template(this.model.toJSON()));
|
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();
|
this.loginpanel.render();
|
||||||
} else if (!this.contactspanel) {
|
} else if (!this.contactspanel) {
|
||||||
this.$el.html(this.template(this.model.toJSON()));
|
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) {
|
messageReceived: function (message) {
|
||||||
var partner_jid, $message = $(message),
|
var partner_jid, $message = $(message),
|
||||||
message_from = $message.attr('from');
|
message_from = $message.attr('from');
|
||||||
@ -1747,6 +1800,20 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, this);
|
}, 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) {
|
openChat: function (ev) {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
converse.chatboxes.createChatBox({
|
converse.chatboxesview.showChatBox({
|
||||||
'id': this.model.get('jid'),
|
'id': this.model.get('jid'),
|
||||||
'jid': this.model.get('jid'),
|
'jid': this.model.get('jid'),
|
||||||
'fullname': this.model.get('fullname'),
|
'fullname': this.model.get('fullname'),
|
||||||
@ -2122,7 +2189,7 @@
|
|||||||
});
|
});
|
||||||
}, this),
|
}, this),
|
||||||
$.proxy(function (jid, fullname, img, img_type, url) {
|
$.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.add({jid: bare_jid, subscription: 'none', ask: 'request', fullname: jid, is_last: true});
|
||||||
}, this)
|
}, this)
|
||||||
);
|
);
|
||||||
@ -2544,44 +2611,26 @@
|
|||||||
'<input type="text" id="bosh_service_url">'),
|
'<input type="text" id="bosh_service_url">'),
|
||||||
|
|
||||||
connect: function ($form, jid, password) {
|
connect: function ($form, jid, password) {
|
||||||
var button = null,
|
|
||||||
connection = new Strophe.Connection(converse.bosh_service_url);
|
|
||||||
if ($form) {
|
if ($form) {
|
||||||
$button = $form.find('input[type=submit]');
|
$form.find('input[type=submit]').hide().after('<span class="spinner login-submit"/>');
|
||||||
$button.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) {
|
initialize: function (cfg) {
|
||||||
cfg.$parent.append(this.$el.html(this.template()));
|
cfg.$parent.append(this.$el.html(this.template()));
|
||||||
this.$tabs = cfg.$parent.parent().find('#controlbox-tabs');
|
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 () {
|
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.initStatus = function (callback) {
|
||||||
this.xmppstatus = new this.XMPPStatus();
|
this.xmppstatus = new this.XMPPStatus();
|
||||||
var id = hex_sha1('converse.xmppstatus-'+this.bare_jid);
|
var id = hex_sha1('converse.xmppstatus-'+this.bare_jid);
|
||||||
@ -2682,8 +2723,7 @@
|
|||||||
this.rosterview = new this.RosterView({'model':this.roster});
|
this.rosterview = new this.RosterView({'model':this.roster});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.onConnected = function (connection, callback) {
|
this.onConnected = function () {
|
||||||
this.connection = connection;
|
|
||||||
if (this.debug) {
|
if (this.debug) {
|
||||||
this.connection.xmlInput = function (body) { console.log(body); };
|
this.connection.xmlInput = function (body) { console.log(body); };
|
||||||
this.connection.xmlOutput = function (body) { console.log(body); };
|
this.connection.xmlOutput = function (body) { console.log(body); };
|
||||||
@ -2722,8 +2762,10 @@
|
|||||||
this.windowState = e.type;
|
this.windowState = e.type;
|
||||||
},this));
|
},this));
|
||||||
this.giveFeedback(__('Online Contacts'));
|
this.giveFeedback(__('Online Contacts'));
|
||||||
if (callback) {
|
if (this.testing) {
|
||||||
callback(this);
|
this.callback(this);
|
||||||
|
} else {
|
||||||
|
this.callback();
|
||||||
}
|
}
|
||||||
}, this));
|
}, this));
|
||||||
};
|
};
|
||||||
@ -2737,17 +2779,21 @@
|
|||||||
e.preventDefault(); this.toggleControlBox();
|
e.preventDefault(); this.toggleControlBox();
|
||||||
}, this)
|
}, this)
|
||||||
);
|
);
|
||||||
if (this.show_controlbox_by_default) {
|
if ((this.prebind) && (!this.connection)) {
|
||||||
this.toggleControlBox();
|
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 {
|
return {
|
||||||
'initialize': function (settings) {
|
'initialize': function (settings, callback) {
|
||||||
converse.initialize(settings);
|
converse.initialize(settings, callback);
|
||||||
},
|
|
||||||
'onConnected': function (connection, callback) {
|
|
||||||
// onConnected can only be called after initialize has been called.
|
|
||||||
converse.onConnected(connection, 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::
|
.. Note::
|
||||||
If you want to enable single session support, make sure to pass **prebind: true**
|
If you want to enable single session support, make sure to pass **prebind: true**
|
||||||
when you call **converse.initialize** (see ./index.html).
|
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
|
When you authenticate to the XMPP server on your backend, you'll receive two
|
||||||
tokens, RID (request ID) and SID (session ID).
|
tokens, RID (request ID) and SID (session ID).
|
||||||
|
|
||||||
These tokens then need to be passed back to the javascript running in your
|
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
|
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
|
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.
|
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) {
|
$.getJSON('/prebind', function (data) {
|
||||||
var connection = new Strophe.Connection(converse.bosh_service_url);
|
converse.initialize({
|
||||||
connection.attach(data.jid, data.sid, data.rid, function (status) {
|
prebind: true,
|
||||||
if ((status === Strophe.Status.ATTACHED) || (status === Strophe.Status.CONNECTED)) {
|
bosh_service_url: data.bosh_service_url,
|
||||||
converse.onConnected(connection)
|
jid: data.jid,
|
||||||
}
|
sid: data.sid,
|
||||||
});
|
rid: data.rid
|
||||||
}
|
});
|
||||||
);
|
);
|
||||||
|
|
||||||
**Here's what's happening:**
|
**Here's what's happening:**
|
||||||
|
|
||||||
The JSON data contains the user's JID (jabber ID), RID and SID. The URL to the
|
The JSON data contains the user's JID (jabber ID), RID, SID and the URL to the
|
||||||
BOSH connection manager is already set as a configuration setting on the
|
BOSH connection manager.
|
||||||
*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.
|
|
||||||
|
|
||||||
|
|
||||||
Facebook integration
|
Facebook integration
|
||||||
@ -471,22 +466,28 @@ If set to true, debugging output will be logged to the browser console.
|
|||||||
fullname
|
fullname
|
||||||
--------
|
--------
|
||||||
|
|
||||||
If you are using prebinding, you need to specify the fullname of the currently
|
If you are using prebinding, can specify the fullname of the currently
|
||||||
logged in user.
|
logged in user, otherwise the user's vCard will be fetched.
|
||||||
|
|
||||||
hide_muc_server
|
hide_muc_server
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
Default = False
|
Default = false
|
||||||
|
|
||||||
Hide the ``server`` input field of the form inside the ``Room`` panel of the
|
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
|
controlbox. Useful if you want to restrict users to a specific XMPP server of
|
||||||
your choosing.
|
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
|
prebind
|
||||||
--------
|
--------
|
||||||
|
|
||||||
Default = False
|
Default = false
|
||||||
|
|
||||||
Use this option when you want to attach to an existing XMPP connection that was
|
Use this option when you want to attach to an existing XMPP connection that was
|
||||||
already authenticated (usually on the backend before page load).
|
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
|
This is useful when you don't want to render the login form on the chat control
|
||||||
box with each page load.
|
box with each page load.
|
||||||
|
|
||||||
When set to true, you'll need to make sure that the onConnected method is
|
For prebinding to work, your backend server must authenticate for you, and
|
||||||
called, and passed to it a Strophe connection object.
|
then return a JID (jabber ID), SID (session ID) and RID (Request ID).
|
||||||
|
|
||||||
Besides requiring the back-end to authenticate you, you'll also
|
If you set ``prebind`` to ``true``, you have to make sure to also pass in these
|
||||||
have to write a Javascript snippet to attach to the set up connection::
|
values as ``jid``, ``sid``, ``rid``.
|
||||||
|
|
||||||
$.JSON({
|
Additionally, you have to specify ``bosh_service_url``.
|
||||||
'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);
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
show_controlbox_by_default
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
||||||
Default = False
|
Default = false
|
||||||
|
|
||||||
The "controlbox" refers to the special chatbox containing your contacts roster,
|
The "controlbox" refers to the special chatbox containing your contacts roster,
|
||||||
status widget, chatrooms and other controls.
|
status widget, chatrooms and other controls.
|
||||||
@ -542,40 +536,27 @@ be used.
|
|||||||
Minification
|
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
|
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
|
to bundle them together in a single minified file fit for deployment to a
|
||||||
production site.
|
production site.
|
||||||
|
|
||||||
To use the require.js's optimization tool, you'll need Node and it's package
|
To minify the Javascript and CSS, run the following command:
|
||||||
manager, NPM.
|
|
||||||
|
|
||||||
You can then install install require.js for Node like so:
|
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
npm install requirejs
|
grunt minify
|
||||||
|
|
||||||
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).
|
|
||||||
|
|
||||||
|
Javascript will be bundled and minified via `require.js`_'s optimization tool.
|
||||||
You can `read more about require.js's optimizer here`_.
|
You can `read more about require.js's optimizer here`_.
|
||||||
|
|
||||||
Minifying CSS
|
CSS is minified via `cssmin <https://github.com/gruntjs/grunt-contrib-cssmin>`_.
|
||||||
=============
|
|
||||||
|
|
||||||
CSS can be minimized with Yahoo's yuicompressor tool:
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
yui-compressor --type=css converse.css -o converse.min.css
|
|
||||||
|
|
||||||
|
|
||||||
============
|
============
|
||||||
|
@ -33,3 +33,10 @@ h1 a {
|
|||||||
ul {
|
ul {
|
||||||
margin-bottom: 5px;
|
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="#debug" id="id26">debug</a></li>
|
||||||
<li><a class="reference internal" href="#fullname" id="id27">fullname</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="#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="#i18n" id="id29">i18n</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="#prebind" id="id30">prebind</a></li>
|
||||||
<li><a class="reference internal" href="#xhr-user-search" id="id31">xhr_user_search</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>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li><a class="reference internal" href="#minification" id="id32">Minification</a><ul>
|
<li><a class="reference internal" href="#minification" id="id33">Minification</a><ul>
|
||||||
<li><a class="reference internal" href="#minifying-javascript" id="id33">Minifying Javascript</a></li>
|
<li><a class="reference internal" href="#minifying-javascript-and-css" id="id34">Minifying Javascript and CSS</a></li>
|
||||||
<li><a class="reference internal" href="#minifying-css" id="id34">Minifying CSS</a></li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li><a class="reference internal" href="#translations" id="id35">Translations</a></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">
|
<div class="admonition note">
|
||||||
<p class="first admonition-title">Note</p>
|
<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>
|
<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>
|
</div>
|
||||||
<p>When you authenticate to the XMPP server on your backend, you’ll receive two
|
<p>When you authenticate to the XMPP server on your backend, you’ll receive two
|
||||||
tokens, RID (request ID) and SID (session ID).</p>
|
tokens, RID (request ID) and SID (session ID).</p>
|
||||||
<p>These tokens then need to be passed back to the javascript running in your
|
<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
|
<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
|
<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>
|
relative URL <strong>/prebind</strong> and it expects to receive JSON data back.</p>
|
||||||
<div class="highlight-python"><pre>$.getJSON('/prebind', function (data) {
|
<div class="highlight-python"><pre>$.getJSON('/prebind', function (data) {
|
||||||
var connection = new Strophe.Connection(converse.bosh_service_url);
|
converse.initialize({
|
||||||
connection.attach(data.jid, data.sid, data.rid, function (status) {
|
prebind: true,
|
||||||
if ((status === Strophe.Status.ATTACHED) || (status === Strophe.Status.CONNECTED)) {
|
bosh_service_url: data.bosh_service_url,
|
||||||
converse.onConnected(connection)
|
jid: data.jid,
|
||||||
}
|
sid: data.sid,
|
||||||
});
|
rid: data.rid
|
||||||
}
|
});
|
||||||
);</pre>
|
);</pre>
|
||||||
</div>
|
</div>
|
||||||
<p><strong>Here’s what’s happening:</strong></p>
|
<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
|
<p>The JSON data contains the user’s JID (jabber ID), RID, SID and the URL to the
|
||||||
BOSH connection manager is already set as a configuration setting on the
|
BOSH connection manager.</p>
|
||||||
<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>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="facebook-integration">
|
<div class="section" id="facebook-integration">
|
||||||
@ -451,40 +448,37 @@ a middle man between HTTP and XMPP.</p>
|
|||||||
</div>
|
</div>
|
||||||
<div class="section" id="fullname">
|
<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>
|
<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
|
<p>If you are using prebinding, can specify the fullname of the currently
|
||||||
logged in user.</p>
|
logged in user, otherwise the user’s vCard will be fetched.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="hide-muc-server">
|
<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>
|
<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
|
<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
|
controlbox. Useful if you want to restrict users to a specific XMPP server of
|
||||||
your choosing.</p>
|
your choosing.</p>
|
||||||
</div>
|
</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">
|
<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>
|
<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>Default = false</p>
|
||||||
<p>Use this option when you want to attach to an existing XMPP connection that was
|
<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>
|
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
|
<p>This is useful when you don’t want to render the login form on the chat control
|
||||||
box with each page load.</p>
|
box with each page load.</p>
|
||||||
<p>When set to true, you’ll need to make sure that the onConnected method is
|
<p>For prebinding to work, your backend server must authenticate for you, and
|
||||||
called, and passed to it a Strophe connection object.</p>
|
then return a JID (jabber ID), SID (session ID) and RID (Request ID).</p>
|
||||||
<p>Besides requiring the back-end to authenticate you, you’ll also
|
<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
|
||||||
have to write a Javascript snippet to attach to the set up connection:</p>
|
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>
|
||||||
<div class="highlight-python"><pre>$.JSON({
|
<p>Additionally, you have to specify <tt class="docutils literal"><span class="pre">bosh_service_url</span></tt>.</p>
|
||||||
'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>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="show-controlbox-by-default">
|
<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>
|
<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>Default = false</p>
|
||||||
<p>The “controlbox” refers to the special chatbox containing your contacts roster,
|
<p>The “controlbox” refers to the special chatbox containing your contacts roster,
|
||||||
status widget, chatrooms and other controls.</p>
|
status widget, chatrooms and other controls.</p>
|
||||||
<p>By default this box is hidden and can be toggled by clicking on any element in
|
<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>
|
page load.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="xhr-user-search">
|
<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>Default = False</p>
|
||||||
<p>There are two ways to add users.</p>
|
<p>There are two ways to add users.</p>
|
||||||
<ul class="simple">
|
<ul class="simple">
|
||||||
@ -506,28 +500,21 @@ be used.</p>
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="minification">
|
<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>
|
<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">
|
<div class="section" id="minifying-javascript-and-css">
|
||||||
<h2><a class="toc-backref" href="#id33">Minifying Javascript</a><a class="headerlink" href="#minifying-javascript" title="Permalink to this headline">¶</a></h2>
|
<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
|
<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
|
to bundle them together in a single minified file fit for deployment to a
|
||||||
production site.</p>
|
production site.</p>
|
||||||
<p>To use the require.js’s optimization tool, you’ll need Node and it’s package
|
<p>To minify the Javascript and CSS, run the following command:</p>
|
||||||
manager, NPM.</p>
|
<div class="highlight-python"><pre>grunt minify</pre>
|
||||||
<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>
|
|
||||||
</div>
|
</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>
|
</div>
|
||||||
<div class="section" id="translations">
|
<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::
|
.. Note::
|
||||||
If you want to enable single session support, make sure to pass **prebind: true**
|
If you want to enable single session support, make sure to pass **prebind: true**
|
||||||
when you call **converse.initialize** (see ./index.html).
|
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
|
When you authenticate to the XMPP server on your backend, you'll receive two
|
||||||
tokens, RID (request ID) and SID (session ID).
|
tokens, RID (request ID) and SID (session ID).
|
||||||
|
|
||||||
These tokens then need to be passed back to the javascript running in your
|
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
|
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
|
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.
|
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) {
|
$.getJSON('/prebind', function (data) {
|
||||||
var connection = new Strophe.Connection(converse.bosh_service_url);
|
converse.initialize({
|
||||||
connection.attach(data.jid, data.sid, data.rid, function (status) {
|
prebind: true,
|
||||||
if ((status === Strophe.Status.ATTACHED) || (status === Strophe.Status.CONNECTED)) {
|
bosh_service_url: data.bosh_service_url,
|
||||||
converse.onConnected(connection)
|
jid: data.jid,
|
||||||
}
|
sid: data.sid,
|
||||||
});
|
rid: data.rid
|
||||||
}
|
});
|
||||||
);
|
);
|
||||||
|
|
||||||
**Here's what's happening:**
|
**Here's what's happening:**
|
||||||
|
|
||||||
The JSON data contains the user's JID (jabber ID), RID and SID. The URL to the
|
The JSON data contains the user's JID (jabber ID), RID, SID and the URL to the
|
||||||
BOSH connection manager is already set as a configuration setting on the
|
BOSH connection manager.
|
||||||
*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.
|
|
||||||
|
|
||||||
|
|
||||||
Facebook integration
|
Facebook integration
|
||||||
@ -471,22 +466,28 @@ If set to true, debugging output will be logged to the browser console.
|
|||||||
fullname
|
fullname
|
||||||
--------
|
--------
|
||||||
|
|
||||||
If you are using prebinding, you need to specify the fullname of the currently
|
If you are using prebinding, can specify the fullname of the currently
|
||||||
logged in user.
|
logged in user, otherwise the user's vCard will be fetched.
|
||||||
|
|
||||||
hide_muc_server
|
hide_muc_server
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
Default = False
|
Default = false
|
||||||
|
|
||||||
Hide the ``server`` input field of the form inside the ``Room`` panel of the
|
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
|
controlbox. Useful if you want to restrict users to a specific XMPP server of
|
||||||
your choosing.
|
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
|
prebind
|
||||||
--------
|
--------
|
||||||
|
|
||||||
Default = False
|
Default = false
|
||||||
|
|
||||||
Use this option when you want to attach to an existing XMPP connection that was
|
Use this option when you want to attach to an existing XMPP connection that was
|
||||||
already authenticated (usually on the backend before page load).
|
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
|
This is useful when you don't want to render the login form on the chat control
|
||||||
box with each page load.
|
box with each page load.
|
||||||
|
|
||||||
When set to true, you'll need to make sure that the onConnected method is
|
For prebinding to work, your backend server must authenticate for you, and
|
||||||
called, and passed to it a Strophe connection object.
|
then return a JID (jabber ID), SID (session ID) and RID (Request ID).
|
||||||
|
|
||||||
Besides requiring the back-end to authenticate you, you'll also
|
If you set ``prebind`` to ``true``, you have to make sure to also pass in these
|
||||||
have to write a Javascript snippet to attach to the set up connection::
|
values as ``jid``, ``sid``, ``rid``.
|
||||||
|
|
||||||
$.JSON({
|
Additionally, you have to specify ``bosh_service_url``.
|
||||||
'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);
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
show_controlbox_by_default
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
||||||
Default = False
|
Default = false
|
||||||
|
|
||||||
The "controlbox" refers to the special chatbox containing your contacts roster,
|
The "controlbox" refers to the special chatbox containing your contacts roster,
|
||||||
status widget, chatrooms and other controls.
|
status widget, chatrooms and other controls.
|
||||||
@ -542,40 +536,27 @@ be used.
|
|||||||
Minification
|
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
|
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
|
to bundle them together in a single minified file fit for deployment to a
|
||||||
production site.
|
production site.
|
||||||
|
|
||||||
To use the require.js's optimization tool, you'll need Node and it's package
|
To minify the Javascript and CSS, run the following command:
|
||||||
manager, NPM.
|
|
||||||
|
|
||||||
You can then install install require.js for Node like so:
|
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
npm install requirejs
|
grunt minify
|
||||||
|
|
||||||
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).
|
|
||||||
|
|
||||||
|
Javascript will be bundled and minified via `require.js`_'s optimization tool.
|
||||||
You can `read more about require.js's optimizer here`_.
|
You can `read more about require.js's optimizer here`_.
|
||||||
|
|
||||||
Minifying CSS
|
CSS is minified via `cssmin <https://github.com/gruntjs/grunt-contrib-cssmin>`_.
|
||||||
=============
|
|
||||||
|
|
||||||
CSS can be minimized with Yahoo's yuicompressor tool:
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
yui-compressor --type=css converse.css -o converse.min.css
|
|
||||||
|
|
||||||
|
|
||||||
============
|
============
|
||||||
|
@ -33,3 +33,10 @@ h1 a {
|
|||||||
ul {
|
ul {
|
||||||
margin-bottom: 5px;
|
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,
|
prebind: false,
|
||||||
show_controlbox_by_default: true,
|
show_controlbox_by_default: true,
|
||||||
xhr_user_search: false,
|
xhr_user_search: false,
|
||||||
debug: false
|
debug: true
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
3
mock.js
3
mock.js
@ -23,7 +23,8 @@
|
|||||||
'unauthorize': function () {},
|
'unauthorize': function () {},
|
||||||
'get': function () {},
|
'get': function () {},
|
||||||
'subscribe': function () {},
|
'subscribe': function () {},
|
||||||
'registerCallback': function () {}
|
'registerCallback': function () {},
|
||||||
|
'remove': function (jid, callback) { callback(); }
|
||||||
},
|
},
|
||||||
'vcard': {
|
'vcard': {
|
||||||
'get': function (callback, jid) {
|
'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="chatbox" id="37c0c87392010303765fe36b05c0967d62c6b70f" style="opacity: 1; display: inline;">
|
||||||
<div class="chat-head chat-head-chatbox">
|
<div class="chat-head chat-head-chatbox">
|
||||||
<a class="close-chatbox-button icon-close"></a>
|
<a class="close-chatbox-button icon-close"></a>
|
||||||
<a href="" target="_blank" class="user">
|
<a href="http://opkode.com" target="_blank" class="user">
|
||||||
<div class="chat-title">John Smit</div>
|
<canvas height="35px" width="35px" class="avatar" style="background-color: black"></canvas>
|
||||||
|
<div class="chat-title"> JC Brand </div>
|
||||||
</a>
|
</a>
|
||||||
<p class="user-custom-message"></p>
|
<p class="user-custom-message"></p>
|
||||||
<p></p>
|
<p></p>
|
||||||
@ -203,6 +204,10 @@
|
|||||||
<span class="chat-message-me">19:39 me: </span>
|
<span class="chat-message-me">19:39 me: </span>
|
||||||
<span class="chat-message-content">Hello world</span>
|
<span class="chat-message-content">Hello world</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="chat-message ">
|
||||||
|
<span class="chat-message-them">15:45 Benedict-John: </span>
|
||||||
|
<span class="chat-message-content">Dagsê</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<form class="sendXMPPMessage" action="" method="post">
|
<form class="sendXMPPMessage" action="" method="post">
|
||||||
<textarea type="text" class="chat-textarea" placeholder="Personal message"></textarea>
|
<textarea type="text" class="chat-textarea" placeholder="Personal message"></textarea>
|
||||||
@ -213,7 +218,7 @@
|
|||||||
<div class="chat-head chat-head-chatroom">
|
<div class="chat-head chat-head-chatroom">
|
||||||
<a class="close-chatbox-button icon-close"></a>
|
<a class="close-chatbox-button icon-close"></a>
|
||||||
<a class="configure-chatroom-button icon-wrench" style=""></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 class="chatroom-topic"></p>
|
||||||
<p></p>
|
<p></p>
|
||||||
</div>
|
</div>
|
||||||
@ -222,8 +227,8 @@
|
|||||||
<div class="chat-content">
|
<div class="chat-content">
|
||||||
<time class="chat-date" datetime="2013-06-04T00:00:00.000Z">Tue Jun 04 2013</time>
|
<time class="chat-date" datetime="2013-06-04T00:00:00.000Z">Tue Jun 04 2013</time>
|
||||||
<div class="chat-message ">
|
<div class="chat-message ">
|
||||||
<span class="chat-message-room">18:50 fires: </span>
|
<span class="chat-message-room">18:50 luke: </span>
|
||||||
<span class="chat-message-content">explodingcoder: hi :)</span>
|
<span class="chat-message-content">leia: hi :)</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="chat-message ">
|
<div class="chat-message ">
|
||||||
<span class="chat-message-me">19:40 me: </span>
|
<span class="chat-message-me">19:40 me: </span>
|
||||||
@ -238,8 +243,8 @@
|
|||||||
<div class="participants">
|
<div class="participants">
|
||||||
<ul class="participant-list">
|
<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">jabberthehut</li>
|
||||||
<li class="participant" title="This user can send messages in this room">explodingcoder</li>
|
<li class="participant" title="This user can send messages in this room">leia</li>
|
||||||
<li class="moderator" title="This user is a moderator">jcbrand</li>
|
<li class="moderator" title="This user is a moderator">luke</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -249,7 +254,7 @@
|
|||||||
<div class="chat-head chat-head-chatroom">
|
<div class="chat-head chat-head-chatroom">
|
||||||
<a class="close-chatbox-button icon-close"></a>
|
<a class="close-chatbox-button icon-close"></a>
|
||||||
<a class="configure-chatroom-button" style="display:none"> </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 class="chatroom-topic"></p>
|
||||||
<p></p>
|
<p></p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
<script type="text/javascript" src="components/underscore/underscore.js"></script>
|
<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//backbone.js"></script>
|
||||||
<script type="text/javascript" src="components/backbone.localStorage/backbone.localStorage.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/tinysort/src/jquery.tinysort.js"></script>
|
||||||
<script type="text/javascript" src="components/jed/jed.js"></script>
|
<script type="text/javascript" src="components/jed/jed.js"></script>
|
||||||
<script type="text/javascript" src="locale/en/LC_MESSAGES/en.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;
|
.c('not-authorized').attrs({xmlns:'urn:ietf:params:xml:ns:xmpp-stanzas'}).nodeTree;
|
||||||
|
|
||||||
var view = this.chatboxesview.views['problematic@muc.localhost'];
|
var view = this.chatboxesview.views['problematic@muc.localhost'];
|
||||||
spyOn(converse.connection.muc, 'removeRoom');
|
|
||||||
spyOn(view, 'renderPasswordForm').andCallThrough();
|
spyOn(view, 'renderPasswordForm').andCallThrough();
|
||||||
runs(function () {
|
runs(function () {
|
||||||
view.onChatRoomPresence(presence, {'nick': 'dummy'});
|
view.onChatRoomPresence(presence, {'nick': 'dummy'});
|
||||||
@ -159,7 +158,6 @@
|
|||||||
.c('error').attrs({by:'coven@chat.shakespeare.lit', type:'auth'})
|
.c('error').attrs({by:'coven@chat.shakespeare.lit', type:'auth'})
|
||||||
.c('registration-required').attrs({xmlns:'urn:ietf:params:xml:ns:xmpp-stanzas'}).nodeTree;
|
.c('registration-required').attrs({xmlns:'urn:ietf:params:xml:ns:xmpp-stanzas'}).nodeTree;
|
||||||
var view = this.chatboxesview.views['problematic@muc.localhost'];
|
var view = this.chatboxesview.views['problematic@muc.localhost'];
|
||||||
spyOn(converse.connection.muc, 'removeRoom');
|
|
||||||
spyOn(view, 'showErrorMessage').andCallThrough();
|
spyOn(view, 'showErrorMessage').andCallThrough();
|
||||||
view.onChatRoomPresence(presence, {'nick': 'dummy'});
|
view.onChatRoomPresence(presence, {'nick': 'dummy'});
|
||||||
expect(view.$el.find('.chat-body p').text()).toBe('You are not on the member list of this room');
|
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('error').attrs({by:'coven@chat.shakespeare.lit', type:'auth'})
|
||||||
.c('forbidden').attrs({xmlns:'urn:ietf:params:xml:ns:xmpp-stanzas'}).nodeTree;
|
.c('forbidden').attrs({xmlns:'urn:ietf:params:xml:ns:xmpp-stanzas'}).nodeTree;
|
||||||
var view = this.chatboxesview.views['problematic@muc.localhost'];
|
var view = this.chatboxesview.views['problematic@muc.localhost'];
|
||||||
spyOn(converse.connection.muc, 'removeRoom');
|
|
||||||
spyOn(view, 'showErrorMessage').andCallThrough();
|
spyOn(view, 'showErrorMessage').andCallThrough();
|
||||||
view.onChatRoomPresence(presence, {'nick': 'dummy'});
|
view.onChatRoomPresence(presence, {'nick': 'dummy'});
|
||||||
expect(view.$el.find('.chat-body p').text()).toBe('You have been banned from this room');
|
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('error').attrs({by:'coven@chat.shakespeare.lit', type:'modify'})
|
||||||
.c('jid-malformed').attrs({xmlns:'urn:ietf:params:xml:ns:xmpp-stanzas'}).nodeTree;
|
.c('jid-malformed').attrs({xmlns:'urn:ietf:params:xml:ns:xmpp-stanzas'}).nodeTree;
|
||||||
var view = this.chatboxesview.views['problematic@muc.localhost'];
|
var view = this.chatboxesview.views['problematic@muc.localhost'];
|
||||||
spyOn(converse.connection.muc, 'removeRoom');
|
|
||||||
spyOn(view, 'showErrorMessage').andCallThrough();
|
spyOn(view, 'showErrorMessage').andCallThrough();
|
||||||
view.onChatRoomPresence(presence, {'nick': 'dummy'});
|
view.onChatRoomPresence(presence, {'nick': 'dummy'});
|
||||||
expect(view.$el.find('.chat-body p').text()).toBe('No nickname was specified');
|
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('error').attrs({by:'coven@chat.shakespeare.lit', type:'cancel'})
|
||||||
.c('not-allowed').attrs({xmlns:'urn:ietf:params:xml:ns:xmpp-stanzas'}).nodeTree;
|
.c('not-allowed').attrs({xmlns:'urn:ietf:params:xml:ns:xmpp-stanzas'}).nodeTree;
|
||||||
var view = this.chatboxesview.views['problematic@muc.localhost'];
|
var view = this.chatboxesview.views['problematic@muc.localhost'];
|
||||||
spyOn(converse.connection.muc, 'removeRoom');
|
|
||||||
spyOn(view, 'showErrorMessage').andCallThrough();
|
spyOn(view, 'showErrorMessage').andCallThrough();
|
||||||
view.onChatRoomPresence(presence, {'nick': 'dummy'});
|
view.onChatRoomPresence(presence, {'nick': 'dummy'});
|
||||||
expect(view.$el.find('.chat-body p').text()).toBe('You are not allowed to create new rooms');
|
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('error').attrs({by:'coven@chat.shakespeare.lit', type:'cancel'})
|
||||||
.c('not-acceptable').attrs({xmlns:'urn:ietf:params:xml:ns:xmpp-stanzas'}).nodeTree;
|
.c('not-acceptable').attrs({xmlns:'urn:ietf:params:xml:ns:xmpp-stanzas'}).nodeTree;
|
||||||
var view = this.chatboxesview.views['problematic@muc.localhost'];
|
var view = this.chatboxesview.views['problematic@muc.localhost'];
|
||||||
spyOn(converse.connection.muc, 'removeRoom');
|
|
||||||
spyOn(view, 'showErrorMessage').andCallThrough();
|
spyOn(view, 'showErrorMessage').andCallThrough();
|
||||||
view.onChatRoomPresence(presence, {'nick': 'dummy'});
|
view.onChatRoomPresence(presence, {'nick': 'dummy'});
|
||||||
expect(view.$el.find('.chat-body p').text()).toBe("Your nickname doesn't conform to this room's policies");
|
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('error').attrs({by:'coven@chat.shakespeare.lit', type:'cancel'})
|
||||||
.c('conflict').attrs({xmlns:'urn:ietf:params:xml:ns:xmpp-stanzas'}).nodeTree;
|
.c('conflict').attrs({xmlns:'urn:ietf:params:xml:ns:xmpp-stanzas'}).nodeTree;
|
||||||
var view = this.chatboxesview.views['problematic@muc.localhost'];
|
var view = this.chatboxesview.views['problematic@muc.localhost'];
|
||||||
spyOn(converse.connection.muc, 'removeRoom');
|
|
||||||
spyOn(view, 'showErrorMessage').andCallThrough();
|
spyOn(view, 'showErrorMessage').andCallThrough();
|
||||||
view.onChatRoomPresence(presence, {'nick': 'dummy'});
|
view.onChatRoomPresence(presence, {'nick': 'dummy'});
|
||||||
expect(view.$el.find('.chat-body p').text()).toBe("Your nickname is already taken");
|
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('error').attrs({by:'coven@chat.shakespeare.lit', type:'cancel'})
|
||||||
.c('item-not-found').attrs({xmlns:'urn:ietf:params:xml:ns:xmpp-stanzas'}).nodeTree;
|
.c('item-not-found').attrs({xmlns:'urn:ietf:params:xml:ns:xmpp-stanzas'}).nodeTree;
|
||||||
var view = this.chatboxesview.views['problematic@muc.localhost'];
|
var view = this.chatboxesview.views['problematic@muc.localhost'];
|
||||||
spyOn(converse.connection.muc, 'removeRoom');
|
|
||||||
spyOn(view, 'showErrorMessage').andCallThrough();
|
spyOn(view, 'showErrorMessage').andCallThrough();
|
||||||
view.onChatRoomPresence(presence, {'nick': 'dummy'});
|
view.onChatRoomPresence(presence, {'nick': 'dummy'});
|
||||||
expect(view.$el.find('.chat-body p').text()).toBe("This room does not (yet) exist");
|
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('error').attrs({by:'coven@chat.shakespeare.lit', type:'cancel'})
|
||||||
.c('service-unavailable').attrs({xmlns:'urn:ietf:params:xml:ns:xmpp-stanzas'}).nodeTree;
|
.c('service-unavailable').attrs({xmlns:'urn:ietf:params:xml:ns:xmpp-stanzas'}).nodeTree;
|
||||||
var view = this.chatboxesview.views['problematic@muc.localhost'];
|
var view = this.chatboxesview.views['problematic@muc.localhost'];
|
||||||
spyOn(converse.connection.muc, 'removeRoom');
|
|
||||||
spyOn(view, 'showErrorMessage').andCallThrough();
|
spyOn(view, 'showErrorMessage').andCallThrough();
|
||||||
view.onChatRoomPresence(presence, {'nick': 'dummy'});
|
view.onChatRoomPresence(presence, {'nick': 'dummy'});
|
||||||
expect(view.$el.find('.chat-body p').text()).toBe("This room has reached it's maximum number of occupants");
|
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'
|
'Louw Spekman', 'Mohamad Stet', 'Dominik Beyer'
|
||||||
];
|
];
|
||||||
var pend_names = [
|
var pend_names = [
|
||||||
'Suleyman van Beusichem', 'Nicole Diederich', 'Nanja van Yperen'
|
'Suleyman van Beusichem', 'Nanja van Yperen', 'Nicole Diederich'
|
||||||
];
|
];
|
||||||
var cur_names = [
|
var cur_names = [
|
||||||
'Max Frankfurter', 'Candice van der Knijff', 'Irini Vlastuin', 'Rinse Sommer', 'Annegreet Gomez',
|
'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');
|
expect(this.rosterview.$el.find('dt#pending-xmpp-contacts').css('display')).toEqual('none');
|
||||||
}, converse));
|
}, 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 () {
|
it("can be added to the roster and they will be sorted alphabetically", $.proxy(function () {
|
||||||
var i, t, is_last;
|
var i, t, is_last;
|
||||||
spyOn(this.rosterview, 'render').andCallThrough();
|
spyOn(this.rosterview, 'render').andCallThrough();
|
||||||
@ -136,13 +178,10 @@
|
|||||||
fullname: pend_names[i],
|
fullname: pend_names[i],
|
||||||
is_last: is_last
|
is_last: is_last
|
||||||
});
|
});
|
||||||
// For performance reasons, the roster should only be shown once
|
|
||||||
// the last contact has been added.
|
|
||||||
if (is_last) {
|
if (is_last) {
|
||||||
expect(this.rosterview.$el.is(':visible')).toEqual(true);
|
|
||||||
expect(this.xmppstatus.sendPresence).toHaveBeenCalled();
|
expect(this.xmppstatus.sendPresence).toHaveBeenCalled();
|
||||||
} else {
|
} else {
|
||||||
expect(this.rosterview.$el.is(':visible')).toEqual(false);
|
expect(this.xmppstatus.sendPresence).not.toHaveBeenCalled();
|
||||||
}
|
}
|
||||||
expect(this.rosterview.render).toHaveBeenCalled();
|
expect(this.rosterview.render).toHaveBeenCalled();
|
||||||
// Check that they are sorted alphabetically
|
// Check that they are sorted alphabetically
|
||||||
@ -154,6 +193,7 @@
|
|||||||
it("will have their own heading once they have been added", $.proxy(function () {
|
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');
|
expect(this.rosterview.$el.find('dt#pending-xmpp-contacts').css('display')).toEqual('block');
|
||||||
}, converse));
|
}, converse));
|
||||||
|
|
||||||
}, converse));
|
}, converse));
|
||||||
|
|
||||||
describe("Existing Contacts", $.proxy(function () {
|
describe("Existing Contacts", $.proxy(function () {
|
||||||
|
@ -68,37 +68,35 @@ require([
|
|||||||
prebind: false,
|
prebind: false,
|
||||||
xhr_user_search: false,
|
xhr_user_search: false,
|
||||||
auto_subscribe: 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