Commit 6553b5ba authored by JC Brand's avatar JC Brand

Merge branch 'master' of github.com:jcbrand/converse.js

parents d6ecef48 ef38fd09
...@@ -4,22 +4,27 @@ Changelog ...@@ -4,22 +4,27 @@ Changelog
0.3 (unreleased) 0.3 (unreleased)
---------------- ----------------
- Add vCard support [jcbrand] - Add vCard support
- Remember custom status messages upon reload. [jcbrand] [jcbrand]
- Remove jquery-ui dependency. [jcbrand] - Remember custom status messages upon reload.
[jcbrand]
- Remove jquery-ui dependency.
[jcbrand]
- Use backbone.localStorage to store the contacts roster, open chatboxes and - Use backbone.localStorage to store the contacts roster, open chatboxes and
chat messages. [jcbrand] chat messages.
- Fixed user status handling, which wasn't 100% according to the [jcbrand]
spec. [jcbrand] - Fixed user status handling, which wasn't 100% according to the spec.
- Separate messages according to day in chats. [jcbrand] [jcbrand]
- Separate messages according to day in chats.
[jcbrand]
- Add support for specifying the BOSH bind URL as configuration setting. - Add support for specifying the BOSH bind URL as configuration setting.
[jcbrand] [jcbrand]
- Improve the message counter to only increment when the window is not focused - Improve the message counter to only increment when the window is not focused
[witekdev] [witekdev]
- Make fetching of list of chatrooms on a server a configuration option. - Make fetching of list of chatrooms on a server a configuration option.
[jcbrand] [jcbrand]
- Use service discovery to show whether a chatroom is password protected as - Use service discovery to show all available features on a room.
well as its number of occupents. [jcbrand] [jcbrand]
0.2 (2013-03-28) 0.2 (2013-03-28)
......
...@@ -57,6 +57,7 @@ ...@@ -57,6 +57,7 @@
* (String) nick - Optional nickname to use in the chat room. * (String) nick - Optional nickname to use in the chat room.
* (Function) msg_handler_cb - The function call to handle messages from the specified chat room. * (Function) msg_handler_cb - The function call to handle messages from the specified chat room.
* (Function) pres_handler_cb - The function call back to handle presence in the chat room. * (Function) pres_handler_cb - The function call back to handle presence in the chat room.
* (Function) roster_cb - The function call back to handle roster changes in the chat room.
* (String) password - The optional password to use. (password protected rooms only) * (String) password - The optional password to use. (password protected rooms only)
*/ */
var msg, room_nick, _this = this; var msg, room_nick, _this = this;
......
...@@ -92,7 +92,11 @@ img.spinner { ...@@ -92,7 +92,11 @@ img.spinner {
display: block; display: block;
font-size: 12px; font-size: 12px;
padding: 0.5em 0 0 0.5em; padding: 0.5em 0 0 0.5em;
cursor: default;
}
ul.participant-list li.moderator {
color: #FE0007;
} }
.chatroom form.sendXMPPMessage { .chatroom form.sendXMPPMessage {
...@@ -223,6 +227,7 @@ div.chat-title { ...@@ -223,6 +227,7 @@ div.chat-title {
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
text-shadow: rgba(0,0,0,0.51) 0 -1px 0; text-shadow: rgba(0,0,0,0.51) 0 -1px 0;
height: 1em;
} }
.chat-head-chatbox, .chat-head-chatbox,
...@@ -441,7 +446,7 @@ form.search-xmpp-contact input { ...@@ -441,7 +446,7 @@ form.search-xmpp-contact input {
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
display: inline-block; display: inline-block;
width: 160px; width: 170px;
} }
#available-chatrooms dt, #available-chatrooms dt,
...@@ -468,6 +473,41 @@ dd.available-chatroom, ...@@ -468,6 +473,41 @@ dd.available-chatroom,
text-shadow: 0 1px 0 rgba(250, 250, 250, 1); text-shadow: 0 1px 0 rgba(250, 250, 250, 1);
} }
.room-info {
font-size: 11px;
font-style: normal;
font-weight: normal;
}
p.room-info {
margin: 0;
padding: 0;
display: block;
white-space: normal;
}
a.room-info {
background: url('images/information.png') no-repeat right top;
width: 22px;
float: right;
display: none;
}
a.open-room {
display: inline-block;
white-space: nowrap;
text-overflow: ellipsis;
overflow-x: hidden;
}
dd.available-chatroom:hover a.room-info {
display: inline-block;
}
dd.available-chatroom:hover a.open-room {
width: 75%;
}
#converse-roster dd a.remove-xmpp-contact { #converse-roster dd a.remove-xmpp-contact {
background: url('images/delete_icon.png') no-repeat right top; background: url('images/delete_icon.png') no-repeat right top;
padding: 0 0 1em 0; padding: 0 0 1em 0;
...@@ -477,11 +517,11 @@ dd.available-chatroom, ...@@ -477,11 +517,11 @@ dd.available-chatroom,
display: none; display: none;
} }
#converse-roster dd:hover *[class*="remove-xmpp-contact"] { #converse-roster dd:hover a.remove-xmpp-contact {
display: inline-block; display: inline-block;
} }
#converse-roster dd:hover *[class*="open-chat"] { #converse-roster dd:hover a.open-chat {
width: 75%; width: 75%;
} }
...@@ -541,10 +581,12 @@ form#converse-login { ...@@ -541,10 +581,12 @@ form#converse-login {
form#converse-login input { form#converse-login input {
display: block; display: block;
width: 90%;
} }
form#converse-login .login-submit { form#converse-login .login-submit {
margin-top: 1em; margin-top: 1em;
width: auto;
} }
form.set-xmpp-status, form.set-xmpp-status,
......
This diff is collapsed.
(function (root, factory) {
define("mock",
['converse'],
function() {
return factory();
});
}(this, function (converse) {
var mock_connection = {
'muc': {
'listRooms': function () {},
'join': function () {},
'leave': function () {}
},
'jid': 'dummy@localhost',
'addHandler': function (handler, ns, name, type, id, from, options) {
return function () {};
},
'send': function () {},
'roster': {
'add': function () {},
'authorize': function () {},
'unauthorize': function () {},
'get': function () {},
'subscribe': function () {},
'registerCallback': function () {}
},
'vcard': {
'get': function (callback, jid) {
var name = jid.split('@')[0].replace('.', ' ').split(' ');
var firstname = name[0].charAt(0).toUpperCase()+name[0].slice(1);
var lastname = name[1].charAt(0).toUpperCase()+name[1].slice(1);
var fullname = firstname+' '+lastname;
var vcard = $iq().c('vCard').c('FN').t(fullname);
callback(vcard.tree());
}
},
'disco': {
'info': function () {},
'items': function () {}
}
};
return mock_connection;
}));
This diff is collapsed.
(function (root, factory) { (function (root, factory) {
define([ define([
"converse" "converse",
], function (converse) { "mock"
return factory(converse); ], function (converse, mock_connection) {
return factory(converse, mock_connection);
} }
); );
} (this, function (converse) { } (this, function (converse, mock_connection) {
return describe("Converse.js", $.proxy(function() { return describe("Converse.js", $.proxy(function() {
// Names from http://www.fakenamegenerator.com/ // Names from http://www.fakenamegenerator.com/
var req_names = [ var req_names = [
...@@ -20,56 +20,7 @@ ...@@ -20,56 +20,7 @@
'Robin Schook', 'Marcel Eberhardt', 'Simone Brauer', 'Asmaa Haakman', 'Felix Amsel', 'Robin Schook', 'Marcel Eberhardt', 'Simone Brauer', 'Asmaa Haakman', 'Felix Amsel',
'Lena Grunewald', 'Laura Grunewald', 'Mandy Seiler', 'Sven Bosch', 'Nuriye Cuypers' 'Lena Grunewald', 'Laura Grunewald', 'Mandy Seiler', 'Sven Bosch', 'Nuriye Cuypers'
]; ];
var chatroom_names = [
'Dyon van de Wege', 'Thomas Kalb', 'Dirk Theissen', 'Felix Hofmann', 'Ka Lek', 'Anne Ebersbacher'
];
var num_contacts = req_names.length + pend_names.length + cur_names.length; var num_contacts = req_names.length + pend_names.length + cur_names.length;
mock_connection = {
'muc': {
'listRooms': function () {},
'join': function () {},
'leave': function () {}
},
'jid': 'dummy@localhost',
'addHandler': function (handler, ns, name, type, id, from, options) {
return function () {};
},
'send': function () {},
'roster': {
'add': function () {},
'authorize': function () {},
'unauthorize': function () {},
'get': function () {},
'subscribe': function () {},
'registerCallback': function () {}
},
'vcard': {
'get': function (callback, jid) {
var name = jid.split('@')[0].replace('.', ' ').split(' ');
var firstname = name[0].charAt(0).toUpperCase()+name[0].slice(1);
var lastname = name[1].charAt(0).toUpperCase()+name[1].slice(1);
var fullname = firstname+' '+lastname;
var vcard = $iq().c('vCard').c('FN').t(fullname);
callback(vcard.tree());
}
},
'disco': {
'info': function () {},
'items': function () {}
}
};
// Clear localStorage
window.localStorage.clear();
this.initialize({
prebind: false,
xhr_user_search: false,
auto_subscribe: false,
animate: false
});
this.onConnected(mock_connection);
// Variable declarations for specs
var open_controlbox; var open_controlbox;
describe("The Control Box", $.proxy(function () { describe("The Control Box", $.proxy(function () {
...@@ -82,8 +33,10 @@ ...@@ -82,8 +33,10 @@
// open yet. // open yet.
expect($("div#controlbox").is(':visible')).toBe(false); expect($("div#controlbox").is(':visible')).toBe(false);
spyOn(this, 'toggleControlBox').andCallThrough(); spyOn(this, 'toggleControlBox').andCallThrough();
spyOn(this, 'showControlBox').andCallThrough();
$('.toggle-online-users').click(); $('.toggle-online-users').click();
expect(this.toggleControlBox).toHaveBeenCalled(); expect(this.toggleControlBox).toHaveBeenCalled();
expect(this.showControlBox).toHaveBeenCalled();
expect($("div#controlbox").is(':visible')).toBe(true); expect($("div#controlbox").is(':visible')).toBe(true);
}, converse); }, converse);
it("can be opened by clicking a DOM element with class 'toggle-online-users'", open_controlbox); it("can be opened by clicking a DOM element with class 'toggle-online-users'", open_controlbox);
...@@ -577,8 +530,13 @@ ...@@ -577,8 +530,13 @@
it("is cleared when the window is focused", $.proxy(function () { it("is cleared when the window is focused", $.proxy(function () {
spyOn(converse, 'clearMsgCounter').andCallThrough(); spyOn(converse, 'clearMsgCounter').andCallThrough();
runs(function () {
$(window).trigger('focus'); $(window).trigger('focus');
});
waits(50);
runs(function () {
expect(converse.clearMsgCounter).toHaveBeenCalled(); expect(converse.clearMsgCounter).toHaveBeenCalled();
});
}, converse)); }, converse));
it("is not incremented when the message is received and the window is focused", $.proxy(function () { it("is not incremented when the message is received and the window is focused", $.proxy(function () {
...@@ -667,51 +625,5 @@ ...@@ -667,51 +625,5 @@
}, converse)); }, converse));
}, converse)); }, converse));
}, converse)); }, converse));
describe("A Chat Room", $.proxy(function () {
it("shows users currently present in the room", $.proxy(function () {
var chatroomview = this.chatboxesview.views['lounge@muc.localhost'];
var $participant_list = chatroomview.$el.find('.participant-list');
var roster = {}, room = {}, i;
for (i=0; i<chatroom_names.length; i++) {
roster[chatroom_names[i]] = {};
chatroomview.onChatRoomRoster(roster, room);
expect($participant_list.find('li').length).toBe(1+i);
expect($($participant_list.find('li')[i]).text()).toBe(chatroom_names[i]);
}
roster[converse.bare_jid] = {};
chatroomview.onChatRoomRoster(roster, room);
}, converse));
it("can be saved to, and retrieved from, localStorage", $.proxy(function () {
// We instantiate a new ChatBoxes collection, which by default
// will be empty.
var newchatboxes = new this.ChatBoxes();
expect(newchatboxes.length).toEqual(0);
// The chatboxes will then be fetched from localStorage inside the
// onConnected method
newchatboxes.onConnected();
expect(newchatboxes.length).toEqual(2); // controlbox is also included
// Check that the chatrooms retrieved from localStorage
// have the same attributes values as the original ones.
attrs = ['id', 'box_id', 'visible'];
for (i=0; i<attrs.length; i++) {
new_attrs = _.pluck(_.pluck(newchatboxes.models, 'attributes'), attrs[i]);
old_attrs = _.pluck(_.pluck(this.chatboxes.models, 'attributes'), attrs[i]);
expect(_.isEqual(new_attrs, old_attrs)).toEqual(true);
}
this.rosterview.render();
}, converse));
it("can be closed again by clicking a DOM element with class 'close-chatbox-button'", $.proxy(function () {
var view = this.chatboxesview.views['lounge@muc.localhost'], chatroom = view.model, $el;
spyOn(view, 'closeChat').andCallThrough();
spyOn(converse.connection.muc, 'leave');
view.delegateEvents(); // We need to rebind all events otherwise our spy won't be called
view.$el.find('.close-chatbox-button').click();
expect(view.closeChat).toHaveBeenCalled();
expect(converse.connection.muc.leave).toHaveBeenCalled();
}, converse));
}, converse));
}, converse)); }, converse));
})); }));
require(["jquery", "spec/MainSpec"], function($) { require(["jquery", "converse", "mock", "spec/MainSpec", "spec/ChatRoomSpec"], function($, converse, mock_connection) {
// Set up converse.js
window.localStorage.clear();
converse.initialize({
prebind: false,
xhr_user_search: false,
auto_subscribe: false,
animate: false
});
converse.onConnected(mock_connection);
$(function($) { // Jasmine stuff
var jasmineEnv = jasmine.getEnv(); var jasmineEnv = jasmine.getEnv();
jasmineEnv.updateInterval = 500; jasmineEnv.updateInterval = 50;
var htmlReporter = new jasmine.HtmlReporter(); var htmlReporter = new jasmine.HtmlReporter();
jasmineEnv.addReporter(htmlReporter); jasmineEnv.addReporter(htmlReporter);
jasmineEnv.specFilter = function(spec) { jasmineEnv.specFilter = function(spec) {
return htmlReporter.specFilter(spec); return htmlReporter.specFilter(spec);
}; };
jasmineEnv.execute(); jasmineEnv.execute();
});
}); });
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment