Return a Backbone.View object instead of a wrapper

When returning chat boxes via the API.

We can do this now because these API methods are only available to
(whitelisted) plugins.
This commit is contained in:
JC Brand 2017-02-14 14:58:29 +00:00
parent fe6a9ca748
commit bc8e3e1a01
7 changed files with 46 additions and 83 deletions

View File

@ -13,6 +13,10 @@
- New configuration setting: - New configuration setting:
[show_chatstate_notifications](https://conversejs.org/docs/html/configuration.html#show-chatstate-notifications) [show_chatstate_notifications](https://conversejs.org/docs/html/configuration.html#show-chatstate-notifications)
[jcbrand] [jcbrand]
- The API now no longer returns wrapped chatboxes (or rooms) but instead a
Backbone.View object. This means the API of the returned object has changed.
You're still able to do everything from before but now also much more.
[jcbrand]
- Allow JIDs not on the roster to be invited to a chatroom. [jcbrand] - Allow JIDs not on the roster to be invited to a chatroom. [jcbrand]
- #770 Allow setting contact attrs on chats.open [Ape] - #770 Allow setting contact attrs on chats.open [Ape]

View File

@ -699,7 +699,7 @@ To return all open chat boxes, call the method without any JIDs::
open open
~~~~ ~~~~
Opens a chat box and returns an object representing a chat box. Opens a chat box and returns a Backbone.View object representing a chat box.
To open a single chat box, provide the JID of the contact: To open a single chat box, provide the JID of the contact:
@ -724,25 +724,27 @@ To return an array of chat boxes, provide an array of JIDs:
*The returned chat box object contains the following methods:* *The returned chat box object contains the following methods:*
+-------------+------------------------------------------+ +-------------------+------------------------------------------+
| Method | Description | | Method | Description |
+=============+==========================================+ +===================+==========================================+
| endOTR | End an OTR (Off-the-record) session. | | close | Close the chat box. |
+-------------+------------------------------------------+ +-------------------+------------------------------------------+
| get | Get an attribute (i.e. accessor). | | focus | Focuses the chat box textarea |
+-------------+------------------------------------------+ +-------------------+------------------------------------------+
| initiateOTR | Start an OTR (off-the-record) session. | | model.endOTR | End an OTR (Off-the-record) session. |
+-------------+------------------------------------------+ +-------------------+------------------------------------------+
| maximize | Minimize the chat box. | | model.get | Get an attribute (i.e. accessor). |
+-------------+------------------------------------------+ +-------------------+------------------------------------------+
| minimize | Maximize the chat box. | | model.initiateOTR | Start an OTR (off-the-record) session. |
+-------------+------------------------------------------+ +-------------------+------------------------------------------+
| set | Set an attribute (i.e. mutator). | | model.maximize | Minimize the chat box. |
+-------------+------------------------------------------+ +-------------------+------------------------------------------+
| close | Close the chat box. | | model.minimize | Maximize the chat box. |
+-------------+------------------------------------------+ +-------------------+------------------------------------------+
| open | Opens the chat box. | | model.set | Set an attribute (i.e. mutator). |
+-------------+------------------------------------------+ +-------------------+------------------------------------------+
| show | Opens/shows the chat box. |
+-------------------+------------------------------------------+
*The get and set methods can be used to retrieve and change the following attributes:* *The get and set methods can be used to retrieve and change the following attributes:*

View File

@ -247,7 +247,7 @@
test_utils.openChatBoxFor(_converse, jid); test_utils.openChatBoxFor(_converse, jid);
box = _converse.api.chats.get(jid); box = _converse.api.chats.get(jid);
expect(box instanceof Object).toBeTruthy(); expect(box instanceof Object).toBeTruthy();
expect(box.get('box_id')).toBe(b64_sha1(jid)); expect(box.model.get('box_id')).toBe(b64_sha1(jid));
chatboxview = _converse.chatboxviews.get(jid); chatboxview = _converse.chatboxviews.get(jid);
expect(chatboxview.$el.is(':visible')).toBeTruthy(); expect(chatboxview.$el.is(':visible')).toBeTruthy();
// Test for multiple JIDs // Test for multiple JIDs
@ -255,8 +255,8 @@
test_utils.openChatBoxFor(_converse, jid2); test_utils.openChatBoxFor(_converse, jid2);
var list = _converse.api.chats.get([jid, jid2]); var list = _converse.api.chats.get([jid, jid2]);
expect(_.isArray(list)).toBeTruthy(); expect(_.isArray(list)).toBeTruthy();
expect(list[0].get('box_id')).toBe(b64_sha1(jid)); expect(list[0].model.get('box_id')).toBe(b64_sha1(jid));
expect(list[1].get('box_id')).toBe(b64_sha1(jid2)); expect(list[1].model.get('box_id')).toBe(b64_sha1(jid2));
})); }));
it("has a method 'open' which opens and returns a wrapped chat box", mock.initConverse(function (_converse) { it("has a method 'open' which opens and returns a wrapped chat box", mock.initConverse(function (_converse) {
@ -269,7 +269,7 @@
expect(_converse.api.chats.get('non-existing@jabber.org')).toBeFalsy(); expect(_converse.api.chats.get('non-existing@jabber.org')).toBeFalsy();
var box = _converse.api.chats.open(jid); var box = _converse.api.chats.open(jid);
expect(box instanceof Object).toBeTruthy(); expect(box instanceof Object).toBeTruthy();
expect(box.get('box_id')).toBe(b64_sha1(jid)); expect(box.model.get('box_id')).toBe(b64_sha1(jid));
expect( expect(
_.keys(box), _.keys(box),
['close', 'endOTR', 'focus', 'get', 'initiateOTR', 'is_chatroom', 'maximize', 'minimize', 'open', 'set'] ['close', 'endOTR', 'focus', 'get', 'initiateOTR', 'is_chatroom', 'maximize', 'minimize', 'open', 'set']
@ -280,8 +280,8 @@
var jid2 = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost'; var jid2 = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost';
var list = _converse.api.chats.open([jid, jid2]); var list = _converse.api.chats.open([jid, jid2]);
expect(_.isArray(list)).toBeTruthy(); expect(_.isArray(list)).toBeTruthy();
expect(list[0].get('box_id')).toBe(b64_sha1(jid)); expect(list[0].model.get('box_id')).toBe(b64_sha1(jid));
expect(list[1].get('box_id')).toBe(b64_sha1(jid2)); expect(list[1].model.get('box_id')).toBe(b64_sha1(jid2));
}); });
})); }));
}); });

