ソースを参照

Case-insensitive matching of moderation commands.

Also add `/subject` as alias to `/topic`
JC Brand 8 年 前
コミット
bcbeb8da6c
4 ファイル変更73 行追加31 行削除
  1. 2 0
      docs/CHANGES.md
  2. 37 1
      spec/chatroom.js
  3. 4 3
      src/converse-chatview.js
  4. 30 27
      src/converse-muc.js

+ 2 - 0
docs/CHANGES.md

@@ -2,6 +2,8 @@
 
 ## 3.0.0 (Unreleased)
 - Use lodash instead of underscore.js [jcbrand]
+- Case insensitive matching of moderation commands. [jcbrand]
+- Add `/subject` as alias to `/topic` [jcbrand]
 
 ## 2.0.5 (2017-02-01)
 - #743, #751, #753 Update to Strophe 1.2.12. SASL-EXTERNAL now has reduced priority, so it won't

+ 37 - 1
spec/chatroom.js

@@ -1151,6 +1151,43 @@
                 test_utils.clearBrowserStorage();
             });
 
+            it("to set the room subject", mock.initConverse(function (converse) {
+                var sent_stanza;
+                test_utils.openChatRoom(converse, 'lounge', 'localhost', 'dummy');
+                var view = converse.chatboxviews.get('lounge@localhost');
+                spyOn(view, 'onMessageSubmitted').andCallThrough();
+                spyOn(view, 'clearChatRoomMessages');
+                spyOn(converse.connection, 'send').andCallFake(function (stanza) {
+                    sent_stanza = stanza;
+                });
+                // Check the alias /topic
+                var $textarea = view.$el.find('.chat-textarea');
+                $textarea.val('/topic This is the room subject');
+                $textarea.trigger($.Event('keypress', {keyCode: 13}));
+                expect(view.onMessageSubmitted).toHaveBeenCalled();
+                expect(converse.connection.send).toHaveBeenCalled();
+                expect(sent_stanza.outerHTML).toBe(
+                    '<message to="lounge@localhost" from="dummy@localhost/resource" type="groupchat" xmlns="jabber:client">'+
+                        '<subject xmlns="jabber:client">This is the room subject</subject>'+
+                    '</message>');
+
+                // Check /subject
+                $textarea.val('/subject This is a new subject');
+                $textarea.trigger($.Event('keypress', {keyCode: 13}));
+                expect(sent_stanza.outerHTML).toBe(
+                    '<message to="lounge@localhost" from="dummy@localhost/resource" type="groupchat" xmlns="jabber:client">'+
+                        '<subject xmlns="jabber:client">This is a new subject</subject>'+
+                    '</message>');
+
+                // Check case insensitivity
+                $textarea.val('/Subject This is yet another subject');
+                $textarea.trigger($.Event('keypress', {keyCode: 13}));
+                expect(sent_stanza.outerHTML).toBe(
+                    '<message to="lounge@localhost" from="dummy@localhost/resource" type="groupchat" xmlns="jabber:client">'+
+                        '<subject xmlns="jabber:client">This is yet another subject</subject>'+
+                    '</message>');
+            }));
+
             it("to clear messages", mock.initConverse(function (converse) {
                 test_utils.openChatRoom(converse, 'lounge', 'localhost', 'dummy');
                 var view = converse.chatboxviews.get('lounge@localhost');
@@ -1160,7 +1197,6 @@
                 view.$el.find('textarea.chat-textarea').trigger($.Event('keypress', {keyCode: 13}));
                 expect(view.onMessageSubmitted).toHaveBeenCalled();
                 expect(view.clearChatRoomMessages).toHaveBeenCalled();
-
             }));
 
             it("to make a user an owner", mock.initConverse(function (converse) {

+ 4 - 3
src/converse-chatview.js

@@ -568,11 +568,12 @@
                 keyPressed: function (ev) {
                     /* Event handler for when a key is pressed in a chat box textarea.
                      */
-                    var $textarea = $(ev.target), message;
+                    var textarea = ev.target, message;
                     if (ev.keyCode === KEY.ENTER) {
                         ev.preventDefault();
-                        message = $textarea.val();
-                        $textarea.val('').focus();
+                        message = textarea.value;
+                        textarea.value = '';
+                        textarea.focus();
                         if (message !== '') {
                             this.onMessageSubmitted(message);
                             converse.emit('messageSend', message);

+ 30 - 27
src/converse-muc.js

@@ -874,17 +874,18 @@
                         return this.sendChatRoomMessage(text);
                     }
                     var match = text.replace(/^\s*/, "").match(/^\/(.*?)(?: (.*))?$/) || [false, '', ''],
-                        args = match[2] && match[2].splitOnce(' ') || [];
-                    switch (match[1]) {
+                        args = match[2] && match[2].splitOnce(' ') || [],
+                        command = match[1].toLowerCase();
+                    switch (command) {
                         case 'admin':
-                            if (!this.validateRoleChangeCommand(match[1], args)) { break; }
+                            if (!this.validateRoleChangeCommand(command, args)) { break; }
                             this.setAffiliation('admin',
                                     [{ 'jid': args[0],
                                        'reason': args[1]
                                     }]).fail(this.onCommandError.bind(this));
                             break;
                         case 'ban':
-                            if (!this.validateRoleChangeCommand(match[1], args)) { break; }
+                            if (!this.validateRoleChangeCommand(command, args)) { break; }
                             this.setAffiliation('outcast',
                                     [{ 'jid': args[0],
                                        'reason': args[1]
@@ -894,44 +895,45 @@
                             this.clearChatRoomMessages();
                             break;
                         case 'deop':
-                            if (!this.validateRoleChangeCommand(match[1], args)) { break; }
+                            if (!this.validateRoleChangeCommand(command, args)) { break; }
                             this.modifyRole(
                                     this.model.get('jid'), args[0], 'occupant', args[1],
                                     undefined, this.onCommandError.bind(this));
                             break;
                         case 'help':
                             this.showHelpMessages([
-                                '<strong>/admin</strong>: ' +__("Change user's affiliation to admin"),
-                                '<strong>/ban</strong>: '   +__('Ban user from room'),
-                                '<strong>/clear</strong>: ' +__('Remove messages'),
-                                '<strong>/deop</strong>: '  +__('Change user role to occupant'),
-                                '<strong>/help</strong>: '  +__('Show this menu'),
-                                '<strong>/kick</strong>: '  +__('Kick user from room'),
-                                '<strong>/me</strong>: '    +__('Write in 3rd person'),
-                                '<strong>/member</strong>: '+__('Grant membership to a user'),
-                                '<strong>/mute</strong>: '  +__("Remove user's ability to post messages"),
-                                '<strong>/nick</strong>: '  +__('Change your nickname'),
-                                '<strong>/op</strong>: '    +__('Grant moderator role to user'),
-                                '<strong>/owner</strong>: ' +__('Grant ownership of this room'),
-                                '<strong>/revoke</strong>: '+__("Revoke user's membership"),
-                                '<strong>/topic</strong>: ' +__('Set room topic'),
-                                '<strong>/voice</strong>: ' +__('Allow muted user to post messages')
+                                '<strong>/admin</strong>: '   +__("Change user's affiliation to admin"),
+                                '<strong>/ban</strong>: '     +__('Ban user from room'),
+                                '<strong>/clear</strong>: '   +__('Remove messages'),
+                                '<strong>/deop</strong>: '    +__('Change user role to occupant'),
+                                '<strong>/help</strong>: '    +__('Show this menu'),
+                                '<strong>/kick</strong>: '    +__('Kick user from room'),
+                                '<strong>/me</strong>: '      +__('Write in 3rd person'),
+                                '<strong>/member</strong>: '  +__('Grant membership to a user'),
+                                '<strong>/mute</strong>: '    +__("Remove user's ability to post messages"),
+                                '<strong>/nick</strong>: '    +__('Change your nickname'),
+                                '<strong>/op</strong>: '      +__('Grant moderator role to user'),
+                                '<strong>/owner</strong>: '   +__('Grant ownership of this room'),
+                                '<strong>/revoke</strong>: '  +__("Revoke user's membership"),
+                                '<strong>/subject</strong>: ' +__('Set room subject'),
+                                '<strong>/topic</strong>: '   +__('Set room subject (alias for /subject)'),
+                                '<strong>/voice</strong>: '   +__('Allow muted user to post messages')
                             ]);
                             break;
                         case 'kick':
-                            if (!this.validateRoleChangeCommand(match[1], args)) { break; }
+                            if (!this.validateRoleChangeCommand(command, args)) { break; }
                             this.modifyRole(
                                     this.model.get('jid'), args[0], 'none', args[1],
                                     undefined, this.onCommandError.bind(this));
                             break;
                         case 'mute':
-                            if (!this.validateRoleChangeCommand(match[1], args)) { break; }
+                            if (!this.validateRoleChangeCommand(command, args)) { break; }
                             this.modifyRole(
                                     this.model.get('jid'), args[0], 'visitor', args[1],
                                     undefined, this.onCommandError.bind(this));
                             break;
                         case 'member':
-                            if (!this.validateRoleChangeCommand(match[1], args)) { break; }
+                            if (!this.validateRoleChangeCommand(command, args)) { break; }
                             this.setAffiliation('member',
                                     [{ 'jid': args[0],
                                        'reason': args[1]
@@ -945,26 +947,27 @@
                             }).tree());
                             break;
                         case 'owner':
-                            if (!this.validateRoleChangeCommand(match[1], args)) { break; }
+                            if (!this.validateRoleChangeCommand(command, args)) { break; }
                             this.setAffiliation('owner',
                                     [{ 'jid': args[0],
                                        'reason': args[1]
                                     }]).fail(this.onCommandError.bind(this));
                             break;
                         case 'op':
-                            if (!this.validateRoleChangeCommand(match[1], args)) { break; }
+                            if (!this.validateRoleChangeCommand(command, args)) { break; }
                             this.modifyRole(
                                     this.model.get('jid'), args[0], 'moderator', args[1],
                                     undefined, this.onCommandError.bind(this));
                             break;
                         case 'revoke':
-                            if (!this.validateRoleChangeCommand(match[1], args)) { break; }
+                            if (!this.validateRoleChangeCommand(command, args)) { break; }
                             this.setAffiliation('none',
                                     [{ 'jid': args[0],
                                        'reason': args[1]
                                     }]).fail(this.onCommandError.bind(this));
                             break;
                         case 'topic':
+                        case 'subject':
                             converse.connection.send(
                                 $msg({
                                     to: this.model.get('jid'),
@@ -974,7 +977,7 @@
                             );
                             break;
                         case 'voice':
-                            if (!this.validateRoleChangeCommand(match[1], args)) { break; }
+                            if (!this.validateRoleChangeCommand(command, args)) { break; }
                             this.modifyRole(
                                     this.model.get('jid'), args[0], 'occupant', args[1],
                                     undefined, this.onCommandError.bind(this));