ソースを参照

Simplify the boilerplate HTML require even more.

Use id 'conversejs' instead of 'chatpanel'.

The controlbox toggle is now generated via a backbone view, you don't need to
manually include it in your markup.
JC Brand 11 年 前
コミット
38c26013d0
13 ファイル変更235 行追加141 行削除
  1. 6 1
      CHANGES.rst
  2. 6 6
      converse.css
  3. 74 50
      converse.js
  4. BIN
      docs/doctrees/index.doctree
  5. 77 38
      docs/html/_sources/index.txt
  6. 54 19
      docs/html/index.html
  7. 0 0
      docs/html/searchindex.js
  8. 6 13
      docs/source/index.rst
  9. 1 5
      index.html
  10. 1 1
      mockup.html
  11. 1 1
      non_amd.html
  12. 8 6
      spec/MainSpec.js
  13. 1 1
      tests.html

+ 6 - 1
CHANGES.rst

@@ -4,10 +4,15 @@ Changelog
 0.7.0 (Unreleased)
 0.7.0 (Unreleased)
 ------------------
 ------------------
 
 
+.. Note ::
+    This release introduces a backward incompatible change. The boilerplate
+    HTML needed in your webpage for converse.js to work has been reduced to a
+    single div: <div id="conversejs"></div>
+
 * Add a toolbar for single user chat [jcbrand]
 * Add a toolbar for single user chat [jcbrand]
 * Add support for OTR (off-the-record) encryption [jcbrand]
 * Add support for OTR (off-the-record) encryption [jcbrand]
 * Add support for smileys [jcbrand]
 * Add support for smileys [jcbrand]
-* Simplified initial boilerplate markup [jcbrand]
+* Simplified boilerplate markup [jcbrand]
 * New configuration settings, ``xhr_custom_status_url`` and ``xhr_user_search_url`` [jcbrand]
 * New configuration settings, ``xhr_custom_status_url`` and ``xhr_user_search_url`` [jcbrand]
 
 
 0.6.6 (2013-10-16)
 0.6.6 (2013-10-16)

+ 6 - 6
converse.css

@@ -17,12 +17,12 @@
     user-select: none;
     user-select: none;
 }
 }
 
 
-#chatpanel, #chatpanel input {
+#conversejs, #conversejs input {
   color: rgb(79, 79, 79);
   color: rgb(79, 79, 79);
 }
 }
 
 
 
 
-#chatpanel .emoticon {
+#conversejs .emoticon {
     font-size: 14px;
     font-size: 14px;
 }
 }
 
 
@@ -54,7 +54,7 @@ span.spinner.hor_centered {
     position: absolute;
     position: absolute;
 }
 }
 
 
-#chatpanel {
+#conversejs {
     z-index: 99; /*--Keeps the panel on top of all other elements--*/
     z-index: 99; /*--Keeps the panel on top of all other elements--*/
     position: fixed;
     position: fixed;
     bottom: 0; right: 0;
     bottom: 0; right: 0;
@@ -478,7 +478,7 @@ a.close-chatbox-button:active {
     margin-top: 0.5em;
     margin-top: 0.5em;
 }
 }
 
 
-#chatpanel dd.available-chatroom {
+#conversejs dd.available-chatroom {
     overflow-x: hidden;
     overflow-x: hidden;
     text-overflow: ellipsis;
     text-overflow: ellipsis;
     white-space: nowrap;
     white-space: nowrap;
@@ -486,7 +486,7 @@ a.close-chatbox-button:active {
     width: 175px;
     width: 175px;
 }
 }
 
 
-#chatpanel dd.available-chatroom a.open-room {
+#conversejs dd.available-chatroom a.open-room {
     width: 148px;
     width: 148px;
 }
 }
 
 
@@ -613,7 +613,7 @@ dd.available-chatroom:hover a.room-info {
     background-color: #DCEAC5;
     background-color: #DCEAC5;
 }
 }
 
 
-#chatpanel div.controlbox-panes {
+#conversejs div.controlbox-panes {
     background: -moz-linear-gradient(top, rgba(255,255,255,1) 0%, rgba(240,240,240,1) 100%); /* FF3.6+ */
     background: -moz-linear-gradient(top, rgba(255,255,255,1) 0%, rgba(240,240,240,1) 100%); /* FF3.6+ */
     background: -ms-linear-gradient(top, rgba(255,255,255,1) 0%,rgba(240,240,240,1) 100%); /* IE10+ */
     background: -ms-linear-gradient(top, rgba(255,255,255,1) 0%,rgba(240,240,240,1) 100%); /* IE10+ */
     background: -o-linear-gradient(top, rgba(255,255,255,1) 0%,rgba(240,240,240,1) 100%); /* Opera 11.10+ */
     background: -o-linear-gradient(top, rgba(255,255,255,1) 0%,rgba(240,240,240,1) 100%); /* Opera 11.10+ */

+ 74 - 50
converse.js

@@ -110,7 +110,7 @@
         // Translation machinery
         // Translation machinery
         // ---------------------
         // ---------------------
         var __ = $.proxy(function (str) {
         var __ = $.proxy(function (str) {
-            // Translation factory 
+            // Translation factory
             if (this.i18n === undefined) {
             if (this.i18n === undefined) {
                 this.i18n = locales.en;
                 this.i18n = locales.en;
             }
             }
@@ -332,35 +332,6 @@
             this.updateMsgCounter();
             this.updateMsgCounter();
         };
         };
 
 
-        this.showControlBox = function () {
-            var controlbox = this.chatboxes.get('controlbox');
-            if (!controlbox) {
-                this.chatboxes.add({
-                    id: 'controlbox',
-                    box_id: 'controlbox',
-                    visible: true
-                });
-                if (this.connection) {
-                    this.chatboxes.get('controlbox').save();
-                }
-            } else {
-                controlbox.trigger('show');
-            }
-        };
-
-        this.toggleControlBox = function () {
-            if ($("div#controlbox").is(':visible')) {
-                var controlbox = this.chatboxes.get('controlbox');
-                if (this.connection) {
-                    controlbox.destroy();
-                } else {
-                    controlbox.trigger('hide');
-                }
-            } else {
-                this.showControlBox();
-            }
-        };
-
         this.initStatus = function (callback) {
         this.initStatus = function (callback) {
             this.xmppstatus = new this.XMPPStatus();
             this.xmppstatus = new this.XMPPStatus();
             var id = hex_sha1('converse.xmppstatus-'+this.bare_jid);
             var id = hex_sha1('converse.xmppstatus-'+this.bare_jid);
@@ -455,7 +426,7 @@
                     this.set({
                     this.set({
                         'user_id' : Strophe.getNodeFromJid(this.get('jid')),
                         'user_id' : Strophe.getNodeFromJid(this.get('jid')),
                         'box_id' : hex_sha1(this.get('jid')),
                         'box_id' : hex_sha1(this.get('jid')),
-                        'otr_status': this.get('otr_status') || UNENCRYPTED 
+                        'otr_status': this.get('otr_status') || UNENCRYPTED
                     });
                     });
                 }
                 }
             },
             },
@@ -479,14 +450,14 @@
                             'instance_tag': instance_tag
                             'instance_tag': instance_tag
                         };
                         };
                     }
                     }
-                } 
+                }
                 // We need to generate a new key and instance tag
                 // We need to generate a new key and instance tag
                 result = alert(__('Your browser needs to generate a private key, which will be used in your encrypted chat session. This can take up to 30 seconds during which your browser might freeze and become unresponsive.'));
                 result = alert(__('Your browser needs to generate a private key, which will be used in your encrypted chat session. This can take up to 30 seconds during which your browser might freeze and become unresponsive.'));
                 instance_tag = otr.OTR.makeInstanceTag();
                 instance_tag = otr.OTR.makeInstanceTag();
                 key = new otr.DSA();
                 key = new otr.DSA();
                 // Encrypt the key and set in sessionStorage. Also store
                 // Encrypt the key and set in sessionStorage. Also store
                 // instance tag
                 // instance tag
-                window.sessionStorage[hex_sha1(this.id+'priv_key')] = 
+                window.sessionStorage[hex_sha1(this.id+'priv_key')] =
                     cipher.encrypt(crypto.algo.AES, key.packPrivate(), pass).toString();
                     cipher.encrypt(crypto.algo.AES, key.packPrivate(), pass).toString();
                 window.sessionStorage[hex_sha1(this.id+'instance_tag')] = instance_tag;
                 window.sessionStorage[hex_sha1(this.id+'instance_tag')] = instance_tag;
 
 
@@ -1107,10 +1078,10 @@
                             this.$el.find('div.chat-event').remove();
                             this.$el.find('div.chat-event').remove();
                         }
                         }
                     }
                     }
-                } 
+                }
                 if (_.has(item.changed, 'status')) {
                 if (_.has(item.changed, 'status')) {
                     this.showStatusMessage(item.get('status'));
                     this.showStatusMessage(item.get('status'));
-                } 
+                }
                 if (_.has(item.changed, 'image')) {
                 if (_.has(item.changed, 'image')) {
                     this.renderAvatar();
                     this.renderAvatar();
                 }
                 }
@@ -1183,7 +1154,7 @@
                     data.allow_otr = converse.allow_otr && !this.is_chatroom;
                     data.allow_otr = converse.allow_otr && !this.is_chatroom;
                     data.show_emoticons = converse.show_emoticons;
                     data.show_emoticons = converse.show_emoticons;
                     data.otr_translated_status = OTR_TRANSLATED_MAPPING[data.otr_status];
                     data.otr_translated_status = OTR_TRANSLATED_MAPPING[data.otr_status];
-                    data.otr_status_class = OTR_CLASS_MAPPING[data.otr_status]; 
+                    data.otr_status_class = OTR_CLASS_MAPPING[data.otr_status];
                     this.$el.find('.chat-toolbar').html(this.toolbar_template(data));
                     this.$el.find('.chat-toolbar').html(this.toolbar_template(data));
                 }
                 }
                 return this;
                 return this;
