Commit 8662f751 authored by JC Brand's avatar JC Brand

Refactor `converse-vcard` and add API method to fetch a VCard

parent 063908e0
...@@ -29,6 +29,8 @@ ...@@ -29,6 +29,8 @@
### API changes ### API changes
- New API method `_converse.disco.supports` to check whether a certain - New API method `_converse.disco.supports` to check whether a certain
service discovery feature is supported by an entity. service discovery feature is supported by an entity.
- New API method `_converse.api.vcard.get` which fetches the VCard for a
particular JID.
### UX/UI changes ### UX/UI changes
- Use CSS3 fade transitions to render various elements. - Use CSS3 fade transitions to render various elements.
......
...@@ -829,6 +829,67 @@ To return an array of chat boxes, provide an array of JIDs: ...@@ -829,6 +829,67 @@ To return an array of chat boxes, provide an array of JIDs:
| url | The URL of the chat box heading. | | url | The URL of the chat box heading. |
+-------------+-----------------------------------------------------+ +-------------+-----------------------------------------------------+
.. _`listen-grouping`:
The **listen** grouping
-----------------------
Converse.js emits events to which you can subscribe from your own JavaScript.
Concerning events, the following methods are available under the "listen"
grouping:
* **on(eventName, callback, [context])**:
Calling the ``on`` method allows you to subscribe to an event.
Every time the event fires, the callback method specified by ``callback`` will be
called.
Parameters:
* ``eventName`` is the event name as a string.
* ``callback`` is the callback method to be called when the event is emitted.
* ``context`` (optional), the value of the `this` parameter for the callback.
For example:
.. code-block:: javascript
_converse.api.listen.on('message', function (messageXML) { ... });
* **once(eventName, callback, [context])**:
Calling the ``once`` method allows you to listen to an event
exactly once.
Parameters:
* ``eventName`` is the event name as a string.
* ``callback`` is the callback method to be called when the event is emitted.
* ``context`` (optional), the value of the `this` parameter for the callback.
For example:
.. code-block:: javascript
_converse.api.listen.once('message', function (messageXML) { ... });
* **not(eventName, callback)**
To stop listening to an event, you can use the ``not`` method.
Parameters:
* ``eventName`` is the event name as a string.
* ``callback`` refers to the function that is to be no longer executed.
For example:
.. code-block:: javascript
_converse.api.listen.not('message', function (messageXML) { ... });
The **rooms** grouping The **rooms** grouping
---------------------- ----------------------
...@@ -1130,63 +1191,28 @@ Example: ...@@ -1130,63 +1191,28 @@ Example:
}); });
.. _`listen-grouping`: The **vcard** grouping
The **listen** grouping
----------------------- -----------------------
Converse.js emits events to which you can subscribe from your own JavaScript. get
~~~
Concerning events, the following methods are available under the "listen"
grouping:
* **on(eventName, callback, [context])**:
Calling the ``on`` method allows you to subscribe to an event.
Every time the event fires, the callback method specified by ``callback`` will be
called.
Parameters:
* ``eventName`` is the event name as a string.
* ``callback`` is the callback method to be called when the event is emitted.
* ``context`` (optional), the value of the `this` parameter for the callback.
For example:
.. code-block:: javascript
_converse.api.listen.on('message', function (messageXML) { ... });
* **once(eventName, callback, [context])**:
Calling the ``once`` method allows you to listen to an event
exactly once.
Parameters:
* ``eventName`` is the event name as a string. Returns a Promise which results with the VCard data for a particular JID.
* ``callback`` is the callback method to be called when the event is emitted.
* ``context`` (optional), the value of the `this` parameter for the callback.
For example: Example:
.. code-block:: javascript .. code-block:: javascript
_converse.api.listen.once('message', function (messageXML) { ... }); converse.plugins.add('myplugin', {
initialize: function () {
* **not(eventName, callback)**
To stop listening to an event, you can use the ``not`` method.
Parameters:
* ``eventName`` is the event name as a string.
* ``callback`` refers to the function that is to be no longer executed.
For example:
.. code-block:: javascript
_converse.api.listen.not('message', function (messageXML) { ... }); _converse.api.waitUntil('rosterContactsFetched').then(() => {
this._converse.api.vcard.get('someone@example.org').then(
(vcard) => {
// Do something with the vcard...
}
);
});
}
});
...@@ -1146,35 +1146,38 @@ ...@@ -1146,35 +1146,38 @@
var stanza = $pres({from: 'data@enterprise/resource', type: 'subscribe'}); var stanza = $pres({from: 'data@enterprise/resource', type: 'subscribe'});
_converse.connection._dataRecv(test_utils.createRequest(stanza)); _converse.connection._dataRecv(test_utils.createRequest(stanza));
expect(_converse.roster.pluck('jid').length).toBe(1); test_utils.waitUntil(function () {
expect(_.includes(_converse.roster.pluck('jid'), 'data@enterprise')).toBeTruthy(); return $('a:contains("Contact requests")').length;
}).then(function () {
// Taken from the spec expect(_converse.roster.pluck('jid').length).toBe(1);
// http://xmpp.org/rfcs/rfc3921.html#rfc.section.7.3 expect(_.includes(_converse.roster.pluck('jid'), 'data@enterprise')).toBeTruthy();
stanza = $iq({ // Taken from the spec
to: _converse.connection.jid, // http://xmpp.org/rfcs/rfc3921.html#rfc.section.7.3
type: 'result', stanza = $iq({
id: 'roster_1' to: _converse.connection.jid,
}).c('query', { type: 'result',
xmlns: 'jabber:iq:roster', id: 'roster_1'
}).c('item', { }).c('query', {
jid: 'romeo@example.net', xmlns: 'jabber:iq:roster',
name: 'Romeo', }).c('item', {
subscription:'both' jid: 'romeo@example.net',
}).c('group').t('Friends').up().up() name: 'Romeo',
.c('item', { subscription:'both'
jid: 'mercutio@example.org', }).c('group').t('Friends').up().up()
name: 'Mercutio', .c('item', {
subscription:'from' jid: 'mercutio@example.org',
}).c('group').t('Friends').up().up() name: 'Mercutio',
.c('item', { subscription:'from'
jid: 'benvolio@example.org', }).c('group').t('Friends').up().up()
name: 'Benvolio', .c('item', {
subscription:'both' jid: 'benvolio@example.org',
}).c('group').t('Friends'); name: 'Benvolio',
_converse.roster.onReceivedFromServer(stanza.tree()); subscription:'both'
expect(_.includes(_converse.roster.pluck('jid'), 'data@enterprise')).toBeTruthy(); }).c('group').t('Friends');
done(); _converse.roster.onReceivedFromServer(stanza.tree());
expect(_.includes(_converse.roster.pluck('jid'), 'data@enterprise')).toBeTruthy();
done();
});
})); }));
}); });
......
...@@ -64,7 +64,7 @@ ...@@ -64,7 +64,7 @@
spyOn(_converse.roster, "addAndSubscribe").and.callThrough(); spyOn(_converse.roster, "addAndSubscribe").and.callThrough();
spyOn(_converse.roster, "addContact").and.callThrough(); spyOn(_converse.roster, "addContact").and.callThrough();
spyOn(_converse.roster, "sendContactAddIQ").and.callThrough(); spyOn(_converse.roster, "sendContactAddIQ").and.callThrough();
spyOn(_converse, "getVCard").and.callThrough(); spyOn(_converse.api.vcard, "get").and.callThrough();
var sendIQ = _converse.connection.sendIQ; var sendIQ = _converse.connection.sendIQ;
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) { spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
sent_stanza = iq; sent_stanza = iq;
...@@ -172,7 +172,7 @@ ...@@ -172,7 +172,7 @@
// A contact should now have been created // A contact should now have been created
expect(_converse.roster.get('contact@example.org') instanceof _converse.RosterContact).toBeTruthy(); expect(_converse.roster.get('contact@example.org') instanceof _converse.RosterContact).toBeTruthy();
expect(contact.get('jid')).toBe('contact@example.org'); expect(contact.get('jid')).toBe('contact@example.org');
expect(_converse.getVCard).toHaveBeenCalled(); expect(_converse.api.vcard.get).toHaveBeenCalled();
/* To subscribe to the contact's presence information, /* To subscribe to the contact's presence information,
* the user's client MUST send a presence stanza of * the user's client MUST send a presence stanza of
...@@ -525,9 +525,9 @@ ...@@ -525,9 +525,9 @@
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched'], {},
function (done, _converse) { function (done, _converse) {
spyOn(_converse, "emit");
test_utils.openControlBox(_converse); test_utils.openControlBox(_converse);
test_utils.createContacts(_converse, 'current'); // Create some contacts so that we can test positioning test_utils.createContacts(_converse, 'current'); // Create some contacts so that we can test positioning
spyOn(_converse, "emit");
/* <presence /* <presence
* from='user@example.com' * from='user@example.com'
* to='contact@example.org' * to='contact@example.org'
...@@ -541,10 +541,10 @@ ...@@ -541,10 +541,10 @@
'xmlns': Strophe.NS.NICK, 'xmlns': Strophe.NS.NICK,
}).t('Clint Contact'); }).t('Clint Contact');
_converse.connection._dataRecv(test_utils.createRequest(stanza)); _converse.connection._dataRecv(test_utils.createRequest(stanza));
expect(_converse.emit).toHaveBeenCalledWith('contactRequest', jasmine.any(Object));
test_utils.waitUntil(function () { test_utils.waitUntil(function () {
return $('a:contains("Contact requests")').length; return $('a:contains("Contact requests")').length;
}).then(function () { }).then(function () {
expect(_converse.emit).toHaveBeenCalledWith('contactRequest', jasmine.any(Object));
var $header = $('a:contains("Contact requests")'); var $header = $('a:contains("Contact requests")');
expect($header.length).toBe(1); expect($header.length).toBe(1);
expect($header.is(":visible")).toBeTruthy(); expect($header.is(":visible")).toBeTruthy();
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment