Browse Source

Fixes #537 Open xmpp: URIs inside Converse

JC Brand 6 năm trước cách đây
mục cha
commit
99c0687684

+ 19 - 5
dist/converse.js

@@ -68945,11 +68945,12 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
           'click .chatbox-navback': 'showControlBox',
           'click .chatbox-navback': 'showControlBox',
           'click .close-chatbox-button': 'close',
           'click .close-chatbox-button': 'close',
           'click .configure-chatroom-button': 'getAndRenderConfigurationForm',
           'click .configure-chatroom-button': 'getAndRenderConfigurationForm',
-          'click .show-room-details-modal': 'showRoomDetailsModal',
           'click .hide-occupants': 'hideOccupants',
           'click .hide-occupants': 'hideOccupants',
           'click .new-msgs-indicator': 'viewUnreadMessages',
           'click .new-msgs-indicator': 'viewUnreadMessages',
           'click .occupant-nick': 'onOccupantClicked',
           'click .occupant-nick': 'onOccupantClicked',
+          'click a.open-chatroom': 'openChatRoomFromURIClicked',
           'click .send-button': 'onFormSubmitted',
           'click .send-button': 'onFormSubmitted',
+          'click .show-room-details-modal': 'showRoomDetailsModal',
           'click .toggle-call': 'toggleCall',
           'click .toggle-call': 'toggleCall',
           'click .toggle-occupants': 'toggleOccupants',
           'click .toggle-occupants': 'toggleOccupants',
           'click .toggle-smiley ul.emoji-picker li': 'insertEmoji',
           'click .toggle-smiley ul.emoji-picker li': 'insertEmoji',
@@ -69284,6 +69285,12 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
           this.insertIntoTextArea(ev.target.textContent);
           this.insertIntoTextArea(ev.target.textContent);
         },
         },
 
 
