diff --git a/converse.js b/converse.js index 6490ac0d3..cc5aa215e 100644 --- a/converse.js +++ b/converse.js @@ -710,11 +710,13 @@ createChatRoom: function (ev) { ev.preventDefault(); - var name, jid; + var name, jid, input; if (ev.type === 'click') { jid = $(ev.target).attr('data-room-jid'); } else { - name = $(ev.target).find('input.new-chatroom-name').val().trim().toLowerCase(); + input = this.$el.find('input.new-chatroom-name'); + name = input.val().trim().toLowerCase(); + input.val(''); // Clear the input if (name) { jid = Strophe.escapeNode(name) + '@' + xmppchat.muc_domain; } else { @@ -882,11 +884,11 @@ initialize: function () { xmppchat.connection.muc.join( - this.model.get('jid'), - this.model.get('nick'), - $.proxy(this.onChatRoomMessage, this), - $.proxy(this.onChatRoomPresence, this), - $.proxy(this.onChatRoomRoster, this)); + this.model.get('jid'), + this.model.get('nick'), + $.proxy(this.onChatRoomMessage, this), + $.proxy(this.onChatRoomPresence, this), + $.proxy(this.onChatRoomRoster, this)); this.model.messages.on('add', this.showMessage, this); @@ -983,7 +985,7 @@ }, onChatRoomRoster: function (roster, room) { - // underscore size is needed because roster is on object + // underscore size is needed because roster is an object var controlboxview = xmppchat.chatboxesview.views.controlbox, roster_size = _.size(roster), $participant_list = this.$el.find('.participant-list'), diff --git a/index.html b/index.html index f42b7c4b9..40e510bc5 100644 --- a/index.html +++ b/index.html @@ -16,7 +16,7 @@
View on GitHub -

Converse.js

+

Converse.js

Browser-based Instant Messaging with Strophe.js and Backbone.js

@@ -111,15 +111,14 @@

Licence

Converse.js is released under both the MIT - and GPL licenses.

+ and GPL licenses.

diff --git a/spec/MainSpec.js b/spec/MainSpec.js index b3681bdb6..515aa5423 100644 --- a/spec/MainSpec.js +++ b/spec/MainSpec.js @@ -24,7 +24,8 @@ this.bare_jid = 'dummy@localhost'; mock_connection = { 'muc': { - 'listRooms': function () {} + 'listRooms': function () {}, + 'join': function () {} }, 'jid': this.bare_jid, 'addHandler': function (handler, ns, name, type, id, from, options) { @@ -57,35 +58,44 @@ this.onConnected(mock_connection); this.animate = false; // don't use animations + // Variable declarations for specs + var open_controlbox; + describe("The Control Box", $.proxy(function () { it("is not shown by default", $.proxy(function () { expect(this.rosterview.$el.is(':visible')).toEqual(false); }, xmppchat)); - it("can be opened by clicking a DOM element with class 'toggle-online-users'", $.proxy(function () { + open_controlbox = $.proxy(function () { + // This spec will only pass if the controlbox is not currently + // open yet. + expect($("div#controlbox").is(':visible')).toBe(false); spyOn(this, 'toggleControlBox').andCallThrough(); $('.toggle-online-users').click(); expect(this.toggleControlBox).toHaveBeenCalled(); - }, xmppchat)); - + expect($("div#controlbox").is(':visible')).toBe(true); + }, xmppchat); + it("can be opened by clicking a DOM element with class 'toggle-online-users'", open_controlbox); + describe("The Status Widget", $.proxy(function () { it("can be used to set the current user's chat status", $.proxy(function () { var view = this.xmppstatusview; spyOn(view, 'toggleOptions').andCallThrough(); spyOn(view, 'setStatus').andCallThrough(); view.delegateEvents(); // We need to rebind all events otherwise our spy won't be called - - view.$el.find('a.choose-xmpp-status').click(); - expect(view.toggleOptions).toHaveBeenCalled(); - expect(view.$el.find('a.choose-xmpp-status').hasClass('online')).toBe(false); - + runs(function () { + view.$el.find('a.choose-xmpp-status').click(); + expect(view.toggleOptions).toHaveBeenCalled(); + expect(view.$el.find('a.choose-xmpp-status').hasClass('online')).toBe(false); + }); + waits(250); runs(function () { spyOn(view, 'updateStatusUI').andCallThrough(); view.initialize(); // Rebind events for spy view.$el.find('.dropdown dd ul li a').first().click(); expect(view.setStatus).toHaveBeenCalled(); }); - waits(100); + waits(250); runs($.proxy(function () { expect(view.updateStatusUI).toHaveBeenCalled(); expect(view.$el.find('a.choose-xmpp-status').hasClass('online')).toBe(true); @@ -98,14 +108,16 @@ spyOn(view, 'setStatusMessage').andCallThrough(); spyOn(view, 'renderStatusChangeForm').andCallThrough(); view.delegateEvents(); // We need to rebind all events otherwise our spy won't be called - runs(function () { - view.$el.find('a.change-xmpp-status-message').click(); - expect(view.renderStatusChangeForm).toHaveBeenCalled(); + view.$el.find('a.change-xmpp-status-message').click(); + expect(view.renderStatusChangeForm).toHaveBeenCalled(); + // The async testing here is used only to provide time for + // visual feedback + var msg = 'I am happy'; + runs (function () { + view.$el.find('form input.custom-xmpp-status').val(msg); }); waits(250); - runs(function () { - var msg = 'I am happy'; - view.$el.find('form input.custom-xmpp-status').val(msg); + runs (function () { view.$el.find('form#set-custom-xmpp-status').submit(); expect(view.setStatusMessage).toHaveBeenCalled(); expect(view.$el.find('a.choose-xmpp-status').hasClass('online')).toBe(true); @@ -450,6 +462,9 @@ // in localStorage either. newchatboxes.onConnected(); expect(newchatboxes.length).toEqual(0); + + // Lets open the controlbox again, purely for visual feedback + open_controlbox(); }, xmppchat)); describe("A Chat Message", $.proxy(function () { @@ -517,5 +532,63 @@ }, xmppchat)); }, xmppchat)); + describe("The Controlbox Tabs", $.proxy(function () { + it("consist of two tabs, 'Contacts' and 'ChatRooms', of which 'Contacts' is by default visible", $.proxy(function () { + var cbview = this.chatboxesview.views.controlbox; + var $panels = cbview.$el.find('#controlbox-panes'); + expect($panels.children().length).toBe(2); + expect($panels.children().first().attr('id')).toBe('users'); + expect($panels.children().first().is(':visible')).toBe(true); + expect($panels.children().last().attr('id')).toBe('chatrooms'); + expect($panels.children().last().is(':visible')).toBe(false); + }, xmppchat)); + + describe("The Chatrooms Panel", $.proxy(function () { + + it("is opened by clicking the 'Chatrooms' tab", $.proxy(function () { + var cbview = this.chatboxesview.views.controlbox; + var $tabs = cbview.$el.find('#controlbox-tabs'); + var $panels = cbview.$el.find('#controlbox-panes'); + var $contacts = $panels.children().first(); + var $chatrooms = $panels.children().last(); + spyOn(cbview, 'switchTab').andCallThrough(); + cbview.delegateEvents(); // We need to rebind all events otherwise our spy won't be called + runs(function () { + $tabs.find('li').last().find('a').click(); // Clicks the chatrooms tab + }); + waits(250); + runs(function () { + expect($contacts.is(':visible')).toBe(false); + expect($chatrooms.is(':visible')).toBe(true); + expect(cbview.switchTab).toHaveBeenCalled(); + }); + }, xmppchat)); + + it("contains a form through which a new chatroom can be created", $.proxy(function () { + var roomspanel = this.chatboxesview.views.controlbox.roomspanel; + var $input = roomspanel.$el.find('input.new-chatroom-name'); + expect($input.length).toBe(1); + expect($('.chatroom').length).toBe(0); // There shouldn't be any chatrooms open currently + spyOn(roomspanel, 'createChatRoom').andCallThrough(); + roomspanel.delegateEvents(); // We need to rebind all events otherwise our spy won't be called + runs(function () { + $input.val('Lounge'); + }); + waits('250'); + runs(function () { + roomspanel.$el.find('form').submit(); + expect(roomspanel.createChatRoom).toHaveBeenCalled(); + }); + waits('250'); + runs($.proxy(function () { + expect($('.chatroom').length).toBe(1); // There should now be an open chatroom + }, xmppchat)); + }, xmppchat)); + + + }, xmppchat)); + }, xmppchat)); + + }, xmppchat)); })); diff --git a/stylesheets/stylesheet.css b/stylesheets/stylesheet.css index d00fb4529..b1be82a9b 100644 --- a/stylesheets/stylesheet.css +++ b/stylesheets/stylesheet.css @@ -124,6 +124,10 @@ a { -ms-transition: text-shadow 0.5s ease; } +h1 a { + color: white; +} + #main_content a:hover { color: #0069ba; text-shadow: #5390c8 0px 0px 2px; @@ -300,10 +304,6 @@ Full-Width Styles background: linear-gradient(top, #373737, #212121); } -#header_wrap .inner { - padding: 50px 10px 30px 10px; -} - #project_title { margin: 0; color: #fff; diff --git a/tests.html b/tests.html index 6584eadb1..355632e1c 100644 --- a/tests.html +++ b/tests.html @@ -16,7 +16,7 @@
-

Converse.js

+

Converse.js

Tests