Sfoglia il codice sorgente

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

JC Brand 8 anni fa
parent
commit
0d4993ef86

+ 1 - 1
.travis.yml

@@ -1,6 +1,6 @@
 language: node_js
 node_js:
- - "0.10"
+ - 6
 before_script: make dev
 script: make check
 sudo: false

+ 1 - 1
README.md

@@ -48,7 +48,7 @@ which shows you how to use the CDN (content delivery network) to quickly get a d
 -   **[Ruby on Rails](http://rubyonrails.org)**: [conversejs-rails](https://github.com/mikemarsian/conversejs-rails)
 -   **[Django](http://www.djangoproject.com)**: [django-conversejs](https://pypi.python.org/pypi/django-conversejs) or [django-xmpp](https://github.com/fpytloun/django-xmpp)
 -   **[Plone](http://plone.com)**: [collective.xmpp.chat](http://github.com/collective/collective.xmpp.chat)
--   **[Roundcube](http://roundcube.net)**: [roundcube-converse.js-xmpp-plugin](https://github.com/priyadi/roundcube-converse.js-xmpp-plugin)
+-   **[Roundcube](http://roundcube.net)**: [roundcube-converse.js-xmpp-plugin](https://github.com/devurandom/roundcube-converse.js-xmpp-plugin)
 -   **[Wordpress](http://wordpress.org)**: [ConverseJS](http://wordpress.org/plugins/conversejs)
 -   **[Patternslib](http://patternslib.com)**: [patterns.converse](https://github.com/jcbrand/patterns.converse)
 -   **[Alfresco](http://www.alfresco.com)**: [alfresco-js-chat-share](https://github.com/keensoft/alfresco-js-chat-share)

+ 1 - 0
config.js

@@ -139,6 +139,7 @@ require.config({
         "chatroom_nickname_form":   "src/templates/chatroom_nickname_form",
         "chatroom_password_form":   "src/templates/chatroom_password_form",
         "chatroom_sidebar":         "src/templates/chatroom_sidebar",
+        "chatroom_toolbar":         "src/templates/chatroom_toolbar",
         "chatrooms_tab":            "src/templates/chatrooms_tab",
         "chats_panel":              "src/templates/chats_panel",
         "choose_status":            "src/templates/choose_status",

+ 7 - 0
docs/source/events.rst

@@ -118,6 +118,13 @@ Once converse.js has been initialized.
 
 See also `pluginsInitialized`_.
 
+logout
+~~~~~~
+
+The user has logged out.
+
+``converse.listen.on('logout', function (event) { ... });``
+
 messageSend
 ~~~~~~~~~~~
 

+ 1 - 1
index.html

@@ -116,7 +116,7 @@
                             <li><a href="http://github.com/collective/collective.xmpp.chat" target="_blank">Plone</a></li>
                             <li><a href="https://pypi.python.org/pypi/django-conversejs" target="_blank">Django (option 1)</a></li>
                             <li><a href="https://github.com/fpytloun/django-xmpp" target="_blank">Django (option 2)</a></li>
-                            <li><a href="https://github.com/priyadi/roundcube-converse.js-xmpp-plugin" target="_blank">Roundcube</a></li>
+                            <li><a href="https://github.com/devurandom/roundcube-converse.js-xmpp-plugin" target="_blank">Roundcube</a></li>
                             <li><a href="http://wordpress.org/plugins/conversejs" target="_blank">Wordpress</a></li>
                             <li><a href="https://github.com/jcbrand/patterns.converse" target="_blank">Patternslib</a></li>
                             <li><a href="https://github.com/keensoft/alfresco-js-chat-share" target="_blank">Alfresco</a></li>

+ 40 - 55
locale/it/LC_MESSAGES/converse.po

@@ -1,14 +1,15 @@
-# German translations for Converse.js package.
+# Italian translations for Converse.js package.
 # Copyright (C) 2013 Jan-Carel Brand
 # This file is distributed under the same license as the Converse.js package.
 # JC Brand <jc@opkode.com>, 2013.
+# Camaran <camaran@gmail.com>, 2016.
 #
 msgid ""
 msgstr ""
 "Project-Id-Version: Converse.js 0.4\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2016-09-16 11:45+0000\n"
-"PO-Revision-Date: 2016-04-07 10:23+0000\n"
+"PO-Revision-Date: 2016-11-01 11:24+0100\n"
 "Last-Translator: Fabio Bas <ctrlaltca@gmail.com>\n"
 "Language-Team: Italian\n"
 "Language: it\n"
@@ -19,18 +20,16 @@ msgstr ""
 "domain: converse\n"
 "lang: it\n"
 "plural_forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Poedit 1.8.4\n"
+"X-Generator: Poedit 1.8.11\n"
 
 #: src/converse-chatview.js:103 src/converse-headline.js:99
 #: src/converse-muc.js:252
-#, fuzzy
 msgid "You have unread messages"
-msgstr "Rimuovi messaggi"
+msgstr "Hai messaggi non letti"
 
 #: src/converse-chatview.js:104
-#, fuzzy
 msgid "Close this chat box"
-msgstr "Clicca per ripristinare questa chat"
+msgstr "Chiudi questa chat"
 
 #: src/converse-chatview.js:105
 msgid "Personal message"
@@ -57,7 +56,7 @@ msgstr "ha smesso di scrivere"
 #: src/converse-chatview.js:344 src/converse-chatview.js:598
 #: src/converse-notification.js:171
 msgid "has gone away"
-msgstr ""
+msgstr "si è allontanato"
 
 #: src/converse-chatview.js:468 src/converse-muc.js:468
 msgid "Show this menu"
@@ -73,11 +72,11 @@ msgstr "Rimuovi messaggi"
 
 #: src/converse-chatview.js:551
 msgid "Are you sure you want to clear the messages from this chat box?"
-msgstr ""
+msgstr "Sei sicuro di volere pulire i messaggi da questo chat box?"
 
 #: src/converse-chatview.js:596 src/converse-notification.js:169
 msgid "has gone offline"
-msgstr ""
+msgstr "è andato offline"
 
 #: src/converse-chatview.js:600 src/converse-notification.js:173
 msgid "is busy"
@@ -89,15 +88,15 @@ msgstr "Pulisci tutti i messaggi"
 
 #: src/converse-chatview.js:644
 msgid "Hide the list of occupants"
-msgstr ""
+msgstr "Nascondi la lista degli occupanti"
 
 #: src/converse-chatview.js:645
 msgid "Insert a smiley"
-msgstr ""
+msgstr "Inserisci uno smiley"
 
 #: src/converse-chatview.js:646
 msgid "Start a call"
-msgstr ""
+msgstr "Inizia una chiamata"
 
 #: src/converse-controlbox.js:191 src/converse-core.js:616
 #: src/converse-core.js:685 src/converse-rosterview.js:62
@@ -125,9 +124,8 @@ msgid "Log In"
 msgstr "Entra"
 
 #: src/converse-controlbox.js:381
-#, fuzzy
 msgid "Username"
-msgstr "XMPP Username:"
+msgstr "Username"
 
 #: src/converse-controlbox.js:381
 msgid "user@server"
@@ -212,9 +210,8 @@ msgid "Search"
 msgstr "Cerca"
 
 #: src/converse-controlbox.js:599
-#, fuzzy
 msgid "e.g. user@example.org"
-msgstr "es. user@example.com"
+msgstr "es. user@example.org"
 
 #: src/converse-controlbox.js:600
 msgid "Add"
@@ -245,9 +242,8 @@ msgid "Click to hide these contacts"
 msgstr "Clicca per nascondere questi contatti"
 
 #: src/converse-core.js:413
-#, fuzzy
 msgid "Reconnecting"
-msgstr "Connessione in corso"
+msgstr "Riconnessione"
 
 #: src/converse-core.js:413
 msgid "The connection has dropped, attempting to reconnect."
@@ -262,23 +258,20 @@ msgid "The connection to the chat server has dropped"
 msgstr ""
 
 #: src/converse-core.js:481
-#, fuzzy
 msgid "Connection error"
-msgstr "Connessione fallita"
+msgstr "Errore di connessione"
 
 #: src/converse-core.js:482
-#, fuzzy
 msgid "An error occurred while connecting to the chat server."
-msgstr "Errore durante il salvataggio del modulo"
+msgstr "Si è verificato un errore durante la connessione al server."
 
 #: src/converse-core.js:487
 msgid "Authenticating"
 msgstr "Autenticazione in corso"
 
 #: src/converse-core.js:489
-#, fuzzy
 msgid "Authentication failed."
-msgstr "Autenticazione fallita"
+msgstr "Autenticazione fallita."
 
 #: src/converse-core.js:490
 msgid "Authentication Failed"
@@ -293,14 +286,12 @@ msgid "This client does not allow presence subscriptions"
 msgstr "Questo client non consente sottoscrizioni di presenza"
 
 #: src/converse-headline.js:100
-#, fuzzy
 msgid "Close this box"
-msgstr "Clicca per ripristinare questa chat"
+msgstr "Chiudi questo box"
 
 #: src/converse-headline.js:101
-#, fuzzy
 msgid "Minimize this box"
-msgstr "Ridotto"
+msgstr "Riduci questo box"
 
 #: src/converse-minimize.js:315
 msgid "Click to restore this chat"
@@ -312,7 +303,7 @@ msgstr "Ridotto"
 
 #: src/converse-minimize.js:488
 msgid "Minimize this chat box"
-msgstr ""
+msgstr "Riduci questo chat box"
 
 #: src/converse-muc.js:254
 msgid "Message"
@@ -367,9 +358,8 @@ msgid "Grant moderator role to user"
 msgstr ""
 
 #: src/converse-muc.js:475
-#, fuzzy
 msgid "Grant ownership of this room"
-msgstr "Non sei nella lista dei membri di questa stanza"
+msgstr ""
 
 #: src/converse-muc.js:476
 msgid "Revoke user's membership"
@@ -397,19 +387,19 @@ msgid ""
 "The nickname you chose is reserved or currently in use, please choose a "
 "different one."
 msgstr ""
+"Il nickname scelto è riservato o attualmente in uso, indicane uno diverso."
 
 #: src/converse-muc.js:816
 msgid "Please choose your nickname"
-msgstr ""
+msgstr "Scegli il tuo nickname"
 
 #: src/converse-muc.js:817 src/converse-muc.js:1348
 msgid "Nickname"
 msgstr "Soprannome"
 
 #: src/converse-muc.js:818
-#, fuzzy
 msgid "Enter room"
-msgstr "Stanza aperta"
+msgstr "Entra nella stanza"
 
 #: src/converse-muc.js:836
 msgid "This chatroom requires a password"
@@ -558,33 +548,28 @@ msgid "This room does not (yet) exist"
 msgstr "Questa stanza non esiste (per ora)"
 
 #: src/converse-muc.js:1002
-#, fuzzy
 msgid "This room has reached its maximum number of occupants"
-msgstr "Questa stanza ha raggiunto il limite massimo di utenti"
+msgstr "Questa stanza ha raggiunto il limite massimo di occupanti"
 
 #: src/converse-muc.js:1059
 msgid "Topic set by %1$s to: %2$s"
 msgstr "Topic impostato da %1$s a: %2$s"
 
 #: src/converse-muc.js:1146
-#, fuzzy
 msgid "Click to mention this user in your message."
-msgstr "Clicca per aprire questa stanza"
+msgstr "Clicca per menzionare questo utente nel tuo messaggio."
 
 #: src/converse-muc.js:1147
-#, fuzzy
 msgid "This user is a moderator."
-msgstr "Questo utente è un moderatore"
+msgstr "Questo utente è un moderatore."
 
 #: src/converse-muc.js:1148
-#, fuzzy
 msgid "This user can send messages in this room."
-msgstr "Questo utente può inviare messaggi in questa stanza"
+msgstr "Questo utente può inviare messaggi in questa stanza."
 
 #: src/converse-muc.js:1149
-#, fuzzy
 msgid "This user can NOT send messages in this room."
-msgstr "Questo utente NON può inviare messaggi in questa stanza"
+msgstr "Questo utente NON può inviare messaggi in questa stanza."
 
 #: src/converse-muc.js:1185
 msgid "Invite"
@@ -715,16 +700,15 @@ msgstr ""
 #. give type "headline"
 #: src/converse-notification.js:136
 msgid "Notification from %1$s"
-msgstr ""
+msgstr "Notifica da %1$s"
 
 #: src/converse-notification.js:139 src/converse-notification.js:147
 msgid "%1$s says"
-msgstr ""
+msgstr "%1$s dice"
 
 #: src/converse-notification.js:175
-#, fuzzy
 msgid "has come online"
-msgstr "Questo contatto è online"
+msgstr "è online"
 
 #: src/converse-notification.js:190
 msgid "wants to be your contact"
@@ -733,11 +717,11 @@ msgstr ""
 #. Verified that the passphrase is still the same
 #: src/converse-otr.js:152
 msgid "Re-establishing encrypted session"
-msgstr ""
+msgstr "Ristabilisci sessione criptata"
 
 #: src/converse-otr.js:164
 msgid "Generating private key."
-msgstr ""
+msgstr "Generazione chiave private in corso."
 
 #: src/converse-otr.js:165
 msgid "Your browser might become unresponsive."
@@ -946,11 +930,12 @@ msgid "Return"
 msgstr ""
 
 #: src/converse-register.js:366
-#, fuzzy
 msgid ""
 "The provider rejected your registration attempt. Please check the values you "
 "entered for correctness."
-msgstr "Il provider ha respinto il tentativo di registrazione."
+msgstr ""
+"Il provider ha respinto il tentativo di registrazione. Controlla i dati "
+"inseriti."
 
 #: src/converse-rosterview.js:55
 msgid "This contact is busy"
@@ -998,7 +983,7 @@ msgstr "Senza Gruppo"
 
 #: src/converse-rosterview.js:123
 msgid "Filter"
-msgstr ""
+msgstr "Filtri"
 
 #: src/converse-rosterview.js:126
 msgid "State"
@@ -1014,7 +999,7 @@ msgstr ""
 
 #: src/converse-rosterview.js:132
 msgid "Extended Away"
-msgstr ""
+msgstr "Away estesa"
 
 #: src/converse-rosterview.js:595 src/converse-rosterview.js:616
 msgid "Click to remove this contact"

+ 9 - 0
spec/utils.js

@@ -44,6 +44,15 @@
             expect(context.visible_toolbar_buttons.call).toBeFalsy();
             expect(context.visible_toolbar_buttons.toggle_occupants).toBeFalsy();
             expect(context.visible_toolbar_buttons.invalid).toBeFalsy();
+
+            user_settings = {
+                visible_toolbar_buttons: {
+                    'toggle_occupants': true
+                }
+            };
+            utils.applyUserSettings(context, settings, user_settings);
+            expect(Object.keys(context.visible_toolbar_buttons)).toEqual(Object.keys(settings.visible_toolbar_buttons));
+            expect(context.visible_toolbar_buttons.toggle_occupants).toBeTruthy();
         });
     });
 }));

+ 3 - 1
src/converse-bookmarks.js

@@ -341,7 +341,9 @@
                     })).hide();
                     this.model.each(this.renderBookmarkListElement, this);
                     var controlboxview = converse.chatboxviews.get('controlbox');