+        openChatRoomFromURIClicked(ev) {
+          ev.preventDefault();
+
+          _converse.api.rooms.open(ev.target.href);
+        },
+
         handleChatStateNotification(message) {
         handleChatStateNotification(message) {
           /* Override the method on the ChatBoxView base class to
           /* Override the method on the ChatBoxView base class to
            * ignore <gone/> notifications in groupchats.
            * ignore <gone/> notifications in groupchats.
@@ -72164,6 +72171,10 @@ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
       };
       };
 
 
       const createChatRoom = function createChatRoom(jid, attrs) {
       const createChatRoom = function createChatRoom(jid, attrs) {
+        if (jid.startsWith('xmpp:') && jid.endsWith('?join')) {
+          jid = jid.replace(/^xmpp:/, '').replace(/\?join$/, '');
+        }
+
         return getChatRoom(jid, attrs, true);
         return getChatRoom(jid, attrs, true);
       };
       };
 
 
@@ -79418,9 +79429,7 @@ __e( o.Strophe.getNodeFromJid(o.jid) ) +
 __e( o.Strophe.getDomainFromJid(o.jid) ) +
 __e( o.Strophe.getDomainFromJid(o.jid) ) +
 '\n        ';
 '\n        ';
  } ;
  } ;
-__p += '\n    </div>\n    <!-- Sanitized in converse-muc-views. We want to render links. -->\n    <p class="chatroom-description" title="' +
-__e(o.description) +
-'">' +
+__p += '\n    </div>\n    <!-- Sanitized in converse-muc-views. We want to render links. -->\n    <p class="chatroom-description">' +
 ((__t = (o.description)) == null ? '' : __t) +
 ((__t = (o.description)) == null ? '' : __t) +
 '</p>\n</div>\n<div class="chatbox-buttons row no-gutters">\n    <a class="chatbox-btn close-chatbox-button fa fa-sign-out-alt" title="' +
 '</p>\n</div>\n<div class="chatbox-buttons row no-gutters">\n    <a class="chatbox-btn close-chatbox-button fa fa-sign-out-alt" title="' +
 __e(o.info_close) +
 __e(o.info_close) +
@@ -82057,6 +82066,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
 
 
   u.addHyperlinks = function (text) {
   u.addHyperlinks = function (text) {
     return URI.withinString(text, url => {
     return URI.withinString(text, url => {
+      let classes = '';
       const uri = new URI(url);
       const uri = new URI(url);
       url = uri.normalize()._string;
       url = uri.normalize()._string;
       const pretty_url = uri._parts.urn ? url : uri.readable();
       const pretty_url = uri._parts.urn ? url : uri.readable();
@@ -82065,7 +82075,11 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
         url = 'http://' + url;
         url = 'http://' + url;
       }
       }
 
 
-      return `<a target="_blank" rel="noopener" href="${url}">${u.escapeHTML(pretty_url)}</a>`;
+      if (uri._parts.protocol === 'xmpp' && uri._parts.query === 'join') {
+        classes += 'open-chatroom';
+      }
+
+      return `<a target="_blank" rel="noopener" class="${classes}" href="${url}">${u.escapeHTML(pretty_url)}</a>`;
     }, {
     }, {
       'start': /\b(?:([a-z][a-z0-9.+-]*:\/\/)|xmpp:|mailto:|www\.)/gi
       'start': /\b(?:([a-z][a-z0-9.+-]*:\/\/)|xmpp:|mailto:|www\.)/gi
     });
     });

+ 32 - 0
spec/chatroom.js

@@ -411,6 +411,38 @@
 
 
         describe("A Groupchat", function () {
         describe("A Groupchat", function () {
 
 
+            it("is opened when an xmpp: URI is clicked inside another groupchat",
+                mock.initConverseWithPromises(
+                    null, ['rosterGroupsFetched'], {},
+                    function (done, _converse) {
+
+                let view;
+                test_utils.createContacts(_converse, 'current');
+                test_utils.waitUntil(() => test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy'))
+                .then(() => {
+                    view = _converse.chatboxviews.get('lounge@localhost');
+                    if (!view.el.querySelectorAll('.chat-area').length) {
+                        view.renderChatArea();
+                    }
+                    expect(_converse.chatboxes.length).toEqual(2);
+                    const message = 'Please go to xmpp:coven@chat.shakespeare.lit?join',
+                          nick = mock.chatroom_names[0],
+                          msg = $msg({
+                            'from': 'lounge@localhost/'+nick,
+                            'id': (new Date()).getTime(),
+                            'to': 'dummy@localhost',
+                            'type': 'groupchat'
+                        }).c('body').t(message).tree();
+
+                    view.model.onMessage(msg);
+                    view.el.querySelector('.chat-msg__text a').click();
+                    return test_utils.waitUntil(() => _converse.chatboxes.length === 3)
+                }).then(() => {
+                    expect(_.includes(_converse.chatboxes.pluck('id'), 'coven@chat.shakespeare.lit')).toBe(true);
+                    done()
+                }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL))
+            }));
+
             it("shows a notification if its not anonymous",
             it("shows a notification if its not anonymous",
                     mock.initConverseWithPromises(
                     mock.initConverseWithPromises(
                         null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                         null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},

+ 7 - 1
src/converse-muc-views.js

@@ -509,11 +509,12 @@
                     'click .chatbox-navback': 'showControlBox',
                     'click .chatbox-navback': 'showControlBox',
                     'click .close-chatbox-button': 'close',
                     'click .close-chatbox-button': 'close',
                     'click .configure-chatroom-button': 'getAndRenderConfigurationForm',
                     'click .configure-chatroom-button': 'getAndRenderConfigurationForm',
-                    'click .show-room-details-modal': 'showRoomDetailsModal',
                     'click .hide-occupants': 'hideOccupants',
                     'click .hide-occupants': 'hideOccupants',
                     'click .new-msgs-indicator': 'viewUnreadMessages',
                     'click .new-msgs-indicator': 'viewUnreadMessages',
                     'click .occupant-nick': 'onOccupantClicked',
                     'click .occupant-nick': 'onOccupantClicked',
+                    'click a.open-chatroom': 'openChatRoomFromURIClicked',
                     'click .send-button': 'onFormSubmitted',
                     'click .send-button': 'onFormSubmitted',
+                    'click .show-room-details-modal': 'showRoomDetailsModal',
                     'click .toggle-call': 'toggleCall',
                     'click .toggle-call': 'toggleCall',
                     'click .toggle-occupants': 'toggleOccupants',
                     'click .toggle-occupants': 'toggleOccupants',
                     'click .toggle-smiley ul.emoji-picker li': 'insertEmoji',
                     'click .toggle-smiley ul.emoji-picker li': 'insertEmoji',
@@ -813,6 +814,11 @@
                     this.insertIntoTextArea(ev.target.textContent);
                     this.insertIntoTextArea(ev.target.textContent);
                 },
                 },
 
 
+                openChatRoomFromURIClicked (ev) {
+                    ev.preventDefault();
+                    _converse.api.rooms.open(ev.target.href);
+                },
+
                 handleChatStateNotification (message) {
                 handleChatStateNotification (message) {
                     /* Override the method on the ChatBoxView base class to
                     /* Override the method on the ChatBoxView base class to
                      * ignore <gone/> notifications in groupchats.
                      * ignore <gone/> notifications in groupchats.

+ 3 - 0
src/converse-muc.js

@@ -1275,6 +1275,9 @@
             };
             };
 
 
             const createChatRoom = function (jid, attrs) {
             const createChatRoom = function (jid, attrs) {
+                if (jid.startsWith('xmpp:') && jid.endsWith('?join')) {
+                    jid = jid.replace(/^xmpp:/, '').replace(/\?join$/, '');
+                }
                 return getChatRoom(jid, attrs, true);
                 return getChatRoom(jid, attrs, true);
             };
             };
 
 

+ 1 - 1
src/templates/chatroom_head.html

@@ -8,7 +8,7 @@
         {[ } ]}
         {[ } ]}
     </div>
     </div>
     <!-- Sanitized in converse-muc-views. We want to render links. -->
     <!-- Sanitized in converse-muc-views. We want to render links. -->
-    <p class="chatroom-description" title="{{{o.description}}}">{{o.description}}</p>
+    <p class="chatroom-description">{{o.description}}</p>
 </div>
 </div>
 <div class="chatbox-buttons row no-gutters">
 <div class="chatbox-buttons row no-gutters">
     <a class="chatbox-btn close-chatbox-button fa fa-sign-out-alt" title="{{{o.info_close}}}"></a>
     <a class="chatbox-btn close-chatbox-button fa fa-sign-out-alt" title="{{{o.info_close}}}"></a>

+ 5 - 1
src/utils/core.js

@@ -262,13 +262,17 @@
 
 
     u.addHyperlinks = function (text) {
     u.addHyperlinks = function (text) {
         return URI.withinString(text, url => {
         return URI.withinString(text, url => {
+            let classes = '';
             const uri = new URI(url);
             const uri = new URI(url);
             url = uri.normalize()._string;
             url = uri.normalize()._string;
             const pretty_url = uri._parts.urn ? url : uri.readable();
             const pretty_url = uri._parts.urn ? url : uri.readable();
             if (!uri._parts.protocol && !url.startsWith('http://') && !url.startsWith('https://')) {
             if (!uri._parts.protocol && !url.startsWith('http://') && !url.startsWith('https://')) {
                 url = 'http://' + url;
                 url = 'http://' + url;
             }
             }
-            return `<a target="_blank" rel="noopener" href="${url}">${u.escapeHTML(pretty_url)}</a>`;
+            if (uri._parts.protocol === 'xmpp' && uri._parts.query === 'join') {
+                classes += 'open-chatroom';
+            }
+            return `<a target="_blank" rel="noopener" class="${classes}" href="${url}">${u.escapeHTML(pretty_url)}</a>`;
         }, {
         }, {
             'start': /\b(?:([a-z][a-z0-9.+-]*:\/\/)|xmpp:|mailto:|www\.)/gi
             'start': /\b(?:([a-z][a-z0-9.+-]*:\/\/)|xmpp:|mailto:|www\.)/gi
         });
         });