View File

@ -292,19 +292,9 @@
// Module-level functions // Module-level functions
// ---------------------- // ----------------------
this.wrappedChatBox = function (chatbox) { this.getViewForChatBox = function (chatbox) {
/* Wrap a chatbox for outside consumption (i.e. so that it can be
* returned via the API.
*/
if (!chatbox) { return; } if (!chatbox) { return; }
var view = _converse.chatboxviews.get(chatbox.get('id')); return _converse.chatboxviews.get(chatbox.get('id'));
return {
'close': view.close.bind(view),
'focus': view.focus.bind(view),
'get': chatbox.get.bind(chatbox),
'open': view.show.bind(view),
'set': chatbox.set.bind(chatbox)
};
}; };
this.generateResource = function () { this.generateResource = function () {
@ -2126,13 +2116,13 @@
_converse.log("chats.open: You need to provide at least one JID", "error"); _converse.log("chats.open: You need to provide at least one JID", "error");
return null; return null;
} else if (_.isString(jids)) { } else if (_.isString(jids)) {
chatbox = _converse.wrappedChatBox( chatbox = _converse.getViewForChatBox(
_converse.chatboxes.getChatBox(jids, true, attrs).trigger('show') _converse.chatboxes.getChatBox(jids, true, attrs).trigger('show')
); );
return chatbox; return chatbox;
} }
return _.map(jids, function (jid) { return _.map(jids, function (jid) {
chatbox = _converse.wrappedChatBox( chatbox = _converse.getViewForChatBox(
_converse.chatboxes.getChatBox(jid, true, attrs).trigger('show') _converse.chatboxes.getChatBox(jid, true, attrs).trigger('show')
); );
return chatbox; return chatbox;
@ -2145,18 +2135,18 @@
// FIXME: Leaky abstraction from MUC. We need to add a // FIXME: Leaky abstraction from MUC. We need to add a
// base type for chat boxes, and check for that. // base type for chat boxes, and check for that.
if (chatbox.get('type') !== 'chatroom') { if (chatbox.get('type') !== 'chatroom') {
result.push(_converse.wrappedChatBox(chatbox)); result.push(_converse.getViewForChatBox(chatbox));
} }
}); });
return result; return result;
} else if (_.isString(jids)) { } else if (_.isString(jids)) {
return _converse.wrappedChatBox(_converse.chatboxes.getChatBox(jids)); return _converse.getViewForChatBox(_converse.chatboxes.getChatBox(jids));
} }
return _.map(jids, return _.map(jids,
_.partial( _.partial(
_.flow( _.flow(
_converse.chatboxes.getChatBox.bind(_converse.chatboxes), _converse.chatboxes.getChatBox.bind(_converse.chatboxes),
_converse.wrappedChatBox.bind(_converse) _converse.getViewForChatBox.bind(_converse)
), _, true ), _, true
) )
); );

View File