-                    this.$el.prependTo(controlboxview.$('#chatrooms'));
+                    if (!_.isUndefined(controlboxview)) {
+                        this.$el.prependTo(controlboxview.$('#chatrooms'));
+                    }
                     return this.$el;
                 },
 

+ 20 - 18
src/converse-chatview.js

@@ -84,8 +84,7 @@
                 visible_toolbar_buttons: {
                     'emoticons': true,
                     'call': false,
-                    'clear': true,
-                    'toggle_occupants': true // Leaky abstraction from MUC
+                    'clear': true
                 },
             });
 
@@ -97,7 +96,7 @@
 
                 events: {
                     'click .close-chatbox-button': 'close',
-                    'keypress textarea.chat-textarea': 'keyPressed',
+                    'keypress .chat-textarea': 'keyPressed',
                     'click .toggle-smiley': 'toggleEmoticonMenu',
                     'click .toggle-smiley ul li': 'insertEmoticon',
                     'click .toggle-clear': 'clearMessages',
@@ -667,22 +666,25 @@
                     return this;
                 },
 
-                renderToolbar: function (options) {
-                    if (!converse.show_toolbar) {
-                        return;
-                    }
-                    options = _.extend(options || {}, {
-                        label_clear: __('Clear all messages'),
-                        label_hide_occupants: __('Hide the list of occupants'),
-                        label_insert_smiley: __('Insert a smiley'),
-                        label_start_call: __('Start a call'),
-                        show_call_button: converse.visible_toolbar_buttons.call,
-                        show_clear_button: converse.visible_toolbar_buttons.clear,
-                        show_emoticons: converse.visible_toolbar_buttons.emoticons,
-                        // FIXME Leaky abstraction MUC
-                        show_occupants_toggle: this.is_chatroom && converse.visible_toolbar_buttons.toggle_occupants
+                getToolbarOptions: function (options) {
+                    return _.extend(options || {}, {
+                        'label_clear': __('Clear all messages'),
+                        'label_insert_smiley': __('Insert a smiley'),
+                        'label_start_call': __('Start a call'),
+                        'show_call_button': converse.visible_toolbar_buttons.call,
+                        'show_clear_button': converse.visible_toolbar_buttons.clear,
+                        'show_emoticons': converse.visible_toolbar_buttons.emoticons,
                     });
-                    this.$el.find('.chat-toolbar').html(converse.templates.toolbar(_.extend(this.model.toJSON(), options || {})));
+                },
+
+                renderToolbar: function (toolbar, options) {
+                    if (!converse.show_toolbar) { return; }
+                    toolbar = toolbar || converse.templates.toolbar;
+                    options = _.extend(
+                        this.model.toJSON(),
+                        this.getToolbarOptions(options || {})
+                    );
+                    this.$el.find('.chat-toolbar').html(toolbar(options));
                     return this;
                 },
 

+ 3 - 2
src/converse-core.js

@@ -542,6 +542,7 @@
                 converse.connection.disconnect();
                 converse.connection.reset();
             }
+            converse.emit('logout');
         };
 
         this.saveWindowState = function (ev, hidden) {
@@ -1946,8 +1947,8 @@
             /* Helper method which gets put on the plugin and allows it to
              * add more user-facing config settings to converse.js.
              */
-            _.extend(converse.default_settings, settings);
-            _.extend(converse, settings);
+            utils.merge(converse.default_settings, settings);
+            utils.merge(converse, settings);
             utils.applyUserSettings(converse, settings, converse.user_settings);
         };
         converse.pluggable.initializePlugins({

+ 19 - 4
src/converse-muc.js

@@ -19,6 +19,7 @@
             "tpl!chatroom_nickname_form",
             "tpl!chatroom_password_form",
             "tpl!chatroom_sidebar",
+            "tpl!chatroom_toolbar",
             "tpl!chatrooms_tab",
             "tpl!info",
             "tpl!occupant",
@@ -37,6 +38,7 @@
             tpl_chatroom_nickname_form,
             tpl_chatroom_password_form,
             tpl_chatroom_sidebar,
+            tpl_chatroom_toolbar,
             tpl_chatrooms_tab,
             tpl_info,
             tpl_occupant,
@@ -215,7 +217,10 @@
                 muc_domain: undefined,
                 muc_history_max_stanzas: undefined,
                 muc_instant_rooms: true,
-                muc_nickname_from_jid: false
+                muc_nickname_from_jid: false,
+                visible_toolbar_buttons: {
+                    'toggle_occupants': true
+                },
             });
 
 
@@ -237,7 +242,7 @@
                     'click .toggle-occupants a': 'toggleOccupants',
                     'click .new-msgs-indicator': 'viewUnreadMessages',
                     'click .occupant': 'onOccupantClicked',
-                    'keypress textarea.chat-textarea': 'keyPressed'
+                    'keypress .chat-textarea': 'keyPressed'
                 },
 
                 initialize: function () {
@@ -304,13 +309,23 @@
                                     'label_message': __('Message')
                                 }))
                             .append(this.occupantsview.render().$el);