@@ -2348,7 +2319,7 @@
         });
         });
 
 
         this.ChatBoxesView = Backbone.View.extend({
         this.ChatBoxesView = Backbone.View.extend({
-            el: '#chatpanel',
+            el: '#conversejs',
 
 
             initialize: function () {
             initialize: function () {
                 // boxesviewinit
                 // boxesviewinit
@@ -2503,7 +2474,7 @@
                 } else if (ask === 'request') {
                 } else if (ask === 'request') {
                     this.$el.addClass('requesting-xmpp-contact');
                     this.$el.addClass('requesting-xmpp-contact');
                     this.$el.html(this.request_template(item.toJSON()));
                     this.$el.html(this.request_template(item.toJSON()));
-                    converse.showControlBox();
+                    converse.controlboxtoggle.showControlBox();
                 } else if (subscription === 'both' || subscription === 'to') {
                 } else if (subscription === 'both' || subscription === 'to') {
                     this.$el.addClass('current-xmpp-contact');
                     this.$el.addClass('current-xmpp-contact');
                     this.$el.html(this.template(
                     this.$el.html(this.template(
@@ -3204,7 +3175,8 @@
                 'submit form#converse-login': 'authenticate'
                 'submit form#converse-login': 'authenticate'
             },
             },
             tab_template: _.template(
             tab_template: _.template(
-                '<li><a class="current" href="#login">'+__('Sign in')+'</a></li>'),
+                '<li><a class="current" href="#login">'+__('Sign in')+'</a></li>'
+            ),
             template: _.template(
             template: _.template(
                 '<form id="converse-login">' +
                 '<form id="converse-login">' +
                 '<label>'+__('XMPP/Jabber Username:')+'</label>' +
                 '<label>'+__('XMPP/Jabber Username:')+'</label>' +
@@ -3212,11 +3184,12 @@
                 '<label>'+__('Password:')+'</label>' +
                 '<label>'+__('Password:')+'</label>' +
                 '<input type="password" name="password">' +
                 '<input type="password" name="password">' +
                 '<input class="login-submit" type="submit" value="'+__('Log In')+'">' +
                 '<input class="login-submit" type="submit" value="'+__('Log In')+'">' +
-                '</form">'),
-
+                '</form">'
+            ),
             bosh_url_input: _.template(
             bosh_url_input: _.template(
                 '<label>'+__('BOSH Service URL:')+'</label>' +
                 '<label>'+__('BOSH Service URL:')+'</label>' +
-                '<input type="text" id="bosh_service_url">'),
+                '<input type="text" id="bosh_service_url">'
+            ),
 
 
             connect: function ($form, jid, password) {
             connect: function ($form, jid, password) {
                 if ($form) {
                 if ($form) {
@@ -3283,18 +3256,69 @@
             }
             }
         });
         });
 
 
+        this.ControlBoxToggle = Backbone.View.extend({
+            tagName: 'a',
+            className: 'toggle-online-users',
+            id: 'toggle-controlbox',
+            events: {
+                'click': 'onClick'
+            },
+            attributes: {
+                'href': "#"
+            },
+
+            template: _.template(
+                '<strong class="conn-feedback">Toggle chat</strong>'+
+                '<strong style="display: none" id="online-count">(0)</strong>'
+            ),
+
+            initialize: function () {
+                this.render();
+            },
+
+            render: function () {
+                $('#conversejs').append(this.$el.html(this.template()));
+                return this;
+            },
+
+            showControlBox: function () {
+                var controlbox = converse.chatboxes.get('controlbox');
+                if (!controlbox) {
+                    converse.chatboxes.add({
+                        id: 'controlbox',
+                        box_id: 'controlbox',
+                        visible: true
+                    });
+                    if (converse.connection) {
+                        converse.chatboxes.get('controlbox').save();
+                    }
+                } else {
+                    controlbox.trigger('show');
+                }
+            },
+
+            onClick: function (e) {
+                e.preventDefault();
+                if ($("div#controlbox").is(':visible')) {
+                    var controlbox = converse.chatboxes.get('controlbox');
+                    if (converse.connection) {
+                        controlbox.destroy();
+                    } else {
+                        controlbox.trigger('hide');
+                    }
+                } else {
+                    this.showControlBox();
+                }
+            }
+        });
+
         // Initialization
         // Initialization
         // --------------
         // --------------
-
         // This is the end of the initialize method.
         // This is the end of the initialize method.
         this.chatboxes = new this.ChatBoxes();
         this.chatboxes = new this.ChatBoxes();
         this.chatboxesview = new this.ChatBoxesView({model: this.chatboxes});
         this.chatboxesview = new this.ChatBoxesView({model: this.chatboxes});
-        $('.toggle-online-users').bind(
-            'click',
-            $.proxy(function (e) {
-                e.preventDefault(); this.toggleControlBox();
-            }, this)
-        );
+        this.controlboxtoggle = new this.ControlBoxToggle();
+
         if ((this.prebind) && (!this.connection)) {
         if ((this.prebind) && (!this.connection)) {
             if ((!this.jid) || (!this.sid) || (!this.rid) || (!this.bosh_service_url)) {
             if ((!this.jid) || (!this.sid) || (!this.rid) || (!this.bosh_service_url)) {
                 this.log('If you set prebind=true, you MUST supply JID, RID and SID values');
                 this.log('If you set prebind=true, you MUST supply JID, RID and SID values');
@@ -3305,7 +3329,7 @@
         } else if (this.connection) {
         } else if (this.connection) {
             this.onConnected();
             this.onConnected();
         }
         }
-        if (this.show_controlbox_by_default) { this.showControlBox(); }
+        if (this.show_controlbox_by_default) { this.controlboxtoggle.showControlBox(); }
     };
     };
     return {
     return {
         'initialize': function (settings, callback) {
         'initialize': function (settings, callback) {

BIN
docs/doctrees/index.doctree


+ 77 - 38
docs/html/_sources/index.txt

@@ -57,14 +57,7 @@ Finally, Converse.js requires a special snippet of HTML markup to be included in
 
 
 ::
 ::
 
 
-    <div id="chatpanel">
-        <div id="collective-xmpp-chat-data"></div>
-        <div id="toggle-controlbox">
-            <a href="#" class="chat toggle-online-users">
-                <strong class="conn-feedback">Toggle chat</strong> <strong style="display: none" id="online-count">(0)</strong>
-            </a>
-        </div>
-    </div>
+    <div id="conversejs"></div>
 
 
 The `index.html <https://github.com/jcbrand/converse.js/blob/master/index.html>`_ file inside the
 The `index.html <https://github.com/jcbrand/converse.js/blob/master/index.html>`_ file inside the
 Converse.js repository serves as a nice usable example of this.
 Converse.js repository serves as a nice usable example of this.
@@ -89,7 +82,7 @@ Introduction
 ============
 ============
 
 
 Even though you can connect to public XMPP servers on the `conversejs.org`_
 Even though you can connect to public XMPP servers on the `conversejs.org`_
-website, *Converse.js* is not really meant to be a "Software-as-a-service" (SaaS) 
+website, *Converse.js* is not really meant to be a "Software-as-a-service" (SaaS)
 webchat.
 webchat.
 
 
 Instead, its goal is to provide the means for website owners to add a tightly
 Instead, its goal is to provide the means for website owners to add a tightly
@@ -153,7 +146,7 @@ Overcoming cross-domain request restrictions
 --------------------------------------------
 --------------------------------------------
 
 
 The domain of the *Converse.js* demo is *conversejs.org*, but the domain of the connection manager is *opkode.im*.
 The domain of the *Converse.js* demo is *conversejs.org*, but the domain of the connection manager is *opkode.im*.
-HTTP requests are made by *Converse.js* to the connection manager via XmlHttpRequests (XHR).  
+HTTP requests are made by *Converse.js* to the connection manager via XmlHttpRequests (XHR).
 Until recently, it was not possible to make such requests to a different domain
 Until recently, it was not possible to make such requests to a different domain
 than the one currently being served (to prevent XSS attacks).
 than the one currently being served (to prevent XSS attacks).
 
 
@@ -202,7 +195,7 @@ Apache
 ::
 ::
 
 
     <VirtualHost *:80>
     <VirtualHost *:80>
-        ServerName mysite.com 
+        ServerName mysite.com
         RewriteEngine On
         RewriteEngine On
         RewriteRule ^/http-bind(.*) http://someothersite.com/http-bind$1 [P,L]
         RewriteRule ^/http-bind(.*) http://someothersite.com/http-bind$1 [P,L]
     </VirtualHost>
     </VirtualHost>
@@ -222,7 +215,7 @@ but this will require custom code on your server.
 
 
 Jack Moffitt has a great `blogpost`_ about this and even provides an `example Django application`_ to demonstrate it.
 Jack Moffitt has a great `blogpost`_ about this and even provides an `example Django application`_ to demonstrate it.
 
 
-.. Note::
+.. Note ::
    If you want to enable single session support, make sure to pass **prebind: true**
    If you want to enable single session support, make sure to pass **prebind: true**
    when you call **converse.initialize** (see ./index.html).
    when you call **converse.initialize** (see ./index.html).
    Additionally you need to pass in valid **jid**, **sid**, **rid** and
    Additionally you need to pass in valid **jid**, **sid**, **rid** and
@@ -240,7 +233,7 @@ XMLHttpRequest call to your server and ask it to return them for you.
 Below is one example of how this could work. An Ajax call is made to the
 Below is one example of how this could work. An Ajax call is made to the
 relative URL **/prebind** and it expects to receive JSON data back.
 relative URL **/prebind** and it expects to receive JSON data back.
 
 
-:: 
+::
 
 
     $.getJSON('/prebind', function (data) {
     $.getJSON('/prebind', function (data) {
         converse.initialize({
         converse.initialize({
@@ -255,13 +248,13 @@ relative URL **/prebind** and it expects to receive JSON data back.
 **Here's what's happening:**
 **Here's what's happening:**
 
 
 The JSON data contains the user's JID (jabber ID), RID, SID and the URL to the
 The JSON data contains the user's JID (jabber ID), RID, SID and the URL to the
-BOSH connection manager. 
+BOSH connection manager.
 
 
 
 
 Facebook integration
 Facebook integration
 ====================
 ====================
 
 
-.. Note :: 
+.. Note ::
     It should be possible to integrate Converse.js with Facebook chat, and
     It should be possible to integrate Converse.js with Facebook chat, and
     below I'll provide some tips and documentation on how to achieve this. That
     below I'll provide some tips and documentation on how to achieve this. That
     said, I don't have a Facebook account and therefore haven't tried to do
     said, I don't have a Facebook account and therefore haven't tried to do
@@ -270,10 +263,10 @@ Facebook integration
 
 
 
 
 Converse.js uses `Strophe.js <http://strophe.im/strophejs>`_ to connect and
 Converse.js uses `Strophe.js <http://strophe.im/strophejs>`_ to connect and
-communicate with the XMPP server. One nice thing about Strophe.js is that it 
+communicate with the XMPP server. One nice thing about Strophe.js is that it
 can be extended via `plugins <http://github.com/strophe/strophejs-plugins>`_.
 can be extended via `plugins <http://github.com/strophe/strophejs-plugins>`_.
 
 
-Here is a `plugin for authenticating with facebook 
+Here is a `plugin for authenticating with facebook
 <https://github.com/kissrobber/turedsocial/blob/master/strophe-plugins/src/facebook.js>`_.
 <https://github.com/kissrobber/turedsocial/blob/master/strophe-plugins/src/facebook.js>`_.
 
 
 You will need your own BOSH connection manager to act as a proxy between
 You will need your own BOSH connection manager to act as a proxy between
@@ -284,7 +277,7 @@ The BOSH connection manager that I make available for
 testing purposes (at https://bind.opkode.im) uses `Punjab <https://github.com/twonds/punjab>`_,
 testing purposes (at https://bind.opkode.im) uses `Punjab <https://github.com/twonds/punjab>`_,
 although there are quite a few other options available as well.
 although there are quite a few other options available as well.
 
 
-When you configure Converse.js, via its ``initialize`` method, you must specify the 
+When you configure Converse.js, via its ``initialize`` method, you must specify the
 `bosh_service_url`_ value, which is to be your BOSH connection manager.
 `bosh_service_url`_ value, which is to be your BOSH connection manager.
 
 
 Please note, to enable Facebook integration, you'll have to
 Please note, to enable Facebook integration, you'll have to
@@ -339,7 +332,7 @@ directory:
     npm install
     npm install
 
 
 This will install all the development dependencies for Converse.js. If you are
 This will install all the development dependencies for Converse.js. If you are
-curious to know what these are, take a look at whats under the *devDependencies* key in 
+curious to know what these are, take a look at whats under the *devDependencies* key in
 `package.json <https://github.com/jcbrand/converse.js/blob/master/package.json>`.
 `package.json <https://github.com/jcbrand/converse.js/blob/master/package.json>`.
 
 
 Install 3rd party dependencies
 Install 3rd party dependencies
@@ -389,7 +382,7 @@ Without AMD and require.js
 ==========================
 ==========================
 
 
 Converse.js can also be used without require.js. If you for some reason prefer
 Converse.js can also be used without require.js. If you for some reason prefer
-to use it this way, please refer to 
+to use it this way, please refer to
 `non_amd.html <https://github.com/jcbrand/converse.js/blob/master/non_amd.html>`_
 `non_amd.html <https://github.com/jcbrand/converse.js/blob/master/non_amd.html>`_
 for an example of how and in what order all the Javascript files that converse.js
 for an example of how and in what order all the Javascript files that converse.js
 depends on need to be loaded.
 depends on need to be loaded.
@@ -402,18 +395,18 @@ Add tests for your bugfix or feature
 ------------------------------------
 ------------------------------------
 
 
 Add a test for any bug fixed or feature added. We use Jasmine
 Add a test for any bug fixed or feature added. We use Jasmine
-for testing. 
+for testing.
 
 
 Take a look at ``tests.html`` and ``spec/MainSpec.js`` to see how
 Take a look at ``tests.html`` and ``spec/MainSpec.js`` to see how
 the tests are implemented.
 the tests are implemented.
 
 
-If you are unsure how to write tests, please 
+If you are unsure how to write tests, please
 `contact me <http://opkode.com/contact>`_ and I'll be happy to help.
 `contact me <http://opkode.com/contact>`_ and I'll be happy to help.
 
 
 Check that the tests pass
 Check that the tests pass
 -------------------------
 -------------------------
 
 
-Check that the Jasmine tests complete sucessfully. Open 
+Check that the Jasmine tests complete sucessfully. Open
 `tests.html <https://github.com/jcbrand/converse.js/blob/master/tests.html>`_
 `tests.html <https://github.com/jcbrand/converse.js/blob/master/tests.html>`_
 in your browser, and the tests will run automatically.
 in your browser, and the tests will run automatically.
 
 
@@ -470,7 +463,7 @@ allow_contact_requests
 
 
 Default = ``true``
 Default = ``true``
 
 
-Allow users to add one another as contacts. If this is set to false, the 
+Allow users to add one another as contacts. If this is set to false, the
 **Add a contact** widget, **Contact Requests** and **Pending Contacts** roster
 **Add a contact** widget, **Contact Requests** and **Pending Contacts** roster
 sections will all not appear. Additionally, all incoming contact requests will be
 sections will all not appear. Additionally, all incoming contact requests will be
 ignored.
 ignored.
@@ -501,7 +494,7 @@ multi-user chat, then a list of rooms on that server will be fetched.
 Not recommended for servers with lots of chat rooms.
 Not recommended for servers with lots of chat rooms.
 
 
 For each room on the server a query is made to fetch further details (e.g.
 For each room on the server a query is made to fetch further details (e.g.
-features, number of occupants etc.), so on servers with many rooms this 
+features, number of occupants etc.), so on servers with many rooms this
 option will create lots of extra connection traffic.
 option will create lots of extra connection traffic.
 
 
 auto_subscribe
 auto_subscribe
@@ -558,7 +551,7 @@ already authenticated (usually on the backend before page load).
 This is useful when you don't want to render the login form on the chat control
 This is useful when you don't want to render the login form on the chat control
 box with each page load.
 box with each page load.
 
 
-For prebinding to work, your backend server must authenticate for you, and 
+For prebinding to work, your backend server must authenticate for you, and
 then return a JID (jabber ID), SID (session ID) and RID (Request ID).
 then return a JID (jabber ID), SID (session ID) and RID (Request ID).
 
 
 If you set ``prebind`` to ``true``, you have to make sure to also pass in these
 If you set ``prebind`` to ``true``, you have to make sure to also pass in these
@@ -589,18 +582,64 @@ Default = ``false``
 If set to ``true``, only online users will be shown in the contacts roster.
 If set to ``true``, only online users will be shown in the contacts roster.
 Users with any other status (e.g. away, busy etc.) will not be shown.
 Users with any other status (e.g. away, busy etc.) will not be shown.
 
 
+xhr_custom_status
+-----------------
+
+Default = ``false``
+
+.. Note ::
+    XHR stands for XMLHTTPRequest, and is meant here in the AJAX sense (Asynchronous Javascript and XML).
+
+This option will let converse.js make an AJAX POST with your changed custom chat status to a
+remote server.
+
+xhr_custom_status_url
+---------------------
+
+.. Note ::
+    XHR stands for XMLHTTPRequest, and is meant here in the AJAX sense (Asynchronous Javascript and XML).
+
+Default = Empty string
+
+Used only in conjunction with ``xhr_custom_status``.
+
+This is the URL to which the AJAX POST request to set the user's custom status
+message will be made.
+
+The message itself is sent in the request under the key ``msg``.
+
 xhr_user_search
 xhr_user_search
 ---------------
 ---------------
 
 
 Default = ``false``
 Default = ``false``
 
 
-There are two ways to add users. 
+.. Note ::
+    XHR stands for XMLHTTPRequest, and is meant here in the AJAX sense (Asynchronous Javascript and XML).
+
+There are two ways to add users.
 
 
 * The user inputs a valid JID (Jabber ID), and the user is added as a pending contact.
 * The user inputs a valid JID (Jabber ID), and the user is added as a pending contact.
-* The user inputs some text (for example part of a firstname or lastname), an XHR will be made to a backend, and a list of matches are returned. The user can then choose one of the matches to add as a contact.
+* The user inputs some text (for example part of a firstname or lastname), an XHR (Ajax Request) will be made to a remote server, and a list of matches are returned. The user can then choose one of the matches to add as a contact.
+
+This setting enables the second mechanism, otherwise by default the first will be used.
+
+*What is expected from the remote server?*
+
+A default JSON encoded list of objects must be returned. Each object
+corresponds to a matched user and needs the keys ``id`` and ``fullname``.
+
+xhr_user_search_url
+-------------------
 
 
-This setting enables the second mechanism, otherwise by default the first will
-be used.
+.. Note ::
+    XHR stands for XMLHTTPRequest, and is meant here in the AJAX sense (Asynchronous Javascript and XML).
+
+Default = Empty string
+
+Used only in conjunction with ``xhr_user_search``.
+
+This is the URL to which an AJAX GET request will be made to fetch user data from your remote server.
+The query string will be included in the request with ``q`` as its key.
 
 
 ============
 ============
 Minification
 Minification
@@ -614,7 +653,7 @@ all development dependencies (long story short, you can run ``npm install``
 and then ``grunt fetch``).
 and then ``grunt fetch``).
 
 
 We  use `require.js`_ to keep track of *Converse.js* and its dependencies and to
 We  use `require.js`_ to keep track of *Converse.js* and its dependencies and to
-to bundle them together in a single minified file fit for deployment to a 
+to bundle them together in a single minified file fit for deployment to a
 production site.
 production site.
 
 
 To minify the Javascript and CSS, run the following command:
 To minify the Javascript and CSS, run the following command:
@@ -635,7 +674,7 @@ CSS is minified via `cssmin <https://github.com/gruntjs/grunt-contrib-cssmin>`_.
 Translations
 Translations
 ============
 ============
 
 
-.. Note :: 
+.. Note ::
    Translations take up a lot of space and will bloat your minified file.
    Translations take up a lot of space and will bloat your minified file.
    At the time of writing, all the translations add about 50KB of extra data to
    At the time of writing, all the translations add about 50KB of extra data to
    the minified javascript file. Therefore, make sure to only
    the minified javascript file. Therefore, make sure to only
@@ -686,9 +725,9 @@ that we're using.
     "domain: converse\n"
     "domain: converse\n"
     "lang: de\n"
     "lang: de\n"
     "plural_forms: nplurals=2; plural=(n != 1);\n"
     "plural_forms: nplurals=2; plural=(n != 1);\n"
-    
 
 
-Unfortunately `Jed <http://slexaxton.github.io/Jed>`_ cannot use the PO files directly. We have to generate from it 
+
+Unfortunately `Jed <http://slexaxton.github.io/Jed>`_ cannot use the PO files directly. We have to generate from it
 a file in JSON format and then put that in a .js file for the specific
 a file in JSON format and then put that in a .js file for the specific
 language.
 language.
 
 
@@ -698,7 +737,7 @@ following command to install it (npm being the node.js package manager):
 ::
 ::
 
 
     npm install po2json
     npm install po2json
-    
+
 You can then convert the translations into JSON format:
 You can then convert the translations into JSON format:
 
 
 ::
 ::
@@ -722,13 +761,13 @@ create or update the file ./locale/LC_MESSAGES/de.js with the following code:
                 }
                 }
             })
             })
         }
         }
-    }(this, function (i18n) { 
-        return i18n; 
+    }(this, function (i18n) {
+        return i18n;
     }));
     }));
 
 
 making sure to also paste the JSON data as value to the "locale_data" key.
 making sure to also paste the JSON data as value to the "locale_data" key.
 
 
-.. Note :: 
+.. Note ::
     If you are adding translations for a new language that is not already supported,
     If you are adding translations for a new language that is not already supported,
     you'll have to make one more edit in ./locale/locales.js to make sure the
     you'll have to make one more edit in ./locale/locales.js to make sure the
     language is loaded by require.js.
     language is loaded by require.js.

+ 54 - 19
docs/html/index.html

@@ -108,16 +108,19 @@
 <li><a class="reference internal" href="#prebind" id="id32">prebind</a></li>
 <li><a class="reference internal" href="#prebind" id="id32">prebind</a></li>
 <li><a class="reference internal" href="#show-controlbox-by-default" id="id33">show_controlbox_by_default</a></li>
 <li><a class="reference internal" href="#show-controlbox-by-default" id="id33">show_controlbox_by_default</a></li>
 <li><a class="reference internal" href="#show-only-online-users" id="id34">show_only_online_users</a></li>
 <li><a class="reference internal" href="#show-only-online-users" id="id34">show_only_online_users</a></li>
-<li><a class="reference internal" href="#xhr-user-search" id="id35">xhr_user_search</a></li>
+<li><a class="reference internal" href="#xhr-custom-status" id="id35">xhr_custom_status</a></li>
+<li><a class="reference internal" href="#xhr-custom-status-url" id="id36">xhr_custom_status_url</a></li>
+<li><a class="reference internal" href="#xhr-user-search" id="id37">xhr_user_search</a></li>
+<li><a class="reference internal" href="#xhr-user-search-url" id="id38">xhr_user_search_url</a></li>
 </ul>
 </ul>
 </li>
 </li>
 </ul>
 </ul>
 </li>
 </li>
-<li><a class="reference internal" href="#minification" id="id36">Minification</a><ul>
-<li><a class="reference internal" href="#minifying-javascript-and-css" id="id37">Minifying Javascript and CSS</a></li>
+<li><a class="reference internal" href="#minification" id="id39">Minification</a><ul>
+<li><a class="reference internal" href="#minifying-javascript-and-css" id="id40">Minifying Javascript and CSS</a></li>
 </ul>
 </ul>
 </li>
 </li>
-<li><a class="reference internal" href="#translations" id="id38">Translations</a></li>
+<li><a class="reference internal" href="#translations" id="id41">Translations</a></li>
 </ul>
 </ul>
 </div>
 </div>
 <div class="section" id="quickstart-to-get-a-demo-up-and-running">
 <div class="section" id="quickstart-to-get-a-demo-up-and-running">
@@ -152,14 +155,7 @@ bottom of your page (after the closing <em>&lt;/body&gt;</em> element).</p>
 });</pre>
 });</pre>
 </div>
 </div>
 <p>Finally, Converse.js requires a special snippet of HTML markup to be included in your page:</p>
 <p>Finally, Converse.js requires a special snippet of HTML markup to be included in your page:</p>
-<div class="highlight-python"><pre>&lt;div id="chatpanel"&gt;
-    &lt;div id="collective-xmpp-chat-data"&gt;&lt;/div&gt;
-    &lt;div id="toggle-controlbox"&gt;
-        &lt;a href="#" class="chat toggle-online-users"&gt;
-            &lt;strong class="conn-feedback"&gt;Toggle chat&lt;/strong&gt; &lt;strong style="display: none" id="online-count"&gt;(0)&lt;/strong&gt;
-        &lt;/a&gt;
-    &lt;/div&gt;
-&lt;/div&gt;</pre>
+<div class="highlight-python"><pre>&lt;div id="conversejs"&gt;&lt;/div&gt;</pre>
 </div>
 </div>
 <p>The <a class="reference external" href="https://github.com/jcbrand/converse.js/blob/master/index.html">index.html</a> file inside the
 <p>The <a class="reference external" href="https://github.com/jcbrand/converse.js/blob/master/index.html">index.html</a> file inside the
 Converse.js repository serves as a nice usable example of this.</p>
 Converse.js repository serves as a nice usable example of this.</p>
@@ -547,23 +543,62 @@ page load.</p>
 <p>If set to <tt class="docutils literal"><span class="pre">true</span></tt>, only online users will be shown in the contacts roster.
 <p>If set to <tt class="docutils literal"><span class="pre">true</span></tt>, only online users will be shown in the contacts roster.
 Users with any other status (e.g. away, busy etc.) will not be shown.</p>
 Users with any other status (e.g. away, busy etc.) will not be shown.</p>
 </div>
 </div>
+<div class="section" id="xhr-custom-status">
+<h3><a class="toc-backref" href="#id35">xhr_custom_status</a><a class="headerlink" href="#xhr-custom-status" title="Permalink to this headline">¶</a></h3>
+<p>Default = <tt class="docutils literal"><span class="pre">false</span></tt></p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">XHR stands for XMLHTTPRequest, and is meant here in the AJAX sense (Asynchronous Javascript and XML).</p>
+</div>
+<p>This option will let converse.js make an AJAX POST with your changed custom chat status to a
+remote server.</p>
+</div>
+<div class="section" id="xhr-custom-status-url">
+<h3><a class="toc-backref" href="#id36">xhr_custom_status_url</a><a class="headerlink" href="#xhr-custom-status-url" title="Permalink to this headline">¶</a></h3>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">XHR stands for XMLHTTPRequest, and is meant here in the AJAX sense (Asynchronous Javascript and XML).</p>
+</div>
+<p>Default = Empty string</p>
+<p>Used only in conjunction with <tt class="docutils literal"><span class="pre">xhr_custom_status</span></tt>.</p>
+<p>This is the URL to which the AJAX POST request to set the user&#8217;s custom status
+message will be made.</p>
+<p>The message itself is sent in the request under the key <tt class="docutils literal"><span class="pre">msg</span></tt>.</p>
+</div>
 <div class="section" id="xhr-user-search">
 <div class="section" id="xhr-user-search">
-<h3><a class="toc-backref" href="#id35">xhr_user_search</a><a class="headerlink" href="#xhr-user-search" title="Permalink to this headline">¶</a></h3>
+<h3><a class="toc-backref" href="#id37">xhr_user_search</a><a class="headerlink" href="#xhr-user-search" title="Permalink to this headline">¶</a></h3>
 <p>Default = <tt class="docutils literal"><span class="pre">false</span></tt></p>
 <p>Default = <tt class="docutils literal"><span class="pre">false</span></tt></p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">XHR stands for XMLHTTPRequest, and is meant here in the AJAX sense (Asynchronous Javascript and XML).</p>
+</div>
 <p>There are two ways to add users.</p>
 <p>There are two ways to add users.</p>
 <ul class="simple">
 <ul class="simple">
 <li>The user inputs a valid JID (Jabber ID), and the user is added as a pending contact.</li>
 <li>The user inputs a valid JID (Jabber ID), and the user is added as a pending contact.</li>
-<li>The user inputs some text (for example part of a firstname or lastname), an XHR will be made to a backend, and a list of matches are returned. The user can then choose one of the matches to add as a contact.</li>
+<li>The user inputs some text (for example part of a firstname or lastname), an XHR (Ajax Request) will be made to a remote server, and a list of matches are returned. The user can then choose one of the matches to add as a contact.</li>
 </ul>
 </ul>
-<p>This setting enables the second mechanism, otherwise by default the first will
-be used.</p>
+<p>This setting enables the second mechanism, otherwise by default the first will be used.</p>
+<p><em>What is expected from the remote server?</em></p>
+<p>A default JSON encoded list of objects must be returned. Each object
+corresponds to a matched user and needs the keys <tt class="docutils literal"><span class="pre">id</span></tt> and <tt class="docutils literal"><span class="pre">fullname</span></tt>.</p>
+</div>
+<div class="section" id="xhr-user-search-url">
+<h3><a class="toc-backref" href="#id38">xhr_user_search_url</a><a class="headerlink" href="#xhr-user-search-url" title="Permalink to this headline">¶</a></h3>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">XHR stands for XMLHTTPRequest, and is meant here in the AJAX sense (Asynchronous Javascript and XML).</p>
+</div>
+<p>Default = Empty string</p>
+<p>Used only in conjunction with <tt class="docutils literal"><span class="pre">xhr_user_search</span></tt>.</p>
+<p>This is the URL to which an AJAX GET request will be made to fetch user data from your remote server.
+The query string will be included in the request with <tt class="docutils literal"><span class="pre">q</span></tt> as its key.</p>
 </div>
 </div>
 </div>
 </div>
 </div>
 </div>
 <div class="section" id="minification">
 <div class="section" id="minification">
-<h1><a class="toc-backref" href="#id36">Minification</a><a class="headerlink" href="#minification" title="Permalink to this headline">¶</a></h1>
+<h1><a class="toc-backref" href="#id39">Minification</a><a class="headerlink" href="#minification" title="Permalink to this headline">¶</a></h1>
 <div class="section" id="minifying-javascript-and-css">
 <div class="section" id="minifying-javascript-and-css">
-<h2><a class="toc-backref" href="#id37">Minifying Javascript and CSS</a><a class="headerlink" href="#minifying-javascript-and-css" title="Permalink to this headline">¶</a></h2>
+<h2><a class="toc-backref" href="#id40">Minifying Javascript and CSS</a><a class="headerlink" href="#minifying-javascript-and-css" title="Permalink to this headline">¶</a></h2>
 <p>Please make sure to read the section <a class="reference internal" href="#development">Development</a> and that you have installed
 <p>Please make sure to read the section <a class="reference internal" href="#development">Development</a> and that you have installed
 all development dependencies (long story short, you can run <tt class="docutils literal"><span class="pre">npm</span> <span class="pre">install</span></tt>
 all development dependencies (long story short, you can run <tt class="docutils literal"><span class="pre">npm</span> <span class="pre">install</span></tt>
 and then <tt class="docutils literal"><span class="pre">grunt</span> <span class="pre">fetch</span></tt>).</p>
 and then <tt class="docutils literal"><span class="pre">grunt</span> <span class="pre">fetch</span></tt>).</p>
@@ -580,7 +615,7 @@ using <a class="reference external" href="https://github.com/jrburke/almond">alm
 </div>
 </div>
 </div>
 </div>
 <div class="section" id="translations">
 <div class="section" id="translations">
-<h1><a class="toc-backref" href="#id38">Translations</a><a class="headerlink" href="#translations" title="Permalink to this headline">¶</a></h1>
+<h1><a class="toc-backref" href="#id41">Translations</a><a class="headerlink" href="#translations" title="Permalink to this headline">¶</a></h1>
 <div class="admonition note">
 <div class="admonition note">
 <p class="first admonition-title">Note</p>
 <p class="first admonition-title">Note</p>
 <p class="last">Translations take up a lot of space and will bloat your minified file.
 <p class="last">Translations take up a lot of space and will bloat your minified file.

ファイルの差分が大きいため隠しています
+ 0 - 0
docs/html/searchindex.js


+ 6 - 13
docs/source/index.rst

@@ -57,14 +57,7 @@ Finally, Converse.js requires a special snippet of HTML markup to be included in
 
 
 ::
 ::
 
 
-    <div id="chatpanel">
-        <div id="collective-xmpp-chat-data"></div>
-        <div id="toggle-controlbox">
-            <a href="#" class="chat toggle-online-users">
-                <strong class="conn-feedback">Toggle chat</strong> <strong style="display: none" id="online-count">(0)</strong>
-            </a>
-        </div>
-    </div>
+    <div id="conversejs"></div>
 
 
 The `index.html <https://github.com/jcbrand/converse.js/blob/master/index.html>`_ file inside the
 The `index.html <https://github.com/jcbrand/converse.js/blob/master/index.html>`_ file inside the
 Converse.js repository serves as a nice usable example of this.
 Converse.js repository serves as a nice usable example of this.
@@ -222,7 +215,7 @@ but this will require custom code on your server.
 
 
 Jack Moffitt has a great `blogpost`_ about this and even provides an `example Django application`_ to demonstrate it.
 Jack Moffitt has a great `blogpost`_ about this and even provides an `example Django application`_ to demonstrate it.
 
 
-.. Note::
+.. Note ::
    If you want to enable single session support, make sure to pass **prebind: true**
    If you want to enable single session support, make sure to pass **prebind: true**
    when you call **converse.initialize** (see ./index.html).
    when you call **converse.initialize** (see ./index.html).
    Additionally you need to pass in valid **jid**, **sid**, **rid** and
    Additionally you need to pass in valid **jid**, **sid**, **rid** and
@@ -594,7 +587,7 @@ xhr_custom_status
 
 
 Default = ``false``
 Default = ``false``
 
 
-Note::
+.. Note ::
     XHR stands for XMLHTTPRequest, and is meant here in the AJAX sense (Asynchronous Javascript and XML).
     XHR stands for XMLHTTPRequest, and is meant here in the AJAX sense (Asynchronous Javascript and XML).
 
 
 This option will let converse.js make an AJAX POST with your changed custom chat status to a
 This option will let converse.js make an AJAX POST with your changed custom chat status to a
@@ -603,7 +596,7 @@ remote server.
 xhr_custom_status_url
 xhr_custom_status_url
 ---------------------
 ---------------------
 
 
-Note::
+.. Note ::
     XHR stands for XMLHTTPRequest, and is meant here in the AJAX sense (Asynchronous Javascript and XML).
     XHR stands for XMLHTTPRequest, and is meant here in the AJAX sense (Asynchronous Javascript and XML).
 
 
 Default = Empty string
 Default = Empty string
@@ -620,7 +613,7 @@ xhr_user_search
 
 
 Default = ``false``
 Default = ``false``
 
 
-Note::
+.. Note ::
     XHR stands for XMLHTTPRequest, and is meant here in the AJAX sense (Asynchronous Javascript and XML).
     XHR stands for XMLHTTPRequest, and is meant here in the AJAX sense (Asynchronous Javascript and XML).
 
 
 There are two ways to add users.
 There are two ways to add users.
@@ -638,7 +631,7 @@ corresponds to a matched user and needs the keys ``id`` and ``fullname``.
 xhr_user_search_url
 xhr_user_search_url
 -------------------
 -------------------
 
 
-Note::
+.. Note ::
     XHR stands for XMLHTTPRequest, and is meant here in the AJAX sense (Asynchronous Javascript and XML).
     XHR stands for XMLHTTPRequest, and is meant here in the AJAX sense (Asynchronous Javascript and XML).
 
 
 Default = Empty string
 Default = Empty string

+ 1 - 5
index.html

@@ -178,11 +178,7 @@
     </footer>
     </footer>
 </div>
 </div>
 
 
-<div id="chatpanel">
-    <a id="toggle-controlbox" href="#" class="chat toggle-online-users">
-        <strong class="conn-feedback">Toggle chat</strong> <strong style="display: none" id="online-count">(0)</strong>
-    </a>
-</div>
+<div id="conversejs"></div>
 
 
 <script type="text/javascript">
 <script type="text/javascript">
     var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
     var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");

+ 1 - 1
mockup.html

@@ -19,7 +19,7 @@
     </header>
     </header>
 </div>
 </div>
 
 
-<div id="chatpanel" style="width: 100%;">
+<div id="conversejs" style="width: 100%;">
     <div id="controlbox" class="chatbox" style="opacity: 1; display: inline;">
     <div id="controlbox" class="chatbox" style="opacity: 1; display: inline;">
         <div class="chat-head oc-chat-head">
         <div class="chat-head oc-chat-head">
             <ul id="controlbox-tabs">
             <ul id="controlbox-tabs">

+ 1 - 1
non_amd.html

@@ -163,7 +163,7 @@
     </footer>
     </footer>
 </div>
 </div>
 
 
-<div id="chatpanel">
+<div id="conversejs">
     <div id="collective-xmpp-chat-data"></div>
     <div id="collective-xmpp-chat-data"></div>
     <div id="toggle-controlbox">
     <div id="toggle-controlbox">
         <a href="#" class="chat toggle-online-users">
         <a href="#" class="chat toggle-online-users">

+ 8 - 6
spec/MainSpec.js

@@ -46,11 +46,13 @@
                 // This spec will only pass if the controlbox is not currently
                 // This spec will only pass if the controlbox is not currently
                 // open yet.
                 // open yet.
                 expect($("div#controlbox").is(':visible')).toBe(false);
                 expect($("div#controlbox").is(':visible')).toBe(false);
-                spyOn(this, 'toggleControlBox').andCallThrough();
-                spyOn(this, 'showControlBox').andCallThrough();
+                spyOn(this.controlboxtoggle, 'onClick').andCallThrough();
+                spyOn(this.controlboxtoggle, 'showControlBox').andCallThrough();
+                // Redelegate so that the spies are now registered as the event handlers (specifically for 'onClick')
+                this.controlboxtoggle.delegateEvents();
                 $('.toggle-online-users').click();
                 $('.toggle-online-users').click();
-                expect(this.toggleControlBox).toHaveBeenCalled();
-                expect(this.showControlBox).toHaveBeenCalled();
+                expect(this.controlboxtoggle.onClick).toHaveBeenCalled();
+                expect(this.controlboxtoggle.showControlBox).toHaveBeenCalled();
                 expect($("div#controlbox").is(':visible')).toBe(true);
                 expect($("div#controlbox").is(':visible')).toBe(true);
             }, converse);
             }, converse);
             it("can be opened by clicking a DOM element with class 'toggle-online-users'", open_controlbox);
             it("can be opened by clicking a DOM element with class 'toggle-online-users'", open_controlbox);
