Commit bf837a92 authored by JC Brand's avatar JC Brand

Merge branch 'live-filter'

Conflicts:
	builds/converse-no-locales-no-otr.min.js
	builds/converse-no-otr.min.js
	builds/converse.min.js
	builds/converse.website-no-otr.min.js
	builds/converse.website.min.js
parents 33aac2cf c5ce850e
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -292,6 +292,9 @@ ...@@ -292,6 +292,9 @@
var HEADER_REQUESTING_CONTACTS = __('Contact requests'); var HEADER_REQUESTING_CONTACTS = __('Contact requests');
var HEADER_UNGROUPED = __('Ungrouped'); var HEADER_UNGROUPED = __('Ungrouped');
var LABEL_CONTACTS = __('Contacts');
var LABEL_GROUPS = __('Groups');
var HEADER_WEIGHTS = {}; var HEADER_WEIGHTS = {};
HEADER_WEIGHTS[HEADER_CURRENT_CONTACTS] = 0; HEADER_WEIGHTS[HEADER_CURRENT_CONTACTS] = 0;
HEADER_WEIGHTS[HEADER_UNGROUPED] = 1; HEADER_WEIGHTS[HEADER_UNGROUPED] = 1;
...@@ -307,8 +310,7 @@ ...@@ -307,8 +310,7 @@
// Module-level functions // Module-level functions
// ---------------------- // ----------------------
this.giveFeedback = function (message, klass) { this.giveFeedback = function (message, klass) {
$('.conn-feedback').text(message); $('.conn-feedback').attr('class', 'conn-feedback').text(message);
$('.conn-feedback').attr('class', 'conn-feedback');
if (klass) { if (klass) {
$('.conn-feedback').addClass(klass); $('.conn-feedback').addClass(klass);
} }
...@@ -1497,7 +1499,7 @@ ...@@ -1497,7 +1499,7 @@
label_away: __('Away'), label_away: __('Away'),
label_offline: __('Offline') label_offline: __('Offline')
}); });
this.$tabs.append(converse.templates.contacts_tab({label_contacts: __('Contacts')})); this.$tabs.append(converse.templates.contacts_tab({label_contacts: LABEL_CONTACTS}));
if (converse.xhr_user_search) { if (converse.xhr_user_search) {
markup = converse.templates.search_contact({ markup = converse.templates.search_contact({
label_contact_name: __('Contact name'), label_contact_name: __('Contact name'),
...@@ -1517,9 +1519,9 @@ ...@@ -1517,9 +1519,9 @@
}); });
} }
this.$el.html(widgets); this.$el.html(widgets);
this.$el.find('.search-xmpp ul').append(markup); this.$el.find('.search-xmpp ul').append(markup);
this.$el.append(converse.rosterview.$el); this.$el.append(converse.rosterview.$el);
converse.rosterview.update(); // Will render live filter if needed.
return this; return this;
}, },
...@@ -3245,7 +3247,8 @@ ...@@ -3245,7 +3247,8 @@
initialize: function () { initialize: function () {
this.model.contacts.on("add", this.addContact, this); this.model.contacts.on("add", this.addContact, this);
this.model.contacts.on("change:chat_status", function (contact) { this.model.contacts.on("change:chat_status", function (contact) {
// This might be optimized by instead of first sorting, finding the correct position in positionContact // This might be optimized by instead of first sorting,
// finding the correct position in positionContact
this.model.contacts.sort(); this.model.contacts.sort();
this.positionContact(contact).render(); this.positionContact(contact).render();
}, this); }, this);
...@@ -3282,23 +3285,73 @@ ...@@ -3282,23 +3285,73 @@
return view; return view;
}, },
hide: function () {
this.$el.nextUntil('dt').addBack().hide();
},
filter: function (q) {
/* Filter the group's contacts based on the query "q".
* The query is matched against the contact's full name.
* If all contacts are filtered out (i.e. hidden), then the
* group must be filtered out as well.
*/
var matches, rejects;
var predicate = function (item) {
return item.get('fullname').toLowerCase().indexOf(q) === -1;
};
if (q.length === 0) {
if (this.model.get('state') === OPENED) {
this.model.contacts.each($.proxy(function (item) {
if (!(converse.show_only_online_users && item.get('chat_status') === 'online')) {
this.get(item.get('id')).$el.show();
}
}, this));
}
this.showIfInvisible();
} else {
q = q.toLowerCase();
matches = this.model.contacts.filter(predicate);
if (matches.length === this.model.contacts.length) { // hide the whole group
this.hide();
} else {
_.each(matches, $.proxy(function (item) {
this.get(item.get('id')).$el.hide();
}, this));
_.each(this.model.contacts.reject(predicate), $.proxy(function (item) {
this.get(item.get('id')).$el.show();
}, this));
this.showIfInvisible();
}
}
},
showIfInvisible: function () {
if (!this.$el.is(':visible')) {
this.$el.show();
}
},
toggle: function (ev) { toggle: function (ev) {
if (ev && ev.preventDefault) { ev.preventDefault(); } if (ev && ev.preventDefault) { ev.preventDefault(); }
var $el = $(ev.target); var $el = $(ev.target);
this.$el.nextUntil('dt').slideToggle();
if ($el.hasClass("icon-opened")) { if ($el.hasClass("icon-opened")) {
this.$el.nextUntil('dt').slideUp();
this.model.save({state: CLOSED}); this.model.save({state: CLOSED});
$el.removeClass("icon-opened").addClass("icon-closed"); $el.removeClass("icon-opened").addClass("icon-closed");
} else { } else {
$el.removeClass("icon-closed").addClass("icon-opened"); $el.removeClass("icon-closed").addClass("icon-opened");
this.model.save({state: OPENED}); this.model.save({state: OPENED});
this.filter(
converse.rosterview.$('.roster-filter').val(),
converse.rosterview.$('.filter-type').val()
);
} }
}, },
addContact: function (contact) { addContact: function (contact) {
var view = new converse.RosterContactView({model: contact}); var view = new converse.RosterContactView({model: contact});
this.add(contact.get('id'), view); this.add(contact.get('id'), view);
var view = this.positionContact(contact).render(); view = this.positionContact(contact).render();
if (this.model.get('state') === CLOSED) { if (this.model.get('state') === CLOSED) {
view.$el.hide(); view.$el.hide();
} }
...@@ -3347,8 +3400,14 @@ ...@@ -3347,8 +3400,14 @@
}); });
this.RosterView = Backbone.Overview.extend({ this.RosterView = Backbone.Overview.extend({
tagName: 'dl', tagName: 'div',
id: 'converse-roster', id: 'converse-roster',
events: {
"keydown .roster-filter": "liveFilter",
"click .onX": "clearFilter",
"mousemove .x": "togglePointer",
"change .filter-type": "changeFilterType"
},
initialize: function () { initialize: function () {
this.registerRosterHandler(); this.registerRosterHandler();
...@@ -3369,7 +3428,80 @@ ...@@ -3369,7 +3428,80 @@
}, },
render: function () { render: function () {
this.$el.empty(); this.$el.html(converse.templates.roster({
placeholder: __('Type to filter'),
label_contacts: LABEL_CONTACTS,
label_groups: LABEL_GROUPS
}));
return this;
},
changeFilterType: function (ev) {
if (ev && ev.preventDefault) { ev.preventDefault(); }
this.clearFilter();
this.filter(
this.$('.roster-filter').val(),
ev.target.value
);
},
tog: function (v) {
return v?'addClass':'removeClass';
},
togglePointer: function (ev) {
if (ev && ev.preventDefault) { ev.preventDefault(); }
var el = ev.target;
$(el)[this.tog(el.offsetWidth-18 < ev.clientX-el.getBoundingClientRect().left)]('onX');
},
filter: function (query, type) {
var matches;
query = query.toLowerCase();
if (type === 'groups') {
matches = _.filter(this.getAll(), function (view) {
return view.model.get('name').toLowerCase().indexOf(query) === -1;
});
_.each(matches, function (view) {
view.hide();
});
} else {
_.each(this.getAll(), function (view) {
view.filter(query, type);
});
}
},
liveFilter: _.debounce(function (ev) {
if (ev && ev.preventDefault) { ev.preventDefault(); }
var q = ev.target.value;
var t = this.$('.filter-type').val();
$(ev.target)[this.tog(q)]('x');
this.filter(q, t);
}, 500),
clearFilter: function (ev) {
if (ev && ev.preventDefault) {
ev.preventDefault();
$(ev.target).removeClass('x onX').val('');
}
this.filter('');
},
showHideFilter: function () {
var $filter = this.$('.roster-filter');
var visible = $filter.is(':visible');
if (visible && $filter.val().length > 0) {
// Don't hide if user is currently filtering.
return;
}
if (this.$('.roster-contacts').hasScrollBar()) {
if (!visible) {
$filter.show();
}
} else {
$filter.hide();
}
return this; return this;
}, },
...@@ -3380,7 +3512,7 @@ ...@@ -3380,7 +3512,7 @@
if (!$count.is(':visible')) { if (!$count.is(':visible')) {
$count.show(); $count.show();
} }
return this; return this.showHideFilter();
}, },
reset: function () { reset: function () {
...@@ -3457,13 +3589,13 @@ ...@@ -3457,13 +3589,13 @@
*/ */
model.sort(); model.sort();
model.each($.proxy(function (group, idx) { model.each($.proxy(function (group, idx) {
var view = this.get(group.get('name')) var view = this.get(group.get('name'));
if (!view) { if (!view) {
view = new converse.RosterGroupView({model: group}); view = new converse.RosterGroupView({model: group});
this.add(group.get('name'), view.render()); this.add(group.get('name'), view.render());
} }
if (idx === 0) { if (idx === 0) {
this.$el.append(view.$el); this.$('.roster-contacts').append(view.$el);
} else { } else {
this.appendGroup(view); this.appendGroup(view);
} }
...@@ -3476,7 +3608,7 @@ ...@@ -3476,7 +3608,7 @@
*/ */
var index = this.model.indexOf(view.model); var index = this.model.indexOf(view.model);
if (index === 0) { if (index === 0) {
this.$el.prepend(view.$el); this.$('.roster-contacts').prepend(view.$el);
} else if (index == (this.model.length-1)) { } else if (index == (this.model.length-1)) {
this.appendGroup(view); this.appendGroup(view);
} else { } else {
......
...@@ -754,7 +754,7 @@ dl.add-converse-contact { ...@@ -754,7 +754,7 @@ dl.add-converse-contact {
clear: right; clear: right;
height: 22px; height: 22px;
width: 12px; width: 12px;
padding: 0px 5px 0 0; padding: 0px 15px 0 0;
color: #4f4f4f; color: #4f4f4f;
} }
#conversejs ul#found-users { #conversejs ul#found-users {
...@@ -817,7 +817,7 @@ dl.add-converse-contact { ...@@ -817,7 +817,7 @@ dl.add-converse-contact {
top: 1px; top: 1px;
} }
#conversejs .controlbox-pane dt { #conversejs .controlbox-pane dt {
padding: 3px; padding-bottom: 3px;
} }
#conversejs .chatroom-form-container { #conversejs .chatroom-form-container {
height: 100%; height: 100%;
...@@ -872,24 +872,52 @@ dl.add-converse-contact { ...@@ -872,24 +872,52 @@ dl.add-converse-contact {
white-space: nowrap; white-space: nowrap;
text-overflow: ellipsis; text-overflow: ellipsis;
} }
#conversejs #converse-roster span.req-contact-name { #converse-roster span.req-contact-name {
width: 65%; width: 65%;
} }
#conversejs #converse-roster span.pending-contact-name, #converse-roster span.pending-contact-name,
#conversejs #converse-roster a.open-chat { #converse-roster a.open-chat {
width: 80%; width: 80%;
} }
#converse-roster dd span { #converse-roster dd span {
padding: 0 5px 0 0; padding: 0 5px 0 0;
} }
#converse-roster { #converse-roster {
overflow-y: auto;
overflow-x: hidden;
width: 100%; width: 100%;
position: relative; position: relative;
margin: 0.5em 0 0 0; margin: 0.5em 0 0 0;
height: 254px; height: 194px;
height: calc(100% - 70px); height: calc(100% - 25px);
overflow-x: hidden;
}
#converse-roster .roster-filter {
padding: 0;
margin: 0 0 5px 0.5em;
width: 111px;
height: 20px;
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAABNSURBVHjaXI7BDcAwCAMvyQjMyQ6dAbZiKfqoUK34g2zJh1dENIC7M8pMAPYdzAVY3d0ajNz9aypS/b5R6o+ZPdqoKgCq6h80KH3xDgBqNR97p8oAGQAAAABJRU5ErkJggg== ) no-repeat right -20px center;
border: 1px solid #999;
display: inline-block;
}
#converse-roster .filter-type {
height: 20px;
padding: 0;
margin: 0 0 0 -5px;
}
/* (jQ addClass:) if input has value: */
#converse-roster .roster-filter.x {
background-position: right 3px center;
}
/* (jQ addClass:) if mouse is over the 'x' input area*/
#converse-roster .roster-filter.onX {
cursor: pointer;
}
#converse-roster .roster-contacts {
margin: 0;
overflow-y: auto;
overflow-x: hidden;
max-height: 195px;
max-height: calc(100% - 67px);
} }
#converse-roster .group-toggle { #converse-roster .group-toggle {
color: #666; color: #666;
...@@ -961,7 +989,7 @@ dl.add-converse-contact { ...@@ -961,7 +989,7 @@ dl.add-converse-contact {
text-shadow: 0 1px 0 #fafafa; text-shadow: 0 1px 0 #fafafa;
clear: both; clear: both;
} }
#conversejs #converse-roster dd { #converse-roster dd {
line-height: 16px; line-height: 16px;
} }
#conversejs .group-toggle { #conversejs .group-toggle {
...@@ -970,20 +998,20 @@ dl.add-converse-contact { ...@@ -970,20 +998,20 @@ dl.add-converse-contact {
} }
#conversejs .roster-group:hover, #conversejs .roster-group:hover,
#conversejs dd.available-chatroom:hover, #conversejs dd.available-chatroom:hover,
#conversejs #converse-roster dd:hover { #converse-roster dd:hover {
background-color: #eee; background-color: #eee;
} }
#conversejs #converse-roster dd a.decline-xmpp-request { #converse-roster dd a.decline-xmpp-request {
margin-left: 5px; margin-left: 5px;
} }
#conversejs #converse-roster dd a.remove-xmpp-contact { #converse-roster dd a.remove-xmpp-contact {
float: right; float: right;
width: 22px; width: 22px;
margin: 0; margin: 0;
display: none; display: none;
color: #4f4f4f; color: #4f4f4f;
} }
#conversejs #converse-roster dd:hover a.remove-xmpp-contact { #converse-roster dd:hover a.remove-xmpp-contact {
display: inline-block; display: inline-block;
} }
#conversejs .chatbox, #conversejs .chatbox,
......
...@@ -9,4 +9,4 @@ ...@@ -9,4 +9,4 @@
* *
* Copyright (c) 2012-2014, Jan-Carel Brand <jc@opkode.com> * Copyright (c) 2012-2014, Jan-Carel Brand <jc@opkode.com>
* Licensed under the Mozilla Public License * Licensed under the Mozilla Public License
*/@font-face{font-family:Converse-js;src:url(../fonticons/fonts/icomoon.eot?7poj4t);src:url(../fonticons/fonts/icomoon.eot?#iefix7poj4t) format('embedded-opentype'),url(../fonticons/fonts/icomoon.woff?7poj4t) format('woff'),url(../fonticons/fonts/icomoon.ttf?7poj4t) format('truetype'),url(../fonticons/fonts/icomoon.svg?7poj4t#icomoon) format('svg');font-weight:400;font-style:normal}#conversejs [data-icon]:before{font-family:Converse-js;content:attr(data-icon);speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#conversejs [class*=" icon-"],#conversejs [class^=icon-]{font-family:Converse-js;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.icon-closed:before{content:"\25ba"}.icon-opened:before{content:"\25bc"}.icon-checkmark:before{content:"\2713"}#conversejs .icon-home:before{content:"\e000"}#conversejs .icon-pencil:before{content:"\270e"}#conversejs .icon-camera:before{content:"\e003"}#conversejs .icon-camera-2:before{content:"\2616"}#conversejs .icon-play:before{content:"\25d9"}#conversejs .icon-music:before{content:"\266b"}#conversejs .icon-headphones:before{content:"\266c"}#conversejs .icon-phone:before{content:"\260f"}#conversejs .icon-phone-hang-up:before{content:"\260e"}#conversejs .icon-address-book:before{content:"\270f"}#conversejs .icon-notebook:before{content:"\2710"}#conversejs .icon-envelop:before{content:"\2709"}#conversejs .icon-pushpin:before{content:"\e012"}#conversejs .icon-online:before{content:"\25fc"}#conversejs .icon-away:before{content:"\25fb"}#conversejs .icon-bubbles:before{content:"\e015"}#conversejs .icon-bubbles-2:before{content:"\e016"}#conversejs .icon-bubbles-3:before{content:"\e017"}#conversejs .icon-user:before{content:"\e01a"}#conversejs .icon-users:before{content:"\e01b"}#conversejs .icon-quotes-left:before{content:"\e01d"}#conversejs .icon-spinner:before{content:"\231b"}#conversejs .icon-search:before{content:"\e021"}#conversejs .icon-cogs:before{content:"\e022"}#conversejs .icon-wrench:before{content:"\e024"}#conversejs .icon-unlocked:before{content:"\e025"}#conversejs .icon-lock:before{content:"\e026"}#conversejs .icon-lock-2:before{content:"\e027"}#conversejs .icon-key:before{content:"\e028"}#conversejs .icon-key-2:before{content:"\e029"}#conversejs .icon-zoom-out:before{content:"\e02a"}#conversejs .icon-zoom-in:before{content:"\e02b"}#conversejs .icon-cog:before{content:"\e02f"}#conversejs .icon-remove:before{content:"\e02d"}#conversejs .icon-remove-2:before{content:"\e02e"}#conversejs .icon-eye:before{content:"\e030"}#conversejs .icon-eye-blocked:before{content:"\e031"}#conversejs .icon-attachment:before{content:"\e032"}#conversejs .icon-globe:before{content:"\e033"}#conversejs .icon-heart:before{content:"\2764"}#conversejs .icon-happy:before{content:"\263b"}#conversejs .icon-thumbs-up:before{content:"\261d"}#conversejs .icon-smiley:before{content:"\263a"}#conversejs .icon-tongue:before{content:"\e038"}#conversejs .icon-sad:before{content:"\2639"}#conversejs .icon-wink:before{content:"\e03a"}#conversejs .icon-wondering:before{content:"\2369"}#conversejs .icon-confused:before{content:"\2368"}#conversejs .icon-shocked:before{content:"\2364"}#conversejs .icon-evil:before{content:"\261f"}#conversejs .icon-angry:before{content:"\e03f"}#conversejs .icon-cool:before{content:"\e040"}#conversejs .icon-grin:before{content:"\e041"}#conversejs .icon-info:before{content:"\2360"}#conversejs .icon-notification:before{content:"\e01f"}#conversejs .icon-warning:before{content:"\26a0"}#conversejs .icon-spell-check:before{content:"\e045"}#conversejs .icon-volume-high:before{content:"\e046"}#conversejs .icon-volume-medium:before{content:"\e047"}#conversejs .icon-volume-low:before{content:"\e048"}#conversejs .icon-volume-mute:before{content:"\e049"}#conversejs .icon-volume-mute-2:before{content:"\e04a"}#conversejs .icon-volume-decrease:before{content:"\e04b"}#conversejs .icon-volume-increase:before{content:"\e04c"}#conversejs .icon-bold:before{content:"\e04d"}#conversejs .icon-underline:before{content:"\e04e"}#conversejs .icon-italic:before{content:"\e04f"}#conversejs .icon-strikethrough:before{content:"\e050"}#conversejs .icon-new-tab:before{content:"\e053"}#conversejs .icon-youtube:before{content:"\e055"}#conversejs .icon-close:before{content:"\2715"}#conversejs .icon-blocked:before{content:"\2718"}#conversejs .icon-cancel-circle:before{content:"\e058"}#conversejs .icon-minus:before{content:"\e05a"}#conversejs .icon-plus:before{content:"\271a"}#conversejs .icon-checkbox-checked:before{content:"\2611"}#conversejs .icon-checkbox-unchecked:before{content:"\2b27"}#conversejs .icon-checkbox-partial:before{content:"\2b28"}#conversejs .icon-radio-checked:before{content:"\2b26"}#conversejs .icon-radio-unchecked:before{content:"\2b25"}#conversejs .icon-room-info:before{content:"\e059"}#conversejs .icon-newspaper:before{content:"\e001"}#conversejs .icon-image:before{content:"\2b14"}#conversejs .icon-offline:before,#conversejs .icon-unavailable:before,#conversejs .icon-xa:before{content:"\e002"}#conversejs .icon-dnd:before{content:"\e004"}#conversejs .no-text-select{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:-moz-none;-ms-user-select:none;user-select:none}#conversejs{bottom:0;direction:ltr;height:25px;left:0;position:fixed;right:0;z-index:30;display:block;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}#conversejs div{box-sizing:border-box}#conversejs ul li{height:auto}#conversejs a,#conversejs article,#conversejs aside,#conversejs audio,#conversejs blockquote,#conversejs canvas,#conversejs caption,#conversejs dd,#conversejs details,#conversejs div,#conversejs dl,#conversejs dt,#conversejs em,#conversejs embed,#conversejs fieldset,#conversejs figcaption,#conversejs figure,#conversejs footer,#conversejs form,#conversejs h1,#conversejs h2,#conversejs h3,#conversejs h4,#conversejs h5,#conversejs h6,#conversejs header,#conversejs hgroup,#conversejs img,#conversejs label,#conversejs legend,#conversejs li,#conversejs mark,#conversejs menu,#conversejs nav,#conversejs ol,#conversejs output,#conversejs p,#conversejs pre,#conversejs ruby,#conversejs section,#conversejs span,#conversejs strong,#conversejs summary,#conversejs table,#conversejs tbody,#conversejs td,#conversejs tfoot,#conversejs th,#conversejs thead,#conversejs time,#conversejs tr,#conversejs ul,#conversejs video{margin:0;padding:0;border:0;font:inherit;vertical-align:baseline}#conversejs,#conversejs input,#conversejs textarea{font-size:14px;color:#4f4f4f}#conversejs ol,#conversejs ul{list-style:none}#conversejs li{height:10px}#conversejs a{text-decoration:none;color:#2D617A;text-shadow:none}#conversejs dl,#conversejs ol,#conversejs ul{font:inherit;margin:0 0 15px}#conversejs .emoticon{font-size:14px}#conversejs .hidden{display:none}#conversejs .locked{padding-right:22px}@-moz-keyframes spin{0%{-moz-transform:rotate(0deg)}100%{-moz-transform:rotate(359deg)}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg)}}@-o-keyframes spin{0%{-o-transform:rotate(0deg)}100%{-o-transform:rotate(359deg)}}@keyframes spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}span.spinner:before{font-size:24px;font-family:Converse-js!important;content:"\231b"}span.spinner{-webkit-animation:spin 2s infinite linear;-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;animation:spin 2s infinite linear;width:100%;display:block;text-align:center}span.spinner.centered{text-align:center;padding-top:5em}span.spinner.hor_centered{text-align:center}#conversejs #minimized-chats .box-flyout{position:absolute;display:block;height:auto;bottom:25px;margin-left:0}#conversejs #minimized-chats .box-flyout .chat-head{font-size:100%;border-radius:4px;padding:3px 0 0 5px;margin:0 0 1px;box-shadow:1px 3px 5px 3px rgba(0,0,0,.4);height:24px;width:130px}#conversejs #minimized-chats,#conversejs .toggle-controlbox{float:right;font-size:90%;border-top-right-radius:2px;border-top-left-radius:2px;background-color:#F4F4F4;padding:4px 8px;margin-right:5px;color:#0a0a0a;font-weight:700;height:100%}#conversejs #minimized-chats{width:130px;padding:0;display:none}#conversejs #toggle-minimized-chats{position:relative;padding:4px 0 0 4px;display:block;width:100%;height:100%;color:#0f0f0f}#conversejs #toggle-minimized-chats .unread-message-count{right:5px;bottom:5px}#conversejs .toggle-controlbox,#conversejs .toggle-minimized-chats{float:right;font-size:85%;border-top-right-radius:4px;border-top-left-radius:4px;background-color:#5390c8;padding:4px 8px;margin-right:5px;color:#fff}#conversejs .chat-head{color:#fff;font-size:100%;border-top-right-radius:4px;border-top-left-radius:4px;padding:2px 2px 2px 4px;margin:0}#conversejs .chat-head-chatbox{background-color:#2D617A}#conversejs .chat-head-chatroom{background-color:#0F592F}#conversejs .chat-body{background-color:#fff;border-bottom-right-radius:4px;border-bottom-left-radius:4px;height:289px;height:calc(100% - 35px);border-top:0}#conversejs .chatroom .chat-area{float:left;width:200px;height:100%}#conversejs .chatroom .participants{float:left;background-color:#fff;overflow:auto;border-left:1px solid #AAA;width:100px;border-bottom-right-radius:4px;height:100%}#conversejs .participants ul.participant-list li{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block;font-size:12px;font-weight:700;padding:.5em 0 0 .5em;cursor:default}#conversejs ul.participant-list li.moderator{color:#8f2831}#conversejs .chatroom .participant-list{list-style:none}#conversejs .chat-blink{background-color:#176679;border-right:1px solid #176679;border-left:1px solid #176679}#conversejs .chat-content{position:relative;padding:4px;font-size:13px;color:#4f4f4f;overflow-y:auto;border:0;background-color:#fff;line-height:1.3em;box-sizing:border-box;-moz-box-sizing:border-box;height:206px;height:calc(100% - 84px)}#conversejs .chat-error{color:#8f2831}#conversejs .chat-message-me,#conversejs .chat-message-room,#conversejs .chat-message-them{font-weight:700;white-space:nowrap;max-width:100px;text-overflow:ellipsis;overflow:hidden;display:inline-block;float:left;padding-right:3px}#conversejs .chat-message-content{word-wrap:break-word}#conversejs .chat-message-them{color:#8f2831}#conversejs .chat-message-me{color:#2D617A}#conversejs .chat-message-room{color:#4B7003}#conversejs .chat-date,#conversejs .chat-event,#conversejs .chat-info{color:gray}#conversejs li.chat-info{padding-left:10px}#conversejs .chat-date{display:inline-block;padding-top:10px}#conversejs p.not-implemented{margin-top:3em;margin-left:.3em;color:gray}#conversejs div.delayed .chat-message-them{color:#FB5D50}#conversejs div.delayed .chat-message-me{color:#7EABBB}input.error{border:1px solid red}#conversejs .conn-feedback.error{color:red}#converse-login .conn-feedback{width:100%;text-align:center;display:block}#conversejs .chat-message-error{color:#76797C;font-size:90%;font-weight:400}#conversejs .chat-head .avatar{float:left;margin-right:6px}#conversejs .chat-title,#conversejs .restore-chat{padding:1px 0;color:#fff;font-weight:700;line-height:15px;display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-shadow:rgba(0,0,0,.51)0 -1px 0}#conversejs .chat-title a{color:#fff;width:100%;text-overflow:ellipsis;white-space:nowrap}#conversejs .chat-head-chatbox,#conversejs .chat-head-chatroom{height:35px;position:relative}#conversejs p.chatroom-topic,#conversejs p.user-custom-message{font-size:80%;font-style:italic;height:1.3em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin:0;padding:1px 0}#conversejs div.chat-head-chatbox a.user-custom-message{color:#fff}#conversejs .activated{display:block!important}#conversejs a.subscribe-to-user{padding-left:2em;font-weight:700}dl.add-converse-contact{margin:0 0 0 .5em}#conversejs .fancy-dropdown{border:1px solid #ddd;height:22px}#conversejs .fancy-dropdown a.choose-xmpp-status{width:155px}#conversejs .fancy-dropdown a.choose-xmpp-status,#conversejs .fancy-dropdown a.toggle-xmpp-contact-form{text-shadow:0 1px 0 #fff;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:inline}#conversejs .fancy-dropdown a.toggle-xmpp-contact-form span{float:left}#conversejs .choose-xmpp-status span{padding-right:5px;padding-left:5px;float:left}#conversejs #fancy-xmpp-status-select a.change-xmpp-status-message{float:right;clear:right;height:22px;width:12px;padding:0 5px 0 0;color:#4f4f4f}#conversejs ul#found-users{padding:10px 0 5px 5px;border:0}#conversejs form.search-xmpp-contact{margin:0;padding:0 0 5px 5px}#conversejs form.search-xmpp-contact input{width:8em}#conversejs .controlbox-head{margin:0;color:#FFF;border-top-right-radius:4px;border-top-left-radius:4px;height:35px;clear:right;background-color:#2D617A;padding:3px 0 0}#conversejs .chat-head-message-count,#conversejs .unread-message-count{font-weight:700;background:-webkit-gradient(linear,left top,left bottom,color-stop(0.35,#f6f6f6),color-stop(1,gray));background:-moz-linear-gradient(center top,#ff0 5%,#f6f6f6 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='yellow', endColorstr='#f6f6f6');border:1px solid;text-shadow:1px 1px 0 #ccc;color:#8b0000;border-radius:5px;padding:2px 4px;font-size:15px;text-align:center;position:absolute;right:22px;bottom:1px}#conversejs a.close-chatbox-button,#conversejs a.configure-chatroom-button,#conversejs a.toggle-chatbox-button{font-size:10px;padding:3px 3px 2px;margin-right:3px;cursor:pointer;border-radius:6px;border:1px solid #888;display:inline-block;color:#fff;text-decoration:none;float:right}#conversejs a.close-chatbox-button:active,#conversejs a.configure-chatroom-button:active,#conversejs a.toggle-chatbox-button:active{position:relative;top:1px}#conversejs .controlbox-pane dt{padding:3px}#conversejs .chatroom-form-container{height:100%;color:#666;overflow-y:auto;border-bottom-right-radius:4px;border-bottom-left-radius:4px}#conversejs .chatroom-form{background:#fff;font-size:12px;padding:10px 5px}#conversejs .chat-body p{font-size:14px;color:#666;padding:5px;margin:0}#conversejs .chatroom-form legend{font-size:14px;font-weight:700;margin-bottom:5px}#conversejs .chatroom-form label{font-weight:700;display:block;clear:both}#conversejs .chatroom-form label input,#conversejs .chatroom-form label select{float:right}#converse-roster dd.odd{background-color:#DCEAC5}#converse-roster dd.current-xmpp-contact span{font-size:16px;float:left;color:#4f4f4f}#conversejs .requesting-xmpp-contact .request-actions{margin-left:.5em;float:right}#converse-roster dd a,#converse-roster dd span{text-shadow:0 1px 0 #fafafa;display:inline-block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}#conversejs #converse-roster span.req-contact-name{width:65%}#conversejs #converse-roster a.open-chat,#conversejs #converse-roster span.pending-contact-name{width:80%}#converse-roster dd span{padding:0 5px 0 0}#converse-roster{overflow-y:auto;overflow-x:hidden;width:100%;position:relative;margin:.5em 0 0;height:254px;height:calc(100% - 70px)}#converse-roster .group-toggle{color:#666}#conversejs dd.available-chatroom{overflow-x:hidden;text-overflow:ellipsis;white-space:nowrap}#conversejs dd.available-chatroom a.open-room{width:148px}#available-chatrooms dt,#converse-roster dt{font-weight:400;font-size:13px;color:#666;border:none;padding:.3em 0 0 .5em;text-shadow:0 1px 0 #fafafa}#converse-roster dt{display:none}#conversejs .room-info{font-size:11px;font-style:normal;font-weight:400}#conversejs li.room-info{display:block;margin-left:5px}#conversejs div.room-info{clear:left}#conversejs p.room-info{margin:0;padding:0;display:block;white-space:normal}#conversejs a.room-info{width:22px;height:22px;float:right;display:none;clear:right}#conversejs a.open-room{float:left;white-space:nowrap;text-overflow:ellipsis;overflow-x:hidden}#conversejs dd.available-chatroom:hover a.room-info{display:inline-block;margin-top:3px;font-size:15px}#conversejs #converse-roster dd,#conversejs dd.available-chatroom{font-weight:700;border:none;display:block;padding:1px 0 0 .5em;color:#666;text-shadow:0 1px 0 #fafafa;clear:both}#conversejs #converse-roster dd{line-height:16px}#conversejs .group-toggle{display:block;width:100%}#conversejs #converse-roster dd:hover,#conversejs .roster-group:hover,#conversejs dd.available-chatroom:hover{background-color:#eee}#conversejs #converse-roster dd a.decline-xmpp-request{margin-left:5px}#conversejs #converse-roster dd a.remove-xmpp-contact{float:right;width:22px;margin:0;display:none;color:#4f4f4f}#conversejs #converse-roster dd:hover a.remove-xmpp-contact{display:inline-block}#conversejs .chatbox,#conversejs .chatroom{height:25px;float:right;margin-right:15px;display:block}#conversejs .chatbox{width:200px}#conversejs .chatroom{width:300px}#conversejs .controlbox-pane{padding:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}#conversejs .controlbox-pane dd{margin-left:0;margin-bottom:0;padding:1em}#conversejs .controlbox-pane dd.odd{background-color:#DCEAC5}#conversejs form#converse-login{background:#fff;padding:2em .5em}#conversejs form#converse-login input{width:100%}#conversejs form#converse-login label{margin-top:.5em}#conversejs form#converse-login .login-submit{margin-top:1em}#conversejs form.set-xmpp-status{background:0 0;margin:none;padding:none}#conversejs form.add-chatroom{background:0 0;padding:3px}#conversejs form.add-chatroom input[type=text]{width:95%;margin:3px}#conversejs form.add-chatroom input[type=button],#conversejs form.add-chatroom input[type=submit]{width:48%}select#select-xmpp-status{float:right;margin-right:.5em}#conversejs .chat-head #controlbox-tabs{text-align:center;display:inline;overflow:hidden;font-size:12px;list-style-type:none}#conversejs .chat-head #controlbox-tabs li{float:left;list-style:none;padding-left:0;text-shadow:#fff 0 1px 0;width:38%}#conversejs ul#controlbox-tabs li a{display:block;font-size:12px;height:34px;line-height:34px;margin:0;text-align:center;text-decoration:none;border-top-right-radius:4px;border-top-left-radius:4px;color:#666;text-shadow:0 1px 0 #fafafa}#conversejs .chat-head #controlbox-tabs li a:hover{color:#000}#conversejs .chat-head #controlbox-tabs li a{background-color:#fff;box-shadow:inset 0 4px 12px rgba(0,0,0,.3);border-bottom:1px solid #CCC}#conversejs ul#controlbox-tabs a.current,#conversejs ul#controlbox-tabs a.current:hover{box-shadow:none;border-bottom:0;height:35px;cursor:default;color:#666}#conversejs div#chatrooms,#conversejs div#login-dialog,#conversejs div#settings,#conversejs div#users{border:0;font-size:14px;background-color:#fff;border-bottom-right-radius:4px;border-bottom-left-radius:4px;width:100%;height:289px;height:calc(100% - 35px);overflow-y:hidden;position:absolute}#conversejs div#chatrooms{overflow-y:auto}#conversejs form.sendXMPPMessage{background:#fff;border:0;border-top:1px solid #BBB;padding:0;margin:0;position:relative;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-moz-background-clip:padding;-webkit-background-clip:padding-box;background-clip:padding-box;border-top-left-radius:0;border-top-right-radius:0;width:200px}#conversejs .chatroom form.sendXMPPMessage{-webkit-border-bottom-right-radius:0;border-bottom-right-radius:0}#conversejs .chat-textarea{box-sizing:border-box;-moz-box-sizing:border-box;border:0;width:100%;padding:3px;border-bottom-left-radius:4px;border-bottom-right-radius:4px;resize:none;height:59px}#conversejs .chatroom .chat-textarea{border-bottom-right-radius:0}#conversejs ul.chat-toolbar{font-size:14px;margin:0;padding:0 5px 0 0;height:20px;display:block;width:195px}#conversejs .chat-toolbar .toggle-clear,#conversejs .chat-toolbar .toggle-otr{float:right}#conversejs .chat-toolbar a{color:#4f4f4f}#conversejs .chat-toolbar ul li a:hover{color:#8f2831}#conversejs .chat-toolbar ul{display:none;font-size:12px;position:absolute;bottom:100%;margin-bottom:1px;right:0;background:#fff;box-shadow:0 -1px 2px 0 rgba(0,0,0,.4)}#conversejs .chat-toolbar ul li{position:relative;list-style:none;cursor:pointer}#conversejs .chat-toolbar .toggle-smiley{padding-left:5px}#conversejs .chat-toolbar .toggle-smiley ul li{font-size:14px;padding:5px;z-index:98}#conversejs .chat-toolbar .toggle-otr ul li{background-color:#fff;display:block;z-index:99}#conversejs .chat-toolbar ul li:hover{background-color:#eee}#conversejs .chat-toolbar .toggle-otr ul li a{transition:background-color .2s ease-in-out;-webkit-transition:background-color .2s ease-in-out;-moz-transition:background-color .2s ease-in-out;display:block;padding:1px;text-decoration:none}#conversejs .chat-toolbar-text{font-size:12px;padding-right:3px}#conversejs .unencrypted,#conversejs .unencrypted a{color:#8f2831}#conversejs .unverified,#conversejs .unverified a{color:#cf5300}#conversejs .private,#conversejs .private a{color:#4b7003}#conversejs ul.chat-toolbar li{display:inline-block;list-style:none;padding:0 3px;cursor:pointer;margin-top:1px}#conversejs ul.chat-toolbar li:hover{cursor:pointer}#conversejs form#set-custom-xmpp-status{float:left;padding:0}#conversejs .chat-textarea-chatbox-selected{border:1px solid #578308;margin:0}#conversejs .chat-textarea-chatroom-selected{border:2px solid #2D617A;margin:0}#conversejs #set-custom-xmpp-status button{padding:1px 2px 1px 1px}#conversejs #controlbox{display:none}#conversejs #controlbox div.xmpp-status{display:inline}#conversejs .chatbox dl.dropdown{margin:.5em;background-color:#f0f0f0}#conversejs .chatbox .dropdown dd,#conversejs .dropdown dt,#conversejs .dropdown ul{margin:0;padding:0}#conversejs .chatbox .dropdown dd{position:relative}input.custom-xmpp-status{width:124px}#conversejs form.add-xmpp-contact{background:0 0;padding:5px}#conversejs form.add-xmpp-contact input{width:108px}#conversejs .chatbox .dropdown dt a span{cursor:pointer;display:block;padding:4px 7px 0 5px;color:#4f4f4f}#conversejs .chatbox .dropdown dd ul{padding:5px 0;list-style:none;position:absolute;left:0;top:0;border:1px solid #ddd;border-top:0;width:99%;z-index:21;background-color:#f0f0f0}#conversejs .chatbox .dropdown li{list-style:none;padding-left:0}#conversejs .chatbox .dropdown a{height:22px;width:148px;display:inline-block;line-height:24px}#conversejs .chatbox .dropdown dd ul li:hover,#conversejs .chatbox .dropdown dd.search-xmpp ul li:hover{background-color:#bed6e5}#conversejs .xmpp-status-menu li a{width:100%}#conversejs .xmpp-status-menu li a span{padding:0 5px;color:#4f4f4f}#conversejs .set-xmpp-status .dropdown dd ul{z-index:22}#conversejs .box-flyout,#conversejs .minimized-chats-flyout{border-radius:4px;bottom:6px;box-shadow:1px 3px 5px 3px rgba(0,0,0,.4);display:block;height:324px;position:absolute}#conversejs .minimized-chats-flyout{border-radius:4px;bottom:25px;box-shadow:1px 3px 5px 3px rgba(0,0,0,.4);display:block;position:absolute;height:auto;width:130px}#conversejs .minimized-chats-flyout.minimized{height:auto}#conversejs .minimized-chats-flyout .chat-head,#conversejs .minimized-chats-flyout .chat-head-chatroom{border-radius:4px;width:130px;height:25px;margin-bottom:1px}#conversejs .chatbox .box-flyout{width:200px}#conversejs .chatroom .box-flyout{width:300px}#conversejs .dragresize{position:absolute;width:200px;height:5px;background:0 0;border:0;top:0;margin-left:0;cursor:n-resize;z-index:20} */@font-face{font-family:Converse-js;src:url(../fonticons/fonts/icomoon.eot?7poj4t);src:url(../fonticons/fonts/icomoon.eot?#iefix7poj4t) format('embedded-opentype'),url(../fonticons/fonts/icomoon.woff?7poj4t) format('woff'),url(../fonticons/fonts/icomoon.ttf?7poj4t) format('truetype'),url(../fonticons/fonts/icomoon.svg?7poj4t#icomoon) format('svg');font-weight:400;font-style:normal}#conversejs [data-icon]:before{font-family:Converse-js;content:attr(data-icon);speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#conversejs [class*=" icon-"],#conversejs [class^=icon-]{font-family:Converse-js;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.icon-closed:before{content:"\25ba"}.icon-opened:before{content:"\25bc"}.icon-checkmark:before{content:"\2713"}#conversejs .icon-home:before{content:"\e000"}#conversejs .icon-pencil:before{content:"\270e"}#conversejs .icon-camera:before{content:"\e003"}#conversejs .icon-camera-2:before{content:"\2616"}#conversejs .icon-play:before{content:"\25d9"}#conversejs .icon-music:before{content:"\266b"}#conversejs .icon-headphones:before{content:"\266c"}#conversejs .icon-phone:before{content:"\260f"}#conversejs .icon-phone-hang-up:before{content:"\260e"}#conversejs .icon-address-book:before{content:"\270f"}#conversejs .icon-notebook:before{content:"\2710"}#conversejs .icon-envelop:before{content:"\2709"}#conversejs .icon-pushpin:before{content:"\e012"}#conversejs .icon-online:before{content:"\25fc"}#conversejs .icon-away:before{content:"\25fb"}#conversejs .icon-bubbles:before{content:"\e015"}#conversejs .icon-bubbles-2:before{content:"\e016"}#conversejs .icon-bubbles-3:before{content:"\e017"}#conversejs .icon-user:before{content:"\e01a"}#conversejs .icon-users:before{content:"\e01b"}#conversejs .icon-quotes-left:before{content:"\e01d"}#conversejs .icon-spinner:before{content:"\231b"}#conversejs .icon-search:before{content:"\e021"}#conversejs .icon-cogs:before{content:"\e022"}#conversejs .icon-wrench:before{content:"\e024"}#conversejs .icon-unlocked:before{content:"\e025"}#conversejs .icon-lock:before{content:"\e026"}#conversejs .icon-lock-2:before{content:"\e027"}#conversejs .icon-key:before{content:"\e028"}#conversejs .icon-key-2:before{content:"\e029"}#conversejs .icon-zoom-out:before{content:"\e02a"}#conversejs .icon-zoom-in:before{content:"\e02b"}#conversejs .icon-cog:before{content:"\e02f"}#conversejs .icon-remove:before{content:"\e02d"}#conversejs .icon-remove-2:before{content:"\e02e"}#conversejs .icon-eye:before{content:"\e030"}#conversejs .icon-eye-blocked:before{content:"\e031"}#conversejs .icon-attachment:before{content:"\e032"}#conversejs .icon-globe:before{content:"\e033"}#conversejs .icon-heart:before{content:"\2764"}#conversejs .icon-happy:before{content:"\263b"}#conversejs .icon-thumbs-up:before{content:"\261d"}#conversejs .icon-smiley:before{content:"\263a"}#conversejs .icon-tongue:before{content:"\e038"}#conversejs .icon-sad:before{content:"\2639"}#conversejs .icon-wink:before{content:"\e03a"}#conversejs .icon-wondering:before{content:"\2369"}#conversejs .icon-confused:before{content:"\2368"}#conversejs .icon-shocked:before{content:"\2364"}#conversejs .icon-evil:before{content:"\261f"}#conversejs .icon-angry:before{content:"\e03f"}#conversejs .icon-cool:before{content:"\e040"}#conversejs .icon-grin:before{content:"\e041"}#conversejs .icon-info:before{content:"\2360"}#conversejs .icon-notification:before{content:"\e01f"}#conversejs .icon-warning:before{content:"\26a0"}#conversejs .icon-spell-check:before{content:"\e045"}#conversejs .icon-volume-high:before{content:"\e046"}#conversejs .icon-volume-medium:before{content:"\e047"}#conversejs .icon-volume-low:before{content:"\e048"}#conversejs .icon-volume-mute:before{content:"\e049"}#conversejs .icon-volume-mute-2:before{content:"\e04a"}#conversejs .icon-volume-decrease:before{content:"\e04b"}#conversejs .icon-volume-increase:before{content:"\e04c"}#conversejs .icon-bold:before{content:"\e04d"}#conversejs .icon-underline:before{content:"\e04e"}#conversejs .icon-italic:before{content:"\e04f"}#conversejs .icon-strikethrough:before{content:"\e050"}#conversejs .icon-new-tab:before{content:"\e053"}#conversejs .icon-youtube:before{content:"\e055"}#conversejs .icon-close:before{content:"\2715"}#conversejs .icon-blocked:before{content:"\2718"}#conversejs .icon-cancel-circle:before{content:"\e058"}#conversejs .icon-minus:before{content:"\e05a"}#conversejs .icon-plus:before{content:"\271a"}#conversejs .icon-checkbox-checked:before{content:"\2611"}#conversejs .icon-checkbox-unchecked:before{content:"\2b27"}#conversejs .icon-checkbox-partial:before{content:"\2b28"}#conversejs .icon-radio-checked:before{content:"\2b26"}#conversejs .icon-radio-unchecked:before{content:"\2b25"}#conversejs .icon-room-info:before{content:"\e059"}#conversejs .icon-newspaper:before{content:"\e001"}#conversejs .icon-image:before{content:"\2b14"}#conversejs .icon-offline:before,#conversejs .icon-unavailable:before,#conversejs .icon-xa:before{content:"\e002"}#conversejs .icon-dnd:before{content:"\e004"}#conversejs .no-text-select{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:-moz-none;-ms-user-select:none;user-select:none}#conversejs{bottom:0;direction:ltr;height:25px;left:0;position:fixed;right:0;z-index:30;display:block;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}#conversejs div{box-sizing:border-box}#conversejs ul li{height:auto}#conversejs a,#conversejs article,#conversejs aside,#conversejs audio,#conversejs blockquote,#conversejs canvas,#conversejs caption,#conversejs dd,#conversejs details,#conversejs div,#conversejs dl,#conversejs dt,#conversejs em,#conversejs embed,#conversejs fieldset,#conversejs figcaption,#conversejs figure,#conversejs footer,#conversejs form,#conversejs h1,#conversejs h2,#conversejs h3,#conversejs h4,#conversejs h5,#conversejs h6,#conversejs header,#conversejs hgroup,#conversejs img,#conversejs label,#conversejs legend,#conversejs li,#conversejs mark,#conversejs menu,#conversejs nav,#conversejs ol,#conversejs output,#conversejs p,#conversejs pre,#conversejs ruby,#conversejs section,#conversejs span,#conversejs strong,#conversejs summary,#conversejs table,#conversejs tbody,#conversejs td,#conversejs tfoot,#conversejs th,#conversejs thead,#conversejs time,#conversejs tr,#conversejs ul,#conversejs video{margin:0;padding:0;border:0;font:inherit;vertical-align:baseline}#conversejs,#conversejs input,#conversejs textarea{font-size:14px;color:#4f4f4f}#conversejs ol,#conversejs ul{list-style:none}#conversejs li{height:10px}#conversejs a{text-decoration:none;color:#2D617A;text-shadow:none}#conversejs dl,#conversejs ol,#conversejs ul{font:inherit;margin:0 0 15px}#conversejs .emoticon{font-size:14px}#conversejs .hidden{display:none}#conversejs .locked{padding-right:22px}@-moz-keyframes spin{0%{-moz-transform:rotate(0deg)}100%{-moz-transform:rotate(359deg)}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg)}}@-o-keyframes spin{0%{-o-transform:rotate(0deg)}100%{-o-transform:rotate(359deg)}}@keyframes spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}span.spinner:before{font-size:24px;font-family:Converse-js!important;content:"\231b"}span.spinner{-webkit-animation:spin 2s infinite linear;-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;animation:spin 2s infinite linear;width:100%;display:block;text-align:center}span.spinner.centered{text-align:center;padding-top:5em}span.spinner.hor_centered{text-align:center}#conversejs #minimized-chats .box-flyout{position:absolute;display:block;height:auto;bottom:25px;margin-left:0}#conversejs #minimized-chats .box-flyout .chat-head{font-size:100%;border-radius:4px;padding:3px 0 0 5px;margin:0 0 1px;box-shadow:1px 3px 5px 3px rgba(0,0,0,.4);height:24px;width:130px}#conversejs #minimized-chats,#conversejs .toggle-controlbox{float:right;font-size:90%;border-top-right-radius:2px;border-top-left-radius:2px;background-color:#F4F4F4;padding:4px 8px;margin-right:5px;color:#0a0a0a;font-weight:700;height:100%}#conversejs #minimized-chats{width:130px;padding:0;display:none}#conversejs #toggle-minimized-chats{position:relative;padding:4px 0 0 4px;display:block;width:100%;height:100%;color:#0f0f0f}#conversejs #toggle-minimized-chats .unread-message-count{right:5px;bottom:5px}#conversejs .toggle-controlbox,#conversejs .toggle-minimized-chats{float:right;font-size:85%;border-top-right-radius:4px;border-top-left-radius:4px;background-color:#5390c8;padding:4px 8px;margin-right:5px;color:#fff}#conversejs .chat-head{color:#fff;font-size:100%;border-top-right-radius:4px;border-top-left-radius:4px;padding:2px 2px 2px 4px;margin:0}#conversejs .chat-head-chatbox{background-color:#2D617A}#conversejs .chat-head-chatroom{background-color:#0F592F}#conversejs .chat-body{background-color:#fff;border-bottom-right-radius:4px;border-bottom-left-radius:4px;height:289px;height:calc(100% - 35px);border-top:0}#conversejs .chatroom .chat-area{float:left;width:200px;height:100%}#conversejs .chatroom .participants{float:left;background-color:#fff;overflow:auto;border-left:1px solid #AAA;width:100px;border-bottom-right-radius:4px;height:100%}#conversejs .participants ul.participant-list li{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block;font-size:12px;font-weight:700;padding:.5em 0 0 .5em;cursor:default}#conversejs ul.participant-list li.moderator{color:#8f2831}#conversejs .chatroom .participant-list{list-style:none}#conversejs .chat-blink{background-color:#176679;border-right:1px solid #176679;border-left:1px solid #176679}#conversejs .chat-content{position:relative;padding:4px;font-size:13px;color:#4f4f4f;overflow-y:auto;border:0;background-color:#fff;line-height:1.3em;box-sizing:border-box;-moz-box-sizing:border-box;height:206px;height:calc(100% - 84px)}#conversejs .chat-error{color:#8f2831}#conversejs .chat-message-me,#conversejs .chat-message-room,#conversejs .chat-message-them{font-weight:700;white-space:nowrap;max-width:100px;text-overflow:ellipsis;overflow:hidden;display:inline-block;float:left;padding-right:3px}#conversejs .chat-message-content{word-wrap:break-word}#conversejs .chat-message-them{color:#8f2831}#conversejs .chat-message-me{color:#2D617A}#conversejs .chat-message-room{color:#4B7003}#conversejs .chat-date,#conversejs .chat-event,#conversejs .chat-info{color:gray}#conversejs li.chat-info{padding-left:10px}#conversejs .chat-date{display:inline-block;padding-top:10px}#conversejs p.not-implemented{margin-top:3em;margin-left:.3em;color:gray}#conversejs div.delayed .chat-message-them{color:#FB5D50}#conversejs div.delayed .chat-message-me{color:#7EABBB}input.error{border:1px solid red}#conversejs .conn-feedback.error{color:red}#converse-login .conn-feedback{width:100%;text-align:center;display:block}#conversejs .chat-message-error{color:#76797C;font-size:90%;font-weight:400}#conversejs .chat-head .avatar{float:left;margin-right:6px}#conversejs .chat-title,#conversejs .restore-chat{padding:1px 0;color:#fff;font-weight:700;line-height:15px;display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-shadow:rgba(0,0,0,.51)0 -1px 0}#conversejs .chat-title a{color:#fff;width:100%;text-overflow:ellipsis;white-space:nowrap}#conversejs .chat-head-chatbox,#conversejs .chat-head-chatroom{height:35px;position:relative}#conversejs p.chatroom-topic,#conversejs p.user-custom-message{font-size:80%;font-style:italic;height:1.3em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin:0;padding:1px 0}#conversejs div.chat-head-chatbox a.user-custom-message{color:#fff}#conversejs .activated{display:block!important}#conversejs a.subscribe-to-user{padding-left:2em;font-weight:700}dl.add-converse-contact{margin:0 0 0 .5em}#conversejs .fancy-dropdown{border:1px solid #ddd;height:22px}#conversejs .fancy-dropdown a.choose-xmpp-status{width:155px}#conversejs .fancy-dropdown a.choose-xmpp-status,#conversejs .fancy-dropdown a.toggle-xmpp-contact-form{text-shadow:0 1px 0 #fff;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:inline}#conversejs .fancy-dropdown a.toggle-xmpp-contact-form span{float:left}#conversejs .choose-xmpp-status span{padding-right:5px;padding-left:5px;float:left}#conversejs #fancy-xmpp-status-select a.change-xmpp-status-message{float:right;clear:right;height:22px;width:12px;padding:0 15px 0 0;color:#4f4f4f}#conversejs ul#found-users{padding:10px 0 5px 5px;border:0}#conversejs form.search-xmpp-contact{margin:0;padding:0 0 5px 5px}#conversejs form.search-xmpp-contact input{width:8em}#conversejs .controlbox-head{margin:0;color:#FFF;border-top-right-radius:4px;border-top-left-radius:4px;height:35px;clear:right;background-color:#2D617A;padding:3px 0 0}#conversejs .chat-head-message-count,#conversejs .unread-message-count{font-weight:700;background:-webkit-gradient(linear,left top,left bottom,color-stop(0.35,#f6f6f6),color-stop(1,gray));background:-moz-linear-gradient(center top,#ff0 5%,#f6f6f6 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='yellow', endColorstr='#f6f6f6');border:1px solid;text-shadow:1px 1px 0 #ccc;color:#8b0000;border-radius:5px;padding:2px 4px;font-size:15px;text-align:center;position:absolute;right:22px;bottom:1px}#conversejs a.close-chatbox-button,#conversejs a.configure-chatroom-button,#conversejs a.toggle-chatbox-button{font-size:10px;padding:3px 3px 2px;margin-right:3px;cursor:pointer;border-radius:6px;border:1px solid #888;display:inline-block;color:#fff;text-decoration:none;float:right}#conversejs a.close-chatbox-button:active,#conversejs a.configure-chatroom-button:active,#conversejs a.toggle-chatbox-button:active{position:relative;top:1px}#conversejs .controlbox-pane dt{padding-bottom:3px}#conversejs .chatroom-form-container{height:100%;color:#666;overflow-y:auto;border-bottom-right-radius:4px;border-bottom-left-radius:4px}#conversejs .chatroom-form{background:#fff;font-size:12px;padding:10px 5px}#conversejs .chat-body p{font-size:14px;color:#666;padding:5px;margin:0}#conversejs .chatroom-form legend{font-size:14px;font-weight:700;margin-bottom:5px}#conversejs .chatroom-form label{font-weight:700;display:block;clear:both}#conversejs .chatroom-form label input,#conversejs .chatroom-form label select{float:right}#converse-roster dd.odd{background-color:#DCEAC5}#converse-roster dd.current-xmpp-contact span{font-size:16px;float:left;color:#4f4f4f}#conversejs .requesting-xmpp-contact .request-actions{margin-left:.5em;float:right}#converse-roster dd a,#converse-roster dd span{text-shadow:0 1px 0 #fafafa;display:inline-block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}#converse-roster span.req-contact-name{width:65%}#converse-roster a.open-chat,#converse-roster span.pending-contact-name{width:80%}#converse-roster dd span{padding:0 5px 0 0}#converse-roster{width:100%;position:relative;margin:.5em 0 0;height:194px;height:calc(100% - 25px);overflow-x:hidden}#converse-roster .roster-filter{padding:0;margin:0 0 5px .5em;width:111px;height:20px;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAABNSURBVHjaXI7BDcAwCAMvyQjMyQ6dAbZiKfqoUK34g2zJh1dENIC7M8pMAPYdzAVY3d0ajNz9aypS/b5R6o+ZPdqoKgCq6h80KH3xDgBqNR97p8oAGQAAAABJRU5ErkJggg==) no-repeat right -20px center;border:1px solid #999;display:inline-block}#converse-roster .filter-type{height:20px;padding:0;margin:0 0 0 -5px}#converse-roster .roster-filter.x{background-position:right 3px center}#converse-roster .roster-filter.onX{cursor:pointer}#converse-roster .roster-contacts{margin:0;overflow-y:auto;overflow-x:hidden;max-height:195px;max-height:calc(100% - 67px)}#converse-roster .group-toggle{color:#666}#conversejs dd.available-chatroom{overflow-x:hidden;text-overflow:ellipsis;white-space:nowrap}#conversejs dd.available-chatroom a.open-room{width:148px}#available-chatrooms dt,#converse-roster dt{font-weight:400;font-size:13px;color:#666;border:none;padding:.3em 0 0 .5em;text-shadow:0 1px 0 #fafafa}#converse-roster dt{display:none}#conversejs .room-info{font-size:11px;font-style:normal;font-weight:400}#conversejs li.room-info{display:block;margin-left:5px}#conversejs div.room-info{clear:left}#conversejs p.room-info{margin:0;padding:0;display:block;white-space:normal}#conversejs a.room-info{width:22px;height:22px;float:right;display:none;clear:right}#conversejs a.open-room{float:left;white-space:nowrap;text-overflow:ellipsis;overflow-x:hidden}#conversejs dd.available-chatroom:hover a.room-info{display:inline-block;margin-top:3px;font-size:15px}#conversejs #converse-roster dd,#conversejs dd.available-chatroom{font-weight:700;border:none;display:block;padding:1px 0 0 .5em;color:#666;text-shadow:0 1px 0 #fafafa;clear:both}#converse-roster dd{line-height:16px}#conversejs .group-toggle{display:block;width:100%}#converse-roster dd:hover,#conversejs .roster-group:hover,#conversejs dd.available-chatroom:hover{background-color:#eee}#converse-roster dd a.decline-xmpp-request{margin-left:5px}#converse-roster dd a.remove-xmpp-contact{float:right;width:22px;margin:0;display:none;color:#4f4f4f}#converse-roster dd:hover a.remove-xmpp-contact{display:inline-block}#conversejs .chatbox,#conversejs .chatroom{height:25px;float:right;margin-right:15px;display:block}#conversejs .chatbox{width:200px}#conversejs .chatroom{width:300px}#conversejs .controlbox-pane{padding:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}#conversejs .controlbox-pane dd{margin-left:0;margin-bottom:0;padding:1em}#conversejs .controlbox-pane dd.odd{background-color:#DCEAC5}#conversejs form#converse-login{background:#fff;padding:2em .5em}#conversejs form#converse-login input{width:100%}#conversejs form#converse-login label{margin-top:.5em}#conversejs form#converse-login .login-submit{margin-top:1em}#conversejs form.set-xmpp-status{background:0 0;margin:none;padding:none}#conversejs form.add-chatroom{background:0 0;padding:3px}#conversejs form.add-chatroom input[type=text]{width:95%;margin:3px}#conversejs form.add-chatroom input[type=button],#conversejs form.add-chatroom input[type=submit]{width:48%}select#select-xmpp-status{float:right;margin-right:.5em}#conversejs .chat-head #controlbox-tabs{text-align:center;display:inline;overflow:hidden;font-size:12px;list-style-type:none}#conversejs .chat-head #controlbox-tabs li{float:left;list-style:none;padding-left:0;text-shadow:#fff 0 1px 0;width:38%}#conversejs ul#controlbox-tabs li a{display:block;font-size:12px;height:34px;line-height:34px;margin:0;text-align:center;text-decoration:none;border-top-right-radius:4px;border-top-left-radius:4px;color:#666;text-shadow:0 1px 0 #fafafa}#conversejs .chat-head #controlbox-tabs li a:hover{color:#000}#conversejs .chat-head #controlbox-tabs li a{background-color:#fff;box-shadow:inset 0 4px 12px rgba(0,0,0,.3);border-bottom:1px solid #CCC}#conversejs ul#controlbox-tabs a.current,#conversejs ul#controlbox-tabs a.current:hover{box-shadow:none;border-bottom:0;height:35px;cursor:default;color:#666}#conversejs div#chatrooms,#conversejs div#login-dialog,#conversejs div#settings,#conversejs div#users{border:0;font-size:14px;background-color:#fff;border-bottom-right-radius:4px;border-bottom-left-radius:4px;width:100%;height:289px;height:calc(100% - 35px);overflow-y:hidden;position:absolute}#conversejs div#chatrooms{overflow-y:auto}#conversejs form.sendXMPPMessage{background:#fff;border:0;border-top:1px solid #BBB;padding:0;margin:0;position:relative;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-moz-background-clip:padding;-webkit-background-clip:padding-box;background-clip:padding-box;border-top-left-radius:0;border-top-right-radius:0;width:200px}#conversejs .chatroom form.sendXMPPMessage{-webkit-border-bottom-right-radius:0;border-bottom-right-radius:0}#conversejs .chat-textarea{box-sizing:border-box;-moz-box-sizing:border-box;border:0;width:100%;padding:3px;border-bottom-left-radius:4px;border-bottom-right-radius:4px;resize:none;height:59px}#conversejs .chatroom .chat-textarea{border-bottom-right-radius:0}#conversejs ul.chat-toolbar{font-size:14px;margin:0;padding:0 5px 0 0;height:20px;display:block;width:195px}#conversejs .chat-toolbar .toggle-clear,#conversejs .chat-toolbar .toggle-otr{float:right}#conversejs .chat-toolbar a{color:#4f4f4f}#conversejs .chat-toolbar ul li a:hover{color:#8f2831}#conversejs .chat-toolbar ul{display:none;font-size:12px;position:absolute;bottom:100%;margin-bottom:1px;right:0;background:#fff;box-shadow:0 -1px 2px 0 rgba(0,0,0,.4)}#conversejs .chat-toolbar ul li{position:relative;list-style:none;cursor:pointer}#conversejs .chat-toolbar .toggle-smiley{padding-left:5px}#conversejs .chat-toolbar .toggle-smiley ul li{font-size:14px;padding:5px;z-index:98}#conversejs .chat-toolbar .toggle-otr ul li{background-color:#fff;display:block;z-index:99}#conversejs .chat-toolbar ul li:hover{background-color:#eee}#conversejs .chat-toolbar .toggle-otr ul li a{transition:background-color .2s ease-in-out;-webkit-transition:background-color .2s ease-in-out;-moz-transition:background-color .2s ease-in-out;display:block;padding:1px;text-decoration:none}#conversejs .chat-toolbar-text{font-size:12px;padding-right:3px}#conversejs .unencrypted,#conversejs .unencrypted a{color:#8f2831}#conversejs .unverified,#conversejs .unverified a{color:#cf5300}#conversejs .private,#conversejs .private a{color:#4b7003}#conversejs ul.chat-toolbar li{display:inline-block;list-style:none;padding:0 3px;cursor:pointer;margin-top:1px}#conversejs ul.chat-toolbar li:hover{cursor:pointer}#conversejs form#set-custom-xmpp-status{float:left;padding:0}#conversejs .chat-textarea-chatbox-selected{border:1px solid #578308;margin:0}#conversejs .chat-textarea-chatroom-selected{border:2px solid #2D617A;margin:0}#conversejs #set-custom-xmpp-status button{padding:1px 2px 1px 1px}#conversejs #controlbox{display:none}#conversejs #controlbox div.xmpp-status{display:inline}#conversejs .chatbox dl.dropdown{margin:.5em;background-color:#f0f0f0}#conversejs .chatbox .dropdown dd,#conversejs .dropdown dt,#conversejs .dropdown ul{margin:0;padding:0}#conversejs .chatbox .dropdown dd{position:relative}input.custom-xmpp-status{width:124px}#conversejs form.add-xmpp-contact{background:0 0;padding:5px}#conversejs form.add-xmpp-contact input{width:108px}#conversejs .chatbox .dropdown dt a span{cursor:pointer;display:block;padding:4px 7px 0 5px;color:#4f4f4f}#conversejs .chatbox .dropdown dd ul{padding:5px 0;list-style:none;position:absolute;left:0;top:0;border:1px solid #ddd;border-top:0;width:99%;z-index:21;background-color:#f0f0f0}#conversejs .chatbox .dropdown li{list-style:none;padding-left:0}#conversejs .chatbox .dropdown a{height:22px;width:148px;display:inline-block;line-height:24px}#conversejs .chatbox .dropdown dd ul li:hover,#conversejs .chatbox .dropdown dd.search-xmpp ul li:hover{background-color:#bed6e5}#conversejs .xmpp-status-menu li a{width:100%}#conversejs .xmpp-status-menu li a span{padding:0 5px;color:#4f4f4f}#conversejs .set-xmpp-status .dropdown dd ul{z-index:22}#conversejs .box-flyout,#conversejs .minimized-chats-flyout{border-radius:4px;bottom:6px;box-shadow:1px 3px 5px 3px rgba(0,0,0,.4);display:block;height:324px;position:absolute}#conversejs .minimized-chats-flyout{border-radius:4px;bottom:25px;box-shadow:1px 3px 5px 3px rgba(0,0,0,.4);display:block;position:absolute;height:auto;width:130px}#conversejs .minimized-chats-flyout.minimized{height:auto}#conversejs .minimized-chats-flyout .chat-head,#conversejs .minimized-chats-flyout .chat-head-chatroom{border-radius:4px;width:130px;height:25px;margin-bottom:1px}#conversejs .chatbox .box-flyout{width:200px}#conversejs .chatroom .box-flyout{width:300px}#conversejs .dragresize{position:absolute;width:200px;height:5px;background:0 0;border:0;top:0;margin-left:0;cursor:n-resize;z-index:20}
\ No newline at end of file \ No newline at end of file
Changelog Changelog
========= =========
0.8 (2014-08-04) 0.8.1 (Unreleased)
---------------- ------------------
* #212 Provide a live filter of the roster contacts. [jcbrand]
0.8.0 (2014-08-04)
------------------
.. note:: .. note::
1. Converse.js is now relicensed under the `Mozilla Public License <http://www.mozilla.org/MPL/2.0/>`_. 1. Converse.js is now relicensed under the `Mozilla Public License <http://www.mozilla.org/MPL/2.0/>`_.
......
...@@ -11,14 +11,8 @@ ...@@ -11,14 +11,8 @@
<link type="text/css" rel="stylesheet" media="screen" href="components/bootstrap/dist/css/bootstrap.min.css" /> <link type="text/css" rel="stylesheet" media="screen" href="components/bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" media="screen" href="components/fontawesome/css/font-awesome.min.css" /> <link type="text/css" rel="stylesheet" media="screen" href="components/fontawesome/css/font-awesome.min.css" />
<link type="text/css" rel="stylesheet" media="screen" href="css/theme.css" /> <link type="text/css" rel="stylesheet" media="screen" href="css/theme.css" />
<link type="text/css" rel="stylesheet" media="screen" href="css/converse.min.css" /> <link type="text/css" rel="stylesheet" media="screen" href="css/converse.css" />
<!-- Only for development: <script data-main="main" src="components/requirejs/require.js"></script> --> <script data-main="main" src="components/requirejs/require.js"></script>
<![if gte IE 9]>
<script src="builds/converse.website.min.js"></script>
<![endif]>
<!--[if lt IE 9]>
<script src="builds/converse.website-no-otr.min.js"></script>
<![endif]-->
</head> </head>
<body id="page-top" data-spy="scroll" data-target=".navbar-custom"> <body id="page-top" data-spy="scroll" data-target=".navbar-custom">
......
...@@ -831,7 +831,7 @@ dl.add-converse-contact { ...@@ -831,7 +831,7 @@ dl.add-converse-contact {
clear: right; clear: right;
height: 22px; height: 22px;
width: 12px; width: 12px;
padding: 0px 5px 0 0; padding: 0px 15px 0 0;
color: rgb(79, 79, 79); color: rgb(79, 79, 79);
} }
...@@ -902,7 +902,7 @@ dl.add-converse-contact { ...@@ -902,7 +902,7 @@ dl.add-converse-contact {
} }
#conversejs .controlbox-pane dt { #conversejs .controlbox-pane dt {
padding: 3px; padding-bottom: 3px;
} }
#conversejs .chatroom-form-container { #conversejs .chatroom-form-container {
...@@ -967,12 +967,12 @@ dl.add-converse-contact { ...@@ -967,12 +967,12 @@ dl.add-converse-contact {
text-overflow: ellipsis; text-overflow: ellipsis;
} }
#conversejs #converse-roster span.req-contact-name { #converse-roster span.req-contact-name {
width: 65%; width: 65%;
} }
#conversejs #converse-roster span.pending-contact-name, #converse-roster span.pending-contact-name,
#conversejs #converse-roster a.open-chat { #converse-roster a.open-chat {
width: 80%; width: 80%;
} }
...@@ -981,13 +981,46 @@ dl.add-converse-contact { ...@@ -981,13 +981,46 @@ dl.add-converse-contact {
} }
#converse-roster { #converse-roster {
overflow-y: auto;
overflow-x: hidden;
width: 100%; width: 100%;
position: relative; position: relative;
margin: 0.5em 0 0 0; margin: 0.5em 0 0 0;
height: 254px; height: 194px;
height: ~"calc(100% - 70px)"; height: ~"calc(100% - 25px)";
overflow-x: hidden;
}
#converse-roster .roster-filter {
padding: 0;
margin: 0 0 5px 0.5em;
width: 111px;
height: 20px;
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAABNSURBVHjaXI7BDcAwCAMvyQjMyQ6dAbZiKfqoUK34g2zJh1dENIC7M8pMAPYdzAVY3d0ajNz9aypS/b5R6o+ZPdqoKgCq6h80KH3xDgBqNR97p8oAGQAAAABJRU5ErkJggg== ) no-repeat right -20px center;
border: 1px solid #999;
display: inline-block;
}
#converse-roster .filter-type {
height: 20px;
padding: 0;
margin: 0 0 0 -5px;
}
/* (jQ addClass:) if input has value: */
#converse-roster .roster-filter.x {
background-position: right 3px center;
}
/* (jQ addClass:) if mouse is over the 'x' input area*/
#converse-roster .roster-filter.onX{
cursor:pointer;
}
#converse-roster .roster-contacts {
margin: 0;
overflow-y: auto;
overflow-x: hidden;
max-height: 195px;
max-height: ~"calc(100% - 67px)";
} }
#converse-roster .group-toggle { #converse-roster .group-toggle {
...@@ -1073,7 +1106,7 @@ dl.add-converse-contact { ...@@ -1073,7 +1106,7 @@ dl.add-converse-contact {
clear: both; clear: both;
} }
#conversejs #converse-roster dd { #converse-roster dd {
line-height: 16px; line-height: 16px;
} }
...@@ -1084,15 +1117,15 @@ dl.add-converse-contact { ...@@ -1084,15 +1117,15 @@ dl.add-converse-contact {
#conversejs .roster-group:hover, #conversejs .roster-group:hover,
#conversejs dd.available-chatroom:hover, #conversejs dd.available-chatroom:hover,
#conversejs #converse-roster dd:hover { #converse-roster dd:hover {
background-color: #eee; background-color: #eee;
} }
#conversejs #converse-roster dd a.decline-xmpp-request { #converse-roster dd a.decline-xmpp-request {
margin-left: 5px; margin-left: 5px;
} }
#conversejs #converse-roster dd a.remove-xmpp-contact { #converse-roster dd a.remove-xmpp-contact {
float: right; float: right;
width: 22px; width: 22px;
margin: 0; margin: 0;
...@@ -1100,7 +1133,7 @@ dl.add-converse-contact { ...@@ -1100,7 +1133,7 @@ dl.add-converse-contact {
color: rgb(79, 79, 79); color: rgb(79, 79, 79);
} }
#conversejs #converse-roster dd:hover a.remove-xmpp-contact { #converse-roster dd:hover a.remove-xmpp-contact {
display: inline-block; display: inline-block;
} }
......
...@@ -4,6 +4,7 @@ config = { ...@@ -4,6 +4,7 @@ config = {
"jquery": "components/jquery/dist/jquery", "jquery": "components/jquery/dist/jquery",
"jquery.browser": "components/jquery.browser/dist/jquery.browser", "jquery.browser": "components/jquery.browser/dist/jquery.browser",
"jquery.easing": "components/jquery-easing-original/jquery.easing.1.3", // XXX: Only required for https://conversejs.org website "jquery.easing": "components/jquery-easing-original/jquery.easing.1.3", // XXX: Only required for https://conversejs.org website
"utils": "src/utils",
"bootstrap": "components/bootstrap/dist/js/bootstrap", // XXX: Only required for https://conversejs.org website "bootstrap": "components/bootstrap/dist/js/bootstrap", // XXX: Only required for https://conversejs.org website
"locales": "locale/locales", "locales": "locale/locales",
"underscore": "components/underscore/underscore", "underscore": "components/underscore/underscore",
...@@ -74,6 +75,7 @@ config = { ...@@ -74,6 +75,7 @@ config = {
'bigint': { deps: ['crypto'] }, 'bigint': { deps: ['crypto'] },
'jquery.browser': { deps: ['jquery'] }, 'jquery.browser': { deps: ['jquery'] },
'jquery.easing': { deps: ['jquery'] }, 'jquery.easing': { deps: ['jquery'] },
'utils': { deps: ['jquery'] },
'strophe': { deps: ['jquery'] }, 'strophe': { deps: ['jquery'] },
'strophe.disco': { deps: ['strophe'] }, 'strophe.disco': { deps: ['strophe'] },
'strophe.muc': { deps: ['strophe', 'jquery'] }, 'strophe.muc': { deps: ['strophe', 'jquery'] },
......
...@@ -114,139 +114,146 @@ ...@@ -114,139 +114,146 @@
</ul> </ul>
</dd> </dd>
</dl> </dl>
<dl id="converse-roster" style="display: block;"> <div id="converse-roster">
<dt class="roster-group" style="display: block;"> <input class="roster-filter" placeholder="Type to filter">
<a href="#" data-group="Colleagues" class="group-toggle icon-opened" title="Click to hide these contacts">Colleagues</a> <select class="filter-type">
</dt> <option value="contacts">Contacts</option>
<dd class="online current-xmpp-contact"> <option value="groups">Groups</option>
<a class="open-chat" title="Click to chat with this contact" href="#"> </select>
<span class="icon-online" title="This contact is online"></span> <dl class="roster-contacts" style="display: block;">
Victor Matfield <dt class="roster-group" style="display: block;">
</a> <a href="#" data-group="Colleagues" class="group-toggle icon-opened" title="Click to hide these contacts">Colleagues</a>
<a class="remove-xmpp-contact icon-remove" title="Click to remove this contact" href="#"></a> </dt>
</dd> <dd class="online current-xmpp-contact">
<dd class="away current-xmpp-contact"> <a class="open-chat" title="Click to chat with this contact" href="#">
<a class="open-chat" title="Click to chat with this contact" href="#"> <span class="icon-online" title="This contact is online"></span>
<span class="icon-away" title="this contact is away"></span> Victor Matfield
William Winterbottom </a>
</a> <a class="remove-xmpp-contact icon-remove" title="Click to remove this contact" href="#"></a>
<a class="remove-xmpp-contact icon-remove" title="Click to remove this contact" href="#"></a> </dd>
</dd> <dd class="away current-xmpp-contact">
<dd class="dnd current-xmpp-contact"> <a class="open-chat" title="Click to chat with this contact" href="#">
<a class="open-chat" title="Click to chat with this contact" href="#"> <span class="icon-away" title="this contact is away"></span>
<span class="icon-dnd" title="This contact is busy"></span> William Winterbottom
Gary Teichmann </a>
</a> <a class="remove-xmpp-contact icon-remove" title="Click to remove this contact" href="#"></a>
<a class="remove-xmpp-contact icon-remove" title="Click to remove this contact" href="#"></a> </dd>
</dd> <dd class="dnd current-xmpp-contact">
<a class="open-chat" title="Click to chat with this contact" href="#">
<span class="icon-dnd" title="This contact is busy"></span>
Gary Teichmann
</a>
<a class="remove-xmpp-contact icon-remove" title="Click to remove this contact" href="#"></a>
</dd>
<dt class="roster-group" style="display: block;"> <dt class="roster-group" style="display: block;">
<a href="#" data-group="Family" class="group-toggle icon-opened" title="Click to hide these contacts">Family</a> <a href="#" data-group="Family" class="group-toggle icon-opened" title="Click to hide these contacts">Family</a>
</dt> </dt>
<dd class="away current-xmpp-contact"> <dd class="away current-xmpp-contact">
<a class="open-chat" title="Click to chat with this contact" href="#"> <a class="open-chat" title="Click to chat with this contact" href="#">
<span class="icon-away" title="this contact is away"></span> <span class="icon-away" title="this contact is away"></span>
Allan Donald Allan Donald
</a> </a>
<a class="remove-xmpp-contact icon-remove" title="Click to remove this contact" href="#"></a> <a class="remove-xmpp-contact icon-remove" title="Click to remove this contact" href="#"></a>
</dd> </dd>
<dd class="offline current-xmpp-contact"> <dd class="offline current-xmpp-contact">
<a class="open-chat" title="Click to chat with this contact" href="#"> <a class="open-chat" title="Click to chat with this contact" href="#">
<span class="icon-offline" title="This contact is offline"></span> <span class="icon-offline" title="This contact is offline"></span>
Corné Krige Corné Krige
</a> </a>
<a class="remove-xmpp-contact icon-remove" title="Click to remove this contact" href="#"></a> <a class="remove-xmpp-contact icon-remove" title="Click to remove this contact" href="#"></a>
</dd> </dd>
<dt class="roster-group" style="display: block;"> <dt class="roster-group" style="display: block;">
<a href="#" data-group="Friends" class="group-toggle icon-opened" title="Click to hide these contacts">Friends</a> <a href="#" data-group="Friends" class="group-toggle icon-opened" title="Click to hide these contacts">Friends</a>
</dt> </dt>
<dd class="online current-xmpp-contact"> <dd class="online current-xmpp-contact">
<a class="open-chat" title="Click to chat with this contact" href="#"> <a class="open-chat" title="Click to chat with this contact" href="#">
<span class="icon-online" title="This contact is online"></span> <span class="icon-online" title="This contact is online"></span>
John Smit John Smit
</a> </a>
<a class="remove-xmpp-contact icon-remove" title="Click to remove this contact" href="#"></a> <a class="remove-xmpp-contact icon-remove" title="Click to remove this contact" href="#"></a>
</dd> </dd>
<dd class="online current-xmpp-contact"> <dd class="online current-xmpp-contact">
<a class="open-chat" title="Click to chat with this contact" href="#"> <a class="open-chat" title="Click to chat with this contact" href="#">
<span class="icon-online" title="This contact is online"></span> <span class="icon-online" title="This contact is online"></span>
Bakkies Botha Bakkies Botha
</a> </a>
<a class="remove-xmpp-contact icon-remove" title="Click to remove this contact" href="#"></a> <a class="remove-xmpp-contact icon-remove" title="Click to remove this contact" href="#"></a>
</dd> </dd>
<dt class="roster-group" style="display: block;"> <dt class="roster-group" style="display: block;">
<a href="#" class="group-toggle icon-opened" title="Click to hide these contacts">Ungrouped</a> <a href="#" class="group-toggle icon-opened" title="Click to hide these contacts">Ungrouped</a>
</dt> </dt>
<dd class="online current-xmpp-contact"> <dd class="online current-xmpp-contact">
<a class="open-chat" title="Click to chat with this contact" href="#"> <a class="open-chat" title="Click to chat with this contact" href="#">
<span class="icon-online" title="This contact is online"></span> <span class="icon-online" title="This contact is online"></span>
James Small James Small
</a> </a>
<a class="remove-xmpp-contact icon-remove" title="Click to remove this contact" href="#"></a> <a class="remove-xmpp-contact icon-remove" title="Click to remove this contact" href="#"></a>
</dd> </dd>
<dt id="xmpp-contact-requests" style="display: block;"> <dt id="xmpp-contact-requests" style="display: block;">
<a href="#" class="group-toggle icon-opened" title="Click to hide these contacts">Contact Requests</a> <a href="#" class="group-toggle icon-opened" title="Click to hide these contacts">Contact Requests</a>
</dt> </dt>
<dd class="offline requesting-xmpp-contact"> <dd class="offline requesting-xmpp-contact">
<span class="req-contact-name">Bob Skinstad</span> <span class="req-contact-name">Bob Skinstad</span>
<span class="request-actions"> <span class="request-actions">
<a class="accept-xmpp-request icon-checkmark" title="Click here to accept this contact's request" href="#"></a> <a class="accept-xmpp-request icon-checkmark" title="Click here to accept this contact's request" href="#"></a>
<a class="decline-xmpp-request icon-close" title="Click here to decline this contact's request" href="#"></a> <a class="decline-xmpp-request icon-close" title="Click here to decline this contact's request" href="#"></a>
</span> </span>
</dd> </dd>
<dd class="offline requesting-xmpp-contact"> <dd class="offline requesting-xmpp-contact">
<span class="req-contact-name">André Vos</span> <span class="req-contact-name">André Vos</span>
<span class="request-actions"> <span class="request-actions">
<a class="accept-xmpp-request icon-checkmark" title="Click here to accept this contact's request" href="#"></a> <a class="accept-xmpp-request icon-checkmark" title="Click here to accept this contact's request" href="#"></a>
<a class="decline-xmpp-request icon-close" title="Click here to decline this contact's request" href="#"></a> <a class="decline-xmpp-request icon-close" title="Click here to decline this contact's request" href="#"></a>
</span> </span>
</dd> </dd>
<dt id="pending-xmpp-contacts" style="display: block;"> <dt id="pending-xmpp-contacts" style="display: block;">
<a href="#" class="group-toggle icon-opened" title="Click to hide these contacts">Pending Contacts</a> <a href="#" class="group-toggle icon-opened" title="Click to hide these contacts">Pending Contacts</a>
</dt> </dt>
<dd class="offline pending-xmpp-contact"><span class="pending-contact-name">Rassie Erasmus</span> <dd class="offline pending-xmpp-contact"><span class="pending-contact-name">Rassie Erasmus</span>
<a class="remove-xmpp-contact icon-remove" title="Click to remove this contact" href="#"></a> <a class="remove-xmpp-contact icon-remove" title="Click to remove this contact" href="#"></a>
</dd> </dd>
<dd class="offline pending-xmpp-contact"><span class="pending-contact-name">Victor Matfield</span> <dd class="offline pending-xmpp-contact"><span class="pending-contact-name">Victor Matfield</span>
<a class="remove-xmpp-contact icon-remove" title="Click to remove this contact" href="#"></a> <a class="remove-xmpp-contact icon-remove" title="Click to remove this contact" href="#"></a>
</dd> </dd>
</dl> </dl>
</div> </div>
<div id="chatrooms" style="display: none;"> <div id="chatrooms" style="display: none;">
<form class="add-chatroom" action="" method="post"> <form class="add-chatroom" action="" method="post">
<input type="text" name="chatroom" class="new-chatroom-name" placeholder="Room name"> <input type="text" name="chatroom" class="new-chatroom-name" placeholder="Room name">
<input type="text" name="nick" class="new-chatroom-nick" placeholder="Nickname"> <input type="text" name="nick" class="new-chatroom-nick" placeholder="Nickname">
<input type="text" name="server" class="new-chatroom-server" placeholder="Server"> <input type="text" name="server" class="new-chatroom-server" placeholder="Server">
<input type="submit" name="join" value="Join"> <input type="submit" name="join" value="Join">
<input type="button" name="show" id="show-rooms" value="Show rooms" style="display: inline-block;"> <input type="button" name="show" id="show-rooms" value="Show rooms" style="display: inline-block;">
</form> </form>
<dl id="available-chatrooms"> <dl id="available-chatrooms">
<dt>Rooms on conference.opkode.im</dt> <dt>Rooms on conference.opkode.im</dt>
<dd class="available-chatroom"> <dd class="available-chatroom">
<a class="open-room" <a class="open-room"
data-room-jid="converse.js@conference.opkode.im" data-room-jid="converse.js@conference.opkode.im"
title="Click to open this room" href="#">Special chatroom with a long name (2)</a> title="Click to open this room" href="#">Special chatroom with a long name (2)</a>
<a class="room-info icon-room-info" <a class="room-info icon-room-info"
data-room-jid="converse.js@conference.opkode.im" data-room-jid="converse.js@conference.opkode.im"
title="Show more information on this room" href="#">&nbsp;</a> title="Show more information on this room" href="#">&nbsp;</a>
<div class="room-info"> <div class="room-info">
<p class="room-info"><strong>Description:</strong></p> <p class="room-info"><strong>Description:</strong></p>
<p class="room-info"><strong>Occupants:</strong> 2</p> <p class="room-info"><strong>Occupants:</strong> 2</p>
<p class="room-info"><strong>Features:</strong> </p> <p class="room-info"><strong>Features:</strong> </p>
<ul> <ul>
<li class="room-info">Moderated</li><li class="room-info">Open room</li> <li class="room-info">Moderated</li><li class="room-info">Open room</li>
<li class="room-info">Permanent room</li><li class="room-info">Public</li> <li class="room-info">Permanent room</li><li class="room-info">Public</li>
<li class="room-info">Semi-anonymous</li> <li class="room-info">Semi-anonymous</li>
<li class="room-info">Requires authentication <span class="icon-lock"></span></li> <li class="room-info">Requires authentication <span class="icon-lock"></span></li>
<p></p> <p></p>
</ul> </ul>
</div> </div>
</dd> </dd>
</dl> </dl>
</div>
</div> </div>
</div> </div>
</div> </div>
......
...@@ -114,89 +114,146 @@ ...@@ -114,89 +114,146 @@
</ul> </ul>
</dd> </dd>
</dl> </dl>
<dl id="converse-roster" style="display: block;"> <div id="converse-roster">
<dt id="xmpp-contacts" style="display: block;">My contacts</dt> <input class="roster-filter" placeholder="Type to filter">
<dd class="online current-xmpp-contact"> <select class="filter-type">
<a class="open-chat" title="Click to chat with this contact" href="#"> <option value="contacts">Contacts</option>
<span class="icon-online" title="This contact is online"></span> <option value="groups">Groups</option>
John Smit</a> </select>
<a class="remove-xmpp-contact icon-remove" title="Click to remove this contact" href="#"></a> <dl class="roster-contacts" style="display: block;">
</dd> <dt class="roster-group" style="display: block;">
<dd class="away current-xmpp-contact"> <a href="#" data-group="Colleagues" class="group-toggle icon-opened" title="Click to hide these contacts">Colleagues</a>
<a class="open-chat" title="Click to chat with this contact" href="#"> </dt>
<span class="icon-away" title="this contact is away"></span> <dd class="online current-xmpp-contact">
Francois Pienaar</a> <a class="open-chat" title="Click to chat with this contact" href="#">
<a class="remove-xmpp-contact icon-remove" title="Click to remove this contact" href="#"></a> <span class="icon-online" title="This contact is online"></span>
</dd> Victor Matfield
<dd class="dnd current-xmpp-contact"> </a>
<a class="open-chat" title="Click to chat with this contact" href="#"> <a class="remove-xmpp-contact icon-remove" title="Click to remove this contact" href="#"></a>
<span class="icon-dnd" title="This contact is busy"></span> </dd>
Gary Teichmann</a> <dd class="away current-xmpp-contact">
<a class="remove-xmpp-contact icon-remove" title="Click to remove this contact" href="#"></a> <a class="open-chat" title="Click to chat with this contact" href="#">
</dd> <span class="icon-away" title="this contact is away"></span>
<dd class="offline current-xmpp-contact"> William Winterbottom
<a class="open-chat" title="Click to chat with this contact" href="#"> </a>
<span class="icon-offline" title="This contact is offline"></span> <a class="remove-xmpp-contact icon-remove" title="Click to remove this contact" href="#"></a>
Corné Krige</a> </dd>
<a class="remove-xmpp-contact icon-remove" title="Click to remove this contact" href="#"></a> <dd class="dnd current-xmpp-contact">
</dd> <a class="open-chat" title="Click to chat with this contact" href="#">
<span class="icon-dnd" title="This contact is busy"></span>
Gary Teichmann
</a>
<a class="remove-xmpp-contact icon-remove" title="Click to remove this contact" href="#"></a>
</dd>
<dt id="xmpp-contact-requests" style="display: block;">Contact requests</dt> <dt class="roster-group" style="display: block;">
<dd class="offline requesting-xmpp-contact"> <a href="#" data-group="Family" class="group-toggle icon-opened" title="Click to hide these contacts">Family</a>
<span>Bob Skinstad</span> </dt>
<span class="request-actions"> <dd class="away current-xmpp-contact">
<a class="accept-xmpp-request icon-checkmark" title="Click here to accept this contact's request" href="#"></a> <a class="open-chat" title="Click to chat with this contact" href="#">
<a class="decline-xmpp-request icon-close" title="Click here to decline this contact's request" href="#"></a> <span class="icon-away" title="this contact is away"></span>
</span> Allan Donald
</dd> </a>
<dd class="offline requesting-xmpp-contact"> <a class="remove-xmpp-contact icon-remove" title="Click to remove this contact" href="#"></a>
<span>André Vos</span> </dd>
<span class="request-actions"> <dd class="offline current-xmpp-contact">
<a class="accept-xmpp-request icon-checkmark" title="Click here to accept this contact's request" href="#"></a> <a class="open-chat" title="Click to chat with this contact" href="#">
<a class="decline-xmpp-request icon-close" title="Click here to decline this contact's request" href="#"></a> <span class="icon-offline" title="This contact is offline"></span>
</span> Corné Krige
</dd> </a>
<a class="remove-xmpp-contact icon-remove" title="Click to remove this contact" href="#"></a>
</dd>
<dt id="pending-xmpp-contacts" style="display: block;">Pending contacts</dt> <dt class="roster-group" style="display: block;">
<dd class="offline pending-xmpp-contact"><span>Rassie Erasmus</span> <a href="#" data-group="Friends" class="group-toggle icon-opened" title="Click to hide these contacts">Friends</a>
<a class="remove-xmpp-contact icon-remove" title="Click to remove this contact" href="#"></a> </dt>
</dd> <dd class="online current-xmpp-contact">
<dd class="offline pending-xmpp-contact"><span>Victor Matfield</span> <a class="open-chat" title="Click to chat with this contact" href="#">
<a class="remove-xmpp-contact icon-remove" title="Click to remove this contact" href="#"></a> <span class="icon-online" title="This contact is online"></span>
</dd> John Smit
</dl> </a>
</div> <a class="remove-xmpp-contact icon-remove" title="Click to remove this contact" href="#"></a>
<div id="chatrooms" style="display: none;"> </dd>
<form class="add-chatroom" action="" method="post"> <dd class="online current-xmpp-contact">
<input type="text" name="chatroom" class="new-chatroom-name" placeholder="Room name"> <a class="open-chat" title="Click to chat with this contact" href="#">
<input type="text" name="nick" class="new-chatroom-nick" placeholder="Nickname"> <span class="icon-online" title="This contact is online"></span>
<input type="text" name="server" class="new-chatroom-server" placeholder="Server"> Bakkies Botha
<input type="submit" name="join" value="Join"> </a>
<input type="button" name="show" id="show-rooms" value="Show rooms" style="display: inline-block;"> <a class="remove-xmpp-contact icon-remove" title="Click to remove this contact" href="#"></a>
</form> </dd>
<dl id="available-chatrooms">
<dt>Rooms on conference.opkode.im</dt> <dt class="roster-group" style="display: block;">
<dd class="available-chatroom"> <a href="#" class="group-toggle icon-opened" title="Click to hide these contacts">Ungrouped</a>
<a class="open-room" </dt>
data-room-jid="converse.js@conference.opkode.im" <dd class="online current-xmpp-contact">
title="Click to open this room" href="#">Special chatroom with a long name (2)</a> <a class="open-chat" title="Click to chat with this contact" href="#">
<a class="room-info icon-room-info" <span class="icon-online" title="This contact is online"></span>
data-room-jid="converse.js@conference.opkode.im" James Small
title="Show more information on this room" href="#">&nbsp;</a> </a>
<div class="room-info"> <a class="remove-xmpp-contact icon-remove" title="Click to remove this contact" href="#"></a>
<p class="room-info"><strong>Description:</strong></p> </dd>
<p class="room-info"><strong>Occupants:</strong> 2</p>
<p class="room-info"><strong>Features:</strong> </p> <dt id="xmpp-contact-requests" style="display: block;">
<ul> <a href="#" class="group-toggle icon-opened" title="Click to hide these contacts">Contact Requests</a>
<li class="room-info">Moderated</li><li class="room-info">Open room</li> </dt>
<li class="room-info">Permanent room</li><li class="room-info">Public</li> <dd class="offline requesting-xmpp-contact">
<li class="room-info">Semi-anonymous</li> <span class="req-contact-name">Bob Skinstad</span>
<li class="room-info">Requires authentication <span class="icon-lock"></span></li> <span class="request-actions">
<p></p> <a class="accept-xmpp-request icon-checkmark" title="Click here to accept this contact's request" href="#"></a>
</ul> <a class="decline-xmpp-request icon-close" title="Click here to decline this contact's request" href="#"></a>
</div> </span>
</dd> </dd>
</dl> <dd class="offline requesting-xmpp-contact">
<span class="req-contact-name">André Vos</span>
<span class="request-actions">
<a class="accept-xmpp-request icon-checkmark" title="Click here to accept this contact's request" href="#"></a>
<a class="decline-xmpp-request icon-close" title="Click here to decline this contact's request" href="#"></a>
</span>
</dd>
<dt id="pending-xmpp-contacts" style="display: block;">
<a href="#" class="group-toggle icon-opened" title="Click to hide these contacts">Pending Contacts</a>
</dt>
<dd class="offline pending-xmpp-contact"><span class="pending-contact-name">Rassie Erasmus</span>
<a class="remove-xmpp-contact icon-remove" title="Click to remove this contact" href="#"></a>
</dd>
<dd class="offline pending-xmpp-contact"><span class="pending-contact-name">Victor Matfield</span>
<a class="remove-xmpp-contact icon-remove" title="Click to remove this contact" href="#"></a>
</dd>
</dl>
</div>
<div id="chatrooms" style="display: none;">
<form class="add-chatroom" action="" method="post">
<input type="text" name="chatroom" class="new-chatroom-name" placeholder="Room name">
<input type="text" name="nick" class="new-chatroom-nick" placeholder="Nickname">
<input type="text" name="server" class="new-chatroom-server" placeholder="Server">
<input type="submit" name="join" value="Join">
<input type="button" name="show" id="show-rooms" value="Show rooms" style="display: inline-block;">
</form>
<dl id="available-chatrooms">
<dt>Rooms on conference.opkode.im</dt>
<dd class="available-chatroom">
<a class="open-room"
data-room-jid="converse.js@conference.opkode.im"
title="Click to open this room" href="#">Special chatroom with a long name (2)</a>
<a class="room-info icon-room-info"
data-room-jid="converse.js@conference.opkode.im"
title="Show more information on this room" href="#">&nbsp;</a>
<div class="room-info">
<p class="room-info"><strong>Description:</strong></p>
<p class="room-info"><strong>Occupants:</strong> 2</p>
<p class="room-info"><strong>Features:</strong> </p>
<ul>
<li class="room-info">Moderated</li><li class="room-info">Open room</li>
<li class="room-info">Permanent room</li><li class="room-info">Public</li>
<li class="room-info">Semi-anonymous</li>
<li class="room-info">Requires authentication <span class="icon-lock"></span></li>
<p></p>
</ul>
</div>
</dd>
</dl>
</div>
</div> </div>
</div> </div>
</div> </div>
......
(function (root, factory) { (function (root, factory) {
define([ define([
"mock", "mock",
"utils" "test_utils"
], function (mock, utils) { ], function (mock, test_utils) {
return factory(mock, utils); return factory(mock, test_utils);
} }
); );
} (this, function (mock, utils) { } (this, function (mock, test_utils) {
return describe("Chatboxes", $.proxy(function(mock, utils) { return describe("Chatboxes", $.proxy(function(mock, test_utils) {
describe("A Chatbox", $.proxy(function () { describe("A Chatbox", $.proxy(function () {
beforeEach(function () { beforeEach(function () {
runs(function () { runs(function () {
utils.closeAllChatBoxes(); test_utils.closeAllChatBoxes();
utils.removeControlBox(); test_utils.removeControlBox();
utils.clearBrowserStorage(); test_utils.clearBrowserStorage();
utils.initConverse(); test_utils.initConverse();
utils.createContacts(); test_utils.createContacts();
utils.openControlBox(); test_utils.openControlBox();
utils.openContactsPanel(); test_utils.openContactsPanel();
}); });
}); });
...@@ -95,7 +95,7 @@ ...@@ -95,7 +95,7 @@
// openControlBox was called earlier, so the controlbox is // openControlBox was called earlier, so the controlbox is
// visible, but no other chat boxes have been created. // visible, but no other chat boxes have been created.
expect(this.chatboxes.length).toEqual(1); expect(this.chatboxes.length).toEqual(1);
chatbox = utils.openChatBoxFor(contact_jid); chatbox = test_utils.openChatBoxFor(contact_jid);
chatboxview = this.chatboxviews.get(contact_jid); chatboxview = this.chatboxviews.get(contact_jid);
spyOn(chatboxview, 'focus'); spyOn(chatboxview, 'focus');
$el = this.rosterview.$el.find('a.open-chat:contains("'+chatbox.get('fullname')+'")'); $el = this.rosterview.$el.find('a.open-chat:contains("'+chatbox.get('fullname')+'")');
...@@ -109,11 +109,11 @@ ...@@ -109,11 +109,11 @@
spyOn(converse, 'emit'); spyOn(converse, 'emit');
spyOn(this.chatboxviews, 'trimChats'); spyOn(this.chatboxviews, 'trimChats');
runs(function () { runs(function () {
utils.openControlBox(); test_utils.openControlBox();
}); });
waits(250); waits(250);
runs(function () { runs(function () {
utils.openChatBoxes(6); test_utils.openChatBoxes(6);
expect(this.chatboxviews.trimChats).toHaveBeenCalled(); expect(this.chatboxviews.trimChats).toHaveBeenCalled();
// We instantiate a new ChatBoxes collection, which by default // We instantiate a new ChatBoxes collection, which by default
// will be empty. // will be empty.
...@@ -136,7 +136,7 @@ ...@@ -136,7 +136,7 @@
}, converse)); }, converse));
it("can be closed by clicking a DOM element with class 'close-chatbox-button'", $.proxy(function () { it("can be closed by clicking a DOM element with class 'close-chatbox-button'", $.proxy(function () {
var chatbox = utils.openChatBoxes(1)[0], var chatbox = test_utils.openChatBoxes(1)[0],
controlview = this.chatboxviews.get('controlbox'), // The controlbox is currently open controlview = this.chatboxviews.get('controlbox'), // The controlbox is currently open
chatview = this.chatboxviews.get(chatbox.get('jid')); chatview = this.chatboxviews.get(chatbox.get('jid'));
spyOn(chatview, 'close').andCallThrough(); spyOn(chatview, 'close').andCallThrough();
...@@ -166,7 +166,7 @@ ...@@ -166,7 +166,7 @@
}, converse)); }, converse));
it("can be minimized by clicking a DOM element with class 'toggle-chatbox-button'", function () { it("can be minimized by clicking a DOM element with class 'toggle-chatbox-button'", function () {
var chatbox = utils.openChatBoxes(1)[0], var chatbox = test_utils.openChatBoxes(1)[0],
chatview = this.chatboxviews.get(chatbox.get('jid')), chatview = this.chatboxviews.get(chatbox.get('jid')),
trimmed_chatboxes = this.minimized_chats, trimmed_chatboxes = this.minimized_chats,
trimmedview; trimmedview;
...@@ -207,17 +207,17 @@ ...@@ -207,17 +207,17 @@
spyOn(converse.chatboxviews, 'trimChats'); spyOn(converse.chatboxviews, 'trimChats');
this.chatboxes.browserStorage._clear(); this.chatboxes.browserStorage._clear();
runs(function () { runs(function () {
utils.closeControlBox(); test_utils.closeControlBox();
}); });
waits(250); waits(250);
runs(function () { runs(function () {
expect(converse.emit).toHaveBeenCalledWith('chatBoxClosed', jasmine.any(Object)); expect(converse.emit).toHaveBeenCalledWith('chatBoxClosed', jasmine.any(Object));
expect(converse.chatboxes.length).toEqual(0); expect(converse.chatboxes.length).toEqual(0);
utils.openChatBoxes(6); test_utils.openChatBoxes(6);
expect(converse.chatboxviews.trimChats).toHaveBeenCalled(); expect(converse.chatboxviews.trimChats).toHaveBeenCalled();
expect(converse.chatboxes.length).toEqual(6); expect(converse.chatboxes.length).toEqual(6);
expect(converse.emit).toHaveBeenCalledWith('chatBoxOpened', jasmine.any(Object)); expect(converse.emit).toHaveBeenCalledWith('chatBoxOpened', jasmine.any(Object));
utils.closeAllChatBoxes(); test_utils.closeAllChatBoxes();
}); });
waits(250); waits(250);
runs(function () { runs(function () {
...@@ -237,7 +237,7 @@ ...@@ -237,7 +237,7 @@
describe("A chat toolbar", $.proxy(function () { describe("A chat toolbar", $.proxy(function () {
it("can be found on each chat box", $.proxy(function () { it("can be found on each chat box", $.proxy(function () {
var contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost'; var contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost';
utils.openChatBoxFor(contact_jid); test_utils.openChatBoxFor(contact_jid);
var chatbox = this.chatboxes.get(contact_jid); var chatbox = this.chatboxes.get(contact_jid);
var view = this.chatboxviews.get(contact_jid); var view = this.chatboxviews.get(contact_jid);
expect(chatbox).toBeDefined(); expect(chatbox).toBeDefined();
...@@ -249,7 +249,7 @@ ...@@ -249,7 +249,7 @@
it("contains a button for inserting emoticons", $.proxy(function () { it("contains a button for inserting emoticons", $.proxy(function () {
var contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost'; var contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost';
utils.openChatBoxFor(contact_jid); test_utils.openChatBoxFor(contact_jid);
var view = this.chatboxviews.get(contact_jid); var view = this.chatboxviews.get(contact_jid);
var $toolbar = view.$el.find('ul.chat-toolbar'); var $toolbar = view.$el.find('ul.chat-toolbar');
var $textarea = view.$el.find('textarea.chat-textarea'); var $textarea = view.$el.find('textarea.chat-textarea');
...@@ -308,7 +308,7 @@ ...@@ -308,7 +308,7 @@
it("contains a button for starting an encrypted chat session", $.proxy(function () { it("contains a button for starting an encrypted chat session", $.proxy(function () {
// TODO: More tests can be added here... // TODO: More tests can be added here...
var contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost'; var contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost';
utils.openChatBoxFor(contact_jid); test_utils.openChatBoxFor(contact_jid);
var view = this.chatboxviews.get(contact_jid); var view = this.chatboxviews.get(contact_jid);
var $toolbar = view.$el.find('ul.chat-toolbar'); var $toolbar = view.$el.find('ul.chat-toolbar');
expect($toolbar.children('li.toggle-otr').length).toBe(1); expect($toolbar.children('li.toggle-otr').length).toBe(1);
...@@ -336,7 +336,7 @@ ...@@ -336,7 +336,7 @@
// First check that the button doesn't show if it's not enabled // First check that the button doesn't show if it's not enabled
// via "visible_toolbar_buttons" // via "visible_toolbar_buttons"
converse.visible_toolbar_buttons.call = false; converse.visible_toolbar_buttons.call = false;
utils.openChatBoxFor(contact_jid); test_utils.openChatBoxFor(contact_jid);
view = this.chatboxviews.get(contact_jid); view = this.chatboxviews.get(contact_jid);
$toolbar = view.$el.find('ul.chat-toolbar'); $toolbar = view.$el.find('ul.chat-toolbar');
callButton = $toolbar.find('.toggle-call'); callButton = $toolbar.find('.toggle-call');
...@@ -345,7 +345,7 @@ ...@@ -345,7 +345,7 @@
// Now check that it's shown if enabled and that it emits // Now check that it's shown if enabled and that it emits
// callButtonClicked // callButtonClicked
converse.visible_toolbar_buttons.call = true; // enable the button converse.visible_toolbar_buttons.call = true; // enable the button
utils.openChatBoxFor(contact_jid); test_utils.openChatBoxFor(contact_jid);
view = this.chatboxviews.get(contact_jid); view = this.chatboxviews.get(contact_jid);
$toolbar = view.$el.find('ul.chat-toolbar'); $toolbar = view.$el.find('ul.chat-toolbar');
callButton = $toolbar.find('.toggle-call'); callButton = $toolbar.find('.toggle-call');
...@@ -360,7 +360,7 @@ ...@@ -360,7 +360,7 @@
// First check that the button doesn't show if it's not enabled // First check that the button doesn't show if it's not enabled
// via "visible_toolbar_buttons" // via "visible_toolbar_buttons"
converse.visible_toolbar_buttons.clear = false; converse.visible_toolbar_buttons.clear = false;
utils.openChatBoxFor(contact_jid); test_utils.openChatBoxFor(contact_jid);
view = this.chatboxviews.get(contact_jid); view = this.chatboxviews.get(contact_jid);
view = this.chatboxviews.get(contact_jid); view = this.chatboxviews.get(contact_jid);
$toolbar = view.$el.find('ul.chat-toolbar'); $toolbar = view.$el.find('ul.chat-toolbar');
...@@ -370,7 +370,7 @@ ...@@ -370,7 +370,7 @@
// Now check that it's shown if enabled and that it calls // Now check that it's shown if enabled and that it calls
// clearMessages // clearMessages
converse.visible_toolbar_buttons.clear = true; // enable the button converse.visible_toolbar_buttons.clear = true; // enable the button
utils.openChatBoxFor(contact_jid); test_utils.openChatBoxFor(contact_jid);
view = this.chatboxviews.get(contact_jid); view = this.chatboxviews.get(contact_jid);
$toolbar = view.$el.find('ul.chat-toolbar'); $toolbar = view.$el.find('ul.chat-toolbar');
clearButton = $toolbar.find('.toggle-clear'); clearButton = $toolbar.find('.toggle-clear');
...@@ -387,7 +387,7 @@ ...@@ -387,7 +387,7 @@
beforeEach(function () { beforeEach(function () {
runs(function () { runs(function () {
utils.closeAllChatBoxes(); test_utils.closeAllChatBoxes();
}); });
waits(250); waits(250);
runs(function () {}); runs(function () {});
...@@ -445,7 +445,7 @@ ...@@ -445,7 +445,7 @@
var contact_jid = contact_name.replace(/ /g,'.').toLowerCase() + '@localhost'; var contact_jid = contact_name.replace(/ /g,'.').toLowerCase() + '@localhost';
spyOn(this, 'emit'); spyOn(this, 'emit');
runs(function () { runs(function () {
utils.openChatBoxFor(contact_jid); test_utils.openChatBoxFor(contact_jid);
var chatview = converse.chatboxviews.get(contact_jid); var chatview = converse.chatboxviews.get(contact_jid);
expect(chatview.model.get('minimized')).toBeFalsy(); expect(chatview.model.get('minimized')).toBeFalsy();
chatview.$el.find('.toggle-chatbox-button').click(); chatview.$el.find('.toggle-chatbox-button').click();
...@@ -505,8 +505,8 @@ ...@@ -505,8 +505,8 @@
spyOn(converse, 'emit'); spyOn(converse, 'emit');
var contact_name = mock.cur_names[1]; var contact_name = mock.cur_names[1];
var contact_jid = contact_name.replace(/ /g,'.').toLowerCase() + '@localhost'; var contact_jid = contact_name.replace(/ /g,'.').toLowerCase() + '@localhost';
utils.openChatBoxFor(contact_jid); test_utils.openChatBoxFor(contact_jid);
utils.clearChatBoxMessages(contact_jid); test_utils.clearChatBoxMessages(contact_jid);
var one_day_ago = moment(); var one_day_ago = moment();
one_day_ago.subtract('days', 1); one_day_ago.subtract('days', 1);
var message = 'This is a day old message'; var message = 'This is a day old message';
...@@ -574,7 +574,7 @@ ...@@ -574,7 +574,7 @@
spyOn(converse, 'emit'); spyOn(converse, 'emit');
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
runs(function () { runs(function () {
utils.openChatBoxFor(contact_jid); test_utils.openChatBoxFor(contact_jid);
}); });
waits(250); waits(250);
runs(function () { runs(function () {
...@@ -582,7 +582,7 @@ ...@@ -582,7 +582,7 @@
var view = this.chatboxviews.get(contact_jid); var view = this.chatboxviews.get(contact_jid);
var message = 'This message is sent from this chatbox'; var message = 'This message is sent from this chatbox';
spyOn(view, 'sendMessage').andCallThrough(); spyOn(view, 'sendMessage').andCallThrough();
utils.sendMessage(view, message); test_utils.sendMessage(view, message);
expect(view.sendMessage).toHaveBeenCalled(); expect(view.sendMessage).toHaveBeenCalled();
expect(view.model.messages.length, 2); expect(view.model.messages.length, 2);
expect(converse.emit.mostRecentCall.args, ['messageSend', message]); expect(converse.emit.mostRecentCall.args, ['messageSend', message]);
...@@ -592,11 +592,11 @@ ...@@ -592,11 +592,11 @@
it("is sanitized to prevent Javascript injection attacks", $.proxy(function () { it("is sanitized to prevent Javascript injection attacks", $.proxy(function () {
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
utils.openChatBoxFor(contact_jid); test_utils.openChatBoxFor(contact_jid);
var view = this.chatboxviews.get(contact_jid); var view = this.chatboxviews.get(contact_jid);
var message = '<p>This message contains <em>some</em> <b>markup</b></p>'; var message = '<p>This message contains <em>some</em> <b>markup</b></p>';
spyOn(view, 'sendMessage').andCallThrough(); spyOn(view, 'sendMessage').andCallThrough();
utils.sendMessage(view, message); test_utils.sendMessage(view, message);
expect(view.sendMessage).toHaveBeenCalled(); expect(view.sendMessage).toHaveBeenCalled();
var msg = view.$el.find('.chat-content').find('.chat-message').last().find('.chat-message-content'); var msg = view.$el.find('.chat-content').find('.chat-message').last().find('.chat-message-content');
expect(msg.text()).toEqual(message); expect(msg.text()).toEqual(message);
...@@ -605,11 +605,11 @@ ...@@ -605,11 +605,11 @@
it("can contain hyperlinks, which will be clickable", $.proxy(function () { it("can contain hyperlinks, which will be clickable", $.proxy(function () {
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
utils.openChatBoxFor(contact_jid); test_utils.openChatBoxFor(contact_jid);
var view = this.chatboxviews.get(contact_jid); var view = this.chatboxviews.get(contact_jid);
var message = 'This message contains a hyperlink: www.opkode.com'; var message = 'This message contains a hyperlink: www.opkode.com';
spyOn(view, 'sendMessage').andCallThrough(); spyOn(view, 'sendMessage').andCallThrough();
utils.sendMessage(view, message); test_utils.sendMessage(view, message);
expect(view.sendMessage).toHaveBeenCalled(); expect(view.sendMessage).toHaveBeenCalled();
var msg = view.$el.find('.chat-content').find('.chat-message').last().find('.chat-message-content'); var msg = view.$el.find('.chat-content').find('.chat-message').last().find('.chat-message-content');
expect(msg.text()).toEqual(message); expect(msg.text()).toEqual(message);
...@@ -618,7 +618,7 @@ ...@@ -618,7 +618,7 @@
it("should display emoticons correctly", $.proxy(function () { it("should display emoticons correctly", $.proxy(function () {
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
utils.openChatBoxFor(contact_jid); test_utils.openChatBoxFor(contact_jid);
var view = this.chatboxviews.get(contact_jid); var view = this.chatboxviews.get(contact_jid);
var messages = [':)', ';)', ':D', ':P', '8)', '>:)', ':S', ':\\', '>:(', ':(', ':O', '(^.^)b', '<3']; var messages = [':)', ';)', ':D', ':P', '8)', '>:)', ':S', ':\\', '>:(', ':(', ':O', '(^.^)b', '<3'];
var emoticons = [ var emoticons = [
...@@ -633,7 +633,7 @@ ...@@ -633,7 +633,7 @@
spyOn(view, 'sendMessage').andCallThrough(); spyOn(view, 'sendMessage').andCallThrough();
for (var i = 0; i < messages.length; i++) { for (var i = 0; i < messages.length; i++) {
var message = messages[i]; var message = messages[i];
utils.sendMessage(view, message); test_utils.sendMessage(view, message);
expect(view.sendMessage).toHaveBeenCalled(); expect(view.sendMessage).toHaveBeenCalled();
var msg = view.$el.find('.chat-content').find('.chat-message').last().find('.chat-message-content'); var msg = view.$el.find('.chat-content').find('.chat-message').last().find('.chat-message-content');
expect(msg.html()).toEqual(emoticons[i]); expect(msg.html()).toEqual(emoticons[i]);
...@@ -642,33 +642,33 @@ ...@@ -642,33 +642,33 @@
it("will have properly escaped URLs", $.proxy(function () { it("will have properly escaped URLs", $.proxy(function () {
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
utils.openChatBoxFor(contact_jid); test_utils.openChatBoxFor(contact_jid);
var view = this.chatboxviews.get(contact_jid); var view = this.chatboxviews.get(contact_jid);
spyOn(view, 'sendMessage').andCallThrough(); spyOn(view, 'sendMessage').andCallThrough();
var message = "http://www.opkode.com/'onmouseover='alert(1)'whatever"; var message = "http://www.opkode.com/'onmouseover='alert(1)'whatever";
utils.sendMessage(view, message); test_utils.sendMessage(view, message);
expect(view.sendMessage).toHaveBeenCalled(); expect(view.sendMessage).toHaveBeenCalled();
var msg = view.$el.find('.chat-content').find('.chat-message').last().find('.chat-message-content'); var msg = view.$el.find('.chat-content').find('.chat-message').last().find('.chat-message-content');
expect(msg.text()).toEqual(message); expect(msg.text()).toEqual(message);
expect(msg.html()).toEqual('<a target="_blank" href="http://www.opkode.com/%27onmouseover=%27alert%281%29%27whatever">http://www.opkode.com/\'onmouseover=\'alert(1)\'whatever</a>'); expect(msg.html()).toEqual('<a target="_blank" href="http://www.opkode.com/%27onmouseover=%27alert%281%29%27whatever">http://www.opkode.com/\'onmouseover=\'alert(1)\'whatever</a>');
message = 'http://www.opkode.com/"onmouseover="alert(1)"whatever'; message = 'http://www.opkode.com/"onmouseover="alert(1)"whatever';
utils.sendMessage(view, message); test_utils.sendMessage(view, message);
expect(view.sendMessage).toHaveBeenCalled(); expect(view.sendMessage).toHaveBeenCalled();
msg = view.$el.find('.chat-content').find('.chat-message').last().find('.chat-message-content'); msg = view.$el.find('.chat-content').find('.chat-message').last().find('.chat-message-content');
expect(msg.text()).toEqual(message); expect(msg.text()).toEqual(message);
expect(msg.html()).toEqual('<a target="_blank" href="http://www.opkode.com/%22onmouseover=%22alert%281%29%22whatever">http://www.opkode.com/"onmouseover="alert(1)"whatever</a>'); expect(msg.html()).toEqual('<a target="_blank" href="http://www.opkode.com/%22onmouseover=%22alert%281%29%22whatever">http://www.opkode.com/"onmouseover="alert(1)"whatever</a>');
message = "https://en.wikipedia.org/wiki/Ender's_Game"; message = "https://en.wikipedia.org/wiki/Ender's_Game";
utils.sendMessage(view, message); test_utils.sendMessage(view, message);
expect(view.sendMessage).toHaveBeenCalled(); expect(view.sendMessage).toHaveBeenCalled();
msg = view.$el.find('.chat-content').find('.chat-message').last().find('.chat-message-content'); msg = view.$el.find('.chat-content').find('.chat-message').last().find('.chat-message-content');
expect(msg.text()).toEqual(message); expect(msg.text()).toEqual(message);
expect(msg.html()).toEqual('<a target="_blank" href="https://en.wikipedia.org/wiki/Ender%27s_Game">https://en.wikipedia.org/wiki/Ender\'s_Game</a>'); expect(msg.html()).toEqual('<a target="_blank" href="https://en.wikipedia.org/wiki/Ender%27s_Game">https://en.wikipedia.org/wiki/Ender\'s_Game</a>');
message = "https://en.wikipedia.org/wiki/Ender%27s_Game"; message = "https://en.wikipedia.org/wiki/Ender%27s_Game";
utils.sendMessage(view, message); test_utils.sendMessage(view, message);
expect(view.sendMessage).toHaveBeenCalled(); expect(view.sendMessage).toHaveBeenCalled();
msg = view.$el.find('.chat-content').find('.chat-message').last().find('.chat-message-content'); msg = view.$el.find('.chat-content').find('.chat-message').last().find('.chat-message-content');
expect(msg.text()).toEqual(message); expect(msg.text()).toEqual(message);
...@@ -680,24 +680,24 @@ ...@@ -680,24 +680,24 @@
describe("Special Messages", $.proxy(function () { describe("Special Messages", $.proxy(function () {
beforeEach(function () { beforeEach(function () {
utils.closeAllChatBoxes(); test_utils.closeAllChatBoxes();
utils.removeControlBox(); test_utils.removeControlBox();
converse.roster.browserStorage._clear(); converse.roster.browserStorage._clear();
utils.initConverse(); test_utils.initConverse();
utils.createContacts(); test_utils.createContacts();
utils.openControlBox(); test_utils.openControlBox();
utils.openContactsPanel(); test_utils.openContactsPanel();
}); });
it("'/clear' can be used to clear messages in a conversation", $.proxy(function () { it("'/clear' can be used to clear messages in a conversation", $.proxy(function () {
spyOn(converse, 'emit'); spyOn(converse, 'emit');
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
utils.openChatBoxFor(contact_jid); test_utils.openChatBoxFor(contact_jid);
var view = this.chatboxviews.get(contact_jid); var view = this.chatboxviews.get(contact_jid);
var message = 'This message is another sent from this chatbox'; var message = 'This message is another sent from this chatbox';
// Lets make sure there is at least one message already // Lets make sure there is at least one message already
// (e.g for when this test is run on its own). // (e.g for when this test is run on its own).
utils.sendMessage(view, message); test_utils.sendMessage(view, message);
expect(view.model.messages.length > 0).toBeTruthy(); expect(view.model.messages.length > 0).toBeTruthy();
expect(view.model.messages.browserStorage.records.length > 0).toBeTruthy(); expect(view.model.messages.browserStorage.records.length > 0).toBeTruthy();
expect(converse.emit).toHaveBeenCalledWith('messageSend', message); expect(converse.emit).toHaveBeenCalledWith('messageSend', message);
...@@ -709,7 +709,7 @@ ...@@ -709,7 +709,7 @@
spyOn(window, 'confirm').andCallFake(function () { spyOn(window, 'confirm').andCallFake(function () {
return true; return true;
}); });
utils.sendMessage(view, message); test_utils.sendMessage(view, message);
expect(view.sendMessage).toHaveBeenCalled(); expect(view.sendMessage).toHaveBeenCalled();
expect(view.clearMessages).toHaveBeenCalled(); expect(view.clearMessages).toHaveBeenCalled();
expect(window.confirm).toHaveBeenCalled(); expect(window.confirm).toHaveBeenCalled();
...@@ -775,5 +775,5 @@ ...@@ -775,5 +775,5 @@
expect(this.msg_counter).toBe(0); expect(this.msg_counter).toBe(0);
}, converse)); }, converse));
}, converse)); }, converse));
}, converse, mock, utils)); }, converse, mock, test_utils));
})); }));
(function (root, factory) { (function (root, factory) {
define([ define([
"mock", "mock",
"utils" "test_utils"
], function (mock, utils) { ], function (mock, test_utils) {
return factory(mock, utils); return factory(mock, test_utils);
} }
); );
} (this, function (mock, utils) { } (this, function (mock, test_utils) {
return describe("ChatRooms", $.proxy(function (mock, utils) { return describe("ChatRooms", $.proxy(function (mock, test_utils) {
describe("A Chat Room", $.proxy(function () { describe("A Chat Room", $.proxy(function () {
beforeEach(function () { beforeEach(function () {
runs(function () { runs(function () {
utils.closeAllChatBoxes(); test_utils.closeAllChatBoxes();
}); });
waits(250); waits(250);
runs(function () { runs(function () {
utils.openControlBox(); test_utils.openControlBox();
}); });
waits(250); waits(250);
runs(function () { runs(function () {
utils.openRoomsPanel(); test_utils.openRoomsPanel();
}); });
waits(501); waits(501);
runs(function () { runs(function () {
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
}); });
waits(250); waits(250);
runs(function () { runs(function () {
utils.closeControlBox(); test_utils.closeControlBox();
}); });
waits(250); waits(250);
runs(function () {}); runs(function () {});
...@@ -116,7 +116,7 @@ ...@@ -116,7 +116,7 @@
// We instantiate a new ChatBoxes collection, which by default // We instantiate a new ChatBoxes collection, which by default
// will be empty. // will be empty.
spyOn(this.chatboxviews, 'trimChats'); spyOn(this.chatboxviews, 'trimChats');
utils.openControlBox(); test_utils.openControlBox();
var newchatboxes = new this.ChatBoxes(); var newchatboxes = new this.ChatBoxes();
expect(newchatboxes.length).toEqual(0); expect(newchatboxes.length).toEqual(0);
// The chatboxes will then be fetched from browserStorage inside the // The chatboxes will then be fetched from browserStorage inside the
...@@ -350,5 +350,5 @@ ...@@ -350,5 +350,5 @@
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");
}, converse)); }, converse));
}, converse)); }, converse));
}, converse, mock, utils)); }, converse, mock, test_utils));
})); }));
(function (root, factory) { (function (root, factory) {
define([ define([
"mock", "mock",
"utils" "test_utils"
], function (mock, utils) { ], function (mock, test_utils) {
return factory(mock, utils); return factory(mock, test_utils);
} }
); );
} (this, function (mock, utils) { } (this, function (mock, test_utils) {
var checkHeaderToggling = function ($header) { var checkHeaderToggling = function ($header) {
var $toggle = $header.find('a.group-toggle'); var $toggle = $header.find('a.group-toggle');
...@@ -24,16 +24,16 @@ ...@@ -24,16 +24,16 @@
expect($header.nextUntil('dt', 'dd').length === $header.nextUntil('dt', 'dd:visible').length).toBeTruthy(); expect($header.nextUntil('dt', 'dd').length === $header.nextUntil('dt', 'dd:visible').length).toBeTruthy();
}; };
describe("The Control Box", $.proxy(function (mock, utils) { describe("The Control Box", $.proxy(function (mock, test_utils) {
beforeEach(function () { beforeEach(function () {
runs(function () { runs(function () {
utils.openControlBox(); test_utils.openControlBox();
}); });
}); });
it("can be opened by clicking a DOM element with class 'toggle-controlbox'", $.proxy(function () { it("can be opened by clicking a DOM element with class 'toggle-controlbox'", $.proxy(function () {
runs(function () { runs(function () {
utils.closeControlBox(); test_utils.closeControlBox();
}); });
waits(50); waits(50);
runs(function () { runs(function () {
...@@ -59,7 +59,7 @@ ...@@ -59,7 +59,7 @@
describe("The Status Widget", $.proxy(function () { describe("The Status Widget", $.proxy(function () {
beforeEach(function () { beforeEach(function () {
utils.openControlBox(); test_utils.openControlBox();
}); });
it("shows the user's chat status, which is online by default", $.proxy(function () { it("shows the user's chat status, which is online by default", $.proxy(function () {
...@@ -120,9 +120,9 @@ ...@@ -120,9 +120,9 @@
}); });
}, converse)); }, converse));
}, converse)); }, converse));
}, converse, mock, utils)); }, converse, mock, test_utils));
describe("The Contacts Roster", $.proxy(function (mock, utils) { describe("The Contacts Roster", $.proxy(function (mock, test_utils) {
describe("A Roster Group", $.proxy(function () { describe("A Roster Group", $.proxy(function () {
...@@ -135,7 +135,7 @@ ...@@ -135,7 +135,7 @@
}); });
function _clearContacts () { function _clearContacts () {
utils.clearBrowserStorage(); test_utils.clearBrowserStorage();
converse.rosterview.model.reset(); converse.rosterview.model.reset();
} }
...@@ -146,8 +146,8 @@ ...@@ -146,8 +146,8 @@
spyOn(this.rosterview, 'update').andCallThrough(); spyOn(this.rosterview, 'update').andCallThrough();
converse.rosterview.render(); converse.rosterview.render();
utils.createContacts('pending'); test_utils.createContacts('pending');
utils.createContacts('requesting'); test_utils.createContacts('requesting');
var groups = { var groups = {
'colleagues': 3, 'colleagues': 3,
'friends & acquaintences': 3, 'friends & acquaintences': 3,
...@@ -243,14 +243,14 @@ ...@@ -243,14 +243,14 @@
describe("Pending Contacts", $.proxy(function () { describe("Pending Contacts", $.proxy(function () {
function _clearContacts () { function _clearContacts () {
utils.clearBrowserStorage(); test_utils.clearBrowserStorage();
converse.rosterview.model.reset(); converse.rosterview.model.reset();
} }
function _addContacts () { function _addContacts () {
_clearContacts(); _clearContacts();
// Must be initialized, so that render is called and documentFragment set up. // Must be initialized, so that render is called and documentFragment set up.
utils.createContacts('pending').openControlBox().openContactsPanel(); test_utils.createContacts('pending').openControlBox().openContactsPanel();
} }
it("can be collapsed under their own header", $.proxy(function () { it("can be collapsed under their own header", $.proxy(function () {
...@@ -350,13 +350,13 @@ ...@@ -350,13 +350,13 @@
describe("Existing Contacts", $.proxy(function () { describe("Existing Contacts", $.proxy(function () {
function _clearContacts () { function _clearContacts () {
utils.clearBrowserStorage(); test_utils.clearBrowserStorage();
converse.rosterview.model.reset(); converse.rosterview.model.reset();
} }
var _addContacts = function () { var _addContacts = function () {
_clearContacts(); _clearContacts();
utils.createContacts().openControlBox().openContactsPanel(); test_utils.createContacts().openControlBox().openContactsPanel();
}; };
it("can be collapsed under their own header", $.proxy(function () { it("can be collapsed under their own header", $.proxy(function () {
...@@ -561,13 +561,13 @@ ...@@ -561,13 +561,13 @@
describe("Requesting Contacts", $.proxy(function () { describe("Requesting Contacts", $.proxy(function () {
beforeEach($.proxy(function () { beforeEach($.proxy(function () {
runs(function () { runs(function () {
utils.clearBrowserStorage(); test_utils.clearBrowserStorage();
converse.rosterview.model.reset(); converse.rosterview.model.reset();
utils.createContacts('requesting').openControlBox(); test_utils.createContacts('requesting').openControlBox();
}); });
waits(50); waits(50);
runs(function () { runs(function () {
utils.openContactsPanel(); test_utils.openContactsPanel();
}); });
}, converse)); }, converse));
...@@ -646,7 +646,7 @@ ...@@ -646,7 +646,7 @@
spyOn(converse, 'emit'); spyOn(converse, 'emit');
spyOn(this.connection.roster, 'unauthorize'); spyOn(this.connection.roster, 'unauthorize');
spyOn(window, 'confirm').andReturn(true); spyOn(window, 'confirm').andReturn(true);
utils.createContacts('requesting').openControlBox(); test_utils.createContacts('requesting').openControlBox();
var name = mock.req_names.sort()[1]; var name = mock.req_names.sort()[1];
var jid = name.replace(/ /g,'.').toLowerCase() + '@localhost'; var jid = name.replace(/ /g,'.').toLowerCase() + '@localhost';
converse.rosterview.$el.find(".req-contact-name:contains('"+name+"')") converse.rosterview.$el.find(".req-contact-name:contains('"+name+"')")
...@@ -661,10 +661,10 @@ ...@@ -661,10 +661,10 @@
describe("All Contacts", $.proxy(function () { describe("All Contacts", $.proxy(function () {
beforeEach($.proxy(function () { beforeEach($.proxy(function () {
utils.clearBrowserStorage(); test_utils.clearBrowserStorage();
converse.rosterview.model.reset(); converse.rosterview.model.reset();
utils.createContacts('all').openControlBox(); test_utils.createContacts('all').openControlBox();
utils.openContactsPanel(); test_utils.openContactsPanel();
}, converse)); }, converse));
it("are saved to, and can be retrieved from, browserStorage", $.proxy(function () { it("are saved to, and can be retrieved from, browserStorage", $.proxy(function () {
...@@ -700,9 +700,9 @@ ...@@ -700,9 +700,9 @@
} }
}, converse)); }, converse));
}, converse)); }, converse));
}, converse, mock, utils)); }, converse, mock, test_utils));
describe("The 'Add Contact' widget", $.proxy(function (mock, utils) { describe("The 'Add Contact' widget", $.proxy(function (mock, test_utils) {
it("opens up an add form when you click on it", $.proxy(function () { it("opens up an add form when you click on it", $.proxy(function () {
var panel = this.chatboxviews.get('controlbox').contactspanel; var panel = this.chatboxviews.get('controlbox').contactspanel;
spyOn(panel, 'toggleContactForm').andCallThrough(); spyOn(panel, 'toggleContactForm').andCallThrough();
...@@ -713,16 +713,16 @@ ...@@ -713,16 +713,16 @@
panel.$el.find('a.toggle-xmpp-contact-form').click(); panel.$el.find('a.toggle-xmpp-contact-form').click();
}, converse)); }, converse));
}, converse, mock, utils)); }, converse, mock, test_utils));
describe("The Controlbox Tabs", $.proxy(function () { describe("The Controlbox Tabs", $.proxy(function () {
beforeEach($.proxy(function () { beforeEach($.proxy(function () {
runs(function () { runs(function () {
utils.closeAllChatBoxes(); test_utils.closeAllChatBoxes();
}); });
waits(50); waits(50);
runs(function () { runs(function () {
utils.openControlBox(); test_utils.openControlBox();
}); });
}, converse)); }, converse));
...@@ -739,11 +739,11 @@ ...@@ -739,11 +739,11 @@
describe("chatrooms panel", $.proxy(function () { describe("chatrooms panel", $.proxy(function () {
beforeEach($.proxy(function () { beforeEach($.proxy(function () {
runs(function () { runs(function () {
utils.closeAllChatBoxes(); test_utils.closeAllChatBoxes();
}); });
waits(50); waits(50);
runs(function () { runs(function () {
utils.openControlBox(); test_utils.openControlBox();
}); });
}, converse)); }, converse));
...@@ -792,5 +792,5 @@ ...@@ -792,5 +792,5 @@
}, converse)); }, converse));
}, converse)); }, converse));
}, converse)); }, converse));
}, converse, mock, utils)); }, converse, mock, test_utils));
})); }));
(function (root, factory) { (function (root, factory) {
define([ define([
"mock", "mock",
"utils" "test_utils"
], function (mock, utils) { ], function (mock, test_utils) {
return factory(mock, utils); return factory(mock, test_utils);
} }
); );
} (this, function (mock, utils) { } (this, function (mock, test_utils) {
return describe("Converse", $.proxy(function(mock, utils) { return describe("Converse", $.proxy(function(mock, test_utils) {
beforeEach($.proxy(function () { beforeEach($.proxy(function () {
window.localStorage.clear(); window.localStorage.clear();
...@@ -43,5 +43,5 @@ ...@@ -43,5 +43,5 @@
// Restore the connection // Restore the connection
converse.connection = old_connection; converse.connection = old_connection;
}, converse)); }, converse));
}, converse, mock, utils)); }, converse, mock, test_utils));
})); }));
(function (root, factory) { (function (root, factory) {
define([ define([
"mock", "mock",
"utils" "test_utils"
], function (mock, utils) { ], function (mock, test_utils) {
return factory(mock, utils); return factory(mock, test_utils);
} }
); );
} (this, function (mock, utils) { } (this, function (mock, test_utils) {
return describe("The Converse Event Emitter", $.proxy(function(mock, utils) { return describe("The Converse Event Emitter", $.proxy(function(mock, test_utils) {
window.localStorage.clear(); window.localStorage.clear();
window.sessionStorage.clear(); window.sessionStorage.clear();
...@@ -64,5 +64,5 @@ ...@@ -64,5 +64,5 @@
expect(this.anotherCallback.callCount, 3); expect(this.anotherCallback.callCount, 3);
expect(this.neverCalled).not.toHaveBeenCalled(); expect(this.neverCalled).not.toHaveBeenCalled();
}); });
}, converse, mock, utils)); }, converse, mock, test_utils));
})); }));
(function (root, factory) { (function (root, factory) {
define([ define([
"mock", "mock",
"utils" "test_utils"
], function (mock, utils) { ], function (mock, test_utils) {
return factory(mock, utils); return factory(mock, test_utils);
} }
); );
} (this, function (mock, utils) { } (this, function (mock, test_utils) {
return describe("The Minimized Chats Widget", $.proxy(function(mock, utils) { return describe("The Minimized Chats Widget", $.proxy(function(mock, test_utils) {
beforeEach(function () { beforeEach(function () {
runs(function () { runs(function () {
utils.closeAllChatBoxes(); test_utils.closeAllChatBoxes();
utils.removeControlBox(); test_utils.removeControlBox();
converse.roster.browserStorage._clear(); converse.roster.browserStorage._clear();
utils.initConverse(); test_utils.initConverse();
utils.createContacts(); test_utils.createContacts();
utils.openControlBox(); test_utils.openControlBox();
utils.openContactsPanel(); test_utils.openContactsPanel();
converse.minimized_chats.toggleview.model.browserStorage._clear(); converse.minimized_chats.toggleview.model.browserStorage._clear();
converse.minimized_chats.initToggle(); converse.minimized_chats.initToggle();
}); });
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
it("shows chats that have been minimized", $.proxy(function () { it("shows chats that have been minimized", $.proxy(function () {
var contact_jid, chatview; var contact_jid, chatview;
contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
utils.openChatBoxFor(contact_jid); test_utils.openChatBoxFor(contact_jid);
chatview = converse.chatboxviews.get(contact_jid); chatview = converse.chatboxviews.get(contact_jid);
expect(chatview.model.get('minimized')).toBeFalsy(); expect(chatview.model.get('minimized')).toBeFalsy();
expect(this.minimized_chats.$el.is(':visible')).toBeFalsy(); expect(this.minimized_chats.$el.is(':visible')).toBeFalsy();
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
expect(this.minimized_chats.keys()[0]).toBe(contact_jid); expect(this.minimized_chats.keys()[0]).toBe(contact_jid);
contact_jid = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost'; contact_jid = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost';
utils.openChatBoxFor(contact_jid); test_utils.openChatBoxFor(contact_jid);
chatview = converse.chatboxviews.get(contact_jid); chatview = converse.chatboxviews.get(contact_jid);
expect(chatview.model.get('minimized')).toBeFalsy(); expect(chatview.model.get('minimized')).toBeFalsy();
chatview.$el.find('.toggle-chatbox-button').click(); chatview.$el.find('.toggle-chatbox-button').click();
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
it("can be toggled to hide or show minimized chats", $.proxy(function () { it("can be toggled to hide or show minimized chats", $.proxy(function () {
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
utils.openChatBoxFor(contact_jid); test_utils.openChatBoxFor(contact_jid);
var chatview = converse.chatboxviews.get(contact_jid); var chatview = converse.chatboxviews.get(contact_jid);
expect(this.minimized_chats.$el.is(':visible')).toBeFalsy(); expect(this.minimized_chats.$el.is(':visible')).toBeFalsy();
chatview.model.set({'minimized': true}); chatview.model.set({'minimized': true});
...@@ -70,7 +70,7 @@ ...@@ -70,7 +70,7 @@
expect(this.minimized_chats.toggleview.$('.unread-message-count').is(':visible')).toBeFalsy(); expect(this.minimized_chats.toggleview.$('.unread-message-count').is(':visible')).toBeFalsy();
for (i=0; i<3; i++) { for (i=0; i<3; i++) {
contact_jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@localhost'; contact_jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@localhost';
utils.openChatBoxFor(contact_jid); test_utils.openChatBoxFor(contact_jid);
chatview = converse.chatboxviews.get(contact_jid); chatview = converse.chatboxviews.get(contact_jid);
chatview.model.set({'minimized': true}); chatview.model.set({'minimized': true});
msg = $msg({ msg = $msg({
...@@ -86,5 +86,5 @@ ...@@ -86,5 +86,5 @@
} }
}, converse)); }, converse));
}, converse, mock, utils)); }, converse, mock, test_utils));
})); }));
(function (root, factory) { (function (root, factory) {
define([ define([
"mock", "mock",
"utils" "test_utils"
], function (mock, utils) { ], function (mock, test_utils) {
return factory(mock, utils); return factory(mock, test_utils);
} }
); );
} (this, function (mock, utils) { } (this, function (mock, test_utils) {
return describe("The OTR module", $.proxy(function(mock, utils) { return describe("The OTR module", $.proxy(function(mock, test_utils) {
beforeEach($.proxy(function () { beforeEach($.proxy(function () {
window.localStorage.clear(); window.localStorage.clear();
...@@ -36,5 +36,5 @@ ...@@ -36,5 +36,5 @@
// Clean up // Clean up
this.prebind = false; this.prebind = false;
}, converse)); }, converse));
}, converse, mock, utils)); }, converse, mock, test_utils));
})); }));
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
"strophe.disco": "components/strophe.disco/index", "strophe.disco": "components/strophe.disco/index",
"converse-dependencies": "src/deps-no-otr", "converse-dependencies": "src/deps-no-otr",
"jquery.browser": "components/jquery.browser/dist/jquery.browser", "jquery.browser": "components/jquery.browser/dist/jquery.browser",
"utils": "src/utils",
"moment":"components/momentjs/moment", "moment":"components/momentjs/moment",
"converse-templates":"src/templates", "converse-templates":"src/templates",
"tpl": "components/requirejs-tpl-jcbrand/tpl", "tpl": "components/requirejs-tpl-jcbrand/tpl",
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
"ru": "locale/ru/LC_MESSAGES/ru", "ru": "locale/ru/LC_MESSAGES/ru",
"zh": "locale/zh/LC_MESSAGES/zh", "zh": "locale/zh/LC_MESSAGES/zh",
"jquery.browser": "components/jquery.browser/dist/jquery.browser", "jquery.browser": "components/jquery.browser/dist/jquery.browser",
"utils": "src/utils",
"underscore": "components/underscore/underscore", "underscore": "components/underscore/underscore",
"backbone": "components/backbone/backbone", "backbone": "components/backbone/backbone",
"backbone.browserStorage": "components/backbone.browserStorage/backbone.browserStorage", "backbone.browserStorage": "components/backbone.browserStorage/backbone.browserStorage",
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
"ru": "locale/ru/LC_MESSAGES/ru", "ru": "locale/ru/LC_MESSAGES/ru",
"zh": "locale/zh/LC_MESSAGES/zh", "zh": "locale/zh/LC_MESSAGES/zh",
"jquery.browser": "components/jquery.browser/dist/jquery.browser", "jquery.browser": "components/jquery.browser/dist/jquery.browser",
"utils": "src/utils",
"underscore": "components/underscore/underscore", "underscore": "components/underscore/underscore",
"backbone": "components/backbone/backbone", "backbone": "components/backbone/backbone",
"backbone.browserStorage": "components/backbone.browserStorage/backbone.browserStorage", "backbone.browserStorage": "components/backbone.browserStorage/backbone.browserStorage",
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
"backbone.overview": "components/backbone.overview/backbone.overview", "backbone.overview": "components/backbone.overview/backbone.overview",
"bootstrap": "components/bootstrap/dist/js/bootstrap", // XXX: Only required for https://conversejs.org website "bootstrap": "components/bootstrap/dist/js/bootstrap", // XXX: Only required for https://conversejs.org website
"jquery.easing": "components/jquery-easing-original/jquery.easing.1.3", // XXX: Only required for https://conversejs.org website "jquery.easing": "components/jquery-easing-original/jquery.easing.1.3", // XXX: Only required for https://conversejs.org website
"utils": "src/utils",
"strophe": "components/strophe/strophe", "strophe": "components/strophe/strophe",
"strophe.muc": "components/strophe.muc/index", "strophe.muc": "components/strophe.muc/index",
"strophe.roster": "components/strophe.roster/index", "strophe.roster": "components/strophe.roster/index",
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
"ru": "locale/ru/LC_MESSAGES/ru", "ru": "locale/ru/LC_MESSAGES/ru",
"zh": "locale/zh/LC_MESSAGES/zh", "zh": "locale/zh/LC_MESSAGES/zh",
"jquery.browser": "components/jquery.browser/dist/jquery.browser", "jquery.browser": "components/jquery.browser/dist/jquery.browser",
"utils": "src/utils",
"underscore": "components/underscore/underscore", "underscore": "components/underscore/underscore",
"backbone": "components/backbone/backbone", "backbone": "components/backbone/backbone",
"backbone.browserStorage": "components/backbone.browserStorage/backbone.browserStorage", "backbone.browserStorage": "components/backbone.browserStorage/backbone.browserStorage",
......
...@@ -5,6 +5,7 @@ define("converse-dependencies", [ ...@@ -5,6 +5,7 @@ define("converse-dependencies", [
"backbone.browserStorage", "backbone.browserStorage",
"backbone.overview", "backbone.overview",
"jquery.browser", "jquery.browser",
"utils",
"strophe", "strophe",
"strophe.muc", "strophe.muc",
"strophe.roster", "strophe.roster",
......
...@@ -4,6 +4,7 @@ define("converse-dependencies", [ ...@@ -4,6 +4,7 @@ define("converse-dependencies", [
"backbone.browserStorage", "backbone.browserStorage",
"backbone.overview", "backbone.overview",
"jquery.browser", "jquery.browser",
"utils",
"strophe", "strophe",
"strophe.muc", "strophe.muc",
"strophe.roster", "strophe.roster",
......
...@@ -6,6 +6,7 @@ define("converse-dependencies", [ ...@@ -6,6 +6,7 @@ define("converse-dependencies", [
"backbone.overview", "backbone.overview",
"jquery.browser", "jquery.browser",
"jquery.easing", // XXX: Can be removed, only for https://conversejs.org "jquery.easing", // XXX: Can be removed, only for https://conversejs.org
"utils",
"strophe", "strophe",
"strophe.muc", "strophe.muc",
"strophe.roster", "strophe.roster",
......
...@@ -2,11 +2,12 @@ define("converse-dependencies", [ ...@@ -2,11 +2,12 @@ define("converse-dependencies", [
"otr", "otr",
"moment", "moment",
"locales", "locales",
"bootstrap", // XXX: Can be removed, only for https://conversejs.org "bootstrap", // XXX: Only for https://conversejs.org
"backbone.browserStorage", "backbone.browserStorage",
"backbone.overview", "backbone.overview",
"jquery.browser", "jquery.browser",
"jquery.easing", // XXX: Can be removed, only for https://conversejs.org "jquery.easing", // XXX: Only for https://conversejs.org
"utils",
"strophe", "strophe",
"strophe.muc", "strophe.muc",
"strophe.roster", "strophe.roster",
......
...@@ -32,6 +32,7 @@ define("converse-templates", [ ...@@ -32,6 +32,7 @@ define("converse-templates", [
"tpl!src/templates/room_description", "tpl!src/templates/room_description",
"tpl!src/templates/room_item", "tpl!src/templates/room_item",
"tpl!src/templates/room_panel", "tpl!src/templates/room_panel",
"tpl!src/templates/roster",
"tpl!src/templates/roster_item", "tpl!src/templates/roster_item",
"tpl!src/templates/select_option", "tpl!src/templates/select_option",
"tpl!src/templates/status_option", "tpl!src/templates/status_option",
...@@ -73,11 +74,12 @@ define("converse-templates", [ ...@@ -73,11 +74,12 @@ define("converse-templates", [
room_description: arguments[30], room_description: arguments[30],
room_item: arguments[31], room_item: arguments[31],
room_panel: arguments[32], room_panel: arguments[32],
roster_item: arguments[33], roster: arguments[33],
select_option: arguments[34], roster_item: arguments[34],
status_option: arguments[35], select_option: arguments[35],
toggle_chats: arguments[36], status_option: arguments[36],
toolbar: arguments[37], toggle_chats: arguments[37],
trimmed_chat: arguments[38] toolbar: arguments[38],
trimmed_chat: arguments[39]
}; };
}); });
<input class="roster-filter" placeholder="{{placeholder}}">
<select class="filter-type">
<option value="contacts">{{label_contacts}}</option>
<option value="groups">{{label_groups}}</option>
</select>
<dl class="roster-contacts" style="display: block;">
jQuery.fn.hasScrollBar = function() {
if (!$.contains(document, this.get(0))) {
return false;
}
if(this.parent().height() < this.get(0).scrollHeight) {
return true;
}
return false;
};
// Extra test dependencies // Extra test dependencies
config.paths.mock = "tests/mock"; config.paths.mock = "tests/mock";
config.paths.utils = "tests/utils"; config.paths.test_utils = "tests/utils";
config.paths.jasmine = "components/jasmine/lib/jasmine-core/jasmine"; config.paths.jasmine = "components/jasmine/lib/jasmine-core/jasmine";
config.paths["jasmine-html"] = "components/jasmine/lib/jasmine-core/jasmine-html"; config.paths["jasmine-html"] = "components/jasmine/lib/jasmine-core/jasmine-html";
config.paths["console-runner"] = "node_modules/phantom-jasmine/lib/console-runner"; config.paths["console-runner"] = "node_modules/phantom-jasmine/lib/console-runner";
......
(function (root, factory) { (function (root, factory) {
define("utils", [ define("test_utils", [
'jquery', 'jquery',
'mock' 'mock'
], ],
......
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