-                        this.renderToolbar();
+                        this.renderToolbar(tpl_chatroom_toolbar);
                         this.$content = this.$el.find('.chat-content');
                     }
                     this.toggleOccupants(null, true);
                     return this;
                 },
 
+                getToolbarOptions: function () {
+                    return _.extend(
+                        converse.ChatBoxView.prototype.getToolbarOptions.apply(this, arguments),
+                        {
+                          label_hide_occupants: __('Hide the list of occupants'),
+                          show_occupants_toggle: this.is_chatroom && converse.visible_toolbar_buttons.toggle_occupants
+                        }
+                    );
+                },
+
                 close: function (ev) {
                     this.leave();
                     converse.ChatBoxView.prototype.close.apply(this, arguments);
@@ -415,7 +430,7 @@
                         type: 'groupchat',
                         id: msgid
                     }).c("body").t(text).up()
-                    .c("x", {xmlns: "jabber:x:event"}).c("composing");
+                    .c("x", {xmlns: "jabber:x:event"}).c(converse.COMPOSING);
                     converse.connection.send(msg);
                     this.model.messages.create({
                         fullname: this.model.get('nick'),

+ 2 - 2
src/converse-otr.js

@@ -426,7 +426,7 @@
                     }
                 },
 
-                renderToolbar: function (options) {
+                renderToolbar: function (toolbar, options) {
                     var converse = this.__super__.converse;
                     if (!converse.show_toolbar) {
                         return;
@@ -449,7 +449,7 @@
                         otr_tooltip: this.getOTRTooltip(),
                         otr_translated_status: OTR_TRANSLATED_MAPPING[data.otr_status],
                     });
-                    this.__super__.renderToolbar.call(this, options);
+                    this.__super__.renderToolbar.apply(this, arguments);
                     this.$el.find('.chat-toolbar').append(
                             converse.templates.toolbar_otr(
                                 _.extend(this.model.toJSON(), options || {})

+ 29 - 0
src/templates/chatroom_toolbar.html

@@ -0,0 +1,29 @@
+{[ if (show_emoticons)  { ]}
+    <li class="toggle-smiley icon-happy" title="{{label_insert_smiley}}">
+        <ul>
+            <li><a class="icon-smiley" href="#" data-emoticon=":)"></a></li>
+            <li><a class="icon-wink" href="#" data-emoticon=";)"></a></li>
+            <li><a class="icon-grin" href="#" data-emoticon=":D"></a></li>
+            <li><a class="icon-tongue" href="#" data-emoticon=":P"></a></li>
+            <li><a class="icon-cool" href="#" data-emoticon="8)"></a></li>
+            <li><a class="icon-evil" href="#" data-emoticon=">:)"></a></li>
+            <li><a class="icon-confused" href="#" data-emoticon=":S"></a></li>
+            <li><a class="icon-wondering" href="#" data-emoticon=":\"></a></li>
+            <li><a class="icon-angry" href="#" data-emoticon=">:("></a></li>
+            <li><a class="icon-sad" href="#" data-emoticon=":("></a></li>
+            <li><a class="icon-shocked" href="#" data-emoticon=":O"></a></li>
+            <li><a class="icon-thumbs-up" href="#" data-emoticon="(^.^)b"></a></li>
+            <li><a class="icon-heart" href="#" data-emoticon="<3"></a></li>
+        </ul>
+    </li>
+{[ } ]}
+{[ if (show_call_button)  { ]}
+<li class="toggle-call"><a class="icon-phone" title="{{label_start_call}}"></a></li>
+{[ } ]}
+{[ if (show_occupants_toggle)  { ]}
+<li class="toggle-occupants"><a class="icon-hide-users" title="{{label_hide_occupants}}"></a></li>
+{[ } ]}
+{[ if (show_clear_button)  { ]}
+<li class="toggle-clear"><a class="icon-remove" title="{{label_clear}}"></a></li>
+{[ } ]}
+

+ 0 - 3
src/templates/toolbar.html

@@ -20,9 +20,6 @@
 {[ if (show_call_button)  { ]}
 <li class="toggle-call"><a class="icon-phone" title="{{label_start_call}}"></a></li>
 {[ } ]}
-{[ if (show_occupants_toggle)  { ]}
-<li class="toggle-occupants"><a class="icon-hide-users" title="{{label_hide_occupants}}"></a></li>
-{[ } ]}
 {[ if (show_clear_button)  { ]}
 <li class="toggle-clear"><a class="icon-remove" title="{{label_clear}}"></a></li>
 {[ } ]}

+ 12 - 0
src/utils.js

@@ -233,6 +233,18 @@
             return false;
         },
 
+        merge: function merge (first, second) {
+            /* Merge the second object into the first one.
+             */
+            for (var k in second) {
+                if (_.isObject(first[k])) {
+                    merge(first[k], second[k]);
+                } else {
+                    first[k] = second[k];
+                }
+            }
+        },
+
         applyUserSettings: function applyUserSettings (context, settings, user_settings) {
             /* Configuration settings might be nested objects. We only want to
              * add settings which are whitelisted.

+ 0 - 1
tests.html

@@ -9,7 +9,6 @@
     <link type="text/css" rel="stylesheet" media="screen" href="css/theme.css" />
     <link type="text/css" rel="stylesheet" media="screen" href="css/converse.css" />
     <script src="config.js"></script>
-    <script src="converse.js"></script>
     <script data-main="tests/main" src="node_modules/requirejs/require.js"></script>
 </head>