@ -57,17 +57,6 @@
return this.__super__.registerGlobalEventHandlers.apply(this, arguments); return this.__super__.registerGlobalEventHandlers.apply(this, arguments);
}, },
wrappedChatBox: function (chatbox) {
/* Wrap a chatbox for outside consumption (i.e. so that it can be
* returned via the API.
*/
if (!chatbox) { return; }
var box = this.__super__.wrappedChatBox.apply(this, arguments);
box.maximize = chatbox.maximize.bind(chatbox);
box.minimize = chatbox.minimize.bind(chatbox);
return box;
},
ChatBox: { ChatBox: {
initialize: function () { initialize: function () {
this.__super__.initialize.apply(this, arguments); this.__super__.initialize.apply(this, arguments);

View File

@ -88,18 +88,6 @@
// //
// New functions which don't exist yet can also be added. // New functions which don't exist yet can also be added.
wrappedChatBox: function (chatbox) {
/* Wrap a chatbox for outside consumption (i.e. so that it can be
* returned via the API.
*/
if (!chatbox) { return; }
var _converse = this.__super__._converse;
var view = _converse.chatboxviews.get(chatbox.get('id'));
var box = this.__super__.wrappedChatBox.apply(this, arguments);
box.is_chatroom = view.is_chatroom;
return box;
},
Features: { Features: {
addClientFeatures: function () { addClientFeatures: function () {
var _converse = this.__super__._converse; var _converse = this.__super__._converse;
@ -2395,9 +2383,9 @@
}; };
_converse.on('chatBoxesFetched', autoJoinRooms); _converse.on('chatBoxesFetched', autoJoinRooms);
_converse.getWrappedChatRoom = function (jid, attrs, fetcher) { _converse.getChatRoom = function (jid, attrs, fetcher) {
jid = jid.toLowerCase(); jid = jid.toLowerCase();
return _converse.wrappedChatBox(fetcher(_.extend({ return _converse.getViewForChatBox(fetcher(_.extend({
'id': jid, 'id': jid,
'jid': jid, 'jid': jid,
'name': Strophe.unescapeNode(Strophe.getNodeFromJid(jid)), 'name': Strophe.unescapeNode(Strophe.getNodeFromJid(jid)),
@ -2406,7 +2394,6 @@
}, attrs))); }, attrs)));
}; };
/* We extend the default converse.js API to add methods specific to MUC /* We extend the default converse.js API to add methods specific to MUC
* chat rooms. * chat rooms.
*/ */
@ -2444,9 +2431,9 @@
if (_.isUndefined(jids)) { if (_.isUndefined(jids)) {
throw new TypeError('rooms.open: You need to provide at least one JID'); throw new TypeError('rooms.open: You need to provide at least one JID');
} else if (_.isString(jids)) { } else if (_.isString(jids)) {
return _converse.getWrappedChatRoom(jids, attrs, _converse.createChatRoom); return _converse.getChatRoom(jids, attrs, _converse.createChatRoom);
} }
return _.map(jids, _.partial(_converse.getWrappedChatRoom, _, attrs, _converse.createChatRoom)); return _.map(jids, _.partial(_converse.getChatRoom, _, attrs, _converse.createChatRoom));
}, },
'get': function (jids, attrs, create) { 'get': function (jids, attrs, create) {
if (_.isString(attrs)) { if (_.isString(attrs)) {
@ -2458,7 +2445,7 @@
var result = []; var result = [];
_converse.chatboxes.each(function (chatbox) { _converse.chatboxes.each(function (chatbox) {
if (chatbox.get('type') === 'chatroom') { if (chatbox.get('type') === 'chatroom') {
result.push(_converse.wrappedChatBox(chatbox)); result.push(_converse.getViewForChatBox(chatbox));
} }
}); });
return result; return result;
@ -2468,9 +2455,9 @@
attrs.nick = Strophe.getNodeFromJid(_converse.bare_jid); attrs.nick = Strophe.getNodeFromJid(_converse.bare_jid);
} }
if (_.isString(jids)) { if (_.isString(jids)) {
return _converse.getWrappedChatRoom(jids, attrs, fetcher); return _converse.getChatRoom(jids, attrs, fetcher);
} }
return _.map(jids, _.partial(_converse.getWrappedChatRoom, _, attrs, fetcher)); return _.map(jids, _.partial(_converse.getChatRoom, _, attrs, fetcher));
} }
} }
}); });

View File

@ -70,15 +70,6 @@
}); });
}, },
wrappedChatBox: function (chatbox) {
var wrapped_chatbox = this.__super__.wrappedChatBox.apply(this, arguments);
if (!chatbox) { return; }
return _.extend(wrapped_chatbox, {
'endOTR': chatbox.endOTR.bind(chatbox),
'initiateOTR': chatbox.initiateOTR.bind(chatbox),
});
},
ChatBox: { ChatBox: {
initialize: function () { initialize: function () {
this.__super__.initialize.apply(this, arguments); this.__super__.initialize.apply(this, arguments);