Commit 2de794ab authored by JC Brand's avatar JC Brand Committed by GitHub

Merge branch 'master' into master

parents 86730b86 a15aec35
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
Contribution Guidelines Contribution Guidelines
======================= =======================
Thanks for contributing to `Converse.js <http://conversejs.org>`_. Thanks for contributing to `Converse.js <https://conversejs.org>`_.
Support questions Support questions
================= =================
......
...@@ -2,8 +2,10 @@ ...@@ -2,8 +2,10 @@
## 4.1.3 (Unreleased) ## 4.1.3 (Unreleased)
- Updated translation: lt
- Upgrade to Backbone 1.4.0 - Upgrade to Backbone 1.4.0
- Fix "flashing" of roster filter when you have less than 5 roster contacts. - Fix "flashing" of roster filter when you have less than 5 roster contacts.
- Fix handling of CAPTCHAs offered by ejabberd.
- Allow setting of debug mode via URL with `/#converse?debug=true` - Allow setting of debug mode via URL with `/#converse?debug=true`
- New config setting [locked_muc_domain](https://conversejs.org/docs/html/configuration.html#locked-muc-domain) - New config setting [locked_muc_domain](https://conversejs.org/docs/html/configuration.html#locked-muc-domain)
- New config setting [show_client_info](https://conversejs.org/docs/html/configuration.html#show-client-info) - New config setting [show_client_info](https://conversejs.org/docs/html/configuration.html#show-client-info)
...@@ -13,7 +15,8 @@ ...@@ -13,7 +15,8 @@
- #1400: When a chat message is just an emoji, enlarge the emoji - #1400: When a chat message is just an emoji, enlarge the emoji
- #1437: List of groupchats in modal doesn't scroll - #1437: List of groupchats in modal doesn't scroll
- #1457: Wrong tooltip shown for "unbookmark" icon - #1457: Wrong tooltip shown for "unbookmark" icon
- #1474: Update Lithuanian (lt) translation - #1479: Allow file upload by drag & drop also in MUCs
## 4.1.2 (2019-02-22) ## 4.1.2 (2019-02-22)
...@@ -647,7 +650,7 @@ More info here: https://github.com/LeaVerou/awesomplete/pull/17082 ...@@ -647,7 +650,7 @@ More info here: https://github.com/LeaVerou/awesomplete/pull/17082
## 2.0.4 (2016-12-13) ## 2.0.4 (2016-12-13)
- #737: Bugfix. Translations weren't being applied. [jcbrand] - #737: Bugfix. Translations weren't being applied. [jcbrand]
- Fetch room info and store it on the room model. - Fetch room info and store it on the room model.
For context, see: http://xmpp.org/extensions/xep-0045.html#disco-roominfo [jcbrand] For context, see: https://xmpp.org/extensions/xep-0045.html#disco-roominfo [jcbrand]
- Bugfix. Switching from bookmarks form to config form shows only the spinner. [jcbrand] - Bugfix. Switching from bookmarks form to config form shows only the spinner. [jcbrand]
- Bugfix. Other room occupants sometimes not shown when reloading the page. [jcbrand] - Bugfix. Other room occupants sometimes not shown when reloading the page. [jcbrand]
- Bugfix. Due to changes in `converse-core` the controlbox wasn't aware anymore of - Bugfix. Due to changes in `converse-core` the controlbox wasn't aware anymore of
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
6. `git commit -am "New release 5.0.0"` 6. `git commit -am "New release 5.0.0"`
7. `git tag -s v5.0.0 7. `git tag -s v5.0.0
8. Run `git push && git push --tags` 8. Run `git push && git push --tags`
9. Update http://conversejs.org 9. Update https://conversejs.org
10. Create `5.0.0` directory for the CDN. 10. Create `5.0.0` directory for the CDN.
* Create a new version for the CDN by copying * Create a new version for the CDN by copying
* Check out the correct tag * Check out the correct tag
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
"type": "library", "type": "library",
"license": "MPL-2.0", "license": "MPL-2.0",
"minimum-stability": "stable", "minimum-stability": "stable",
"homepage": "http://conversejs.org/", "homepage": "https://conversejs.org/",
"keywords": ["xmpp", "messaging", "chat", "presence"], "keywords": ["xmpp", "messaging", "chat", "presence"],
"require": {} "require": {}
} }
/*! /*!
* Converse.js (Web-based XMPP instant messaging client) * Converse.js (Web-based XMPP instant messaging client)
* http://conversejs.org * https://conversejs.org
* *
* Copyright (c) 2013-2018, JC Brand <jc@opkode.com> * Copyright (c) 2013-2018, JC Brand <jc@opkode.com>
* Licensed under the Mozilla Public License * Licensed under the Mozilla Public License
......
This diff is collapsed.
...@@ -222,7 +222,7 @@ allow_registration ...@@ -222,7 +222,7 @@ allow_registration
* Default: ``true`` * Default: ``true``
Support for `XEP-0077: In band registration <http://xmpp.org/extensions/xep-0077.html>`_ Support for `XEP-0077: In band registration <https://xmpp.org/extensions/xep-0077.html>`_
Allow XMPP account registration showing the corresponding UI register form interface. Allow XMPP account registration showing the corresponding UI register form interface.
...@@ -572,7 +572,7 @@ csi_waiting_time ...@@ -572,7 +572,7 @@ csi_waiting_time
* Default: ``0`` * Default: ``0``
This option adds support for `XEP-0352 Client State Indication <http://xmpp.org/extensions/xep-0352.html>_` This option adds support for `XEP-0352 Client State Indication <https://xmpp.org/extensions/xep-0352.html>_`
If Converse is idle for the configured amount of seconds, a chat state If Converse is idle for the configured amount of seconds, a chat state
indication of ``inactive`` will be sent out to the XMPP server (if the server indication of ``inactive`` will be sent out to the XMPP server (if the server
...@@ -806,7 +806,7 @@ See also: ...@@ -806,7 +806,7 @@ See also:
Currently the "keepalive" setting only works with BOSH and not with Currently the "keepalive" setting only works with BOSH and not with
websockets. This is because XMPP over websocket does not use the same websockets. This is because XMPP over websocket does not use the same
session token as with BOSH. A possible solution for this is to implement session token as with BOSH. A possible solution for this is to implement
`XEP-0198 <http://xmpp.org/extensions/xep-0198.html>`_, specifically `XEP-0198 <https://xmpp.org/extensions/xep-0198.html>`_, specifically
with regards to "stream resumption". with regards to "stream resumption".
.. _`locales`: .. _`locales`:
...@@ -993,7 +993,7 @@ muc_instant_rooms ...@@ -993,7 +993,7 @@ muc_instant_rooms
Determines whether 'instant' (also called 'dynamic' in OpenFire) rooms are created. Determines whether 'instant' (also called 'dynamic' in OpenFire) rooms are created.
Otherwise rooms first have to be configured before they're available to other Otherwise rooms first have to be configured before they're available to other
users (so-called "registered rooms" in `MUC-0045 <http://xmpp.org/extensions/xep-0045.html#createroom>`_). users (so-called "registered rooms" in `MUC-0045 <https://xmpp.org/extensions/xep-0045.html#createroom>`_).
From a UX perspective, if this settings is `false`, then a configuration form will From a UX perspective, if this settings is `false`, then a configuration form will
render, that has to be filled in first, before the room can be joined by other render, that has to be filled in first, before the room can be joined by other
......
...@@ -1050,7 +1050,7 @@ Room attributes that may be passed in: ...@@ -1050,7 +1050,7 @@ Room attributes that may be passed in:
configured automatically. Currently it doesn't make sense to specify configured automatically. Currently it doesn't make sense to specify
``roomconfig`` values if ``auto_configure`` is set to ``false``. ``roomconfig`` values if ``auto_configure`` is set to ``false``.
For a list of configuration values that can be passed in, refer to these values For a list of configuration values that can be passed in, refer to these values
in the `XEP-0045 MUC specification <http://xmpp.org/extensions/xep-0045.html#registrar-formtype-owner>`_. in the `XEP-0045 MUC specification <https://xmpp.org/extensions/xep-0045.html#registrar-formtype-owner>`_.
The values should be named without the ``muc#roomconfig_`` prefix. The values should be named without the ``muc#roomconfig_`` prefix.
* *maximize*: A boolean, indicating whether minimized rooms should also be * *maximize*: A boolean, indicating whether minimized rooms should also be
maximized, when opened. Set to ``false`` by default. maximized, when opened. Set to ``false`` by default.
......
...@@ -20,7 +20,7 @@ contribute, please read the :doc:`documentation` page. ...@@ -20,7 +20,7 @@ contribute, please read the :doc:`documentation` page.
Introduction Introduction
============ ============
Converse is a free and open-source `XMPP <http://xmpp.org/about-xmpp/>`_ Converse is a free and open-source `XMPP <https://xmpp.org/about-xmpp/>`_
chat client written in JavaScript which can be tightly integrated into any website. chat client written in JavaScript which can be tightly integrated into any website.
The benefit of using converse.js as opposed to relying on a SaaS The benefit of using converse.js as opposed to relying on a SaaS
......
...@@ -57,7 +57,7 @@ The various components ...@@ -57,7 +57,7 @@ The various components
An XMPP server An XMPP server
============== ==============
Converse uses `XMPP <http://xmpp.org/about-xmpp/>`_ as its Converse uses `XMPP <https://xmpp.org/about-xmpp/>`_ as its
messaging protocol, and therefore needs to connect to an XMPP/Jabber messaging protocol, and therefore needs to connect to an XMPP/Jabber
server (Jabber® is an older and more user-friendly synonym for XMPP). server (Jabber® is an older and more user-friendly synonym for XMPP).
...@@ -67,7 +67,7 @@ authentication sessions to log in users to the XMPP server (i.e. :ref:`session s ...@@ -67,7 +67,7 @@ authentication sessions to log in users to the XMPP server (i.e. :ref:`session s
then you'll have to set up your own XMPP server. then you'll have to set up your own XMPP server.
You can find a list of public XMPP servers/providers on `compliance.conversations.im <http://compliance.conversations.im/>`_ You can find a list of public XMPP servers/providers on `compliance.conversations.im <http://compliance.conversations.im/>`_
and a list of servers that you can set up yourself on `xmpp.org <http://xmpp.org/xmpp-software/servers/>`_. and a list of servers that you can set up yourself on `xmpp.org <https://xmpp.org/xmpp-software/servers/>`_.
.. _`BOSH-section`: .. _`BOSH-section`:
...@@ -90,7 +90,7 @@ server, we need a proxy which acts as a bridge between these two protocols. ...@@ -90,7 +90,7 @@ server, we need a proxy which acts as a bridge between these two protocols.
This is the job of a BOSH connection manager. BOSH (Bidirectional-streams Over This is the job of a BOSH connection manager. BOSH (Bidirectional-streams Over
Synchronous HTTP) is a protocol for allowing XMPP communication over HTTP. The Synchronous HTTP) is a protocol for allowing XMPP communication over HTTP. The
protocol is defined in `XEP-0206: XMPP Over BOSH <http://xmpp.org/extensions/xep-0206.html>`_. protocol is defined in `XEP-0206: XMPP Over BOSH <https://xmpp.org/extensions/xep-0206.html>`_.
Popular XMPP servers such as `Ejabberd <http://www.ejabberd.im>`_, Popular XMPP servers such as `Ejabberd <http://www.ejabberd.im>`_,
Prosody `(mod_bosh) <http://prosody.im/doc/setting_up_bosh>`_ and Prosody `(mod_bosh) <http://prosody.im/doc/setting_up_bosh>`_ and
...@@ -104,7 +104,7 @@ https://conversejs.org does), then you'll need a standalone connection manager. ...@@ -104,7 +104,7 @@ https://conversejs.org does), then you'll need a standalone connection manager.
For a standalone manager, see for example `Punjab <https://github.com/twonds/punjab>`_ For a standalone manager, see for example `Punjab <https://github.com/twonds/punjab>`_
and `node-xmpp-bosh <https://github.com/dhruvbird/node-xmpp-bosh>`_. and `node-xmpp-bosh <https://github.com/dhruvbird/node-xmpp-bosh>`_.
The demo on the `Converse homepage <http://conversejs.org>`_ uses a connection The demo on the `Converse homepage <https://conversejs.org>`_ uses a connection
manager located at https://conversejs.org/http-bind. manager located at https://conversejs.org/http-bind.
This connection manager is available for testing purposes only, please don't This connection manager is available for testing purposes only, please don't
...@@ -258,7 +258,7 @@ Option 1). Server-side authentication via BOSH prebinding ...@@ -258,7 +258,7 @@ Option 1). Server-side authentication via BOSH prebinding
--------------------------------------------------------- ---------------------------------------------------------
To **prebind** refers to a technique whereby your web application sets up an To **prebind** refers to a technique whereby your web application sets up an
authenticated BOSH session with the XMPP server or a standalone `BOSH <http://xmpp.org/about-xmpp/technology-overview/bosh/>`_ authenticated BOSH session with the XMPP server or a standalone `BOSH <https://xmpp.org/about-xmpp/technology-overview/bosh/>`_
connection manager. connection manager.
Once authenticated, it receives RID and SID tokens which need to be passed Once authenticated, it receives RID and SID tokens which need to be passed
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
<body> <body>
<div id="header_wrap" class="outer"> <div id="header_wrap" class="outer">
<header class="inner"> <header class="inner">
<h1 id="project_title"><a href="http://conversejs.org">Converse.js</a></h1> <h1 id="project_title"><a href="https://conversejs.org">Converse.js</a></h1>
<h2 id="project_tagline">Mockups</h2> <h2 id="project_tagline">Mockups</h2>
</header> </header>
</div> </div>
......
/*! /*!
* Converse.js (Web-based XMPP instant messaging client) * Converse.js (Web-based XMPP instant messaging client)
* http://conversejs.org * https://conversejs.org
* *
* Copyright (c) 2013-2018, JC Brand <jc@opkode.com> * Copyright (c) 2013-2018, JC Brand <jc@opkode.com>
* Licensed under the Mozilla Public License * Licensed under the Mozilla Public License
......
...@@ -18,45 +18,44 @@ ...@@ -18,45 +18,44 @@
it("shows all autocompletion options when the user presses @", it("shows all autocompletion options when the user presses @",
mock.initConverse( mock.initConverse(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched'], {},
function (done, _converse) { async function (done, _converse) {
test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'tom') await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'tom');
.then(() => { const view = _converse.chatboxviews.get('lounge@localhost');
const view = _converse.chatboxviews.get('lounge@localhost');
['dick', 'harry'].forEach((nick) => {
['dick', 'harry'].forEach((nick) => { _converse.connection._dataRecv(test_utils.createRequest(
_converse.connection._dataRecv(test_utils.createRequest( $pres({
$pres({ 'to': 'tom@localhost/resource',
'to': 'tom@localhost/resource', 'from': `lounge@localhost/${nick}`
'from': `lounge@localhost/${nick}` })
}) .c('x', {xmlns: Strophe.NS.MUC_USER})
.c('x', {xmlns: Strophe.NS.MUC_USER}) .c('item', {
.c('item', { 'affiliation': 'none',
'affiliation': 'none', 'jid': `${nick}@localhost/resource`,
'jid': `${nick}@localhost/resource`, 'role': 'participant'
'role': 'participant' })));
}))); });
});
// Test that pressing @ brings up all options // Test that pressing @ brings up all options
const textarea = view.el.querySelector('textarea.chat-textarea'); const textarea = view.el.querySelector('textarea.chat-textarea');
const at_event = { const at_event = {
'target': textarea, 'target': textarea,
'preventDefault': _.noop, 'preventDefault': _.noop,
'stopPropagation': _.noop, 'stopPropagation': _.noop,
'keyCode': 50 'keyCode': 50,
}; 'key': '@'
view.keyPressed(at_event); };
textarea.value = '@'; view.keyPressed(at_event);
view.keyUp(at_event); textarea.value = '@';
view.keyUp(at_event);
expect(view.el.querySelectorAll('.suggestion-box__results li').length).toBe(3);
expect(view.el.querySelector('.suggestion-box__results li[aria-selected="true"]').textContent).toBe('tom'); expect(view.el.querySelectorAll('.suggestion-box__results li').length).toBe(3);
expect(view.el.querySelector('.suggestion-box__results li:first-child').textContent).toBe('tom'); expect(view.el.querySelector('.suggestion-box__results li[aria-selected="true"]').textContent).toBe('tom');
expect(view.el.querySelector('.suggestion-box__results li:nth-child(2)').textContent).toBe('dick'); expect(view.el.querySelector('.suggestion-box__results li:first-child').textContent).toBe('tom');
expect(view.el.querySelector('.suggestion-box__results li:nth-child(3)').textContent).toBe('harry'); expect(view.el.querySelector('.suggestion-box__results li:nth-child(2)').textContent).toBe('dick');
done(); expect(view.el.querySelector('.suggestion-box__results li:nth-child(3)').textContent).toBe('harry');
}).catch(_.partial(console.error, _)); done();
})); }));
it("autocompletes when the user presses tab", it("autocompletes when the user presses tab",
...@@ -88,7 +87,8 @@ ...@@ -88,7 +87,8 @@
'target': textarea, 'target': textarea,
'preventDefault': _.noop, 'preventDefault': _.noop,
'stopPropagation': _.noop, 'stopPropagation': _.noop,
'keyCode': 9 'keyCode': 9,
'key': 'Tab'
} }
view.keyPressed(tab_event); view.keyPressed(tab_event);
view.keyUp(tab_event); view.keyUp(tab_event);
...@@ -168,5 +168,46 @@ ...@@ -168,5 +168,46 @@
expect(textarea.value).toBe('hello @z3r0 '); expect(textarea.value).toBe('hello @z3r0 ');
done(); done();
})); }));
it("autocompletes when the user presses backspace",
mock.initConverse(
null, ['rosterGroupsFetched'], {},
async function (done, _converse) {
await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy');
const view = _converse.chatboxviews.get('lounge@localhost');
expect(view.model.occupants.length).toBe(1);
const presence = $pres({
'to': 'dummy@localhost/resource',
'from': 'lounge@localhost/some1'
})
.c('x', {xmlns: Strophe.NS.MUC_USER})
.c('item', {
'affiliation': 'none',
'jid': 'some1@localhost/resource',
'role': 'participant'
});
_converse.connection._dataRecv(test_utils.createRequest(presence));
expect(view.model.occupants.length).toBe(2);
const textarea = view.el.querySelector('textarea.chat-textarea');
textarea.value = "hello @some1 ";
// Press backspace
const backspace_event = {
'target': textarea,
'preventDefault': _.noop,
'stopPropagation': _.noop,
'keyCode': 8,
'key': 'Backspace'
}
view.keyPressed(backspace_event);
textarea.value = "hello @some1"; // Mimic backspace
view.keyUp(backspace_event);
expect(view.el.querySelector('.suggestion-box__results').hidden).toBeFalsy();
expect(view.el.querySelectorAll('.suggestion-box__results li').length).toBe(1);
expect(view.el.querySelector('.suggestion-box__results li').textContent).toBe('some1');
done();
}));
}); });
})); }));
...@@ -671,7 +671,7 @@ ...@@ -671,7 +671,7 @@
await test_utils.waitForRoster(_converse, 'current'); await test_utils.waitForRoster(_converse, 'current');
test_utils.openControlBox(); test_utils.openControlBox();
// See XEP-0085 http://xmpp.org/extensions/xep-0085.html#definitions // See XEP-0085 https://xmpp.org/extensions/xep-0085.html#definitions
spyOn(_converse, 'emit'); spyOn(_converse, 'emit');
const sender_jid = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost'; const sender_jid = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost';
await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length); await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length);
...@@ -817,7 +817,7 @@ ...@@ -817,7 +817,7 @@
test_utils.openControlBox(); test_utils.openControlBox();
await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length); await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length);
// TODO: only show paused state if the previous state was composing // TODO: only show paused state if the previous state was composing
// See XEP-0085 http://xmpp.org/extensions/xep-0085.html#definitions // See XEP-0085 https://xmpp.org/extensions/xep-0085.html#definitions
spyOn(_converse, 'emit').and.callThrough(); spyOn(_converse, 'emit').and.callThrough();
const sender_jid = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost'; const sender_jid = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost';
const view = await test_utils.openChatBoxFor(_converse, sender_jid); const view = await test_utils.openChatBoxFor(_converse, sender_jid);
...@@ -985,7 +985,7 @@ ...@@ -985,7 +985,7 @@
await test_utils.waitForRoster(_converse, 'current'); await test_utils.waitForRoster(_converse, 'current');
test_utils.openControlBox(); test_utils.openControlBox();
const sender_jid = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost'; const sender_jid = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost';
// See XEP-0085 http://xmpp.org/extensions/xep-0085.html#definitions // See XEP-0085 https://xmpp.org/extensions/xep-0085.html#definitions
spyOn(_converse, 'emit'); spyOn(_converse, 'emit');
await test_utils.openChatBoxFor(_converse, sender_jid); await test_utils.openChatBoxFor(_converse, sender_jid);
const view = _converse.chatboxviews.get(sender_jid); const view = _converse.chatboxviews.get(sender_jid);
......
...@@ -347,7 +347,7 @@ ...@@ -347,7 +347,7 @@
// The user has just entered the room (because join was called) // The user has just entered the room (because join was called)
// and receives their own presence from the server. // and receives their own presence from the server.
// See example 24: // See example 24:
// http://xmpp.org/extensions/xep-0045.html#enter-pres // https://xmpp.org/extensions/xep-0045.html#enter-pres
// //
/* <presence xmlns="jabber:client" to="jordie.langen@chat.example.org/converse.js-11659299" from="myroom@conference.chat.example.org/jc"> /* <presence xmlns="jabber:client" to="jordie.langen@chat.example.org/converse.js-11659299" from="myroom@conference.chat.example.org/jc">
* <x xmlns="http://jabber.org/protocol/muc#user"> * <x xmlns="http://jabber.org/protocol/muc#user">
...@@ -1219,7 +1219,7 @@ ...@@ -1219,7 +1219,7 @@
/* Check that an IQ is sent out, asking for the /* Check that an IQ is sent out, asking for the
* configuration form. * configuration form.
* See: // http://xmpp.org/extensions/xep-0045.html#example-163 * See: // https://xmpp.org/extensions/xep-0045.html#example-163
* *
* <iq from='crone1@shakespeare.lit/desktop' * <iq from='crone1@shakespeare.lit/desktop'
* id='config1' * id='config1'
...@@ -1234,7 +1234,7 @@ ...@@ -1234,7 +1234,7 @@
`</iq>`); `</iq>`);
/* Server responds with the configuration form. /* Server responds with the configuration form.
* See: // http://xmpp.org/extensions/xep-0045.html#example-165 * See: // https://xmpp.org/extensions/xep-0045.html#example-165
*/ */
var config_stanza = $iq({from: 'coven@chat.shakespeare.lit', var config_stanza = $iq({from: 'coven@chat.shakespeare.lit',
'id': IQ_id, 'id': IQ_id,
...@@ -1398,7 +1398,7 @@ ...@@ -1398,7 +1398,7 @@
for (var i=0; i<mock.chatroom_names.length; i++) { for (var i=0; i<mock.chatroom_names.length; i++) {
name = mock.chatroom_names[i]; name = mock.chatroom_names[i];
role = mock.chatroom_roles[name].role; role = mock.chatroom_roles[name].role;
// See example 21 http://xmpp.org/extensions/xep-0045.html#enter-pres // See example 21 https://xmpp.org/extensions/xep-0045.html#enter-pres
jid = jid =
presence = $pres({ presence = $pres({
to:'dummy@localhost/pda', to:'dummy@localhost/pda',
...@@ -1418,11 +1418,11 @@ ...@@ -1418,11 +1418,11 @@
} }
// Test users leaving the groupchat // Test users leaving the groupchat
// http://xmpp.org/extensions/xep-0045.html#exit // https://xmpp.org/extensions/xep-0045.html#exit
for (i=mock.chatroom_names.length-1; i>-1; i--) { for (i=mock.chatroom_names.length-1; i>-1; i--) {
name = mock.chatroom_names[i]; name = mock.chatroom_names[i];
role = mock.chatroom_roles[name].role; role = mock.chatroom_roles[name].role;
// See example 21 http://xmpp.org/extensions/xep-0045.html#enter-pres // See example 21 https://xmpp.org/extensions/xep-0045.html#enter-pres
presence = $pres({ presence = $pres({
to:'dummy@localhost/pda', to:'dummy@localhost/pda',
from:'lounge@localhost/'+name, from:'lounge@localhost/'+name,
...@@ -1452,7 +1452,7 @@ ...@@ -1452,7 +1452,7 @@
for (var i=0; i<mock.chatroom_names.length; i++) { for (var i=0; i<mock.chatroom_names.length; i++) {
name = mock.chatroom_names[i]; name = mock.chatroom_names[i];
role = mock.chatroom_roles[name].role; role = mock.chatroom_roles[name].role;
// See example 21 http://xmpp.org/extensions/xep-0045.html#enter-pres // See example 21 https://xmpp.org/extensions/xep-0045.html#enter-pres
jid = jid =
presence = $pres({ presence = $pres({
to:'dummy@localhost/pda', to:'dummy@localhost/pda',
...@@ -1472,11 +1472,11 @@ ...@@ -1472,11 +1472,11 @@
} }
// Test users leaving the groupchat // Test users leaving the groupchat
// http://xmpp.org/extensions/xep-0045.html#exit // https://xmpp.org/extensions/xep-0045.html#exit
for (i=mock.chatroom_names.length-1; i>-1; i--) { for (i=mock.chatroom_names.length-1; i>-1; i--) {
name = mock.chatroom_names[i]; name = mock.chatroom_names[i];
role = mock.chatroom_roles[name].role; role = mock.chatroom_roles[name].role;
// See example 21 http://xmpp.org/extensions/xep-0045.html#enter-pres // See example 21 https://xmpp.org/extensions/xep-0045.html#enter-pres
presence = $pres({ presence = $pres({
to:'dummy@localhost/pda', to:'dummy@localhost/pda',
from:'lounge@localhost/'+name, from:'lounge@localhost/'+name,
...@@ -1695,7 +1695,7 @@ ...@@ -1695,7 +1695,7 @@
// The user has just entered the groupchat (because join was called) // The user has just entered the groupchat (because join was called)
// and receives their own presence from the server. // and receives their own presence from the server.
// See example 24: // See example 24:
// http://xmpp.org/extensions/xep-0045.html#enter-pres // https://xmpp.org/extensions/xep-0045.html#enter-pres
const presence = $pres({ const presence = $pres({
to:'dummy@localhost/resource', to:'dummy@localhost/resource',
from:'lounge@localhost/thirdwitch', from:'lounge@localhost/thirdwitch',
...@@ -1946,7 +1946,7 @@ ...@@ -1946,7 +1946,7 @@
async function (done, _converse) { async function (done, _converse) {
await test_utils.openAndEnterChatRoom(_converse, 'jdev', 'conference.jabber.org', 'jc'); await test_utils.openAndEnterChatRoom(_converse, 'jdev', 'conference.jabber.org', 'jc');
const text = 'Jabber/XMPP Development | RFCs and Extensions: http://xmpp.org/ | Protocol and XSF discussions: xsf@muc.xmpp.org'; const text = 'Jabber/XMPP Development | RFCs and Extensions: https://xmpp.org/ | Protocol and XSF discussions: xsf@muc.xmpp.org';
let stanza = u.toStanza(` let stanza = u.toStanza(`
<message xmlns="jabber:client" to="jc@opkode.com/_converse.js-60429116" type="groupchat" from="jdev@conference.jabber.org/ralphm"> <message xmlns="jabber:client" to="jc@opkode.com/_converse.js-60429116" type="groupchat" from="jdev@conference.jabber.org/ralphm">
<subject>${text}</subject> <subject>${text}</subject>
...@@ -2008,7 +2008,7 @@ ...@@ -2008,7 +2008,7 @@
* nickname and one indicating availability for the new * nickname and one indicating availability for the new
* nickname. * nickname.
* *
* See: http://xmpp.org/extensions/xep-0045.html#changenick * See: https://xmpp.org/extensions/xep-0045.html#changenick
* *
* <presence * <presence
* from='coven@localhost/thirdwitch' * from='coven@localhost/thirdwitch'
...@@ -4082,7 +4082,7 @@ ...@@ -4082,7 +4082,7 @@
spyOn(_converse.ChatRoom.prototype, 'getRoomFeatures').and.callFake(() => Promise.resolve()); spyOn(_converse.ChatRoom.prototype, 'getRoomFeatures').and.callFake(() => Promise.resolve());
roomspanel.delegateEvents(); // We need to rebind all events otherwise our spy won't be called roomspanel.delegateEvents(); // We need to rebind all events otherwise our spy won't be called
// See: http://xmpp.org/extensions/xep-0045.html#disco-rooms // See: https://xmpp.org/extensions/xep-0045.html#disco-rooms
expect(modal.el.querySelectorAll('.available-chatrooms li').length).toBe(0); expect(modal.el.querySelectorAll('.available-chatrooms li').length).toBe(0);
const server_input = modal.el.querySelector('input[name="server"]'); const server_input = modal.el.querySelector('input[name="server"]');
...@@ -4299,7 +4299,7 @@ ...@@ -4299,7 +4299,7 @@
expect(sizzle('div.chat-info:last', chat_content).pop().textContent) expect(sizzle('div.chat-info:last', chat_content).pop().textContent)
.toBe("nomorenicks has entered the groupchat"); .toBe("nomorenicks has entered the groupchat");
// See XEP-0085 http://xmpp.org/extensions/xep-0085.html#definitions // See XEP-0085 https://xmpp.org/extensions/xep-0085.html#definitions
// <composing> state // <composing> state
let msg = $msg({ let msg = $msg({
...@@ -4368,10 +4368,8 @@ ...@@ -4368,10 +4368,8 @@
expect(notifications.length).toBe(2); expect(notifications.length).toBe(2);
expect(notifications[0].textContent).toEqual('newguy is typing'); expect(notifications[0].textContent).toEqual('newguy is typing');
expect(notifications[1].textContent).toEqual('nomorenicks is typing'); expect(notifications[1].textContent).toEqual('nomorenicks is typing');
expect(timeout_functions.length).toBe(3);
// Check that new messages appear under the chat state // Check that new messages appear under the chat state notifications
// notifications
msg = $msg({ msg = $msg({
from: `${room_jid}/some1`, from: `${room_jid}/some1`,
id: (new Date()).getTime(), id: (new Date()).getTime(),
...@@ -4386,8 +4384,7 @@ ...@@ -4386,8 +4384,7 @@
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1); expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
expect(view.el.querySelector('.chat-msg .chat-msg__text').textContent).toBe('hello world'); expect(view.el.querySelector('.chat-msg .chat-msg__text').textContent).toBe('hello world');
// Test that the composing notifications get removed // Test that the composing notifications get removed via timeout.
// via timeout.
timeout_functions[0](); timeout_functions[0]();
events = view.el.querySelectorAll('.chat-event'); events = view.el.querySelectorAll('.chat-event');
expect(events.length).toBe(3); expect(events.length).toBe(3);
...@@ -4475,7 +4472,7 @@ ...@@ -4475,7 +4472,7 @@
expect(sizzle('div.chat-info:last', chat_content).pop().textContent) expect(sizzle('div.chat-info:last', chat_content).pop().textContent)
.toBe("nomorenicks has entered the groupchat"); .toBe("nomorenicks has entered the groupchat");
// See XEP-0085 http://xmpp.org/extensions/xep-0085.html#definitions // See XEP-0085 https://xmpp.org/extensions/xep-0085.html#definitions
// <composing> state // <composing> state
var msg = $msg({ var msg = $msg({
......
...@@ -112,7 +112,7 @@ ...@@ -112,7 +112,7 @@
}).then(stanza => { }).then(stanza => {
// The user has just entered the room (because join was called) // The user has just entered the room (because join was called)
// and receives their own presence from the server. // and receives their own presence from the server.
// See example 24: http://xmpp.org/extensions/xep-0045.html#enter-pres // See example 24: https://xmpp.org/extensions/xep-0045.html#enter-pres
const presence = $pres({ const presence = $pres({
to: _converse.connection.jid, to: _converse.connection.jid,
from: room_jid, from: room_jid,
......
...@@ -1270,7 +1270,7 @@ ...@@ -1270,7 +1270,7 @@
expect(_converse.roster.pluck('jid').length).toBe(1); expect(_converse.roster.pluck('jid').length).toBe(1);
expect(_.includes(_converse.roster.pluck('jid'), 'data@enterprise')).toBeTruthy(); expect(_.includes(_converse.roster.pluck('jid'), 'data@enterprise')).toBeTruthy();
// Taken from the spec // Taken from the spec
// http://xmpp.org/rfcs/rfc3921.html#rfc.section.7.3 // https://xmpp.org/rfcs/rfc3921.html#rfc.section.7.3
stanza = $iq({ stanza = $iq({
to: _converse.connection.jid, to: _converse.connection.jid,
type: 'result', type: 'result',
......
// Converse.js // Converse.js
// http://conversejs.org // https://conversejs.org
// //
// Copyright (c) 2013-2019, the Converse.js developers // Copyright (c) 2013-2019, the Converse.js developers
// Licensed under the Mozilla Public License (MPLv2) // Licensed under the Mozilla Public License (MPLv2)
...@@ -13,7 +13,6 @@ import converse from "@converse/headless/converse-core"; ...@@ -13,7 +13,6 @@ import converse from "@converse/headless/converse-core";
const { _, Backbone } = converse.env, const { _, Backbone } = converse.env,
u = converse.env.utils; u = converse.env.utils;
converse.plugins.add("converse-autocomplete", { converse.plugins.add("converse-autocomplete", {
initialize () { initialize () {
...@@ -73,12 +72,12 @@ converse.plugins.add("converse-autocomplete", { ...@@ -73,12 +72,12 @@ converse.plugins.add("converse-autocomplete", {
_.assignIn(this, { _.assignIn(this, {
'match_current_word': false, // Match only the current word, otherwise all input is matched 'match_current_word': false, // Match only the current word, otherwise all input is matched
'match_on_tab': false, // Whether matching should only start when tab's pressed 'ac_triggers': [], // Array of keys (`ev.key`) values that will trigger auto-complete
'trigger_on_at': false, // Whether @ should trigger autocomplete 'include_triggers': [], // Array of trigger keys which should be included in the returned value
'min_chars': 2, 'min_chars': 2,
'max_items': 10, 'max_items': 10,
'auto_evaluate': true, 'auto_evaluate': true,
'auto_first': false, 'auto_first': false, // Should the first element be automatically selected?
'data': _.identity, 'data': _.identity,
'filter': _converse.FILTER_CONTAINS, 'filter': _converse.FILTER_CONTAINS,
'sort': config.sort === false ? false : SORT_BYLENGTH, 'sort': config.sort === false ? false : SORT_BYLENGTH,
...@@ -291,11 +290,17 @@ converse.plugins.add("converse-autocomplete", { ...@@ -291,11 +290,17 @@ converse.plugins.add("converse-autocomplete", {
, ev.keyCode)) { , ev.keyCode)) {
return; return;
} }
if (this.match_on_tab && ev.keyCode === _converse.keycodes.TAB) {
ev.preventDefault(); if (this.ac_triggers.includes(ev.key)) {
this.auto_completing = true; if (ev.key === "Tab") {
} else if (this.trigger_on_at && ev.keyCode === _converse.keycodes.AT) { ev.preventDefault();
}
this.auto_completing = true; this.auto_completing = true;
} else if (ev.key === "Backspace") {
const word = u.getCurrentWord(ev.target, ev.target.selectionEnd-1);
if (this.ac_triggers.includes(word[0])) {
this.auto_completing = true;
}
} }
} }
...@@ -316,7 +321,7 @@ converse.plugins.add("converse-autocomplete", { ...@@ -316,7 +321,7 @@ converse.plugins.add("converse-autocomplete", {
let value = this.match_current_word ? u.getCurrentWord(this.input) : this.input.value; let value = this.match_current_word ? u.getCurrentWord(this.input) : this.input.value;
let ignore_min_chars = false; let ignore_min_chars = false;
if (this.trigger_on_at && value.startsWith('@')) { if (this.ac_triggers.includes(value[0]) && !this.include_triggers.includes(ev.key)) {
ignore_min_chars = true; ignore_min_chars = true;
value = value.slice('1'); value = value.slice('1');
} }
......
// Converse.js (A browser based XMPP chat client) // Converse.js (A browser based XMPP chat client)
// http://conversejs.org // https://conversejs.org
// //
// Copyright (c) 2012-2017, Jan-Carel Brand <jc@opkode.com> // Copyright (c) 2012-2017, Jan-Carel Brand <jc@opkode.com>
// Licensed under the Mozilla Public License (MPLv2) // Licensed under the Mozilla Public License (MPLv2)
......
// Converse.js // Converse.js
// http://conversejs.org // https://conversejs.org
// //
// Copyright (c) 2013-2019, the Converse.js developers // Copyright (c) 2013-2019, the Converse.js developers
// Licensed under the Mozilla Public License (MPLv2) // Licensed under the Mozilla Public License (MPLv2)
......
// Converse.js // Converse.js
// http://conversejs.org // https://conversejs.org
// //
// Copyright (c) 2012-2019, the Converse.js developers // Copyright (c) 2012-2019, the Converse.js developers
// Licensed under the Mozilla Public License (MPLv2) // Licensed under the Mozilla Public License (MPLv2)
......
// Converse.js // Converse.js
// http://conversejs.org // https://conversejs.org
// //
// Copyright (c) 2013-2019, the Converse.js developers // Copyright (c) 2013-2019, the Converse.js developers
// Licensed under the Mozilla Public License (MPLv2) // Licensed under the Mozilla Public License (MPLv2)
......
// Converse.js (A browser based XMPP chat client) // Converse.js (A browser based XMPP chat client)
// http://conversejs.org // https://conversejs.org
// //
// Copyright (c) 2012-2017, Jan-Carel Brand <jc@opkode.com> // Copyright (c) 2012-2017, Jan-Carel Brand <jc@opkode.com>
// Licensed under the Mozilla Public License (MPLv2) // Licensed under the Mozilla Public License (MPLv2)
......
// Converse.js (A browser based XMPP chat client) // Converse.js (A browser based XMPP chat client)
// http://conversejs.org // https://conversejs.org
// //
// Copyright (c) 2012-2017, Jan-Carel Brand <jc@opkode.com> // Copyright (c) 2012-2017, Jan-Carel Brand <jc@opkode.com>
// Licensed under the Mozilla Public License (MPLv2) // Licensed under the Mozilla Public License (MPLv2)
......
// Converse.js // Converse.js
// http://conversejs.org // https://conversejs.org
// //
// Copyright (c) 2013-2019, the Converse.js developers // Copyright (c) 2013-2019, the Converse.js developers
// Licensed under the Mozilla Public License (MPLv2) // Licensed under the Mozilla Public License (MPLv2)
......
// Converse.js (A browser based XMPP chat client) // Converse.js (A browser based XMPP chat client)
// http://conversejs.org // https://conversejs.org
// //
// Copyright (c) JC Brand <jc@opkode.com> // Copyright (c) JC Brand <jc@opkode.com>
// Licensed under the Mozilla Public License (MPLv2) // Licensed under the Mozilla Public License (MPLv2)
......
// Converse.js (A browser based XMPP chat client) // Converse.js (A browser based XMPP chat client)
// http://conversejs.org // https://conversejs.org
// //
// Copyright (c) 2012-2017, Jan-Carel Brand <jc@opkode.com> // Copyright (c) 2012-2017, Jan-Carel Brand <jc@opkode.com>
// Licensed under the Mozilla Public License (MPLv2) // Licensed under the Mozilla Public License (MPLv2)
......
// Converse.js (A browser based XMPP chat client) // Converse.js (A browser based XMPP chat client)
// http://conversejs.org // https://conversejs.org
// //
// Copyright (c) 2013-2019, Jan-Carel Brand <jc@opkode.com> // Copyright (c) 2013-2019, Jan-Carel Brand <jc@opkode.com>
// Licensed under the Mozilla Public License (MPLv2) // Licensed under the Mozilla Public License (MPLv2)
......
// Converse.js // Converse.js
// http://conversejs.org // https://conversejs.org
// //
// Copyright (c) 2013-2019, the Converse.js developers // Copyright (c) 2013-2019, the Converse.js developers
// Licensed under the Mozilla Public License (MPLv2) // Licensed under the Mozilla Public License (MPLv2)
......
// Converse.js // Converse.js
// http://conversejs.org // https://conversejs.org
// //
// Copyright (c) 2013-2019, the Converse.js developers // Copyright (c) 2013-2019, the Converse.js developers
// Licensed under the Mozilla Public License (MPLv2) // Licensed under the Mozilla Public License (MPLv2)
...@@ -128,7 +128,7 @@ converse.plugins.add('converse-muc-views', { ...@@ -128,7 +128,7 @@ converse.plugins.add('converse-muc-views', {
return str; return str;
} }
/* http://xmpp.org/extensions/xep-0045.html /* https://xmpp.org/extensions/xep-0045.html
* ---------------------------------------- * ----------------------------------------
* 100 message Entering a groupchat Inform user that any occupant is allowed to see the user's full JID * 100 message Entering a groupchat Inform user that any occupant is allowed to see the user's full JID
* 101 message (out of band) Affiliation change Inform user that his or her affiliation changed while not in the groupchat * 101 message (out of band) Affiliation change Inform user that his or her affiliation changed while not in the groupchat
...@@ -206,7 +206,7 @@ converse.plugins.add('converse-muc-views', { ...@@ -206,7 +206,7 @@ converse.plugins.add('converse-muc-views', {
* (XMLElement) stanza: The IQ stanza containing the groupchat * (XMLElement) stanza: The IQ stanza containing the groupchat
* info. * info.
*/ */
// All MUC features found here: http://xmpp.org/registrar/disco-features.html // All MUC features found here: https://xmpp.org/registrar/disco-features.html
el.querySelector('span.spinner').remove(); el.querySelector('span.spinner').remove();
el.querySelector('a.room-info').classList.add('selected'); el.querySelector('a.room-info').classList.add('selected');
el.insertAdjacentHTML( el.insertAdjacentHTML(
...@@ -506,7 +506,9 @@ converse.plugins.add('converse-muc-views', { ...@@ -506,7 +506,9 @@ converse.plugins.add('converse-muc-views', {
'click .upload-file': 'toggleFileUpload', 'click .upload-file': 'toggleFileUpload',
'keydown .chat-textarea': 'keyPressed', 'keydown .chat-textarea': 'keyPressed',
'keyup .chat-textarea': 'keyUp', 'keyup .chat-textarea': 'keyUp',
'input .chat-textarea': 'inputChanged' 'input .chat-textarea': 'inputChanged',
'dragover .chat-textarea': 'onDragOver',
'drop .chat-textarea': 'onDrop',
}, },
initialize () { initialize () {
...@@ -560,7 +562,7 @@ converse.plugins.add('converse-muc-views', { ...@@ -560,7 +562,7 @@ converse.plugins.add('converse-muc-views', {
this.renderHeading(); this.renderHeading();
this.renderChatArea(); this.renderChatArea();
this.renderMessageForm(); this.renderMessageForm();
this.initAutoComplete(); this.initMentionAutoComplete();
if (this.model.get('connection_status') !== converse.ROOMSTATUS.ENTERED) { if (this.model.get('connection_status') !== converse.ROOMSTATUS.ENTERED) {
this.showSpinner(); this.showSpinner();
} }
...@@ -587,16 +589,16 @@ converse.plugins.add('converse-muc-views', { ...@@ -587,16 +589,16 @@ converse.plugins.add('converse-muc-views', {
return this; return this;
}, },
initAutoComplete () { initMentionAutoComplete () {
this.auto_complete = new _converse.AutoComplete(this.el, { this.auto_complete = new _converse.AutoComplete(this.el, {
'auto_first': true, 'auto_first': true,
'auto_evaluate': false, 'auto_evaluate': false,
'min_chars': 1, 'min_chars': 1,
'match_current_word': true, 'match_current_word': true,
'match_on_tab': true,
'list': () => this.model.occupants.map(o => ({'label': o.getDisplayName(), 'value': `@${o.getDisplayName()}`})), 'list': () => this.model.occupants.map(o => ({'label': o.getDisplayName(), 'value': `@${o.getDisplayName()}`})),
'filter': _converse.FILTER_STARTSWITH, 'filter': _converse.FILTER_STARTSWITH,
'trigger_on_at': true 'ac_triggers': ["Tab", "@"],
'include_triggers': []
}); });
this.auto_complete.on('suggestion-box-selectcomplete', () => (this.auto_completing = false)); this.auto_complete.on('suggestion-box-selectcomplete', () => (this.auto_completing = false));
}, },
...@@ -812,7 +814,7 @@ converse.plugins.add('converse-muc-views', { ...@@ -812,7 +814,7 @@ converse.plugins.add('converse-muc-views', {
* ignore <gone/> notifications in groupchats. * ignore <gone/> notifications in groupchats.
* *
* As laid out in the business rules in XEP-0085 * As laid out in the business rules in XEP-0085
* http://xmpp.org/extensions/xep-0085.html#bizrules-groupchat * https://xmpp.org/extensions/xep-0085.html#bizrules-groupchat
*/ */
if (message.get('fullname') === this.model.get('nick')) { if (message.get('fullname') === this.model.get('nick')) {
// Don't know about other servers, but OpenFire sends // Don't know about other servers, but OpenFire sends
...@@ -1669,7 +1671,7 @@ converse.plugins.add('converse-muc-views', { ...@@ -1669,7 +1671,7 @@ converse.plugins.add('converse-muc-views', {
showStatusMessages (stanza) { showStatusMessages (stanza) {
/* Check for status codes and communicate their purpose to the user. /* Check for status codes and communicate their purpose to the user.
* See: http://xmpp.org/registrar/mucstatus.html * See: https://xmpp.org/registrar/mucstatus.html
* *
* Parameters: * Parameters:
* (XMLElement) stanza: The message or presence stanza * (XMLElement) stanza: The message or presence stanza
...@@ -1837,9 +1839,7 @@ converse.plugins.add('converse-muc-views', { ...@@ -1837,9 +1839,7 @@ converse.plugins.add('converse-muc-views', {
const show = this.model.get('show'); const show = this.model.get('show');
return tpl_occupant( return tpl_occupant(
_.extend( _.extend(
{ '_': _, // XXX Normally this should already be included, { '_': _,
// but with the current webpack build,
// we only get a subset of the _ methods.
'jid': '', 'jid': '',
'show': show, 'show': show,
'hint_show': _converse.PRETTY_CHAT_STATUS[show], 'hint_show': _converse.PRETTY_CHAT_STATUS[show],
......
// Converse.js (A browser based XMPP chat client) // Converse.js (A browser based XMPP chat client)
// http://conversejs.org // https://conversejs.org
// //
// Copyright (c) 2013-2019, JC Brand <jc@opkode.com> // Copyright (c) 2013-2019, JC Brand <jc@opkode.com>
// Licensed under the Mozilla Public License (MPLv2) // Licensed under the Mozilla Public License (MPLv2)
......
// Converse.js // Converse.js
// http://conversejs.org // https://conversejs.org
// //
// Copyright (c) 2013-2019, the Converse.js developers // Copyright (c) 2013-2019, the Converse.js developers
// Licensed under the Mozilla Public License (MPLv2) // Licensed under the Mozilla Public License (MPLv2)
......
// Converse.js (A browser based XMPP chat client) // Converse.js (A browser based XMPP chat client)
// http://conversejs.org // https://conversejs.org
// //
// Copyright (c) 2013-2017, Jan-Carel Brand <jc@opkode.com> // Copyright (c) 2013-2017, Jan-Carel Brand <jc@opkode.com>
// Licensed under the Mozilla Public License (MPLv2) // Licensed under the Mozilla Public License (MPLv2)
......
// Converse.js (A browser based XMPP chat client) // Converse.js (A browser based XMPP chat client)
// http://conversejs.org // https://conversejs.org
// //
// Copyright (c) 2012-2017, Jan-Carel Brand <jc@opkode.com> // Copyright (c) 2012-2017, Jan-Carel Brand <jc@opkode.com>
// Licensed under the Mozilla Public License (MPLv2) // Licensed under the Mozilla Public License (MPLv2)
......
// Converse.js (A browser based XMPP chat client) // Converse.js (A browser based XMPP chat client)
// http://conversejs.org // https://conversejs.org
// //
// Copyright (c) 2013-2019, Jan-Carel Brand <jc@opkode.com> // Copyright (c) 2013-2019, Jan-Carel Brand <jc@opkode.com>
// Licensed under the Mozilla Public License (MPLv2) // Licensed under the Mozilla Public License (MPLv2)
......
// Converse.js // Converse.js
// http://conversejs.org // https://conversejs.org
// //
// Copyright (c) 2013-2019, the Converse.js developers // Copyright (c) 2013-2019, the Converse.js developers
// Licensed under the Mozilla Public License (MPLv2) // Licensed under the Mozilla Public License (MPLv2)
......
// Converse.js // Converse.js
// http://conversejs.org // https://conversejs.org
// //
// Copyright (c) 2013-2019, the Converse.js developers // Copyright (c) 2013-2019, the Converse.js developers
// Licensed under the Mozilla Public License (MPLv2) // Licensed under the Mozilla Public License (MPLv2)
......
// Converse.js // Converse.js
// http://conversejs.org // https://conversejs.org
// //
// Copyright (c) 2012-2019, the Converse.js developers // Copyright (c) 2012-2019, the Converse.js developers
// Licensed under the Mozilla Public License (MPLv2) // Licensed under the Mozilla Public License (MPLv2)
......
...@@ -165,7 +165,7 @@ _converse.TIMEOUTS = { // Set as module attr so that we can override in tests. ...@@ -165,7 +165,7 @@ _converse.TIMEOUTS = { // Set as module attr so that we can override in tests.
}; };
// XEP-0085 Chat states // XEP-0085 Chat states
// http://xmpp.org/extensions/xep-0085.html // https://xmpp.org/extensions/xep-0085.html
_converse.INACTIVE = 'inactive'; _converse.INACTIVE = 'inactive';
_converse.ACTIVE = 'active'; _converse.ACTIVE = 'active';
_converse.COMPOSING = 'composing'; _converse.COMPOSING = 'composing';
......
// Converse.js // Converse.js
// http://conversejs.org // https://conversejs.org
// //
// Copyright (c) 2013-2019, the Converse developers // Copyright (c) 2013-2019, the Converse developers
// Licensed under the Mozilla Public License (MPLv2) // Licensed under the Mozilla Public License (MPLv2)
...@@ -217,7 +217,7 @@ converse.plugins.add('converse-disco', { ...@@ -217,7 +217,7 @@ converse.plugins.add('converse-disco', {
}); });
function addClientFeatures () { function addClientFeatures () {
// See http://xmpp.org/registrar/disco-categories.html // See https://xmpp.org/registrar/disco-categories.html
_converse.api.disco.own.identities.add('client', 'web', 'Converse'); _converse.api.disco.own.identities.add('client', 'web', 'Converse');
_converse.api.disco.own.features.add(Strophe.NS.BOSH); _converse.api.disco.own.features.add(Strophe.NS.BOSH);
......
// Converse.js (A browser based XMPP chat client) // Converse.js (A browser based XMPP chat client)
// http://conversejs.org // https://conversejs.org
// //
// Copyright (c) 2012-2017, Jan-Carel Brand <jc@opkode.com> // Copyright (c) 2012-2017, Jan-Carel Brand <jc@opkode.com>
// Licensed under the Mozilla Public License (MPLv2) // Licensed under the Mozilla Public License (MPLv2)
......
// Converse.js // Converse.js
// http://conversejs.org // https://conversejs.org
// //
// Copyright (c) 2013-2019, the Converse.js developers // Copyright (c) 2013-2019, the Converse.js developers
// Licensed under the Mozilla Public License (MPLv2) // Licensed under the Mozilla Public License (MPLv2)
...@@ -538,7 +538,7 @@ converse.plugins.add('converse-muc', { ...@@ -538,7 +538,7 @@ converse.plugins.add('converse-muc', {
/* Send an IQ stanza to the server, asking it for the /* Send an IQ stanza to the server, asking it for the
* member-list of this groupchat. * member-list of this groupchat.
* *
* See: http://xmpp.org/extensions/xep-0045.html#modifymember * See: https://xmpp.org/extensions/xep-0045.html#modifymember
* *
* Parameters: * Parameters:
* (String) affiliation: The specific member list to * (String) affiliation: The specific member list to
...@@ -559,7 +559,7 @@ converse.plugins.add('converse-muc', { ...@@ -559,7 +559,7 @@ converse.plugins.add('converse-muc', {
/* Send IQ stanzas to the server to set an affiliation for /* Send IQ stanzas to the server to set an affiliation for
* the provided JIDs. * the provided JIDs.
* *
* See: http://xmpp.org/extensions/xep-0045.html#modifymember * See: https://xmpp.org/extensions/xep-0045.html#modifymember
* *
* XXX: Prosody doesn't accept multiple JIDs' affiliations * XXX: Prosody doesn't accept multiple JIDs' affiliations
* being set in one IQ stanza, so as a workaround we send * being set in one IQ stanza, so as a workaround we send
...@@ -728,7 +728,7 @@ converse.plugins.add('converse-muc', { ...@@ -728,7 +728,7 @@ converse.plugins.add('converse-muc', {
/* Send IQ stanzas to the server to modify the /* Send IQ stanzas to the server to modify the
* affiliations in this groupchat. * affiliations in this groupchat.
* *
* See: http://xmpp.org/extensions/xep-0045.html#modifymember * See: https://xmpp.org/extensions/xep-0045.html#modifymember
* *
* Parameters: * Parameters:
* (Object) members: A map of jids, affiliations and optionally reasons * (Object) members: A map of jids, affiliations and optionally reasons
...@@ -1498,7 +1498,7 @@ converse.plugins.add('converse-muc', { ...@@ -1498,7 +1498,7 @@ converse.plugins.add('converse-muc', {
* configured automatically. Currently it doesn't make sense to specify * configured automatically. Currently it doesn't make sense to specify
* `roomconfig` values if `auto_configure` is set to `false`. * `roomconfig` values if `auto_configure` is set to `false`.
* For a list of configuration values that can be passed in, refer to these values * For a list of configuration values that can be passed in, refer to these values
* in the [XEP-0045 MUC specification](http://xmpp.org/extensions/xep-0045.html#registrar-formtype-owner). * in the [XEP-0045 MUC specification](https://xmpp.org/extensions/xep-0045.html#registrar-formtype-owner).
* The values should be named without the `muc#roomconfig_` prefix. * The values should be named without the `muc#roomconfig_` prefix.
* @param {boolean} [attrs.maximize] A boolean, indicating whether minimized rooms should also be * @param {boolean} [attrs.maximize] A boolean, indicating whether minimized rooms should also be
* maximized, when opened. Set to `false` by default. * maximized, when opened. Set to `false` by default.
......
// Converse.js // Converse.js
// http://conversejs.org // https://conversejs.org
// //
// Copyright (c) 2019, the Converse.js developers // Copyright (c) 2019, the Converse.js developers
// Licensed under the Mozilla Public License (MPLv2) // Licensed under the Mozilla Public License (MPLv2)
......
// Converse.js // Converse.js
// http://conversejs.org // https://conversejs.org
// //
// Copyright (c) 2013-2019, the Converse.js developers // Copyright (c) 2013-2019, the Converse.js developers
// Licensed under the Mozilla Public License (MPLv2) // Licensed under the Mozilla Public License (MPLv2)
......
// Converse.js // Converse.js
// http://conversejs.org // https://conversejs.org
// //
// Copyright (c) 2013-2019, the Converse.js developers // Copyright (c) 2013-2019, the Converse.js developers
// Licensed under the Mozilla Public License (MPLv2) // Licensed under the Mozilla Public License (MPLv2)
......
// Converse.js (A browser based XMPP chat client) // Converse.js (A browser based XMPP chat client)
// http://conversejs.org // https://conversejs.org
// //
// This is the internationalization module. // This is the internationalization module.
// //
......
// Converse.js (A browser based XMPP chat client) // Converse.js (A browser based XMPP chat client)
// http://conversejs.org // https://conversejs.org
// //
// This is the utilities module. // This is the utilities module.
// //
...@@ -332,9 +332,11 @@ u.siblingIndex = function (el) { ...@@ -332,9 +332,11 @@ u.siblingIndex = function (el) {
return i; return i;
}; };
u.getCurrentWord = function (input) { u.getCurrentWord = function (input, index) {
const cursor = input.selectionEnd || undefined; if (!index) {
return _.last(input.value.slice(0, cursor).split(' ')); index = input.selectionEnd || undefined;
}
return _.last(input.value.slice(0, index).split(' '));
}; };
u.replaceCurrentWord = function (input, new_value) { u.replaceCurrentWord = function (input, new_value) {
......
// Converse.js (A browser based XMPP chat client) // Converse.js (A browser based XMPP chat client)
// http://conversejs.org // https://conversejs.org
// //
// This is the utilities module. // This is the utilities module.
// //
......
// Converse.js (A browser based XMPP chat client) // Converse.js (A browser based XMPP chat client)
// http://conversejs.org // https://conversejs.org
// //
// This is the utilities module. // This is the utilities module.
// //
......
// Converse.js (A browser based XMPP chat client) // Converse.js (A browser based XMPP chat client)
// http://conversejs.org // https://conversejs.org
// //
// This is a form utilities module. // This is a form utilities module.
// //
...@@ -539,89 +539,85 @@ u.xForm2webForm = function (field, stanza, domain) { ...@@ -539,89 +539,85 @@ u.xForm2webForm = function (field, stanza, domain) {
* Parameters: * Parameters:
* (XMLElement) field - the field to convert * (XMLElement) field - the field to convert
*/ */
if (field.getAttribute('type')) { if (field.getAttribute('type') === 'list-single' ||
if (field.getAttribute('type') === 'list-single' || field.getAttribute('type') === 'list-multi') {
field.getAttribute('type') === 'list-multi') {
const values = _.map(
const values = _.map( u.queryChildren(field, 'value'),
u.queryChildren(field, 'value'), _.partial(_.get, _, 'textContent')
_.partial(_.get, _, 'textContent') );
); const options = _.map(
const options = _.map( u.queryChildren(field, 'option'),
u.queryChildren(field, 'option'), function (option) {
function (option) { const value = _.get(option.querySelector('value'), 'textContent');
const value = _.get(option.querySelector('value'), 'textContent'); return tpl_select_option({
return tpl_select_option({ 'value': value,
'value': value, 'label': option.getAttribute('label'),
'label': option.getAttribute('label'), 'selected': _.includes(values, value),
'selected': _.includes(values, value), 'required': !_.isNil(field.querySelector('required'))
'required': !_.isNil(field.querySelector('required')) })
}) }
} );
); return tpl_form_select({
return tpl_form_select({ 'id': u.getUniqueId(),
'id': u.getUniqueId(), 'name': field.getAttribute('var'),
'name': field.getAttribute('var'), 'label': field.getAttribute('label'),
'label': field.getAttribute('label'), 'options': options.join(''),
'options': options.join(''), 'multiple': (field.getAttribute('type') === 'list-multi'),
'multiple': (field.getAttribute('type') === 'list-multi'), 'required': !_.isNil(field.querySelector('required'))
'required': !_.isNil(field.querySelector('required')) });
}); } else if (field.getAttribute('type') === 'fixed') {
} else if (field.getAttribute('type') === 'fixed') { const text = _.get(field.querySelector('value'), 'textContent');
const text = _.get(field.querySelector('value'), 'textContent'); return '<p class="form-help">'+text+'</p>';
return '<p class="form-help">'+text+'</p>'; } else if (field.getAttribute('type') === 'jid-multi') {
} else if (field.getAttribute('type') === 'jid-multi') { return tpl_form_textarea({
return tpl_form_textarea({ 'name': field.getAttribute('var'),
'name': field.getAttribute('var'), 'label': field.getAttribute('label') || '',
'label': field.getAttribute('label') || '', 'value': _.get(field.querySelector('value'), 'textContent'),
'value': _.get(field.querySelector('value'), 'textContent'), 'required': !_.isNil(field.querySelector('required'))
'required': !_.isNil(field.querySelector('required')) });
}); } else if (field.getAttribute('type') === 'boolean') {
} else if (field.getAttribute('type') === 'boolean') { return tpl_form_checkbox({
return tpl_form_checkbox({ 'id': u.getUniqueId(),
'id': u.getUniqueId(), 'name': field.getAttribute('var'),
'name': field.getAttribute('var'), 'label': field.getAttribute('label') || '',
'label': field.getAttribute('label') || '', 'checked': _.get(field.querySelector('value'), 'textContent') === "1" && 'checked="1"' || '',
'checked': _.get(field.querySelector('value'), 'textContent') === "1" && 'checked="1"' || '', 'required': !_.isNil(field.querySelector('required'))
'required': !_.isNil(field.querySelector('required')) });
}); } else if (field.getAttribute('var') === 'url') {
} else if (field.getAttribute('var') === 'url') { return tpl_form_url({
return tpl_form_url({ 'label': field.getAttribute('label') || '',
'label': field.getAttribute('label') || '', 'value': _.get(field.querySelector('value'), 'textContent')
'value': _.get(field.querySelector('value'), 'textContent') });
}); } else if (field.getAttribute('var') === 'username') {
} else if (field.getAttribute('var') === 'username') { return tpl_form_username({
return tpl_form_username({ 'domain': ' @'+domain,
'domain': ' @'+domain, 'name': field.getAttribute('var'),
'name': field.getAttribute('var'), 'type': XFORM_TYPE_MAP[field.getAttribute('type')],
'type': XFORM_TYPE_MAP[field.getAttribute('type')], 'label': field.getAttribute('label') || '',
'label': field.getAttribute('label') || '', 'value': _.get(field.querySelector('value'), 'textContent'),
'value': _.get(field.querySelector('value'), 'textContent'), 'required': !_.isNil(field.querySelector('required'))
'required': !_.isNil(field.querySelector('required')) });
}); } else if (field.getAttribute('var') === 'ocr') { // Captcha
} else { const uri = field.querySelector('uri');
return tpl_form_input({ const el = sizzle('data[cid="'+uri.textContent.replace(/^cid:/, '')+'"]', stanza)[0];
'id': u.getUniqueId(), return tpl_form_captcha({
'label': field.getAttribute('label') || '', 'label': field.getAttribute('label'),
'name': field.getAttribute('var'), 'name': field.getAttribute('var'),
'placeholder': null, 'data': _.get(el, 'textContent'),
'required': !_.isNil(field.querySelector('required')), 'type': uri.getAttribute('type'),
'type': XFORM_TYPE_MAP[field.getAttribute('type')], 'required': !_.isNil(field.querySelector('required'))
'value': _.get(field.querySelector('value'), 'textContent') });
});
}
} else { } else {
if (field.getAttribute('var') === 'ocr') { // Captcha return tpl_form_input({
const uri = field.querySelector('uri'); 'id': u.getUniqueId(),
const el = sizzle('data[cid="'+uri.textContent.replace(/^cid:/, '')+'"]', stanza)[0]; 'label': field.getAttribute('label') || '',
return tpl_form_captcha({ 'name': field.getAttribute('var'),
'label': field.getAttribute('label'), 'placeholder': null,
'name': field.getAttribute('var'), 'required': !_.isNil(field.querySelector('required')),
'data': _.get(el, 'textContent'), 'type': XFORM_TYPE_MAP[field.getAttribute('type')],
'type': uri.getAttribute('type'), 'value': _.get(field.querySelector('value'), 'textContent')
'required': !_.isNil(field.querySelector('required')) });
});
}
} }
} }
export default u; export default u;
...@@ -182,7 +182,7 @@ ...@@ -182,7 +182,7 @@
// The user has just entered the room (because join was called) // The user has just entered the room (because join was called)
// and receives their own presence from the server. // and receives their own presence from the server.
// See example 24: http://xmpp.org/extensions/xep-0045.html#enter-pres // See example 24: https://xmpp.org/extensions/xep-0045.html#enter-pres
var presence = $pres({ var presence = $pres({
to: _converse.connection.jid, to: _converse.connection.jid,
from: `${room_jid}/${nick}`, from: `${room_jid}/${nick}`,
......
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