diff --git a/.github/CONTRIBUTING.rst b/.github/CONTRIBUTING.rst index 49d719335..e7f4a4898 100644 --- a/.github/CONTRIBUTING.rst +++ b/.github/CONTRIBUTING.rst @@ -2,7 +2,7 @@ Contribution Guidelines ======================= -Thanks for contributing to `Converse.js `_. +Thanks for contributing to `Converse.js `_. Support questions ================= diff --git a/CHANGES.md b/CHANGES.md index fbbb7870d..44b766e0b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,8 +2,10 @@ ## 4.1.3 (Unreleased) +- Updated translation: lt - Upgrade to Backbone 1.4.0 - 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` - 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) @@ -13,7 +15,8 @@ - #1400: When a chat message is just an emoji, enlarge the emoji - #1437: List of groupchats in modal doesn't scroll - #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) @@ -647,7 +650,7 @@ More info here: https://github.com/LeaVerou/awesomplete/pull/17082 ## 2.0.4 (2016-12-13) - #737: Bugfix. Translations weren't being applied. [jcbrand] - 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. 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 diff --git a/RELEASE.md b/RELEASE.md index 2756a49a2..69b8188b1 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -8,7 +8,7 @@ 6. `git commit -am "New release 5.0.0"` 7. `git tag -s v5.0.0 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. * Create a new version for the CDN by copying * Check out the correct tag diff --git a/composer.json b/composer.json index 3ea2c955a..086d0ee7d 100644 --- a/composer.json +++ b/composer.json @@ -4,7 +4,7 @@ "type": "library", "license": "MPL-2.0", "minimum-stability": "stable", - "homepage": "http://conversejs.org/", + "homepage": "https://conversejs.org/", "keywords": ["xmpp", "messaging", "chat", "presence"], "require": {} } diff --git a/css/converse.css b/css/converse.css index a0af445a0..60230c37e 100644 --- a/css/converse.css +++ b/css/converse.css @@ -1,6 +1,6 @@ /*! * Converse.js (Web-based XMPP instant messaging client) - * http://conversejs.org + * https://conversejs.org * * Copyright (c) 2013-2018, JC Brand * Licensed under the Mozilla Public License diff --git a/dist/converse.js b/dist/converse.js index 6a1f75b33..5baead658 100644 --- a/dist/converse.js +++ b/dist/converse.js @@ -47933,7 +47933,7 @@ exports["filterCSS"] = (filterCSS); __webpack_require__.r(__webpack_exports__); /* harmony import */ var _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @converse/headless/converse-core */ "./src/headless/converse-core.js"); // Converse.js -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2013-2019, the Converse.js developers // Licensed under the Mozilla Public License (MPLv2) @@ -48002,14 +48002,15 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_0__["default"].plugins _.assignIn(this, { '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 - 'trigger_on_at': false, - // Whether @ should trigger autocomplete + 'ac_triggers': [], + // Array of keys (`ev.key`) values that will trigger auto-complete + 'include_triggers': [], + // Array of trigger keys which should be included in the returned value 'min_chars': 2, 'max_items': 10, 'auto_evaluate': true, 'auto_first': false, + // Should the first element be automatically selected? 'data': _.identity, 'filter': _converse.FILTER_CONTAINS, 'sort': config.sort === false ? false : SORT_BYLENGTH, @@ -48241,11 +48242,18 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_0__["default"].plugins return; } - if (this.match_on_tab && ev.keyCode === _converse.keycodes.TAB) { - ev.preventDefault(); - this.auto_completing = true; - } else if (this.trigger_on_at && ev.keyCode === _converse.keycodes.AT) { + if (this.ac_triggers.includes(ev.key)) { + if (ev.key === "Tab") { + ev.preventDefault(); + } + 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; + } } } @@ -48265,7 +48273,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_0__["default"].plugins let value = this.match_current_word ? u.getCurrentWord(this.input) : this.input.value; 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; value = value.slice('1'); } @@ -48391,7 +48399,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var templates_chatroom_bookmark_toggle_html__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! templates/chatroom_bookmark_toggle.html */ "./src/templates/chatroom_bookmark_toggle.html"); /* harmony import */ var templates_chatroom_bookmark_toggle_html__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(templates_chatroom_bookmark_toggle_html__WEBPACK_IMPORTED_MODULE_5__); // Converse.js (A browser based XMPP chat client) -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2012-2017, Jan-Carel Brand // Licensed under the Mozilla Public License (MPLv2) @@ -49043,7 +49051,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_0__["default"].plugins __webpack_require__.r(__webpack_exports__); /* harmony import */ var _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @converse/headless/converse-core */ "./src/headless/converse-core.js"); // Converse.js -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2013-2019, the Converse.js developers // Licensed under the Mozilla Public License (MPLv2) @@ -49128,7 +49136,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var templates_chatboxes_html__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! templates/chatboxes.html */ "./src/templates/chatboxes.html"); /* harmony import */ var templates_chatboxes_html__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(templates_chatboxes_html__WEBPACK_IMPORTED_MODULE_6__); // Converse.js -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2012-2019, the Converse.js developers // Licensed under the Mozilla Public License (MPLv2) @@ -49366,7 +49374,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var xss__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! xss */ "./node_modules/xss/dist/xss.js"); /* harmony import */ var xss__WEBPACK_IMPORTED_MODULE_22___default = /*#__PURE__*/__webpack_require__.n(xss__WEBPACK_IMPORTED_MODULE_22__); // Converse.js -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2013-2019, the Converse.js developers // Licensed under the Mozilla Public License (MPLv2) @@ -50812,7 +50820,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var templates_login_panel_html__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! templates/login_panel.html */ "./src/templates/login_panel.html"); /* harmony import */ var templates_login_panel_html__WEBPACK_IMPORTED_MODULE_10___default = /*#__PURE__*/__webpack_require__.n(templates_login_panel_html__WEBPACK_IMPORTED_MODULE_10__); // Converse.js (A browser based XMPP chat client) -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2012-2017, Jan-Carel Brand // Licensed under the Mozilla Public License (MPLv2) @@ -51565,7 +51573,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var templates_dragresize_html__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! templates/dragresize.html */ "./src/templates/dragresize.html"); /* harmony import */ var templates_dragresize_html__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(templates_dragresize_html__WEBPACK_IMPORTED_MODULE_3__); // Converse.js (A browser based XMPP chat client) -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2012-2017, Jan-Carel Brand // Licensed under the Mozilla Public License (MPLv2) @@ -51986,7 +51994,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _converse_headless_converse_muc__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @converse/headless/converse-muc */ "./src/headless/converse-muc.js"); /* harmony import */ var _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @converse/headless/converse-core */ "./src/headless/converse-core.js"); // Converse.js -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2013-2019, the Converse.js developers // Licensed under the Mozilla Public License (MPLv2) @@ -52045,7 +52053,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var templates_inverse_brand_heading_html__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! templates/inverse_brand_heading.html */ "./src/templates/inverse_brand_heading.html"); /* harmony import */ var templates_inverse_brand_heading_html__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(templates_inverse_brand_heading_html__WEBPACK_IMPORTED_MODULE_5__); // Converse.js (A browser based XMPP chat client) -// http://conversejs.org +// https://conversejs.org // // Copyright (c) JC Brand // Licensed under the Mozilla Public License (MPLv2) @@ -52117,7 +52125,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var templates_chatbox_html__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! templates/chatbox.html */ "./src/templates/chatbox.html"); /* harmony import */ var templates_chatbox_html__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(templates_chatbox_html__WEBPACK_IMPORTED_MODULE_2__); // Converse.js (A browser based XMPP chat client) -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2012-2017, Jan-Carel Brand // Licensed under the Mozilla Public License (MPLv2) @@ -52595,7 +52603,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var templates_trimmed_chat_html__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! templates/trimmed_chat.html */ "./src/templates/trimmed_chat.html"); /* harmony import */ var templates_trimmed_chat_html__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(templates_trimmed_chat_html__WEBPACK_IMPORTED_MODULE_5__); // Converse.js (A browser based XMPP chat client) -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2013-2019, Jan-Carel Brand // Licensed under the Mozilla Public License (MPLv2) @@ -53212,7 +53220,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var templates_alert_modal_html__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! templates/alert_modal.html */ "./src/templates/alert_modal.html"); /* harmony import */ var templates_alert_modal_html__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(templates_alert_modal_html__WEBPACK_IMPORTED_MODULE_3__); // Converse.js -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2013-2019, the Converse.js developers // Licensed under the Mozilla Public License (MPLv2) @@ -53392,7 +53400,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var xss__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! xss */ "./node_modules/xss/dist/xss.js"); /* harmony import */ var xss__WEBPACK_IMPORTED_MODULE_26___default = /*#__PURE__*/__webpack_require__.n(xss__WEBPACK_IMPORTED_MODULE_26__); // Converse.js -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2013-2019, the Converse.js developers // Licensed under the Mozilla Public License (MPLv2) @@ -53528,7 +53536,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_3__["default"].plugins */ 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 * 101 message (out of band) Affiliation change Inform user that his or her affiliation changed while not in the groupchat @@ -53604,7 +53612,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_3__["default"].plugins * (XMLElement) stanza: The IQ stanza containing the groupchat * 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('a.room-info').classList.add('selected'); el.insertAdjacentHTML('beforeEnd', templates_room_description_html__WEBPACK_IMPORTED_MODULE_21___default()({ @@ -53920,7 +53928,9 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_3__["default"].plugins 'click .upload-file': 'toggleFileUpload', 'keydown .chat-textarea': 'keyPressed', 'keyup .chat-textarea': 'keyUp', - 'input .chat-textarea': 'inputChanged' + 'input .chat-textarea': 'inputChanged', + 'dragover .chat-textarea': 'onDragOver', + 'drop .chat-textarea': 'onDrop' }, initialize() { @@ -53976,7 +53986,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_3__["default"].plugins this.renderHeading(); this.renderChatArea(); this.renderMessageForm(); - this.initAutoComplete(); + this.initMentionAutoComplete(); if (this.model.get('connection_status') !== _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_3__["default"].ROOMSTATUS.ENTERED) { this.showSpinner(); @@ -54006,19 +54016,19 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_3__["default"].plugins return this; }, - initAutoComplete() { + initMentionAutoComplete() { this.auto_complete = new _converse.AutoComplete(this.el, { 'auto_first': true, 'auto_evaluate': false, 'min_chars': 1, 'match_current_word': true, - 'match_on_tab': true, 'list': () => this.model.occupants.map(o => ({ 'label': o.getDisplayName(), 'value': `@${o.getDisplayName()}` })), 'filter': _converse.FILTER_STARTSWITH, - 'trigger_on_at': true + 'ac_triggers': ["Tab", "@"], + 'include_triggers': [] }); this.auto_complete.on('suggestion-box-selectcomplete', () => this.auto_completing = false); }, @@ -54261,7 +54271,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_3__["default"].plugins * ignore notifications in groupchats. * * 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')) { // Don't know about other servers, but OpenFire sends @@ -55179,7 +55189,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_3__["default"].plugins showStatusMessages(stanza) { /* 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: * (XMLElement) stanza: The message or presence stanza @@ -55358,9 +55368,6 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_3__["default"].plugins const show = this.model.get('show'); return templates_occupant_html__WEBPACK_IMPORTED_MODULE_20___default()(_.extend({ '_': _, - // XXX Normally this should already be included, - // but with the current webpack build, - // we only get a subset of the _ methods. 'jid': '', 'show': show, 'hint_show': _converse.PRETTY_CHAT_STATUS[show], @@ -55732,7 +55739,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_3__["default"].plugins __webpack_require__.r(__webpack_exports__); /* harmony import */ var _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @converse/headless/converse-core */ "./src/headless/converse-core.js"); // Converse.js (A browser based XMPP chat client) -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2013-2019, JC Brand // Licensed under the Mozilla Public License (MPLv2) @@ -56061,7 +56068,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var templates_toolbar_omemo_html__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! templates/toolbar_omemo.html */ "./src/templates/toolbar_omemo.html"); /* harmony import */ var templates_toolbar_omemo_html__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(templates_toolbar_omemo_html__WEBPACK_IMPORTED_MODULE_1__); // Converse.js -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2013-2019, the Converse.js developers // Licensed under the Mozilla Public License (MPLv2) @@ -57495,7 +57502,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var templates_status_option_html__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! templates/status_option.html */ "./src/templates/status_option.html"); /* harmony import */ var templates_status_option_html__WEBPACK_IMPORTED_MODULE_9___default = /*#__PURE__*/__webpack_require__.n(templates_status_option_html__WEBPACK_IMPORTED_MODULE_9__); // Converse.js (A browser based XMPP chat client) -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2013-2017, Jan-Carel Brand // Licensed under the Mozilla Public License (MPLv2) @@ -57988,7 +57995,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var templates_spinner_html__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(templates_spinner_html__WEBPACK_IMPORTED_MODULE_8__); /* harmony import */ var _converse_headless_utils_form__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @converse/headless/utils/form */ "./src/headless/utils/form.js"); // Converse.js (A browser based XMPP chat client) -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2012-2017, Jan-Carel Brand // Licensed under the Mozilla Public License (MPLv2) @@ -58749,7 +58756,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var templates_rooms_list_item_html__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! templates/rooms_list_item.html */ "./src/templates/rooms_list_item.html"); /* harmony import */ var templates_rooms_list_item_html__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(templates_rooms_list_item_html__WEBPACK_IMPORTED_MODULE_3__); // Converse.js (A browser based XMPP chat client) -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2013-2019, Jan-Carel Brand // Licensed under the Mozilla Public License (MPLv2) @@ -59107,7 +59114,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var templates_search_contact_html__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! templates/search_contact.html */ "./src/templates/search_contact.html"); /* harmony import */ var templates_search_contact_html__WEBPACK_IMPORTED_MODULE_13___default = /*#__PURE__*/__webpack_require__.n(templates_search_contact_html__WEBPACK_IMPORTED_MODULE_13__); // Converse.js -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2013-2019, the Converse.js developers // Licensed under the Mozilla Public License (MPLv2) @@ -60229,7 +60236,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var converse_chatview__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! converse-chatview */ "./src/converse-chatview.js"); /* harmony import */ var _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @converse/headless/converse-core */ "./src/headless/converse-core.js"); // Converse.js -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2013-2019, the Converse.js developers // Licensed under the Mozilla Public License (MPLv2) @@ -61577,7 +61584,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var filesize__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! filesize */ "./node_modules/filesize/lib/filesize.js"); /* harmony import */ var filesize__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(filesize__WEBPACK_IMPORTED_MODULE_3__); // Converse.js -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2012-2019, the Converse.js developers // Licensed under the Mozilla Public License (MPLv2) @@ -63029,7 +63036,7 @@ _converse.TIMEOUTS = { 'PAUSED': 10000, 'INACTIVE': 90000 }; // XEP-0085 Chat states -// http://xmpp.org/extensions/xep-0085.html +// https://xmpp.org/extensions/xep-0085.html _converse.INACTIVE = 'inactive'; _converse.ACTIVE = 'active'; @@ -64798,7 +64805,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var sizzle__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! sizzle */ "./node_modules/sizzle/dist/sizzle.js"); /* harmony import */ var sizzle__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(sizzle__WEBPACK_IMPORTED_MODULE_1__); // Converse.js -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2013-2019, the Converse developers // Licensed under the Mozilla Public License (MPLv2) @@ -65024,7 +65031,7 @@ _converse_core__WEBPACK_IMPORTED_MODULE_0__["default"].plugins.add('converse-dis }); 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.features.add(Strophe.NS.BOSH); @@ -65553,7 +65560,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var sizzle__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! sizzle */ "./node_modules/sizzle/dist/sizzle.js"); /* harmony import */ var sizzle__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(sizzle__WEBPACK_IMPORTED_MODULE_3__); // Converse.js (A browser based XMPP chat client) -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2012-2017, Jan-Carel Brand // Licensed under the Mozilla Public License (MPLv2) @@ -66224,7 +66231,7 @@ function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } // Converse.js -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2013-2019, the Converse.js developers // Licensed under the Mozilla Public License (MPLv2) @@ -66834,7 +66841,7 @@ _converse_core__WEBPACK_IMPORTED_MODULE_6__["default"].plugins.add('converse-muc /* Send an IQ stanza to the server, asking it for the * member-list of this groupchat. * - * See: http://xmpp.org/extensions/xep-0045.html#modifymember + * See: https://xmpp.org/extensions/xep-0045.html#modifymember * * Parameters: * (String) affiliation: The specific member list to @@ -66860,7 +66867,7 @@ _converse_core__WEBPACK_IMPORTED_MODULE_6__["default"].plugins.add('converse-muc /* Send IQ stanzas to the server to set an affiliation for * 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 * being set in one IQ stanza, so as a workaround we send @@ -67059,7 +67066,7 @@ _converse_core__WEBPACK_IMPORTED_MODULE_6__["default"].plugins.add('converse-muc /* Send IQ stanzas to the server to modify the * affiliations in this groupchat. * - * See: http://xmpp.org/extensions/xep-0045.html#modifymember + * See: https://xmpp.org/extensions/xep-0045.html#modifymember * * Parameters: * (Object) members: A map of jids, affiliations and optionally reasons @@ -67912,7 +67919,7 @@ _converse_core__WEBPACK_IMPORTED_MODULE_6__["default"].plugins.add('converse-muc * configured automatically. Currently it doesn't make sense to specify * `roomconfig` values if `auto_configure` is set to `false`. * 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. * @param {boolean} [attrs.maximize] A boolean, indicating whether minimized rooms should also be * maximized, when opened. Set to `false` by default. @@ -68173,7 +68180,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _converse_disco__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./converse-disco */ "./src/headless/converse-disco.js"); /* harmony import */ var _converse_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./converse-core */ "./src/headless/converse-core.js"); // Converse.js -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2019, the Converse.js developers // Licensed under the Mozilla Public License (MPLv2) @@ -68296,7 +68303,7 @@ _converse_core__WEBPACK_IMPORTED_MODULE_1__["default"].plugins.add('converse-pub __webpack_require__.r(__webpack_exports__); /* harmony import */ var _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @converse/headless/converse-core */ "./src/headless/converse-core.js"); // Converse.js -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2013-2019, the Converse.js developers // Licensed under the Mozilla Public License (MPLv2) @@ -69390,7 +69397,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _templates_vcard_html__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./templates/vcard.html */ "./src/headless/templates/vcard.html"); /* harmony import */ var _templates_vcard_html__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_templates_vcard_html__WEBPACK_IMPORTED_MODULE_1__); // Converse.js -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2013-2019, the Converse.js developers // Licensed under the Mozilla Public License (MPLv2) @@ -69714,7 +69721,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var moment__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! moment */ "./node_modules/moment/moment.js"); /* harmony import */ var moment__WEBPACK_IMPORTED_MODULE_30___default = /*#__PURE__*/__webpack_require__.n(moment__WEBPACK_IMPORTED_MODULE_30__); // Converse.js (A browser based XMPP chat client) -// http://conversejs.org +// https://conversejs.org // // This is the internationalization module. // @@ -70080,7 +70087,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var sizzle__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! sizzle */ "./node_modules/sizzle/dist/sizzle.js"); /* harmony import */ var sizzle__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(sizzle__WEBPACK_IMPORTED_MODULE_4__); // Converse.js (A browser based XMPP chat client) -// http://conversejs.org +// https://conversejs.org // // This is the utilities module. // @@ -70420,9 +70427,12 @@ u.siblingIndex = function (el) { return i; }; -u.getCurrentWord = function (input) { - const cursor = input.selectionEnd || undefined; - return _lodash_noconflict__WEBPACK_IMPORTED_MODULE_3___default.a.last(input.value.slice(0, cursor).split(' ')); +u.getCurrentWord = function (input, index) { + if (!index) { + index = input.selectionEnd || undefined; + } + + return _lodash_noconflict__WEBPACK_IMPORTED_MODULE_3___default.a.last(input.value.slice(0, index).split(' ')); }; u.replaceCurrentWord = function (input, new_value) { @@ -92075,7 +92085,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _templates_field_html__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_templates_field_html__WEBPACK_IMPORTED_MODULE_1__); /* harmony import */ var _core__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./core */ "./src/headless/utils/core.js"); // Converse.js (A browser based XMPP chat client) -// http://conversejs.org +// https://conversejs.org // // This is the utilities module. // @@ -92125,7 +92135,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @converse/headless/converse-core */ "./src/headless/converse-core.js"); /* harmony import */ var _core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./core */ "./src/headless/utils/core.js"); // Converse.js (A browser based XMPP chat client) -// http://conversejs.org +// https://conversejs.org // // This is the utilities module. // @@ -95611,7 +95621,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _templates_video_html__WEBPACK_IMPORTED_MODULE_15___default = /*#__PURE__*/__webpack_require__.n(_templates_video_html__WEBPACK_IMPORTED_MODULE_15__); /* harmony import */ var _headless_utils_core__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../headless/utils/core */ "./src/headless/utils/core.js"); // Converse.js (A browser based XMPP chat client) -// http://conversejs.org +// https://conversejs.org // // This is a form utilities module. // @@ -96168,86 +96178,82 @@ _headless_utils_core__WEBPACK_IMPORTED_MODULE_16__["default"].xForm2webForm = fu * Parameters: * (XMLElement) field - the field to convert */ - if (field.getAttribute('type')) { - if (field.getAttribute('type') === 'list-single' || field.getAttribute('type') === 'list-multi') { - const values = _headless_lodash_noconflict__WEBPACK_IMPORTED_MODULE_1___default.a.map(_headless_utils_core__WEBPACK_IMPORTED_MODULE_16__["default"].queryChildren(field, 'value'), _headless_lodash_noconflict__WEBPACK_IMPORTED_MODULE_1___default.a.partial(_headless_lodash_noconflict__WEBPACK_IMPORTED_MODULE_1___default.a.get, _headless_lodash_noconflict__WEBPACK_IMPORTED_MODULE_1___default.a, 'textContent')); + if (field.getAttribute('type') === 'list-single' || field.getAttribute('type') === 'list-multi') { + const values = _headless_lodash_noconflict__WEBPACK_IMPORTED_MODULE_1___default.a.map(_headless_utils_core__WEBPACK_IMPORTED_MODULE_16__["default"].queryChildren(field, 'value'), _headless_lodash_noconflict__WEBPACK_IMPORTED_MODULE_1___default.a.partial(_headless_lodash_noconflict__WEBPACK_IMPORTED_MODULE_1___default.a.get, _headless_lodash_noconflict__WEBPACK_IMPORTED_MODULE_1___default.a, 'textContent')); - const options = _headless_lodash_noconflict__WEBPACK_IMPORTED_MODULE_1___default.a.map(_headless_utils_core__WEBPACK_IMPORTED_MODULE_16__["default"].queryChildren(field, 'option'), function (option) { - const value = _headless_lodash_noconflict__WEBPACK_IMPORTED_MODULE_1___default.a.get(option.querySelector('value'), 'textContent'); + const options = _headless_lodash_noconflict__WEBPACK_IMPORTED_MODULE_1___default.a.map(_headless_utils_core__WEBPACK_IMPORTED_MODULE_16__["default"].queryChildren(field, 'option'), function (option) { + const value = _headless_lodash_noconflict__WEBPACK_IMPORTED_MODULE_1___default.a.get(option.querySelector('value'), 'textContent'); - return _templates_select_option_html__WEBPACK_IMPORTED_MODULE_14___default()({ - 'value': value, - 'label': option.getAttribute('label'), - 'selected': _headless_lodash_noconflict__WEBPACK_IMPORTED_MODULE_1___default.a.includes(values, value), - 'required': !_headless_lodash_noconflict__WEBPACK_IMPORTED_MODULE_1___default.a.isNil(field.querySelector('required')) - }); - }); - - return _templates_form_select_html__WEBPACK_IMPORTED_MODULE_9___default()({ - 'id': _headless_utils_core__WEBPACK_IMPORTED_MODULE_16__["default"].getUniqueId(), - 'name': field.getAttribute('var'), - 'label': field.getAttribute('label'), - 'options': options.join(''), - 'multiple': field.getAttribute('type') === 'list-multi', + return _templates_select_option_html__WEBPACK_IMPORTED_MODULE_14___default()({ + 'value': value, + 'label': option.getAttribute('label'), + 'selected': _headless_lodash_noconflict__WEBPACK_IMPORTED_MODULE_1___default.a.includes(values, value), 'required': !_headless_lodash_noconflict__WEBPACK_IMPORTED_MODULE_1___default.a.isNil(field.querySelector('required')) }); - } else if (field.getAttribute('type') === 'fixed') { - const text = _headless_lodash_noconflict__WEBPACK_IMPORTED_MODULE_1___default.a.get(field.querySelector('value'), 'textContent'); + }); - return '

' + text + '

'; - } else if (field.getAttribute('type') === 'jid-multi') { - return _templates_form_textarea_html__WEBPACK_IMPORTED_MODULE_10___default()({ - 'name': field.getAttribute('var'), - 'label': field.getAttribute('label') || '', - 'value': _headless_lodash_noconflict__WEBPACK_IMPORTED_MODULE_1___default.a.get(field.querySelector('value'), 'textContent'), - 'required': !_headless_lodash_noconflict__WEBPACK_IMPORTED_MODULE_1___default.a.isNil(field.querySelector('required')) - }); - } else if (field.getAttribute('type') === 'boolean') { - return _templates_form_checkbox_html__WEBPACK_IMPORTED_MODULE_7___default()({ - 'id': _headless_utils_core__WEBPACK_IMPORTED_MODULE_16__["default"].getUniqueId(), - 'name': field.getAttribute('var'), - 'label': field.getAttribute('label') || '', - 'checked': _headless_lodash_noconflict__WEBPACK_IMPORTED_MODULE_1___default.a.get(field.querySelector('value'), 'textContent') === "1" && 'checked="1"' || '', - 'required': !_headless_lodash_noconflict__WEBPACK_IMPORTED_MODULE_1___default.a.isNil(field.querySelector('required')) - }); - } else if (field.getAttribute('var') === 'url') { - return _templates_form_url_html__WEBPACK_IMPORTED_MODULE_11___default()({ - 'label': field.getAttribute('label') || '', - 'value': _headless_lodash_noconflict__WEBPACK_IMPORTED_MODULE_1___default.a.get(field.querySelector('value'), 'textContent') - }); - } else if (field.getAttribute('var') === 'username') { - return _templates_form_username_html__WEBPACK_IMPORTED_MODULE_12___default()({ - 'domain': ' @' + domain, - 'name': field.getAttribute('var'), - 'type': XFORM_TYPE_MAP[field.getAttribute('type')], - 'label': field.getAttribute('label') || '', - 'value': _headless_lodash_noconflict__WEBPACK_IMPORTED_MODULE_1___default.a.get(field.querySelector('value'), 'textContent'), - 'required': !_headless_lodash_noconflict__WEBPACK_IMPORTED_MODULE_1___default.a.isNil(field.querySelector('required')) - }); - } else { - return _templates_form_input_html__WEBPACK_IMPORTED_MODULE_8___default()({ - 'id': _headless_utils_core__WEBPACK_IMPORTED_MODULE_16__["default"].getUniqueId(), - 'label': field.getAttribute('label') || '', - 'name': field.getAttribute('var'), - 'placeholder': null, - 'required': !_headless_lodash_noconflict__WEBPACK_IMPORTED_MODULE_1___default.a.isNil(field.querySelector('required')), - 'type': XFORM_TYPE_MAP[field.getAttribute('type')], - 'value': _headless_lodash_noconflict__WEBPACK_IMPORTED_MODULE_1___default.a.get(field.querySelector('value'), 'textContent') - }); - } + return _templates_form_select_html__WEBPACK_IMPORTED_MODULE_9___default()({ + 'id': _headless_utils_core__WEBPACK_IMPORTED_MODULE_16__["default"].getUniqueId(), + 'name': field.getAttribute('var'), + 'label': field.getAttribute('label'), + 'options': options.join(''), + 'multiple': field.getAttribute('type') === 'list-multi', + 'required': !_headless_lodash_noconflict__WEBPACK_IMPORTED_MODULE_1___default.a.isNil(field.querySelector('required')) + }); + } else if (field.getAttribute('type') === 'fixed') { + const text = _headless_lodash_noconflict__WEBPACK_IMPORTED_MODULE_1___default.a.get(field.querySelector('value'), 'textContent'); + + return '

' + text + '

'; + } else if (field.getAttribute('type') === 'jid-multi') { + return _templates_form_textarea_html__WEBPACK_IMPORTED_MODULE_10___default()({ + 'name': field.getAttribute('var'), + 'label': field.getAttribute('label') || '', + 'value': _headless_lodash_noconflict__WEBPACK_IMPORTED_MODULE_1___default.a.get(field.querySelector('value'), 'textContent'), + 'required': !_headless_lodash_noconflict__WEBPACK_IMPORTED_MODULE_1___default.a.isNil(field.querySelector('required')) + }); + } else if (field.getAttribute('type') === 'boolean') { + return _templates_form_checkbox_html__WEBPACK_IMPORTED_MODULE_7___default()({ + 'id': _headless_utils_core__WEBPACK_IMPORTED_MODULE_16__["default"].getUniqueId(), + 'name': field.getAttribute('var'), + 'label': field.getAttribute('label') || '', + 'checked': _headless_lodash_noconflict__WEBPACK_IMPORTED_MODULE_1___default.a.get(field.querySelector('value'), 'textContent') === "1" && 'checked="1"' || '', + 'required': !_headless_lodash_noconflict__WEBPACK_IMPORTED_MODULE_1___default.a.isNil(field.querySelector('required')) + }); + } else if (field.getAttribute('var') === 'url') { + return _templates_form_url_html__WEBPACK_IMPORTED_MODULE_11___default()({ + 'label': field.getAttribute('label') || '', + 'value': _headless_lodash_noconflict__WEBPACK_IMPORTED_MODULE_1___default.a.get(field.querySelector('value'), 'textContent') + }); + } else if (field.getAttribute('var') === 'username') { + return _templates_form_username_html__WEBPACK_IMPORTED_MODULE_12___default()({ + 'domain': ' @' + domain, + 'name': field.getAttribute('var'), + 'type': XFORM_TYPE_MAP[field.getAttribute('type')], + 'label': field.getAttribute('label') || '', + 'value': _headless_lodash_noconflict__WEBPACK_IMPORTED_MODULE_1___default.a.get(field.querySelector('value'), 'textContent'), + 'required': !_headless_lodash_noconflict__WEBPACK_IMPORTED_MODULE_1___default.a.isNil(field.querySelector('required')) + }); + } else if (field.getAttribute('var') === 'ocr') { + // Captcha + const uri = field.querySelector('uri'); + const el = sizzle__WEBPACK_IMPORTED_MODULE_2___default()('data[cid="' + uri.textContent.replace(/^cid:/, '') + '"]', stanza)[0]; + return _templates_form_captcha_html__WEBPACK_IMPORTED_MODULE_6___default()({ + 'label': field.getAttribute('label'), + 'name': field.getAttribute('var'), + 'data': _headless_lodash_noconflict__WEBPACK_IMPORTED_MODULE_1___default.a.get(el, 'textContent'), + 'type': uri.getAttribute('type'), + 'required': !_headless_lodash_noconflict__WEBPACK_IMPORTED_MODULE_1___default.a.isNil(field.querySelector('required')) + }); } else { - if (field.getAttribute('var') === 'ocr') { - // Captcha - const uri = field.querySelector('uri'); - const el = sizzle__WEBPACK_IMPORTED_MODULE_2___default()('data[cid="' + uri.textContent.replace(/^cid:/, '') + '"]', stanza)[0]; - return _templates_form_captcha_html__WEBPACK_IMPORTED_MODULE_6___default()({ - 'label': field.getAttribute('label'), - 'name': field.getAttribute('var'), - 'data': _headless_lodash_noconflict__WEBPACK_IMPORTED_MODULE_1___default.a.get(el, 'textContent'), - 'type': uri.getAttribute('type'), - 'required': !_headless_lodash_noconflict__WEBPACK_IMPORTED_MODULE_1___default.a.isNil(field.querySelector('required')) - }); - } + return _templates_form_input_html__WEBPACK_IMPORTED_MODULE_8___default()({ + 'id': _headless_utils_core__WEBPACK_IMPORTED_MODULE_16__["default"].getUniqueId(), + 'label': field.getAttribute('label') || '', + 'name': field.getAttribute('var'), + 'placeholder': null, + 'required': !_headless_lodash_noconflict__WEBPACK_IMPORTED_MODULE_1___default.a.isNil(field.querySelector('required')), + 'type': XFORM_TYPE_MAP[field.getAttribute('type')], + 'value': _headless_lodash_noconflict__WEBPACK_IMPORTED_MODULE_1___default.a.get(field.querySelector('value'), 'textContent') + }); } }; diff --git a/docs/source/configuration.rst b/docs/source/configuration.rst index 0cc08fe75..43c5cc44d 100644 --- a/docs/source/configuration.rst +++ b/docs/source/configuration.rst @@ -222,7 +222,7 @@ allow_registration * Default: ``true`` -Support for `XEP-0077: In band registration `_ +Support for `XEP-0077: In band registration `_ Allow XMPP account registration showing the corresponding UI register form interface. @@ -572,7 +572,7 @@ csi_waiting_time * Default: ``0`` -This option adds support for `XEP-0352 Client State Indication _` +This option adds support for `XEP-0352 Client State Indication _` 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 @@ -806,7 +806,7 @@ See also: Currently the "keepalive" setting only works with BOSH and not with 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 - `XEP-0198 `_, specifically + `XEP-0198 `_, specifically with regards to "stream resumption". .. _`locales`: @@ -993,7 +993,7 @@ muc_instant_rooms Determines whether 'instant' (also called 'dynamic' in OpenFire) rooms are created. Otherwise rooms first have to be configured before they're available to other -users (so-called "registered rooms" in `MUC-0045 `_). +users (so-called "registered rooms" in `MUC-0045 `_). 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 diff --git a/docs/source/developer_api.rst b/docs/source/developer_api.rst index 258c29212..348cbbb1d 100644 --- a/docs/source/developer_api.rst +++ b/docs/source/developer_api.rst @@ -1050,7 +1050,7 @@ Room attributes that may be passed in: configured automatically. Currently it doesn't make sense to specify ``roomconfig`` values if ``auto_configure`` is set to ``false``. For a list of configuration values that can be passed in, refer to these values - in the `XEP-0045 MUC specification `_. + in the `XEP-0045 MUC specification `_. The values should be named without the ``muc#roomconfig_`` prefix. * *maximize*: A boolean, indicating whether minimized rooms should also be maximized, when opened. Set to ``false`` by default. diff --git a/docs/source/index.rst b/docs/source/index.rst index 40e9e06ec..9d6303ce5 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -20,7 +20,7 @@ contribute, please read the :doc:`documentation` page. Introduction ============ -Converse is a free and open-source `XMPP `_ +Converse is a free and open-source `XMPP `_ 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 diff --git a/docs/source/setup.rst b/docs/source/setup.rst index 335a66818..12abeb569 100644 --- a/docs/source/setup.rst +++ b/docs/source/setup.rst @@ -57,7 +57,7 @@ The various components An XMPP server ============== -Converse uses `XMPP `_ as its +Converse uses `XMPP `_ as its messaging protocol, and therefore needs to connect to an XMPP/Jabber 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 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 `_ -and a list of servers that you can set up yourself on `xmpp.org `_. +and a list of servers that you can set up yourself on `xmpp.org `_. .. _`BOSH-section`: @@ -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 Synchronous HTTP) is a protocol for allowing XMPP communication over HTTP. The -protocol is defined in `XEP-0206: XMPP Over BOSH `_. +protocol is defined in `XEP-0206: XMPP Over BOSH `_. Popular XMPP servers such as `Ejabberd `_, Prosody `(mod_bosh) `_ and @@ -104,7 +104,7 @@ https://conversejs.org does), then you'll need a standalone connection manager. For a standalone manager, see for example `Punjab `_ and `node-xmpp-bosh `_. -The demo on the `Converse homepage `_ uses a connection +The demo on the `Converse homepage `_ uses a connection manager located at https://conversejs.org/http-bind. This connection manager is available for testing purposes only, please don't @@ -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 -authenticated BOSH session with the XMPP server or a standalone `BOSH `_ +authenticated BOSH session with the XMPP server or a standalone `BOSH `_ connection manager. Once authenticated, it receives RID and SID tokens which need to be passed diff --git a/mockup/index.html b/mockup/index.html index 3c2fda6bf..aed68211f 100644 --- a/mockup/index.html +++ b/mockup/index.html @@ -11,7 +11,7 @@
-

Converse.js

+

Converse.js

Mockups

diff --git a/sass/converse.scss b/sass/converse.scss index d951413b6..74a05d06c 100644 --- a/sass/converse.scss +++ b/sass/converse.scss @@ -1,6 +1,6 @@ /*! * Converse.js (Web-based XMPP instant messaging client) - * http://conversejs.org + * https://conversejs.org * * Copyright (c) 2013-2018, JC Brand * Licensed under the Mozilla Public License diff --git a/spec/autocomplete.js b/spec/autocomplete.js index c31ad95f2..86cdd5ff1 100644 --- a/spec/autocomplete.js +++ b/spec/autocomplete.js @@ -18,45 +18,44 @@ it("shows all autocompletion options when the user presses @", mock.initConverse( null, ['rosterGroupsFetched'], {}, - function (done, _converse) { + async function (done, _converse) { - test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'tom') - .then(() => { - const view = _converse.chatboxviews.get('lounge@localhost'); + await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'tom'); + const view = _converse.chatboxviews.get('lounge@localhost'); - ['dick', 'harry'].forEach((nick) => { - _converse.connection._dataRecv(test_utils.createRequest( - $pres({ - 'to': 'tom@localhost/resource', - 'from': `lounge@localhost/${nick}` - }) - .c('x', {xmlns: Strophe.NS.MUC_USER}) - .c('item', { - 'affiliation': 'none', - 'jid': `${nick}@localhost/resource`, - 'role': 'participant' - }))); - }); + ['dick', 'harry'].forEach((nick) => { + _converse.connection._dataRecv(test_utils.createRequest( + $pres({ + 'to': 'tom@localhost/resource', + 'from': `lounge@localhost/${nick}` + }) + .c('x', {xmlns: Strophe.NS.MUC_USER}) + .c('item', { + 'affiliation': 'none', + 'jid': `${nick}@localhost/resource`, + 'role': 'participant' + }))); + }); - // Test that pressing @ brings up all options - const textarea = view.el.querySelector('textarea.chat-textarea'); - const at_event = { - 'target': textarea, - 'preventDefault': _.noop, - 'stopPropagation': _.noop, - 'keyCode': 50 - }; - view.keyPressed(at_event); - textarea.value = '@'; - view.keyUp(at_event); + // Test that pressing @ brings up all options + const textarea = view.el.querySelector('textarea.chat-textarea'); + const at_event = { + 'target': textarea, + 'preventDefault': _.noop, + 'stopPropagation': _.noop, + 'keyCode': 50, + 'key': '@' + }; + view.keyPressed(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.querySelector('.suggestion-box__results li:first-child').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:nth-child(3)').textContent).toBe('harry'); - done(); - }).catch(_.partial(console.error, _)); + 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.querySelector('.suggestion-box__results li:first-child').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:nth-child(3)').textContent).toBe('harry'); + done(); })); it("autocompletes when the user presses tab", @@ -88,7 +87,8 @@ 'target': textarea, 'preventDefault': _.noop, 'stopPropagation': _.noop, - 'keyCode': 9 + 'keyCode': 9, + 'key': 'Tab' } view.keyPressed(tab_event); view.keyUp(tab_event); @@ -168,5 +168,46 @@ expect(textarea.value).toBe('hello @z3r0 '); 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(); + })); }); })); diff --git a/spec/chatbox.js b/spec/chatbox.js index 403b022b6..05f961247 100644 --- a/spec/chatbox.js +++ b/spec/chatbox.js @@ -671,7 +671,7 @@ await test_utils.waitForRoster(_converse, 'current'); 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'); const sender_jid = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost'; await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length); @@ -817,7 +817,7 @@ test_utils.openControlBox(); await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length); // 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(); const sender_jid = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost'; const view = await test_utils.openChatBoxFor(_converse, sender_jid); @@ -985,7 +985,7 @@ await test_utils.waitForRoster(_converse, 'current'); test_utils.openControlBox(); 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'); await test_utils.openChatBoxFor(_converse, sender_jid); const view = _converse.chatboxviews.get(sender_jid); diff --git a/spec/muc.js b/spec/muc.js index 1f92af780..f576c2958 100644 --- a/spec/muc.js +++ b/spec/muc.js @@ -347,7 +347,7 @@ // The user has just entered the room (because join was called) // and receives their own presence from the server. // See example 24: - // http://xmpp.org/extensions/xep-0045.html#enter-pres + // https://xmpp.org/extensions/xep-0045.html#enter-pres // /* * @@ -1219,7 +1219,7 @@ /* Check that an IQ is sent out, asking for the * configuration form. - * See: // http://xmpp.org/extensions/xep-0045.html#example-163 + * See: // https://xmpp.org/extensions/xep-0045.html#example-163 * * `); /* 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', 'id': IQ_id, @@ -1398,7 +1398,7 @@ for (var i=0; i-1; i--) { name = mock.chatroom_names[i]; 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({ to:'dummy@localhost/pda', from:'lounge@localhost/'+name, @@ -1452,7 +1452,7 @@ for (var i=0; i-1; i--) { name = mock.chatroom_names[i]; 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({ to:'dummy@localhost/pda', from:'lounge@localhost/'+name, @@ -1695,7 +1695,7 @@ // The user has just entered the groupchat (because join was called) // and receives their own presence from the server. // See example 24: - // http://xmpp.org/extensions/xep-0045.html#enter-pres + // https://xmpp.org/extensions/xep-0045.html#enter-pres const presence = $pres({ to:'dummy@localhost/resource', from:'lounge@localhost/thirdwitch', @@ -1946,7 +1946,7 @@ async function (done, _converse) { 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(` ${text} @@ -2008,7 +2008,7 @@ * nickname and one indicating availability for the new * nickname. * - * See: http://xmpp.org/extensions/xep-0045.html#changenick + * See: https://xmpp.org/extensions/xep-0045.html#changenick * * Promise.resolve()); 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); const server_input = modal.el.querySelector('input[name="server"]'); @@ -4299,7 +4299,7 @@ expect(sizzle('div.chat-info:last', chat_content).pop().textContent) .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 // state let msg = $msg({ @@ -4368,10 +4368,8 @@ expect(notifications.length).toBe(2); expect(notifications[0].textContent).toEqual('newguy 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 - // notifications + // Check that new messages appear under the chat state notifications msg = $msg({ from: `${room_jid}/some1`, id: (new Date()).getTime(), @@ -4386,8 +4384,7 @@ expect(view.el.querySelectorAll('.chat-msg').length).toBe(1); expect(view.el.querySelector('.chat-msg .chat-msg__text').textContent).toBe('hello world'); - // Test that the composing notifications get removed - // via timeout. + // Test that the composing notifications get removed via timeout. timeout_functions[0](); events = view.el.querySelectorAll('.chat-event'); expect(events.length).toBe(3); @@ -4475,7 +4472,7 @@ expect(sizzle('div.chat-info:last', chat_content).pop().textContent) .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 // state var msg = $msg({ diff --git a/spec/room_registration.js b/spec/room_registration.js index 040f3ba72..ce829b39f 100644 --- a/spec/room_registration.js +++ b/spec/room_registration.js @@ -112,7 +112,7 @@ }).then(stanza => { // The user has just entered the room (because join was called) // 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({ to: _converse.connection.jid, from: room_jid, diff --git a/spec/roster.js b/spec/roster.js index ef998af76..d318d6ad0 100644 --- a/spec/roster.js +++ b/spec/roster.js @@ -1270,7 +1270,7 @@ expect(_converse.roster.pluck('jid').length).toBe(1); expect(_.includes(_converse.roster.pluck('jid'), 'data@enterprise')).toBeTruthy(); // 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({ to: _converse.connection.jid, type: 'result', diff --git a/src/converse-autocomplete.js b/src/converse-autocomplete.js index ca0910502..e386d58d2 100644 --- a/src/converse-autocomplete.js +++ b/src/converse-autocomplete.js @@ -1,5 +1,5 @@ // Converse.js -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2013-2019, the Converse.js developers // Licensed under the Mozilla Public License (MPLv2) @@ -13,7 +13,6 @@ import converse from "@converse/headless/converse-core"; const { _, Backbone } = converse.env, u = converse.env.utils; - converse.plugins.add("converse-autocomplete", { initialize () { @@ -73,12 +72,12 @@ converse.plugins.add("converse-autocomplete", { _.assignIn(this, { '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 - 'trigger_on_at': false, // Whether @ should trigger autocomplete + 'ac_triggers': [], // Array of keys (`ev.key`) values that will trigger auto-complete + 'include_triggers': [], // Array of trigger keys which should be included in the returned value 'min_chars': 2, 'max_items': 10, 'auto_evaluate': true, - 'auto_first': false, + 'auto_first': false, // Should the first element be automatically selected? 'data': _.identity, 'filter': _converse.FILTER_CONTAINS, 'sort': config.sort === false ? false : SORT_BYLENGTH, @@ -291,11 +290,17 @@ converse.plugins.add("converse-autocomplete", { , ev.keyCode)) { return; } - if (this.match_on_tab && ev.keyCode === _converse.keycodes.TAB) { - ev.preventDefault(); - this.auto_completing = true; - } else if (this.trigger_on_at && ev.keyCode === _converse.keycodes.AT) { + + if (this.ac_triggers.includes(ev.key)) { + if (ev.key === "Tab") { + ev.preventDefault(); + } 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", { let value = this.match_current_word ? u.getCurrentWord(this.input) : this.input.value; 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; value = value.slice('1'); } diff --git a/src/converse-bookmarks.js b/src/converse-bookmarks.js index 07a24ccdb..085b461a1 100644 --- a/src/converse-bookmarks.js +++ b/src/converse-bookmarks.js @@ -1,5 +1,5 @@ // Converse.js (A browser based XMPP chat client) -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2012-2017, Jan-Carel Brand // Licensed under the Mozilla Public License (MPLv2) diff --git a/src/converse-caps.js b/src/converse-caps.js index 3e6e0401d..d0aefbbf5 100644 --- a/src/converse-caps.js +++ b/src/converse-caps.js @@ -1,5 +1,5 @@ // Converse.js -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2013-2019, the Converse.js developers // Licensed under the Mozilla Public License (MPLv2) diff --git a/src/converse-chatboxviews.js b/src/converse-chatboxviews.js index 371d8c9c1..742fdc3b4 100644 --- a/src/converse-chatboxviews.js +++ b/src/converse-chatboxviews.js @@ -1,5 +1,5 @@ // Converse.js -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2012-2019, the Converse.js developers // Licensed under the Mozilla Public License (MPLv2) diff --git a/src/converse-chatview.js b/src/converse-chatview.js index 60c8c863f..60c80096d 100644 --- a/src/converse-chatview.js +++ b/src/converse-chatview.js @@ -1,5 +1,5 @@ // Converse.js -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2013-2019, the Converse.js developers // Licensed under the Mozilla Public License (MPLv2) diff --git a/src/converse-controlbox.js b/src/converse-controlbox.js index dab2c0b43..65290971b 100644 --- a/src/converse-controlbox.js +++ b/src/converse-controlbox.js @@ -1,5 +1,5 @@ // Converse.js (A browser based XMPP chat client) -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2012-2017, Jan-Carel Brand // Licensed under the Mozilla Public License (MPLv2) diff --git a/src/converse-dragresize.js b/src/converse-dragresize.js index 9dac62493..b81744b02 100644 --- a/src/converse-dragresize.js +++ b/src/converse-dragresize.js @@ -1,5 +1,5 @@ // Converse.js (A browser based XMPP chat client) -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2012-2017, Jan-Carel Brand // Licensed under the Mozilla Public License (MPLv2) diff --git a/src/converse-embedded.js b/src/converse-embedded.js index 5dedd4cb3..6b7af15ec 100644 --- a/src/converse-embedded.js +++ b/src/converse-embedded.js @@ -1,5 +1,5 @@ // Converse.js -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2013-2019, the Converse.js developers // Licensed under the Mozilla Public License (MPLv2) diff --git a/src/converse-fullscreen.js b/src/converse-fullscreen.js index a812eb952..fb441a34a 100644 --- a/src/converse-fullscreen.js +++ b/src/converse-fullscreen.js @@ -1,5 +1,5 @@ // Converse.js (A browser based XMPP chat client) -// http://conversejs.org +// https://conversejs.org // // Copyright (c) JC Brand // Licensed under the Mozilla Public License (MPLv2) diff --git a/src/converse-headline.js b/src/converse-headline.js index b952ff95f..5ef8cc9b8 100644 --- a/src/converse-headline.js +++ b/src/converse-headline.js @@ -1,5 +1,5 @@ // Converse.js (A browser based XMPP chat client) -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2012-2017, Jan-Carel Brand // Licensed under the Mozilla Public License (MPLv2) diff --git a/src/converse-minimize.js b/src/converse-minimize.js index 7a1a2b5c1..160a79024 100644 --- a/src/converse-minimize.js +++ b/src/converse-minimize.js @@ -1,5 +1,5 @@ // Converse.js (A browser based XMPP chat client) -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2013-2019, Jan-Carel Brand // Licensed under the Mozilla Public License (MPLv2) diff --git a/src/converse-modal.js b/src/converse-modal.js index 704eec7b9..e1d9342ab 100644 --- a/src/converse-modal.js +++ b/src/converse-modal.js @@ -1,5 +1,5 @@ // Converse.js -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2013-2019, the Converse.js developers // Licensed under the Mozilla Public License (MPLv2) diff --git a/src/converse-muc-views.js b/src/converse-muc-views.js index ccdaf5144..08954d734 100644 --- a/src/converse-muc-views.js +++ b/src/converse-muc-views.js @@ -1,5 +1,5 @@ // Converse.js -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2013-2019, the Converse.js developers // Licensed under the Mozilla Public License (MPLv2) @@ -128,7 +128,7 @@ converse.plugins.add('converse-muc-views', { 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 * 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', { * (XMLElement) stanza: The IQ stanza containing the groupchat * 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('a.room-info').classList.add('selected'); el.insertAdjacentHTML( @@ -506,7 +506,9 @@ converse.plugins.add('converse-muc-views', { 'click .upload-file': 'toggleFileUpload', 'keydown .chat-textarea': 'keyPressed', 'keyup .chat-textarea': 'keyUp', - 'input .chat-textarea': 'inputChanged' + 'input .chat-textarea': 'inputChanged', + 'dragover .chat-textarea': 'onDragOver', + 'drop .chat-textarea': 'onDrop', }, initialize () { @@ -560,7 +562,7 @@ converse.plugins.add('converse-muc-views', { this.renderHeading(); this.renderChatArea(); this.renderMessageForm(); - this.initAutoComplete(); + this.initMentionAutoComplete(); if (this.model.get('connection_status') !== converse.ROOMSTATUS.ENTERED) { this.showSpinner(); } @@ -587,16 +589,16 @@ converse.plugins.add('converse-muc-views', { return this; }, - initAutoComplete () { + initMentionAutoComplete () { this.auto_complete = new _converse.AutoComplete(this.el, { 'auto_first': true, 'auto_evaluate': false, 'min_chars': 1, 'match_current_word': true, - 'match_on_tab': true, 'list': () => this.model.occupants.map(o => ({'label': o.getDisplayName(), 'value': `@${o.getDisplayName()}`})), 'filter': _converse.FILTER_STARTSWITH, - 'trigger_on_at': true + 'ac_triggers': ["Tab", "@"], + 'include_triggers': [] }); this.auto_complete.on('suggestion-box-selectcomplete', () => (this.auto_completing = false)); }, @@ -812,7 +814,7 @@ converse.plugins.add('converse-muc-views', { * ignore notifications in groupchats. * * 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')) { // Don't know about other servers, but OpenFire sends @@ -1669,7 +1671,7 @@ converse.plugins.add('converse-muc-views', { showStatusMessages (stanza) { /* 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: * (XMLElement) stanza: The message or presence stanza @@ -1837,9 +1839,7 @@ converse.plugins.add('converse-muc-views', { const show = this.model.get('show'); return tpl_occupant( _.extend( - { '_': _, // XXX Normally this should already be included, - // but with the current webpack build, - // we only get a subset of the _ methods. + { '_': _, 'jid': '', 'show': show, 'hint_show': _converse.PRETTY_CHAT_STATUS[show], diff --git a/src/converse-notification.js b/src/converse-notification.js index 967a2ae51..2b95bef6b 100644 --- a/src/converse-notification.js +++ b/src/converse-notification.js @@ -1,5 +1,5 @@ // Converse.js (A browser based XMPP chat client) -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2013-2019, JC Brand // Licensed under the Mozilla Public License (MPLv2) diff --git a/src/converse-omemo.js b/src/converse-omemo.js index 6c6f566f4..0c8698505 100644 --- a/src/converse-omemo.js +++ b/src/converse-omemo.js @@ -1,5 +1,5 @@ // Converse.js -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2013-2019, the Converse.js developers // Licensed under the Mozilla Public License (MPLv2) diff --git a/src/converse-profile.js b/src/converse-profile.js index 4afeea899..5905c70b5 100644 --- a/src/converse-profile.js +++ b/src/converse-profile.js @@ -1,5 +1,5 @@ // Converse.js (A browser based XMPP chat client) -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2013-2017, Jan-Carel Brand // Licensed under the Mozilla Public License (MPLv2) diff --git a/src/converse-register.js b/src/converse-register.js index 89b588c9c..d0c83e625 100644 --- a/src/converse-register.js +++ b/src/converse-register.js @@ -1,5 +1,5 @@ // Converse.js (A browser based XMPP chat client) -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2012-2017, Jan-Carel Brand // Licensed under the Mozilla Public License (MPLv2) diff --git a/src/converse-roomslist.js b/src/converse-roomslist.js index 8fcdd780d..7660962be 100644 --- a/src/converse-roomslist.js +++ b/src/converse-roomslist.js @@ -1,5 +1,5 @@ // Converse.js (A browser based XMPP chat client) -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2013-2019, Jan-Carel Brand // Licensed under the Mozilla Public License (MPLv2) diff --git a/src/converse-rosterview.js b/src/converse-rosterview.js index 258c7228d..d93cddea8 100644 --- a/src/converse-rosterview.js +++ b/src/converse-rosterview.js @@ -1,5 +1,5 @@ // Converse.js -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2013-2019, the Converse.js developers // Licensed under the Mozilla Public License (MPLv2) diff --git a/src/converse-singleton.js b/src/converse-singleton.js index 66479f03d..5894cb70a 100644 --- a/src/converse-singleton.js +++ b/src/converse-singleton.js @@ -1,5 +1,5 @@ // Converse.js -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2013-2019, the Converse.js developers // Licensed under the Mozilla Public License (MPLv2) diff --git a/src/headless/converse-chatboxes.js b/src/headless/converse-chatboxes.js index 8a5664bfa..fe5f64dfb 100644 --- a/src/headless/converse-chatboxes.js +++ b/src/headless/converse-chatboxes.js @@ -1,5 +1,5 @@ // Converse.js -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2012-2019, the Converse.js developers // Licensed under the Mozilla Public License (MPLv2) diff --git a/src/headless/converse-core.js b/src/headless/converse-core.js index 94b765d11..974770c12 100644 --- a/src/headless/converse-core.js +++ b/src/headless/converse-core.js @@ -165,7 +165,7 @@ _converse.TIMEOUTS = { // Set as module attr so that we can override in tests. }; // XEP-0085 Chat states -// http://xmpp.org/extensions/xep-0085.html +// https://xmpp.org/extensions/xep-0085.html _converse.INACTIVE = 'inactive'; _converse.ACTIVE = 'active'; _converse.COMPOSING = 'composing'; diff --git a/src/headless/converse-disco.js b/src/headless/converse-disco.js index 8dd3fdd71..3aa3106fa 100644 --- a/src/headless/converse-disco.js +++ b/src/headless/converse-disco.js @@ -1,5 +1,5 @@ // Converse.js -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2013-2019, the Converse developers // Licensed under the Mozilla Public License (MPLv2) @@ -217,7 +217,7 @@ converse.plugins.add('converse-disco', { }); 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.features.add(Strophe.NS.BOSH); diff --git a/src/headless/converse-mam.js b/src/headless/converse-mam.js index 1878144a1..1aa26910a 100644 --- a/src/headless/converse-mam.js +++ b/src/headless/converse-mam.js @@ -1,5 +1,5 @@ // Converse.js (A browser based XMPP chat client) -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2012-2017, Jan-Carel Brand // Licensed under the Mozilla Public License (MPLv2) diff --git a/src/headless/converse-muc.js b/src/headless/converse-muc.js index f466dafad..015ef7496 100644 --- a/src/headless/converse-muc.js +++ b/src/headless/converse-muc.js @@ -1,5 +1,5 @@ // Converse.js -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2013-2019, the Converse.js developers // Licensed under the Mozilla Public License (MPLv2) @@ -538,7 +538,7 @@ converse.plugins.add('converse-muc', { /* Send an IQ stanza to the server, asking it for the * member-list of this groupchat. * - * See: http://xmpp.org/extensions/xep-0045.html#modifymember + * See: https://xmpp.org/extensions/xep-0045.html#modifymember * * Parameters: * (String) affiliation: The specific member list to @@ -559,7 +559,7 @@ converse.plugins.add('converse-muc', { /* Send IQ stanzas to the server to set an affiliation for * 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 * being set in one IQ stanza, so as a workaround we send @@ -728,7 +728,7 @@ converse.plugins.add('converse-muc', { /* Send IQ stanzas to the server to modify the * affiliations in this groupchat. * - * See: http://xmpp.org/extensions/xep-0045.html#modifymember + * See: https://xmpp.org/extensions/xep-0045.html#modifymember * * Parameters: * (Object) members: A map of jids, affiliations and optionally reasons @@ -1498,7 +1498,7 @@ converse.plugins.add('converse-muc', { * configured automatically. Currently it doesn't make sense to specify * `roomconfig` values if `auto_configure` is set to `false`. * 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. * @param {boolean} [attrs.maximize] A boolean, indicating whether minimized rooms should also be * maximized, when opened. Set to `false` by default. diff --git a/src/headless/converse-pubsub.js b/src/headless/converse-pubsub.js index f9806ebbd..108866582 100644 --- a/src/headless/converse-pubsub.js +++ b/src/headless/converse-pubsub.js @@ -1,5 +1,5 @@ // Converse.js -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2019, the Converse.js developers // Licensed under the Mozilla Public License (MPLv2) diff --git a/src/headless/converse-roster.js b/src/headless/converse-roster.js index 9a82f6d67..cb89778a6 100644 --- a/src/headless/converse-roster.js +++ b/src/headless/converse-roster.js @@ -1,5 +1,5 @@ // Converse.js -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2013-2019, the Converse.js developers // Licensed under the Mozilla Public License (MPLv2) diff --git a/src/headless/converse-vcard.js b/src/headless/converse-vcard.js index 4f73487b8..d9e735de2 100644 --- a/src/headless/converse-vcard.js +++ b/src/headless/converse-vcard.js @@ -1,5 +1,5 @@ // Converse.js -// http://conversejs.org +// https://conversejs.org // // Copyright (c) 2013-2019, the Converse.js developers // Licensed under the Mozilla Public License (MPLv2) diff --git a/src/headless/i18n.js b/src/headless/i18n.js index 2ea5e08c0..e8195de1b 100644 --- a/src/headless/i18n.js +++ b/src/headless/i18n.js @@ -1,5 +1,5 @@ // Converse.js (A browser based XMPP chat client) -// http://conversejs.org +// https://conversejs.org // // This is the internationalization module. // diff --git a/src/headless/utils/core.js b/src/headless/utils/core.js index cfbeb3b2a..2929c81a5 100644 --- a/src/headless/utils/core.js +++ b/src/headless/utils/core.js @@ -1,5 +1,5 @@ // Converse.js (A browser based XMPP chat client) -// http://conversejs.org +// https://conversejs.org // // This is the utilities module. // @@ -332,9 +332,11 @@ u.siblingIndex = function (el) { return i; }; -u.getCurrentWord = function (input) { - const cursor = input.selectionEnd || undefined; - return _.last(input.value.slice(0, cursor).split(' ')); +u.getCurrentWord = function (input, index) { + if (!index) { + index = input.selectionEnd || undefined; + } + return _.last(input.value.slice(0, index).split(' ')); }; u.replaceCurrentWord = function (input, new_value) { diff --git a/src/headless/utils/form.js b/src/headless/utils/form.js index 4a902baf3..7f69c09e9 100644 --- a/src/headless/utils/form.js +++ b/src/headless/utils/form.js @@ -1,5 +1,5 @@ // Converse.js (A browser based XMPP chat client) -// http://conversejs.org +// https://conversejs.org // // This is the utilities module. // diff --git a/src/headless/utils/muc.js b/src/headless/utils/muc.js index eaeb878c9..cf85cf495 100644 --- a/src/headless/utils/muc.js +++ b/src/headless/utils/muc.js @@ -1,5 +1,5 @@ // Converse.js (A browser based XMPP chat client) -// http://conversejs.org +// https://conversejs.org // // This is the utilities module. // diff --git a/src/utils/html.js b/src/utils/html.js index 5183df998..856c22910 100644 --- a/src/utils/html.js +++ b/src/utils/html.js @@ -1,5 +1,5 @@ // Converse.js (A browser based XMPP chat client) -// http://conversejs.org +// https://conversejs.org // // This is a form utilities module. // @@ -539,89 +539,85 @@ u.xForm2webForm = function (field, stanza, domain) { * Parameters: * (XMLElement) field - the field to convert */ - if (field.getAttribute('type')) { - if (field.getAttribute('type') === 'list-single' || - field.getAttribute('type') === 'list-multi') { + if (field.getAttribute('type') === 'list-single' || + field.getAttribute('type') === 'list-multi') { - const values = _.map( - u.queryChildren(field, 'value'), - _.partial(_.get, _, 'textContent') - ); - const options = _.map( - u.queryChildren(field, 'option'), - function (option) { - const value = _.get(option.querySelector('value'), 'textContent'); - return tpl_select_option({ - 'value': value, - 'label': option.getAttribute('label'), - 'selected': _.includes(values, value), - 'required': !_.isNil(field.querySelector('required')) - }) - } - ); - return tpl_form_select({ - 'id': u.getUniqueId(), - 'name': field.getAttribute('var'), - 'label': field.getAttribute('label'), - 'options': options.join(''), - 'multiple': (field.getAttribute('type') === 'list-multi'), - 'required': !_.isNil(field.querySelector('required')) - }); - } else if (field.getAttribute('type') === 'fixed') { - const text = _.get(field.querySelector('value'), 'textContent'); - return '

'+text+'

'; - } else if (field.getAttribute('type') === 'jid-multi') { - return tpl_form_textarea({ - 'name': field.getAttribute('var'), - 'label': field.getAttribute('label') || '', - 'value': _.get(field.querySelector('value'), 'textContent'), - 'required': !_.isNil(field.querySelector('required')) - }); - } else if (field.getAttribute('type') === 'boolean') { - return tpl_form_checkbox({ - 'id': u.getUniqueId(), - 'name': field.getAttribute('var'), - 'label': field.getAttribute('label') || '', - 'checked': _.get(field.querySelector('value'), 'textContent') === "1" && 'checked="1"' || '', - 'required': !_.isNil(field.querySelector('required')) - }); - } else if (field.getAttribute('var') === 'url') { - return tpl_form_url({ - 'label': field.getAttribute('label') || '', - 'value': _.get(field.querySelector('value'), 'textContent') - }); - } else if (field.getAttribute('var') === 'username') { - return tpl_form_username({ - 'domain': ' @'+domain, - 'name': field.getAttribute('var'), - 'type': XFORM_TYPE_MAP[field.getAttribute('type')], - 'label': field.getAttribute('label') || '', - 'value': _.get(field.querySelector('value'), 'textContent'), - 'required': !_.isNil(field.querySelector('required')) - }); - } else { - return tpl_form_input({ - 'id': u.getUniqueId(), - 'label': field.getAttribute('label') || '', - 'name': field.getAttribute('var'), - 'placeholder': null, - 'required': !_.isNil(field.querySelector('required')), - 'type': XFORM_TYPE_MAP[field.getAttribute('type')], - 'value': _.get(field.querySelector('value'), 'textContent') - }); - } + const values = _.map( + u.queryChildren(field, 'value'), + _.partial(_.get, _, 'textContent') + ); + const options = _.map( + u.queryChildren(field, 'option'), + function (option) { + const value = _.get(option.querySelector('value'), 'textContent'); + return tpl_select_option({ + 'value': value, + 'label': option.getAttribute('label'), + 'selected': _.includes(values, value), + 'required': !_.isNil(field.querySelector('required')) + }) + } + ); + return tpl_form_select({ + 'id': u.getUniqueId(), + 'name': field.getAttribute('var'), + 'label': field.getAttribute('label'), + 'options': options.join(''), + 'multiple': (field.getAttribute('type') === 'list-multi'), + 'required': !_.isNil(field.querySelector('required')) + }); + } else if (field.getAttribute('type') === 'fixed') { + const text = _.get(field.querySelector('value'), 'textContent'); + return '

'+text+'

'; + } else if (field.getAttribute('type') === 'jid-multi') { + return tpl_form_textarea({ + 'name': field.getAttribute('var'), + 'label': field.getAttribute('label') || '', + 'value': _.get(field.querySelector('value'), 'textContent'), + 'required': !_.isNil(field.querySelector('required')) + }); + } else if (field.getAttribute('type') === 'boolean') { + return tpl_form_checkbox({ + 'id': u.getUniqueId(), + 'name': field.getAttribute('var'), + 'label': field.getAttribute('label') || '', + 'checked': _.get(field.querySelector('value'), 'textContent') === "1" && 'checked="1"' || '', + 'required': !_.isNil(field.querySelector('required')) + }); + } else if (field.getAttribute('var') === 'url') { + return tpl_form_url({ + 'label': field.getAttribute('label') || '', + 'value': _.get(field.querySelector('value'), 'textContent') + }); + } else if (field.getAttribute('var') === 'username') { + return tpl_form_username({ + 'domain': ' @'+domain, + 'name': field.getAttribute('var'), + 'type': XFORM_TYPE_MAP[field.getAttribute('type')], + 'label': field.getAttribute('label') || '', + 'value': _.get(field.querySelector('value'), 'textContent'), + 'required': !_.isNil(field.querySelector('required')) + }); + } else if (field.getAttribute('var') === 'ocr') { // Captcha + const uri = field.querySelector('uri'); + const el = sizzle('data[cid="'+uri.textContent.replace(/^cid:/, '')+'"]', stanza)[0]; + return tpl_form_captcha({ + 'label': field.getAttribute('label'), + 'name': field.getAttribute('var'), + 'data': _.get(el, 'textContent'), + 'type': uri.getAttribute('type'), + 'required': !_.isNil(field.querySelector('required')) + }); } else { - if (field.getAttribute('var') === 'ocr') { // Captcha - const uri = field.querySelector('uri'); - const el = sizzle('data[cid="'+uri.textContent.replace(/^cid:/, '')+'"]', stanza)[0]; - return tpl_form_captcha({ - 'label': field.getAttribute('label'), - 'name': field.getAttribute('var'), - 'data': _.get(el, 'textContent'), - 'type': uri.getAttribute('type'), - 'required': !_.isNil(field.querySelector('required')) - }); - } + return tpl_form_input({ + 'id': u.getUniqueId(), + 'label': field.getAttribute('label') || '', + 'name': field.getAttribute('var'), + 'placeholder': null, + 'required': !_.isNil(field.querySelector('required')), + 'type': XFORM_TYPE_MAP[field.getAttribute('type')], + 'value': _.get(field.querySelector('value'), 'textContent') + }); } } export default u; diff --git a/tests/utils.js b/tests/utils.js index c7a6bb981..b01f2841c 100644 --- a/tests/utils.js +++ b/tests/utils.js @@ -182,7 +182,7 @@ // The user has just entered the room (because join was called) // 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({ to: _converse.connection.jid, from: `${room_jid}/${nick}`,