@@ -345,7 +347,7 @@
                 it("can be added to the roster and they will be sorted alphabetically", $.proxy(function () {
                 it("can be added to the roster and they will be sorted alphabetically", $.proxy(function () {
                     var i, t;
                     var i, t;
                     spyOn(this.rosterview, 'render').andCallThrough();
                     spyOn(this.rosterview, 'render').andCallThrough();
-                    spyOn(this, 'showControlBox').andCallThrough();
+                    spyOn(this.controlboxtoggle, 'showControlBox').andCallThrough();
                     for (i=0; i<req_names.length; i++) {
                     for (i=0; i<req_names.length; i++) {
                         this.roster.create({
                         this.roster.create({
                             jid: req_names[i].replace(/ /g,'.').toLowerCase() + '@localhost',
                             jid: req_names[i].replace(/ /g,'.').toLowerCase() + '@localhost',
@@ -360,7 +362,7 @@
                         expect(t).toEqual(req_names.slice(0,i+1).sort().join(''));
                         expect(t).toEqual(req_names.slice(0,i+1).sort().join(''));
                         // When a requesting contact is added, the controlbox must
                         // When a requesting contact is added, the controlbox must
                         // be opened.
                         // be opened.
-                        expect(this.showControlBox).toHaveBeenCalled();
+                        expect(this.controlboxtoggle.showControlBox).toHaveBeenCalled();
                     }
                     }
                 }, converse));
                 }, converse));
 
 

+ 1 - 1
tests.html

@@ -19,7 +19,7 @@
         </header>
         </header>
     </div>
     </div>
 
 
-    <div id="chatpanel">
+    <div id="conversejs">
         <div id="collective-xmpp-chat-data"></div>
         <div id="collective-xmpp-chat-data"></div>
         <div id="toggle-controlbox">
         <div id="toggle-controlbox">
             <a href="#" class="chat toggle-online-users">
             <a href="#" class="chat toggle-online-users">

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません