Ver Fonte

Add initial TypeScript support and declaration files

JC Brand há 2 anos atrás
pai
commit
3530ccc35d
46 ficheiros alterados com 1061 adições e 336 exclusões
  1. 8 4
      .eslintrc.json
  2. 2 1
      CHANGES.md
  3. 5 0
      Makefile
  4. 752 100
      package-lock.json
  5. 8 2
      package.json
  6. 1 1
      src/entry.js
  7. 27 30
      src/headless/core.js
  8. 4 2
      src/headless/log.js
  9. 1 1
      src/headless/plugins/bosh.js
  10. 1 1
      src/headless/plugins/caps/utils.js
  11. 6 6
      src/headless/plugins/chat/api.js
  12. 1 1
      src/headless/plugins/chat/parsers.js
  13. 1 1
      src/headless/plugins/chat/utils.js
  14. 1 1
      src/headless/plugins/chatboxes/chatboxes.js
  15. 32 32
      src/headless/plugins/disco/api.js
  16. 2 2
      src/headless/plugins/headlines/api.js
  17. 1 1
      src/headless/plugins/headlines/utils.js
  18. 2 2
      src/headless/plugins/mam/utils.js
  19. 9 9
      src/headless/plugins/muc/api.js
  20. 25 25
      src/headless/plugins/muc/muc.js
  21. 7 7
      src/headless/plugins/muc/parsers.js
  22. 1 1
      src/headless/plugins/muc/utils.js
  23. 1 1
      src/headless/plugins/ping/api.js
  24. 4 4
      src/headless/plugins/pubsub.js
  25. 2 2
      src/headless/plugins/roster/api.js
  26. 4 4
      src/headless/plugins/roster/contacts.js
  27. 1 1
      src/headless/plugins/roster/presence.js
  28. 3 3
      src/headless/plugins/status/api.js
  29. 5 5
      src/headless/plugins/vcard/api.js
  30. 1 1
      src/headless/shared/_converse.js
  31. 11 11
      src/headless/shared/parsers.js
  32. 3 3
      src/headless/shared/rsm.js
  33. 8 8
      src/headless/shared/settings/api.js
  34. 10 10
      src/headless/utils/core.js
  35. 1 1
      src/headless/utils/form.js
  36. 2 2
      src/plugins/chatview/message-form.js
  37. 3 3
      src/plugins/dragresize/utils.js
  38. 1 1
      src/plugins/muc-views/modals/muc-list.js
  39. 1 1
      src/plugins/muc-views/utils.js
  40. 1 1
      src/plugins/omemo/utils.js
  41. 6 6
      src/plugins/register/panel.js
  42. 7 2
      src/shared/components/message-versions.js
  43. 36 14
      src/shared/registry.js
  44. 5 5
      src/shared/rich-text.js
  45. 17 17
      src/utils/html.js
  46. 31 0
      tsconfig.json

+ 8 - 4
.eslintrc.json

@@ -1,7 +1,7 @@
 {
-    "parser": "@babel/eslint-parser",
+    "parser": "@typescript-eslint/parser",
     "parserOptions": {
-        "ecmaVersion": 2017,
+        "ecmaVersion": 2020,
         "sourceType": "module",
         "allowImportExportEverywhere": true
     },
@@ -10,8 +10,12 @@
         "jasmine": true,
         "es6": true
     },
-    "plugins": [],
-    "extends": ["eslint:recommended"],
+    "plugins": ["@typescript-eslint"],
+    "extends": [
+        "eslint:recommended",
+        "plugin:@typescript-eslint/eslint-recommended",
+        "plugin:@typescript-eslint/recommended"
+    ],
     "globals": {
         "Uint8Array": true,
         "Promise": true,

+ 2 - 1
CHANGES.md

@@ -6,6 +6,7 @@
 - Fix `isOnlyEmojis is not a function` when using only `@converse/headless`
 - Fix `autojoin` checkbox state in MUC bookmark form
 - Remove call to `api.confirm` in `@converse/headless`
+- Generate TypeScript declaration files into `dist/types`
 
 ## 10.1.2 (2023-02-17)
 
@@ -29,7 +30,7 @@
 - #2925: File upload is not always enabled
 - #3001: Add option to save SCRAM details and to use them to stay logged in upon reload
 - Add a "Add to Contacts" button in MUC occupant modals
-- Updated tranlsations and new language Uyghur
+- Updated translations and add support for Uyghur
 
 - New config option [reuse_scram_keys](https://conversejs.org/docs/html/configuration.html#reuse-scram-keys)
 

+ 5 - 0
Makefile

@@ -200,6 +200,7 @@ src/headless/dist/converse-headless.min.js: src webpack/webpack.common.js node_m
 dist:: node_modules src/* | dist/website.css dist/website.min.css
 	npm run headless
 	npm run build
+	make types
 
 .PHONY: install
 install:: dist
@@ -208,6 +209,10 @@ install:: dist
 cdn:: node_modules
 	npm run cdn
 
+.PHONY: types
+types:: node_modules
+	npm run types
+
 ########################################################################
 ## Tests
 

Diff do ficheiro suprimidas por serem muito extensas
+ 752 - 100
package-lock.json


+ 8 - 2
package.json

@@ -15,6 +15,7 @@
     "dist/",
     "docs/**/*.md",
     "docs/**/*.rst",
+    "sass/**/*.scss",
     "src/**/*.html",
     "src/**/*.js",
     "src/**/*.json",
@@ -36,7 +37,9 @@
     "nodeps": "webpack --config webpack/webpack.nodeps.js",
     "prepare": "npm run lerna && npm run build",
     "serve": "webpack serve --config webpack/webpack.serve.js",
-    "watch": "webpack --watch --config webpack/webpack.build.js --mode=development"
+    "watch": "webpack --watch --config webpack/webpack.build.js --mode=development",
+    "types": "tsc --declaration --emitDeclarationOnly --allowJs",
+    "check:types": "tsc --noEmit"
   },
   "repository": {
     "type": "git",
@@ -65,9 +68,9 @@
   "devDependencies": {
     "@babel/cli": "^7.17.10",
     "@babel/core": "^7.18.5",
-    "@babel/eslint-parser": "^7.18.9",
     "@babel/preset-env": "^7.18.2",
     "@converse/headless": "file:src/headless",
+    "@typescript-eslint/eslint-plugin": "^5.48.0",
     "autoprefixer": "^10.4.5",
     "babel-loader": "^9.1.0",
     "bootstrap.native-loader": "2.0.0",
@@ -98,6 +101,9 @@
     "sass": "^1.51.0",
     "sass-loader": "^13.1.0",
     "style-loader": "^3.1.0",
+    "tsc": "^2.0.4",
+    "typescript": "^4.9.5",
+    "typescript-eslint-parser": "^22.0.0",
     "webpack": "^5.72.0",
     "webpack-cli": "^4.7.2",
     "webpack-dev-server": "^4.8.1",

+ 1 - 1
src/entry.js

@@ -49,7 +49,7 @@ const converse = {
      *
      * @memberOf converse
      * @method load
-     * @param {object} settings A map of configuration-settings that are needed at load time.
+     * @param { object } settings A map of configuration-settings that are needed at load time.
      * @example
      * converse.load({assets_path: '/path/to/assets/'});
      */

+ 27 - 30
src/headless/core.js

@@ -113,10 +113,10 @@ export const api = _converse.api = {
      * Some events also double as promises and can be waited on via {@link _converse.api.waitUntil}.
      *
      * @method _converse.api.trigger
-     * @param {string} name - The event name
+     * @param { string } name - The event name
      * @param {...any} [argument] - Argument to be passed to the event handler
-     * @param {object} [options]
-     * @param {boolean} [options.synchronous] - Whether the event is synchronous or not.
+     * @param { object } [options]
+     * @param { boolean } [options.synchronous] - Whether the event is synchronous or not.
      *  When a synchronous event is fired, a promise will be returned
      *  by {@link _converse.api.trigger} which resolves once all the
      *  event handlers' promises have been resolved.
@@ -147,7 +147,7 @@ export const api = _converse.api = {
      * A hook is a special kind of event which allows you to intercept a data
      * structure in order to modify it, before passing it back.
      * @async
-     * @param {string} name - The hook name
+     * @param { string } name - The hook name
      * @param {...any} context - The context to which the hook applies (could be for example, a {@link _converse.ChatBox)).
      * @param {...any} data - The data structure to be intercepted and modified by the hook listeners.
      * @returns {Promise<any>} - A promise that resolves with the modified data structure.
@@ -190,9 +190,9 @@ export const api = _converse.api = {
          * on whether prebinding is used or not.
          *
          * @method _converse.api.user.login
-         * @param {string} [jid]
-         * @param {string} [password]
-         * @param {boolean} [automatic=false] - An internally used flag that indicates whether
+         * @param { string } [jid]
+         * @param { string } [password]
+         * @param { boolean } [automatic=false] - An internally used flag that indicates whether
          *  this method was called automatically once the connection has been
          *  initialized. It's used together with the `auto_login` configuration flag
          *  to determine whether Converse should try to log the user in if it
@@ -306,7 +306,7 @@ export const api = _converse.api = {
          *
          * @method _converse.api.promises.add
          * @param {string|array} [name|names] The name or an array of names for the promise(s) to be added
-         * @param {boolean} [replace=true] Whether this promise should be replaced with a new one when the user logs out.
+         * @param { boolean } [replace=true] Whether this promise should be replaced with a new one when the user logs out.
          * @example _converse.api.promises.add('foo-completed');
          */
         add (promises, replace=true) {
@@ -332,9 +332,9 @@ export const api = _converse.api = {
         /**
          * Lets you listen to an event exactly once.
          * @method _converse.api.listen.once
-         * @param {string} name The event's name
-         * @param {function} callback The callback method to be called when the event is emitted.
-         * @param {object} [context] The value of the `this` parameter for the callback.
+         * @param { string } name The event's name
+         * @param { function } callback The callback method to be called when the event is emitted.
+         * @param { object } [context] The value of the `this` parameter for the callback.
          * @example _converse.api.listen.once('message', function (messageXML) { ... });
          */
         once: _converse.once.bind(_converse),
@@ -343,9 +343,9 @@ export const api = _converse.api = {
          * Lets you subscribe to an event.
          * Every time the event fires, the callback method specified by `callback` will be called.
          * @method _converse.api.listen.on
-         * @param {string} name The event's name
-         * @param {function} callback The callback method to be called when the event is emitted.
-         * @param {object} [context] The value of the `this` parameter for the callback.
+         * @param { string } name The event's name
+         * @param { function } callback The callback method to be called when the event is emitted.
+         * @param { object } [context] The value of the `this` parameter for the callback.
          * @example _converse.api.listen.on('message', function (messageXML) { ... });
          */
         on: _converse.on.bind(_converse),
@@ -353,8 +353,8 @@ export const api = _converse.api = {
         /**
          * To stop listening to an event, you can use the `not` method.
          * @method _converse.api.listen.not
-         * @param {string} name The event's name
-         * @param {function} callback The callback method that is to no longer be called when the event fires
+         * @param { string } name The event's name
+         * @param { function } callback The callback method that is to no longer be called when the event fires
          * @example _converse.api.listen.not('message', function (messageXML);
          */
         not: _converse.off.bind(_converse),
@@ -364,9 +364,9 @@ export const api = _converse.api = {
          * Every a matched stanza is received, the callback method specified by
          * `callback` will be called.
          * @method _converse.api.listen.stanza
-         * @param {string} name The stanza's name
-         * @param {object} options Matching options (e.g. 'ns' for namespace, 'type' for stanza type, also 'id' and 'from');
-         * @param {function} handler The callback method to be called when the stanza appears
+         * @param { string } name The stanza's name
+         * @param { object } options Matching options (e.g. 'ns' for namespace, 'type' for stanza type, also 'id' and 'from');
+         * @param { function } handler The callback method to be called when the stanza appears
          */
         stanza (name, options, handler) {
             if (isFunction(options)) {
@@ -410,7 +410,7 @@ export const api = _converse.api = {
     /**
      * Allows you to send XML stanzas.
      * @method _converse.api.send
-     * @param {XMLElement} stanza
+     * @param { Element } stanza
      * @return {void}
      * @example
      * const msg = converse.env.$msg({
@@ -443,9 +443,9 @@ export const api = _converse.api = {
     /**
      * Send an IQ stanza
      * @method _converse.api.sendIQ
-     * @param {XMLElement} stanza
-     * @param {Integer} [timeout=_converse.STANZA_TIMEOUT]
-     * @param {Boolean} [reject=true] - Whether an error IQ should cause the promise
+     * @param { Element } stanza
+     * @param { number } [timeout=_converse.STANZA_TIMEOUT]
+     * @param { Boolean } [reject=true] - Whether an error IQ should cause the promise
      *  to be rejected. If `false`, the promise will resolve instead of being rejected.
      * @returns {Promise} A promise which resolves (or potentially rejected) once we
      *  receive a `result` or `error` stanza or once a timeout is reached.
@@ -500,9 +500,6 @@ _converse.ConnectionFeedback = Model.extend({
 });
 
 
-export const converse = window.converse || {};
-
-
 /**
  * ### The Public API
  *
@@ -516,7 +513,7 @@ export const converse = window.converse || {};
  * @global
  * @namespace converse
  */
-Object.assign(converse, {
+export const converse = Object.assign(window.converse || {}, {
 
     CHAT_STATES,
 
@@ -528,7 +525,7 @@ Object.assign(converse, {
      * @async
      * @memberOf converse
      * @method initialize
-     * @param {object} config A map of [configuration-settings](https://conversejs.org/docs/html/configuration.html#configuration-settings).
+     * @param { object } config A map of [configuration-settings](https://conversejs.org/docs/html/configuration.html#configuration-settings).
      * @example
      * converse.initialize({
      *     auto_list_rooms: false,
@@ -618,8 +615,8 @@ Object.assign(converse, {
         /**
          * Registers a new plugin.
          * @method converse.plugins.add
-         * @param {string} name The name of the plugin
-         * @param {object} plugin The plugin object
+         * @param { string } name The name of the plugin
+         * @param { object } plugin The plugin object
          * @example
          *  const plugin = {
          *      initialize: function () {

+ 4 - 2
src/headless/log.js

@@ -8,12 +8,14 @@ const LEVELS = {
     'fatal': 4
 }
 
+/* eslint-disable @typescript-eslint/no-empty-function */
 const logger = Object.assign({
     'debug': console?.log ? console.log.bind(console) : function noop () {},
     'error': console?.log ? console.log.bind(console) : function noop () {},
     'info': console?.log ? console.log.bind(console) : function noop () {},
     'warn': console?.log ? console.log.bind(console) : function noop () {}
 }, console);
+/* eslint-enable @typescript-eslint/no-empty-function */
 
 
 /**
@@ -25,7 +27,7 @@ const log = {
     /**
      * The the log-level, which determines how verbose the logging is.
      * @method log#setLogLevel
-     * @param { integer } level - The loglevel which allows for filtering of log messages
+     * @param { number } level - The loglevel which allows for filtering of log messages
      */
     setLogLevel (level) {
         if (!['debug', 'info', 'warn', 'error', 'fatal'].includes(level)) {
@@ -42,7 +44,7 @@ const log = {
      * logged as well.
      * @method log#log
      * @param { string | Error } message - The message to be logged
-     * @param { integer } level - The loglevel which allows for filtering of log messages
+     * @param { number } level - The loglevel which allows for filtering of log messages
      */
     log (message, level, style='') {
         if (LEVELS[level] < LEVELS[this.loglevel]) {

+ 1 - 1
src/headless/plugins/bosh.js

@@ -136,7 +136,7 @@ converse.plugins.add('converse-bosh', {
             tokens: {
                 /**
                  * @method api.tokens.get
-                 * @param {string} [id] The type of token to return ('rid' or 'sid').
+                 * @param { string } [id] The type of token to return ('rid' or 'sid').
                  * @returns 'string' A token, either the RID or SID token depending on what's asked for.
                  * @example _converse.api.tokens.get('rid');
                  */

+ 1 - 1
src/headless/plugins/caps/utils.js

@@ -37,7 +37,7 @@ async function createCapsNode () {
 
 /**
  * Given a stanza, adds a XEP-0115 CAPS element
- * @param { XMLElement } stanza
+ * @param { Element } stanza
  */
 export async function addCapsNode (stanza) {
     const caps_el = await createCapsNode();

+ 6 - 6
src/headless/plugins/chat/api.js

@@ -13,7 +13,7 @@ export default {
         /**
          * @method api.chats.create
          * @param {string|string[]} jid|jids An jid or array of jids
-         * @param {object} [attrs] An object containing configuration attributes.
+         * @param { object } [attrs] An object containing configuration attributes.
          */
         async create (jids, attrs) {
             if (typeof jids === 'string') {
@@ -44,9 +44,9 @@ export default {
          *
          * @method api.chats.open
          * @param {String|string[]} name - e.g. 'buddy@example.com' or ['buddy1@example.com', 'buddy2@example.com']
-         * @param {Object} [attrs] - Attributes to be set on the _converse.ChatBox model.
-         * @param {Boolean} [attrs.minimized] - Should the chat be created in minimized state.
-         * @param {Boolean} [force=false] - By default, a minimized
+         * @param { Object } [attrs] - Attributes to be set on the _converse.ChatBox model.
+         * @param { Boolean } [attrs.minimized] - Should the chat be created in minimized state.
+         * @param { Boolean } [force=false] - By default, a minimized
          *   chat won't be maximized (in `overlayed` view mode) and in
          *   `fullscreen` view mode a newly opened chat won't replace
          *   another chat already in the foreground.
@@ -102,8 +102,8 @@ export default {
          *
          * @method api.chats.get
          * @param {String|string[]} jids - e.g. 'buddy@example.com' or ['buddy1@example.com', 'buddy2@example.com']
-         * @param {Object} [attrs] - Attributes to be set on the _converse.ChatBox model.
-         * @param {Boolean} [create=false] - Whether the chat should be created if it's not found.
+         * @param { Object } [attrs] - Attributes to be set on the _converse.ChatBox model.
+         * @param { Boolean } [create=false] - Whether the chat should be created if it's not found.
          * @returns { Promise<_converse.ChatBox> }
          *
          * @example

+ 1 - 1
src/headless/plugins/chat/parsers.js

@@ -32,7 +32,7 @@ const { Strophe, sizzle } = converse.env;
 /**
  * Parses a passed in message stanza and returns an object of attributes.
  * @method st#parseMessage
- * @param { XMLElement } stanza - The message stanza
+ * @param { Element } stanza - The message stanza
  * @param { _converse } _converse
  * @returns { (MessageAttributes|Error) }
  */

+ 1 - 1
src/headless/plugins/chat/utils.js

@@ -113,7 +113,7 @@ export async function handleMessageStanza (stanza) {
      * @typedef { Object } MessageData
      * An object containing the original message stanza, as well as the
      * parsed attributes.
-     * @property { XMLElement } stanza
+     * @property { Element } stanza
      * @property { MessageAttributes } stanza
      * @property { ChatBox } chatbox
      */

+ 1 - 1
src/headless/plugins/chatboxes/chatboxes.js

@@ -16,7 +16,7 @@ const ChatBoxes = Collection.extend({
          * @event _converse#chatBoxesFetched
          * @type { object }
          * @property { _converse.ChatBox | _converse.ChatRoom } chatbox
-         * @property { XMLElement } stanza
+         * @property { Element } stanza
          * @example _converse.api.listen.on('chatBoxesFetched', obj => { ... });
          * @example _converse.api.waitUntil('chatBoxesFetched').then(() => { ... });
          */

+ 32 - 32
src/headless/plugins/disco/api.js

@@ -24,8 +24,8 @@ export default {
         stream: {
             /**
              * @method api.disco.stream.getFeature
-             * @param {String} name The feature name
-             * @param {String} xmlns The XML namespace
+             * @param { String } name The feature name
+             * @param { String } xmlns The XML namespace
              * @example _converse.api.disco.stream.getFeature('ver', 'urn:xmpp:features:rosterver')
              */
             async getFeature (name, xmlns) {
@@ -57,10 +57,10 @@ export default {
                  * Lets you add new identities for this client (i.e. instance of Converse)
                  * @method api.disco.own.identities.add
                  *
-                 * @param {String} category - server, client, gateway, directory, etc.
-                 * @param {String} type - phone, pc, web, etc.
-                 * @param {String} name - "Converse"
-                 * @param {String} lang - en, el, de, etc.
+                 * @param { String } category - server, client, gateway, directory, etc.
+                 * @param { String } type - phone, pc, web, etc.
+                 * @param { String } name - "Converse"
+                 * @param { String } lang - en, el, de, etc.
                  *
                  * @example _converse.api.disco.own.identities.clear();
                  */
@@ -102,7 +102,7 @@ export default {
                 /**
                  * Lets you register new disco features for this client (i.e. instance of Converse)
                  * @method api.disco.own.features.add
-                 * @param {String} name - e.g. http://jabber.org/protocol/caps
+                 * @param { String } name - e.g. http://jabber.org/protocol/caps
                  * @example _converse.api.disco.own.features.add("http://jabber.org/protocol/caps");
                  */
                 add (name) {
@@ -134,8 +134,8 @@ export default {
          * Query for information about an XMPP entity
          *
          * @method api.disco.info
-         * @param {string} jid The Jabber ID of the entity to query
-         * @param {string} [node] A specific node identifier associated with the JID
+         * @param { string } jid The Jabber ID of the entity to query
+         * @param { string } [node] A specific node identifier associated with the JID
          * @returns {promise} Promise which resolves once we have a result from the server.
          */
         info (jid, node) {
@@ -155,8 +155,8 @@ export default {
          * Query for items associated with an XMPP entity
          *
          * @method api.disco.items
-         * @param {string} jid The Jabber ID of the entity to query for items
-         * @param {string} [node] A specific node identifier associated with the JID
+         * @param { string } jid The Jabber ID of the entity to query for items
+         * @param { string } [node] A specific node identifier associated with the JID
          * @returns {promise} Promise which resolves once we have a result from the server.
          */
         items (jid, node) {
@@ -184,8 +184,8 @@ export default {
              * Get the corresponding `DiscoEntity` instance.
              *
              * @method api.disco.entities.get
-             * @param {string} jid The Jabber ID of the entity
-             * @param {boolean} [create] Whether the entity should be created if it doesn't exist.
+             * @param { string } jid The Jabber ID of the entity
+             * @param { boolean } [create] Whether the entity should be created if it doesn't exist.
              * @example _converse.api.disco.entities.get(jid);
              */
             async get (jid, create=false) {
@@ -209,7 +209,7 @@ export default {
              * Return any disco items advertised on this entity
              *
              * @method api.disco.entities.items
-             * @param {string} jid The Jabber ID of the entity for which we want to fetch items
+             * @param { string } jid The Jabber ID of the entity for which we want to fetch items
              * @example api.disco.entities.items(jid);
              */
             items (jid) {
@@ -225,12 +225,12 @@ export default {
              * `ignore_cache: true` in the options parameter.
              *
              * @method api.disco.entities.create
-             * @param {object} data
-             * @param {string} data.jid - The Jabber ID of the entity
-             * @param {string} data.parent_jid - The Jabber ID of the parent entity
-             * @param {string} data.name
-             * @param {object} [options] - Additional options
-             * @param {boolean} [options.ignore_cache]
+             * @param { object } data
+             * @param { string } data.jid - The Jabber ID of the entity
+             * @param { string } data.parent_jid - The Jabber ID of the parent entity
+             * @param { string } data.name
+             * @param { object } [options] - Additional options
+             * @param { boolean } [options.ignore_cache]
              *     If true, fetch all features from the XMPP server instead of restoring them from cache
              * @example _converse.api.disco.entities.create({ jid }, {'ignore_cache': true});
              */
@@ -248,11 +248,11 @@ export default {
              * Return a given feature of a disco entity
              *
              * @method api.disco.features.get
-             * @param {string} feature The feature that might be
+             * @param { string } feature The feature that might be
              *     supported. In the XML stanza, this is the `var`
              *     attribute of the `<feature>` element. For
              *     example: `http://jabber.org/protocol/muc`
-             * @param {string} jid The JID of the entity
+             * @param { string } jid The JID of the entity
              *     (and its associated items) which should be queried
              * @returns {promise} A promise which resolves with a list containing
              *     _converse.Entity instances representing the entity
@@ -285,11 +285,11 @@ export default {
              * associated items, supports a given feature.
              *
              * @method api.disco.features.has
-             * @param {string} feature The feature that might be
+             * @param { string } feature The feature that might be
              *     supported. In the XML stanza, this is the `var`
              *     attribute of the `<feature>` element. For
              *     example: `http://jabber.org/protocol/muc`
-             * @param {string} jid The JID of the entity
+             * @param { string } jid The JID of the entity
              *     (and its associated items) which should be queried
              * @returns {Promise} A promise which resolves with a boolean
              * @example
@@ -319,11 +319,11 @@ export default {
          * Used to determine whether an entity supports a given feature.
          *
          * @method api.disco.supports
-         * @param {string} feature The feature that might be
+         * @param { string } feature The feature that might be
          *     supported. In the XML stanza, this is the `var`
          *     attribute of the `<feature>` element. For
          *     example: `http://jabber.org/protocol/muc`
-         * @param {string} jid The JID of the entity
+         * @param { string } jid The JID of the entity
          *     (and its associated items) which should be queried
          * @returns {promise} A promise which resolves with `true` or `false`.
          * @example
@@ -341,7 +341,7 @@ export default {
          * Refresh the features, fields and identities associated with a
          * disco entity by refetching them from the server
          * @method api.disco.refresh
-         * @param {string} jid The JID of the entity whose features are refreshed.
+         * @param { string } jid The JID of the entity whose features are refreshed.
          * @returns {promise} A promise which resolves once the features have been refreshed
          * @example
          * await api.disco.refresh('room@conference.example.org');
@@ -379,7 +379,7 @@ export default {
          * Return all the features associated with a disco entity
          *
          * @method api.disco.getFeatures
-         * @param {string} jid The JID of the entity whose features are returned.
+         * @param { string } jid The JID of the entity whose features are returned.
          * @returns {promise} A promise which resolves with the returned features
          * @example
          * const features = await api.disco.getFeatures('room@conference.example.org');
@@ -401,7 +401,7 @@ export default {
          * See [XEP-0129: Service Discovery Extensions](https://xmpp.org/extensions/xep-0128.html)
          *
          * @method api.disco.getFields
-         * @param {string} jid The JID of the entity whose fields are returned.
+         * @param { string } jid The JID of the entity whose fields are returned.
          * @example
          * const fields = await api.disco.getFields('room@conference.example.org');
          */
@@ -424,15 +424,15 @@ export default {
          * XEP-0163: https://xmpp.org/extensions/xep-0163.html#support
          *
          * @method api.disco.getIdentity
-         * @param {string} The identity category.
+         * @param { string } The identity category.
          *     In the XML stanza, this is the `category`
          *     attribute of the `<identity>` element.
          *     For example: 'pubsub'
-         * @param {string} type The identity type.
+         * @param { string } type The identity type.
          *     In the XML stanza, this is the `type`
          *     attribute of the `<identity>` element.
          *     For example: 'pep'
-         * @param {string} jid The JID of the entity which might have the identity
+         * @param { string } jid The JID of the entity which might have the identity
          * @returns {promise} A promise which resolves with a map indicating
          *     whether an identity with a given type is provided by the entity.
          * @example

+ 2 - 2
src/headless/plugins/headlines/api.js

@@ -15,8 +15,8 @@ export default {
          *
          * @method api.headlines.get
          * @param {String|String[]} jids - e.g. 'buddy@example.com' or ['buddy1@example.com', 'buddy2@example.com']
-         * @param {Object} [attrs] - Attributes to be set on the _converse.ChatBox model.
-         * @param {Boolean} [create=false] - Whether the chat should be created if it's not found.
+         * @param { Object } [attrs] - Attributes to be set on the _converse.ChatBox model.
+         * @param { Boolean } [create=false] - Whether the chat should be created if it's not found.
          * @returns { Promise<_converse.HeadlinesFeed> }
          */
         async get (jids, attrs={}, create=false) {

+ 1 - 1
src/headless/plugins/headlines/utils.js

@@ -4,7 +4,7 @@ import { parseMessage } from '@converse/headless/plugins/chat/parsers';
 
 /**
  * Handler method for all incoming messages of type "headline".
- * @param { XMLElement } stanza
+ * @param { Element } stanza
  */
 export async function onHeadlineMessage (stanza) {
     if (isHeadline(stanza) || isServerMessage(stanza)) {

+ 2 - 2
src/headless/plugins/mam/utils.js

@@ -100,7 +100,7 @@ export async function handleMAMResult (model, result, query, options, should_pag
 /**
  * @typedef { Object } MAMOptions
  * A map of MAM related options that may be passed to fetchArchivedMessages
- * @param { integer } [options.max] - The maximum number of items to return.
+ * @param { number } [options.max] - The maximum number of items to return.
  *  Defaults to "archived_messages_page_size"
  * @param { string } [options.after] - The XEP-0359 stanza ID of a message
  *  after which messages should be returned. Implies forward paging.
@@ -117,7 +117,7 @@ export async function handleMAMResult (model, result, query, options, should_pag
 
 /**
  * Fetch XEP-0313 archived messages based on the passed in criteria.
- * @param { _converse.ChatBox | _converse.ChatRoom } model
+ * @param { ChatBox | ChatRoom } model
  * @param { MAMOptions } [options]
  * @param { ('forwards'|'backwards'|null)} [should_page=null] - Determines whether
  *  this function should recursively page through the entire result set if a limited

+ 9 - 9
src/headless/plugins/muc/api.js

@@ -23,7 +23,7 @@ export default {
          * @method api.rooms.create
          * @param {(string[]|string)} jid|jids The JID or array of
          *     JIDs of the chatroom(s) to create
-         * @param {object} [attrs] attrs The room attributes
+         * @param { object } [attrs] attrs The room attributes
          * @returns {Promise} Promise which resolves with the Model representing the chat.
          */
         create (jids, attrs = {}) {
@@ -45,24 +45,24 @@ export default {
          * Similar to {@link api.chats.open}, but for groupchats.
          *
          * @method api.rooms.open
-         * @param {string} jid The room JID or JIDs (if not specified, all
+         * @param { string } jid The room JID or JIDs (if not specified, all
          *     currently open rooms will be returned).
-         * @param {string} attrs A map  containing any extra room attributes.
-         * @param {string} [attrs.nick] The current user's nickname for the MUC
-         * @param {boolean} [attrs.auto_configure] A boolean, indicating
+         * @param { string } attrs A map  containing any extra room attributes.
+         * @param { string } [attrs.nick] The current user's nickname for the MUC
+         * @param { boolean } [attrs.auto_configure] A boolean, indicating
          *     whether the room should be configured automatically or not.
          *     If set to `true`, then it makes sense to pass in configuration settings.
-         * @param {object} [attrs.roomconfig] A map of configuration settings to be used when the room gets
+         * @param { object } [attrs.roomconfig] A map of configuration settings to be used when the room gets
          *     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](https://xmpp.org/extensions/xep-0045.html#registrar-formtype-owner).
          *     The values should be named without the `muc#roomconfig_` prefix.
-         * @param {boolean} [attrs.minimized] A boolean, indicating whether the room should be opened minimized or not.
-         * @param {boolean} [attrs.bring_to_foreground] A boolean indicating whether the room should be
+         * @param { boolean } [attrs.minimized] A boolean, indicating whether the room should be opened minimized or not.
+         * @param { boolean } [attrs.bring_to_foreground] A boolean indicating whether the room should be
          *     brought to the foreground and therefore replace the currently shown chat.
          *     If there is no chat currently open, then this option is ineffective.
-         * @param {Boolean} [force=false] - By default, a minimized
+         * @param { Boolean } [force=false] - By default, a minimized
          *   room won't be maximized (in `overlayed` view mode) and in
          *   `fullscreen` view mode a newly opened room won't replace
          *   another chat already in the foreground.

+ 25 - 25
src/headless/plugins/muc/muc.js

@@ -226,7 +226,7 @@ const ChatRoomMixin = {
           * *Hook* which allows plugins to update an outgoing MUC join presence stanza
           * @event _converse#constructedMUCPresence
           * @param { _converse.ChatRoom } - The MUC from which this message stanza is being sent.
-          * @param { XMLElement } stanza - The stanza which will be sent out
+          * @param { Element } stanza - The stanza which will be sent out
           */
         stanza = await api.hook('constructedMUCPresence', this, stanza);
         return stanza;
@@ -507,7 +507,7 @@ const ChatRoomMixin = {
      * Handles incoming message stanzas from the service that hosts this MUC
      * @private
      * @method _converse.ChatRoom#handleMessageFromMUCHost
-     * @param { XMLElement } stanza
+     * @param { Element } stanza
      */
     handleMessageFromMUCHost (stanza) {
         if (this.isEntered()) {
@@ -528,7 +528,7 @@ const ChatRoomMixin = {
      * Handles XEP-0452 MUC Mention Notification messages
      * @private
      * @method _converse.ChatRoom#handleForwardedMentions
-     * @param { XMLElement } stanza
+     * @param { Element } stanza
      */
     handleForwardedMentions (stanza) {
         if (this.isEntered()) {
@@ -558,7 +558,7 @@ const ChatRoomMixin = {
      * Parses an incoming message stanza and queues it for processing.
      * @private
      * @method _converse.ChatRoom#handleMessageStanza
-     * @param { XMLElement } stanza
+     * @param { Element } stanza
      */
     async handleMessageStanza (stanza) {
         stanza = stanza.tree?.() ?? stanza;
@@ -709,8 +709,8 @@ const ChatRoomMixin = {
      * or error message within a specific timeout period.
      * @private
      * @method _converse.ChatRoom#sendTimedMessage
-     * @param { _converse.Message|XMLElement } message
-     * @returns { Promise<XMLElement>|Promise<_converse.TimeoutError> } Returns a promise
+     * @param { _converse.Message|Element } message
+     * @returns { Promise<Element>|Promise<_converse.TimeoutError> } Returns a promise
      *  which resolves with the reflected message stanza or with an error stanza or {@link _converse.TimeoutError}.
      */
     sendTimedMessage (el) {
@@ -793,7 +793,7 @@ const ChatRoomMixin = {
      * Retract someone else's message in this groupchat.
      * @private
      * @method _converse.ChatRoom#retractOtherMessage
-     * @param { _converse.Message } message - The message which we're retracting.
+     * @param { _converse.ChatRoomMessage } message - The message which we're retracting.
      * @param { string } [reason] - The reason for retracting the message.
      * @example
      *  const room = await api.rooms.get(jid);
@@ -828,7 +828,7 @@ const ChatRoomMixin = {
      * Sends an IQ stanza to the XMPP server to retract a message in this groupchat.
      * @private
      * @method _converse.ChatRoom#sendRetractionIQ
-     * @param { _converse.Message } message - The message which we're retracting.
+     * @param { _converse.ChatRoomMessage } message - The message which we're retracting.
      * @param { string } [reason] - The reason for retracting the message.
      */
     sendRetractionIQ (message, reason) {
@@ -1243,7 +1243,7 @@ const ChatRoomMixin = {
      * 'roomconfig' data.
      * @private
      * @method _converse.ChatRoom#autoConfigureChatRoom
-     * @returns { Promise<XMLElement> }
+     * @returns { Promise<Element> }
      * Returns a promise which resolves once a response IQ has
      * been received.
      */
@@ -1262,7 +1262,7 @@ const ChatRoomMixin = {
      * has been received.
      * @private
      * @method _converse.ChatRoom#fetchRoomConfiguration
-     * @returns { Promise<XMLElement> }
+     * @returns { Promise<Element> }
      */
     fetchRoomConfiguration () {
         return api.sendIQ($iq({ 'to': this.get('jid'), 'type': 'get' }).c('query', { xmlns: Strophe.NS.MUC_OWNER }));
@@ -1273,7 +1273,7 @@ const ChatRoomMixin = {
      * @private
      * @method _converse.ChatRoom#sendConfiguration
      * @param { Array } config - The groupchat configuration
-     * @returns { Promise<XMLElement> } - A promise which resolves with
+     * @returns { Promise<Element> } - A promise which resolves with
      * the `result` stanza received from the XMPP server.
      */
     sendConfiguration (config = []) {
@@ -1715,7 +1715,7 @@ const ChatRoomMixin = {
      * Given a presence stanza, update the occupant model based on its contents.
      * @private
      * @method _converse.ChatRoom#updateOccupantsOnPresence
-     * @param { XMLElement } pres - The presence stanza
+     * @param { Element } pres - The presence stanza
      */
     updateOccupantsOnPresence (pres) {
         const data = parseMUCPresence(pres, this);
@@ -1902,7 +1902,7 @@ const ChatRoomMixin = {
      * the `from` attribute. Doesn't check the `type` attribute.
      * @private
      * @method _converse.ChatRoom#isOwnMessage
-     * @param { Object|XMLElement|_converse.Message } msg
+     * @param { Object|Element|_converse.Message } msg
      * @returns { boolean }
      */
     isOwnMessage (msg) {
@@ -2150,7 +2150,7 @@ const ChatRoomMixin = {
     },
 
     /**
-     * @param {String} actor - The nickname of the actor that caused the notification
+     * @param { String } actor - The nickname of the actor that caused the notification
      * @param {String|Array<String>} states - The state or states representing the type of notificcation
      */
     removeNotification (actor, states) {
@@ -2174,8 +2174,8 @@ const ChatRoomMixin = {
      *
      * The state can be a XEP-0085 Chat State or a XEP-0045 join/leave
      * state.
-     * @param {String} actor - The nickname of the actor that causes the notification
-     * @param {String} state - The state representing the type of notificcation
+     * @param { String } actor - The nickname of the actor that causes the notification
+     * @param { String } state - The state representing the type of notificcation
      */
     updateNotifications (actor, state) {
         const actors_per_state = this.notifications.toJSON();
@@ -2223,7 +2223,7 @@ const ChatRoomMixin = {
     /**
      * Given {@link MessageAttributes} look for XEP-0316 Room Notifications and create info
      * messages for them.
-     * @param { XMLElement } stanza
+     * @param { Element } stanza
      */
     handleMEPNotification (attrs) {
         if (attrs.from !== this.get('jid') || !attrs.activities) {
@@ -2320,7 +2320,7 @@ const ChatRoomMixin = {
 
     /**
      * Handle a presence stanza that disconnects the user from the MUC
-     * @param { XMLElement } stanza
+     * @param { Element } stanza
      */
     handleDisconnection (stanza) {
         const is_self = stanza.querySelector("status[code='110']") !== null;
@@ -2455,7 +2455,7 @@ const ChatRoomMixin = {
      * @private
      * @method _converse.ChatRoom#createInfoMessage
      * @param { string } code - The MUC status code
-     * @param { XMLElement } stanza - The original stanza that contains the code
+     * @param { Element } stanza - The original stanza that contains the code
      * @param { Boolean } is_self - Whether this stanza refers to our own presence
      */
     createInfoMessage (code, stanza, is_self) {
@@ -2498,7 +2498,7 @@ const ChatRoomMixin = {
      * Create info messages based on a received presence or message stanza
      * @private
      * @method _converse.ChatRoom#createInfoMessages
-     * @param { XMLElement } stanza
+     * @param { Element } stanza
      */
     createInfoMessages (stanza) {
         const codes = sizzle(`x[xmlns="${Strophe.NS.MUC_USER}"] status`, stanza).map(s => s.getAttribute('code'));
@@ -2517,7 +2517,7 @@ const ChatRoomMixin = {
      *  implied by) the server.
      * @param { String } reason - The reason provided for the disconnection
      * @param { String } actor - The person (if any) responsible for this disconnection
-     * @param { Integer } status - The status code (see `ROOMSTATUS`)
+     * @param { number } status - The status code (see `ROOMSTATUS`)
      */
     setDisconnectionState (message, reason, actor, status=ROOMSTATUS.DISCONNECTED) {
         this.session.save({
@@ -2554,7 +2554,7 @@ const ChatRoomMixin = {
      * `connection_status` value for this {@link _converse.ChatRoom} as
      * well as any additional output that can be shown to the user.
      * @private
-     * @param { XMLElement } stanza - The presence stanza
+     * @param { Element } stanza - The presence stanza
      */
     onErrorPresence (stanza) {
         const __ = _converse.__;
@@ -2619,7 +2619,7 @@ const ChatRoomMixin = {
      * Listens for incoming presence stanzas from the service that hosts this MUC
      * @private
      * @method _converse.ChatRoom#onPresenceFromMUCHost
-     * @param { XMLElement } stanza - The presence stanza
+     * @param { Element } stanza - The presence stanza
      */
     onPresenceFromMUCHost (stanza) {
         if (stanza.getAttribute('type') === 'error') {
@@ -2638,7 +2638,7 @@ const ChatRoomMixin = {
      * Handles incoming presence stanzas coming from the MUC
      * @private
      * @method _converse.ChatRoom#onPresence
-     * @param { XMLElement } stanza
+     * @param { Element } stanza
      */
     onPresence (stanza) {
         if (stanza.getAttribute('type') === 'error') {
@@ -2671,7 +2671,7 @@ const ChatRoomMixin = {
      * user is the groupchat's owner.
      * @private
      * @method _converse.ChatRoom#onOwnPresence
-     * @param { XMLElement } pres - The stanza
+     * @param { Element } pres - The stanza
      */
     async onOwnPresence (stanza) {
         await this.occupants.fetched;

+ 7 - 7
src/headless/plugins/muc/parsers.js

@@ -27,7 +27,7 @@ const { NS } = Strophe;
 
 /**
  * Parses a message stanza for XEP-0317 MEP notification data
- * @param { XMLElement } stanza - The message stanza
+ * @param { Element } stanza - The message stanza
  * @returns { Array } Returns an array of objects representing <activity> elements.
  */
 export function getMEPActivities (stanza) {
@@ -61,7 +61,7 @@ export function getMEPActivities (stanza) {
  * Note, this function doesn't check whether this is actually a MAM archived stanza.
  *
  * @private
- * @param { XMLElement } stanza - The message stanza
+ * @param { Element } stanza - The message stanza
  * @returns { Object }
  */
 function getJIDFromMUCUserData (stanza) {
@@ -71,8 +71,8 @@ function getJIDFromMUCUserData (stanza) {
 
 /**
  * @private
- * @param { XMLElement } stanza - The message stanza
- * @param { XMLElement } original_stanza - The original stanza, that contains the
+ * @param { Element } stanza - The message stanza
+ * @param { Element } original_stanza - The original stanza, that contains the
  *  message stanza, if it was contained, otherwise it's the message stanza itself.
  * @returns { Object }
  */
@@ -140,8 +140,8 @@ function getSender (attrs, chatbox) {
 
 /**
  * Parses a passed in message stanza and returns an object of attributes.
- * @param { XMLElement } stanza - The message stanza
- * @param { XMLElement } original_stanza - The original stanza, that contains the
+ * @param { Element } stanza - The message stanza
+ * @param { Element } original_stanza - The original stanza, that contains the
  *  message stanza, if it was contained, otherwise it's the message stanza itself.
  * @param { _converse.ChatRoom } chatbox
  * @param { _converse } _converse
@@ -342,7 +342,7 @@ export function parseMemberListIQ (iq) {
 /**
  * Parses a passed in MUC presence stanza and returns an object of attributes.
  * @method parseMUCPresence
- * @param { XMLElement } stanza - The presence stanza
+ * @param { Element } stanza - The presence stanza
  * @param { _converse.ChatRoom } chatbox
  * @returns { MUCPresenceAttributes }
  */

+ 1 - 1
src/headless/plugins/muc/utils.js

@@ -85,7 +85,7 @@ export async function openChatRoom (jid, settings) {
  * See XEP-0249: Direct MUC invitations.
  * @private
  * @method _converse.ChatRoom#onDirectMUCInvitation
- * @param { XMLElement } message - The message stanza containing the invitation.
+ * @param { Element } message - The message stanza containing the invitation.
  */
 export async function onDirectMUCInvitation (message) {
     const x_el = sizzle('x[xmlns="jabber:x:conference"]', message).pop(),

+ 1 - 1
src/headless/plugins/ping/api.js

@@ -10,7 +10,7 @@ export default {
      * @method api.ping
      * @param { String } [jid] - The JID of the service to ping
      *  If the ping is sent out to the user's bare JID and no response is received it will attempt to reconnect.
-     * @param { Integer } [timeout] - The amount of time in
+     * @param { number } [timeout] - The amount of time in
      *  milliseconds to wait for a response. The default is 10000;
      * @returns { Boolean | null }
      *  Whether the pinged entity responded with a non-error IQ stanza.

+ 4 - 4
src/headless/plugins/pubsub.js

@@ -32,12 +32,12 @@ converse.plugins.add('converse-pubsub', {
                  * Publshes an item to a PubSub node
                  *
                  * @method _converse.api.pubsub.publish
-                 * @param {string} jid The JID of the pubsub service where the node resides.
-                 * @param {string} node The node being published to
+                 * @param { string } jid The JID of the pubsub service where the node resides.
+                 * @param { string } node The node being published to
                  * @param {Strophe.Builder} item The Strophe.Builder representation of the XML element being published
-                 * @param {object} options An object representing the publisher options
+                 * @param { object } options An object representing the publisher options
                  *      (see https://xmpp.org/extensions/xep-0060.html#publisher-publish-options)
-                 * @param {boolean} strict_options Indicates whether the publisher
+                 * @param { boolean } strict_options Indicates whether the publisher
                  *      options are a strict requirement or not. If they're NOT
                  *      strict, then Converse will publish to the node even if
                  *      the publish options precondication cannot be met.

+ 2 - 2
src/headless/plugins/roster/api.js

@@ -55,8 +55,8 @@ export default {
          * Add a contact.
          *
          * @method _converse.api.contacts.add
-         * @param {string} jid The JID of the contact to be added
-         * @param {string} [name] A custom name to show the user by in the roster
+         * @param { string } jid The JID of the contact to be added
+         * @param { string } [name] A custom name to show the user by in the roster
          * @example
          *     _converse.api.contacts.add('buddy@example.com')
          * @example

+ 4 - 4
src/headless/plugins/roster/contacts.js

@@ -190,7 +190,7 @@ const RosterContacts = Collection.extend({
      * Handle roster updates from the XMPP server.
      * See: https://xmpp.org/rfcs/rfc6121.html#roster-syntax-actions-push
      * @method _converse.RosterContacts#onRosterPush
-     * @param { XMLElement } IQ - The IQ stanza received from the XMPP server.
+     * @param { Element } IQ - The IQ stanza received from the XMPP server.
      */
     onRosterPush (iq) {
         const id = iq.getAttribute('id');
@@ -226,7 +226,7 @@ const RosterContacts = Collection.extend({
         /**
          * When the roster receives a push event from server (i.e. new entry in your contacts roster).
          * @event _converse#rosterPush
-         * @type { XMLElement }
+         * @type { Element }
          * @example _converse.api.listen.on('rosterPush', iq => { ... });
          */
         api.trigger('rosterPush', iq);
@@ -279,7 +279,7 @@ const RosterContacts = Collection.extend({
          * See also the `cachedRoster` event further up, which gets called instead of
          * `roster` if its already in `sessionStorage`.
          * @event _converse#roster
-         * @type { XMLElement }
+         * @type { Element }
          * @example _converse.api.listen.on('roster', iq => { ... });
          * @example _converse.api.waitUntil('roster').then(iq => { ... });
          */
@@ -289,7 +289,7 @@ const RosterContacts = Collection.extend({
     /**
      * Update or create RosterContact models based on the given `item` XML
      * node received in the resulting IQ stanza from the server.
-     * @param { XMLElement } item
+     * @param { Element } item
      */
     updateContact (item) {
         const jid = item.getAttribute('jid');

+ 1 - 1
src/headless/plugins/roster/presence.js

@@ -48,7 +48,7 @@ export const Presence = Model.extend({
      * from the passed in presence stanza.
      * Also updates the presence if the resource has higher priority (and is newer).
      * @private
-     * @param { XMLElement } presence: The presence stanza
+     * @param { Element } presence: The presence stanza
      */
     addResource (presence) {
         const jid = presence.getAttribute('from'),

+ 3 - 3
src/headless/plugins/status/api.js

@@ -55,8 +55,8 @@ export default {
          *
          * @async
          * @method _converse.api.user.status.set
-         * @param {string} value The user's chat status (e.g. 'away', 'dnd', 'offline', 'online', 'unavailable' or 'xa')
-         * @param {string} [message] A custom status message
+         * @param { string } value The user's chat status (e.g. 'away', 'dnd', 'offline', 'online', 'unavailable' or 'xa')
+         * @param { string } [message] A custom status message
          *
          * @example _converse.api.user.status.set('dnd');
          * @example _converse.api.user.status.set('dnd', 'In a meeting');
@@ -95,7 +95,7 @@ export default {
             /**
              * @async
              * @method _converse.api.user.status.message.set
-             * @param {string} status The status message
+             * @param { string } status The status message
              * @example _converse.api.user.status.message.set('In a meeting');
              */
             async set (status) {

+ 5 - 5
src/headless/plugins/vcard/api.js

@@ -22,8 +22,8 @@ export default {
          * for the passed in JID.
          *
          * @method _converse.api.vcard.set
-         * @param {string} jid The JID for which the VCard should be set
-         * @param {object} data A map of VCard keys and values
+         * @param { string } jid The JID for which the VCard should be set
+         * @param { object } data A map of VCard keys and values
          * @example
          * let jid = _converse.bare_jid;
          * _converse.api.vcard.set( jid, {
@@ -67,7 +67,7 @@ export default {
          * @param {Model|string} model Either a `Model` instance, or a string JID.
          *     If a `Model` instance is passed in, then it must have either a `jid`
          *     attribute or a `muc_jid` attribute.
-         * @param {boolean} [force] A boolean indicating whether the vcard should be
+         * @param { boolean } [force] A boolean indicating whether the vcard should be
          *     fetched from the server even if it's been fetched before.
          * @returns {promise} A Promise which resolves with the VCard data for a particular JID or for
          *     a `Model` instance which represents an entity with a JID (such as a roster contact,
@@ -106,8 +106,8 @@ export default {
          * returned VCard data.
          *
          * @method _converse.api.vcard.update
-         * @param {Model} model A `Model` instance
-         * @param {boolean} [force] A boolean indicating whether the vcard should be
+         * @param { Model } model A `Model` instance
+         * @param { boolean } [force] A boolean indicating whether the vcard should be
          *     fetched again even if it's been fetched before.
          * @returns {promise} A promise which resolves once the update has completed.
          * @example

+ 1 - 1
src/headless/shared/_converse.js

@@ -41,7 +41,7 @@ const _converse = {
 
     /**
      * @constant
-     * @type { integer }
+     * @type { number }
      */
     STANZA_TIMEOUT: 20000,
 

+ 11 - 11
src/headless/shared/parsers.js

@@ -28,7 +28,7 @@ export class StanzaParseError extends Error {
  * Extract the XEP-0359 stanza IDs from the passed in stanza
  * and return a map containing them.
  * @private
- * @param { XMLElement } stanza - The message stanza
+ * @param { Element } stanza - The message stanza
  * @returns { Object }
  */
 export function getStanzaIDs (stanza, original_stanza) {
@@ -72,8 +72,8 @@ export function getEncryptionAttributes (stanza) {
 
 /**
  * @private
- * @param { XMLElement } stanza - The message stanza
- * @param { XMLElement } original_stanza - The original stanza, that contains the
+ * @param { Element } stanza - The message stanza
+ * @param { Element } original_stanza - The original stanza, that contains the
  *  message stanza, if it was contained, otherwise it's the message stanza itself.
  * @returns { Object }
  */
@@ -222,7 +222,7 @@ export function getOutOfBandAttributes (stanza) {
 /**
  * Returns the human readable error message contained in a `groupchat` message stanza of type `error`.
  * @private
- * @param { XMLElement } stanza - The message stanza
+ * @param { Element } stanza - The message stanza
  */
 export function getErrorAttributes (stanza) {
     if (stanza.getAttribute('type') === 'error') {
@@ -240,7 +240,7 @@ export function getErrorAttributes (stanza) {
 
 /**
  * Given a message stanza, find and return any XEP-0372 references
- * @param { XMLElement } stana - The message stanza
+ * @param { Element } stana - The message stanza
  * @returns { Reference }
  */
 export function getReferences (stanza) {
@@ -279,7 +279,7 @@ export function getReceiptId (stanza) {
 /**
  * Determines whether the passed in stanza is a XEP-0280 Carbon
  * @private
- * @param { XMLElement } stanza - The message stanza
+ * @param { Element } stanza - The message stanza
  * @returns { Boolean }
  */
 export function isCarbon (stanza) {
@@ -293,7 +293,7 @@ export function isCarbon (stanza) {
 /**
  * Returns the XEP-0085 chat state contained in a message stanza
  * @private
- * @param { XMLElement } stanza - The message stanza
+ * @param { Element } stanza - The message stanza
  */
 export function getChatState (stanza) {
     return sizzle(
@@ -319,7 +319,7 @@ export function isValidReceiptRequest (stanza, attrs) {
 /**
  * Check whether the passed-in stanza is a forwarded message that is "bare",
  * i.e. it's not forwarded as part of a larger protocol, like MAM.
- * @param { XMLElement } stanza
+ * @param { Element } stanza
  */
 export function throwErrorIfInvalidForward (stanza) {
     const bare_forward = sizzle(`message > forwarded[xmlns="${Strophe.NS.FORWARD}"]`, stanza).length;
@@ -334,7 +334,7 @@ export function throwErrorIfInvalidForward (stanza) {
  * Determines whether the passed in stanza is a XEP-0333 Chat Marker
  * @private
  * @method getChatMarker
- * @param { XMLElement } stanza - The message stanza
+ * @param { Element } stanza - The message stanza
  * @returns { Boolean }
  */
 export function getChatMarker (stanza) {
@@ -371,7 +371,7 @@ export function isServerMessage (stanza) {
  * Determines whether the passed in stanza is a XEP-0313 MAM stanza
  * @private
  * @method isArchived
- * @param { XMLElement } stanza - The message stanza
+ * @param { Element } stanza - The message stanza
  * @returns { Boolean }
  */
 export function isArchived (original_stanza) {
@@ -382,7 +382,7 @@ export function isArchived (original_stanza) {
 /**
  * Returns an object containing all attribute names and values for a particular element.
  * @method getAttributes
- * @param { XMLElement } stanza
+ * @param { Element } stanza
  * @returns { Object }
  */
 export function getAttributes (stanza) {

+ 3 - 3
src/headless/shared/rsm.js

@@ -19,8 +19,8 @@ Strophe.addNamespace('RSM', 'http://jabber.org/protocol/rsm');
  * [XEP-0059 RSM](https://xmpp.org/extensions/xep-0059.html) Attributes that can be used to filter query results
  * @property { String } [after] - The XEP-0359 stanza ID of a message after which messages should be returned. Implies forward paging.
  * @property { String } [before] - The XEP-0359 stanza ID of a message before which messages should be returned. Implies backward paging.
- * @property { Integer } [index=0] - The index of the results page to return.
- * @property { Integer } [max] - The maximum number of items to return.
+ * @property { number } [index=0] - The index of the results page to return.
+ * @property { number } [max] - The maximum number of items to return.
  */
 
 const RSM_QUERY_PARAMETERS = ['after', 'before', 'index', 'max'];
@@ -84,7 +84,7 @@ export class RSM {
      * Returns a `<set>` XML element that confirms to XEP-0059 Result Set Management.
      * The element is constructed based on the {@link module:converse-rsm~RSMQueryParameters}
      * that are set on this RSM instance.
-     * @returns { XMLElement }
+     * @returns { Element }
      */
     toXML () {
         const xml = $build('set', {xmlns: Strophe.NS.RSM});

+ 8 - 8
src/headless/shared/settings/api.js

@@ -29,7 +29,7 @@ export const settings_api = {
      * `converse.initialize`.
      *
      * @method _converse.api.settings.extend
-     * @param {object} settings The configuration settings
+     * @param { object } settings The configuration settings
      * @example
      * _converse.api.settings.extend({
      *    'enable_foo': true
@@ -70,9 +70,9 @@ export const settings_api = {
      * running and you want to change the configuration on-the-fly.
      *
      * @method _converse.api.settings.set
-     * @param {Object} [settings] An object containing configuration settings.
-     * @param {string} [key] Alternatively to passing in an object, you can pass in a key and a value.
-     * @param {string} [value]
+     * @param { Object } [settings] An object containing configuration settings.
+     * @param { string } [key] Alternatively to passing in an object, you can pass in a key and a value.
+     * @param { string } [value]
      * @example _converse.api.settings.set("play_sounds", true);
      * @example
      * _converse.api.settings.set({
@@ -142,7 +142,7 @@ export const user_settings_api = {
     /**
      * Get the value of a particular user setting.
      * @method _converse.api.user.settings.get
-     * @param {String} key - The setting name
+     * @param { String } key - The setting name
      * @param {*} [fallback] - An optional fallback value if the user setting is undefined
      * @returns {Promise} Promise which resolves with the value of the particular configuration setting.
      * @example _converse.api.user.settings.get("foo");
@@ -156,9 +156,9 @@ export const user_settings_api = {
      * Set one or many user settings.
      * @async
      * @method _converse.api.user.settings.set
-     * @param {Object} [settings] An object containing configuration settings.
-     * @param {string} [key] Alternatively to passing in an object, you can pass in a key and a value.
-     * @param {string} [value]
+     * @param { Object } [settings] An object containing configuration settings.
+     * @param { string } [key] Alternatively to passing in an object, you can pass in a key and a value.
+     * @param { string } [value]
      * @example _converse.api.user.settings.set("foo", "bar");
      * @example
      * _converse.api.user.settings.set({

+ 10 - 10
src/headless/utils/core.js

@@ -256,7 +256,7 @@ u.stringToElement = function (s) {
  * Checks whether the DOM element matches the given selector.
  * @private
  * @method u#matchesSelector
- * @param { DOMElement } el - The DOM element
+ * @param { Element } el - The DOM element
  * @param { String } selector - The selector
  */
 u.matchesSelector = function (el, selector) {
@@ -275,7 +275,7 @@ u.matchesSelector = function (el, selector) {
  * Returns a list of children of the DOM element that match the selector.
  * @private
  * @method u#queryChildren
- * @param { DOMElement } el - the DOM element
+ * @param { Element } el - the DOM element
  * @param { String } selector - the selector they should be matched against
  */
 u.queryChildren = function (el, selector) {
@@ -394,10 +394,10 @@ u.siblingIndex = function (el) {
 /**
  * Returns the current word being written in the input element
  * @method u#getCurrentWord
- * @param {HTMLElement} input - The HTMLElement in which text is being entered
- * @param {integer} [index] - An optional rightmost boundary index. If given, the text
+ * @param { HTMLElement } input - The HTMLElement in which text is being entered
+ * @param { number } [index] - An optional rightmost boundary index. If given, the text
  *  value of the input element will only be considered up until this index.
- * @param {string} [delineator] - An optional string delineator to
+ * @param { string } [delineator] - An optional string delineator to
  *  differentiate between words.
  * @private
  */
@@ -477,8 +477,8 @@ export function getUniqueId (suffix) {
 /**
  * Clears the specified timeout and interval.
  * @method u#clearTimers
- * @param {number} timeout - Id if the timeout to clear.
- * @param {number} interval - Id of the interval to clear.
+ * @param { number } timeout - Id if the timeout to clear.
+ * @param { number } interval - Id of the interval to clear.
  * @private
  * @copyright Simen Bekkhus 2016
  * @license MIT
@@ -493,10 +493,10 @@ function clearTimers(timeout, interval) {
  * Creates a {@link Promise} that resolves if the passed in function returns a truthy value.
  * Rejects if it throws or does not return truthy within the given max_wait.
  * @method u#waitUntil
- * @param {Function} func - The function called every check_delay,
+ * @param { Function } func - The function called every check_delay,
  *  and the result of which is the resolved value of the promise.
- * @param {number} [max_wait=300] - The time to wait before rejecting the promise.
- * @param {number} [check_delay=3] - The time to wait before each invocation of {func}.
+ * @param { number } [max_wait=300] - The time to wait before rejecting the promise.
+ * @param { number } [check_delay=3] - The time to wait before each invocation of {func}.
  * @returns {Promise} A promise resolved with the value of func,
  *  or rejected with the exception thrown by it or it times out.
  * @copyright Simen Bekkhus 2016

+ 1 - 1
src/headless/utils/form.js

@@ -13,7 +13,7 @@ const tplXformValue = (value) => `<value>${value}</value>`;
  * Takes an HTML DOM and turns it into an XForm field.
  * @private
  * @method u#webForm2xForm
- * @param { DOMElement } field - the field to convert
+ * @param { Element } field - the field to convert
  */
 export function webForm2xForm (field) {
     const name = field.getAttribute('name');

+ 2 - 2
src/plugins/chatview/message-form.js

@@ -48,12 +48,12 @@ export default class MessageForm extends ElementView {
 
     /**
      * Insert a particular string value into the textarea of this chat box.
-     * @param {string} value - The value to be inserted.
+     * @param { string } value - The value to be inserted.
      * @param {(boolean|string)} [replace] - Whether an existing value
      *  should be replaced. If set to `true`, the entire textarea will
      *  be replaced with the new value. If set to a string, then only
      *  that string will be replaced *if* a position is also specified.
-     * @param {integer} [position] - The end index of the string to be
+     * @param { number } [position] - The end index of the string to be
      *  replaced with the new value.
      */
     insertIntoTextArea (value, replace = false, correcting = false, position) {

+ 3 - 3
src/plugins/dragresize/utils.js

@@ -68,9 +68,9 @@ export function onStartDiagonalResize (ev) {
  * Applies some resistance to `value` around the `default_value`.
  * If value is close enough to `default_value`, then it is returned, otherwise
  * `value` is returned.
- * @param { Integer } value
- * @param { Integer } default_value
- * @returns { Integer }
+ * @param { number } value
+ * @param { number } default_value
+ * @returns { number }
  */
 export function applyDragResistance (value, default_value) {
     if (value === undefined) {

+ 1 - 1
src/plugins/muc-views/modals/muc-list.js

@@ -15,7 +15,7 @@ const u = converse.env.utils;
 /* Insert groupchat info (based on returned #disco IQ stanza)
  * @function insertRoomInfo
  * @param { HTMLElement } el - The HTML DOM element that contains the info.
- * @param { XMLElement } stanza - The IQ stanza containing the groupchat info.
+ * @param { Element } stanza - The IQ stanza containing the groupchat info.
  */
 function insertRoomInfo (el, stanza) {
     // All MUC features found here: https://xmpp.org/registrar/disco-features.html

+ 1 - 1
src/plugins/muc-views/utils.js

@@ -25,9 +25,9 @@ const COMMAND_TO_ROLE = {
 };
 
 /**
- * @async
  * Presents a confirmation modal to the user asking them to accept or decline a
  * MUC invitation.
+ * @async
  */
 export function confirmDirectMUCInvitation ({ contact, jid, reason }) {
     if (!reason) {

+ 1 - 1
src/plugins/omemo/utils.js

@@ -256,7 +256,7 @@ export function handleEncryptedFiles (richtext) {
  * Hook handler for { @link parseMessage } and { @link parseMUCMessage }, which
  * parses the passed in `message` stanza for OMEMO attributes and then sets
  * them on the attrs object.
- * @param { XMLElement } stanza - The message stanza
+ * @param { Element } stanza - The message stanza
  * @param { (MUCMessageAttributes|MessageAttributes) } attrs
  * @returns (MUCMessageAttributes|MessageAttributes)
  */

+ 6 - 6
src/plugins/register/panel.js

@@ -126,7 +126,7 @@ class RegisterPanel extends CustomElement {
     /**
      * Handler for {@link _converse.RegisterPanel#getRegistrationFields}
      * @method _converse.RegisterPanel#onRegistrationFields
-     * @param { XMLElement } stanza - The query stanza.
+     * @param { Element } stanza - The query stanza.
      */
     onRegistrationFields (stanza) {
         if (stanza.getAttribute("type") === "error") {
@@ -207,7 +207,7 @@ class RegisterPanel extends CustomElement {
      * Callback function called by Strophe whenever the connection status changes.
      * Passed to Strophe specifically during a registration attempt.
      * @method _converse.RegisterPanel#onConnectStatusChanged
-     * @param { integer } status_code - The Strophe.Status status code
+     * @param { number } status_code - The Strophe.Status status code
      */
     onConnectStatusChanged(status_code) {
         log.debug('converse-register: onConnectStatusChanged');
@@ -286,7 +286,7 @@ class RegisterPanel extends CustomElement {
      * Renders the registration form based on the XForm fields
      * received from the XMPP server.
      * @method _converse.RegisterPanel#renderRegistrationForm
-     * @param { XMLElement } stanza - The IQ stanza received from the XMPP server.
+     * @param { Element } stanza - The IQ stanza received from the XMPP server.
      */
     renderRegistrationForm (stanza) {
         this.form_fields = this.getFormFields(stanza);
@@ -297,7 +297,7 @@ class RegisterPanel extends CustomElement {
      * Report back to the user any error messages received from the
      * XMPP server after attempted registration.
      * @method _converse.RegisterPanel#reportErrors
-     * @param { XMLElement } stanza - The IQ stanza received from the XMPP server
+     * @param { Element } stanza - The IQ stanza received from the XMPP server
      */
     reportErrors (stanza) {
         const errors = Array.from(stanza.querySelectorAll('error'));
@@ -355,7 +355,7 @@ class RegisterPanel extends CustomElement {
     /**
      * Stores the values that will be sent to the XMPP server during attempted registration.
      * @method _converse.RegisterPanel#setFields
-     * @param { XMLElement } stanza - the IQ stanza that will be sent to the XMPP server.
+     * @param { Element } stanza - the IQ stanza that will be sent to the XMPP server.
      */
     setFields (stanza) {
         const query = stanza.querySelector('query');
@@ -403,7 +403,7 @@ class RegisterPanel extends CustomElement {
      * is received from the XMPP server, after attempting to
      * register a new user.
      * @method _converse.RegisterPanel#reportErrors
-     * @param { XMLElement } stanza - The IQ stanza.
+     * @param { Element } stanza - The IQ stanza.
      */
     _onRegisterIQ (stanza) {
         if (stanza.getAttribute("type") === "error") {

+ 7 - 2
src/shared/components/message-versions.js

@@ -1,7 +1,7 @@
 import { CustomElement } from './element.js';
 import { api, converse } from '@converse/headless/core';
 import { html } from 'lit';
-import { __ } from 'i18n';
+import { __ } from 'i18n/index.js';
 import './styles/message-versions.scss';
 
 const { dayjs } = converse.env;
@@ -13,10 +13,15 @@ export class MessageVersions extends CustomElement {
 
     static get properties () {
         return {
-            'model': { type: Object }
+            model: { type: Object }
         }
     }
 
+    constructor () {
+        super();
+        this.model = null;
+    }
+
     render () {
         const older_versions = this.model.get('older_versions');
         const keys = Object.keys(older_versions);

+ 36 - 14
src/shared/registry.js

@@ -2,20 +2,42 @@ import { api } from "@converse/headless/core";
 
 const registry = {};
 
-function define (name, constructor) {
-    this.registry[name] = constructor;
-}
-
-function register () {
-    Object.keys(registry).forEach(name => {
-        if (!customElements.get(name)) {
-            customElements.define(name, registry[name])
-        }
-    });
-}
-
+/**
+ * The "elements" namespace groups methods relevant to registering custom
+ * HTML elements.
+ * @namespace api.elements
+ * @memberOf api
+ */
 api.elements = {
     registry,
-    define,
-    register
+
+    /**
+     * Defines a new custom HTML element.
+     *
+     * By using this API instead of `customElements.define` from the DOM,
+     * we can allow custom elements to be overwritten.
+     *
+     * Once `converse.initialize()` is called, `api.elements.register()`
+     * will get called and all custom elements will be registered to the DOM,
+     * from which point onward they cannot be overwritten.
+     *
+     * @method api.elements.define
+     * @param { string } name
+     * @param { object } constructor
+     */
+    define (name, constructor) {
+        this.registry[name] = constructor;
+    },
+
+    /**
+     * Registers all previously defined custom HTML elements
+     * @method api.elements.register
+     */
+    register () {
+        Object.keys(registry).forEach(name => {
+            if (!customElements.get(name)) {
+                customElements.define(name, registry[name])
+            }
+        });
+    }
 }

+ 5 - 5
src/shared/rich-text.js

@@ -55,7 +55,7 @@ export class RichText extends String {
     /**
      * Create a new {@link RichText} instance.
      * @param { String } text - The text to be annotated
-     * @param { Integer } offset - The offset of this particular piece of text
+     * @param { number } offset - The offset of this particular piece of text
      *  from the start of the original message text. This is necessary because
      *  RichText instances can be nested when templates call directives
      *  which create new RichText instances (as happens with XEP-393 styling directives).
@@ -118,7 +118,7 @@ export class RichText extends String {
     /**
      * Look for `http` URIs and return templates that render them as URL links
      * @param { String } text
-     * @param { Integer } local_offset - The index of the passed in text relative to
+     * @param { number } local_offset - The index of the passed in text relative to
      *  the start of this RichText instance (which is not necessarily the same as the
      *  offset from the start of the original message stanza's body text).
      */
@@ -155,7 +155,7 @@ export class RichText extends String {
     /**
      * Look for `geo` URIs and return templates that render them as URL links
      * @param { String } text
-     * @param { Integer } offset - The index of the passed in text relative to
+     * @param { number } offset - The index of the passed in text relative to
      *  the start of the message body text.
      */
     addMapURLs (text, offset) {
@@ -173,7 +173,7 @@ export class RichText extends String {
     /**
      * Look for emojis (shortnames or unicode) and add templates for rendering them.
      * @param { String } text
-     * @param { Integer } offset - The index of the passed in text relative to
+     * @param { number } offset - The index of the passed in text relative to
      *  the start of the message body text.
      */
     addEmojis (text, offset) {
@@ -187,7 +187,7 @@ export class RichText extends String {
      * Look for mentions included as XEP-0372 references and add templates for
      * rendering them.
      * @param { String } text
-     * @param { Integer } local_offset - The index of the passed in text relative to
+     * @param { number } local_offset - The index of the passed in text relative to
      *  the start of this RichText instance (which is not necessarily the same as the
      *  offset from the start of the original message stanza's body text).
      */

+ 17 - 17
src/utils/html.js

@@ -78,8 +78,8 @@ const serializer = new XMLSerializer();
 
 /**
  * Given two XML or HTML elements, determine if they're equal
- * @param { XMLElement | HTMLElement } actual
- * @param { XMLElement | HTMLElement } expected
+ * @param { Element } actual
+ * @param { Element } expected
  * @returns { Boolean }
  */
 function isEqualNode (actual, expected) {
@@ -176,7 +176,7 @@ export function getFileName (url) {
  * (such as a video, image or audio file).
  * @method u#getOOBURLMarkup
  * @param { String } url
- * @returns { String }
+ * @returns { TemplateResult }
  */
 export function getOOBURLMarkup (url) {
     const uri = getURI(url);
@@ -198,8 +198,8 @@ export function getOOBURLMarkup (url) {
  * Return the height of the passed in DOM element,
  * based on the heights of its children.
  * @method u#calculateElementHeight
- * @param {HTMLElement} el
- * @returns {integer}
+ * @param { HTMLElement } el
+ * @returns {number}
  */
 u.calculateElementHeight = function (el) {
     return Array.from(el.children).reduce((result, child) => result + child.offsetHeight, 0);
@@ -248,8 +248,8 @@ u.toggleClass = function (className, el) {
 /**
  * Add a class to an element.
  * @method u#addClass
- * @param {string} className
- * @param {Element} el
+ * @param { string } className
+ * @param { Element } el
  */
 u.addClass = function (className, el) {
     el instanceof Element && el.classList.add(className);
@@ -259,8 +259,8 @@ u.addClass = function (className, el) {
 /**
  * Remove a class from an element.
  * @method u#removeClass
- * @param {string} className
- * @param {Element} el
+ * @param { string } className
+ * @param { Element } el
  */
 u.removeClass = function (className, el) {
     el instanceof Element && el.classList.remove(className);
@@ -386,7 +386,7 @@ export function slideOut (el, duration = 200) {
         const marker = el.getAttribute('data-slider-marker');
         if (marker) {
             el.removeAttribute('data-slider-marker');
-            window.cancelAnimationFrame(marker);
+            cancelAnimationFrame(marker);
         }
         const end_height = u.calculateElementHeight(el);
         if (window.converse_disable_effects) {
@@ -408,7 +408,7 @@ export function slideOut (el, duration = 200) {
             height += end_height / steps;
             if (height < end_height) {
                 el.style.height = height + 'px';
-                el.setAttribute('data-slider-marker', window.requestAnimationFrame(draw));
+                el.setAttribute('data-slider-marker', requestAnimationFrame(draw).toString());
             } else {
                 // We recalculate the height to work around an apparent
                 // browser bug where browsers don't know the correct
@@ -424,7 +424,7 @@ export function slideOut (el, duration = 200) {
         el.style.overflow = 'hidden';
         el.classList.remove('hidden');
         el.classList.remove('collapsed');
-        el.setAttribute('data-slider-marker', window.requestAnimationFrame(draw));
+        el.setAttribute('data-slider-marker', requestAnimationFrame(draw).toString());
     });
 }
 
@@ -451,7 +451,7 @@ export function slideIn (el, duration = 200) {
         const marker = el.getAttribute('data-slider-marker');
         if (marker) {
             el.removeAttribute('data-slider-marker');
-            window.cancelAnimationFrame(marker);
+            cancelAnimationFrame(marker);
         }
         const original_height = el.offsetHeight,
             steps = duration / 17; // We assume 17ms per animation which is ~60FPS
@@ -463,7 +463,7 @@ export function slideIn (el, duration = 200) {
             height -= original_height / steps;
             if (height > 0) {
                 el.style.height = height + 'px';
-                el.setAttribute('data-slider-marker', window.requestAnimationFrame(draw));
+                el.setAttribute('data-slider-marker', requestAnimationFrame(draw).toString());
             } else {
                 el.removeAttribute('data-slider-marker');
                 el.classList.add('collapsed');
@@ -471,7 +471,7 @@ export function slideIn (el, duration = 200) {
                 resolve(el);
             }
         }
-        el.setAttribute('data-slider-marker', window.requestAnimationFrame(draw));
+        el.setAttribute('data-slider-marker', requestAnimationFrame(draw).toString());
     });
 }
 
@@ -520,8 +520,8 @@ u.fadeIn = function (el, callback) {
  * Takes an XML field in XMPP XForm (XEP-004: Data Forms) format returns a
  * [TemplateResult](https://lit.polymer-project.org/api/classes/_lit_html_.templateresult.html).
  * @method u#xForm2TemplateResult
- * @param { XMLElement } field - the field to convert
- * @param { XMLElement } stanza - the containing stanza
+ * @param { Element } field - the field to convert
+ * @param { Element } stanza - the containing stanza
  * @param { Object } options
  * @returns { TemplateResult }
  */

+ 31 - 0
tsconfig.json

@@ -0,0 +1,31 @@
+{
+  "include": [
+      "src/**/*"
+  ],
+  "exclude": [
+      "src/**/tests/*",
+      "src/headless/dist/",
+      "src/website.js"
+  ],
+  "compilerOptions": {
+    "target": "es2016",
+    "module": "esnext",
+
+    "allowJs": true,
+    "checkJs": true,
+
+    "rootDir": "./src",
+    "outDir": "./dist/types/",
+    "baseUrl": "./src/",
+
+    "esModuleInterop": true,
+    "forceConsistentCasingInFileNames": true,
+
+    "strict": false,
+    "noImplicitAny": false,
+
+    "skipLibCheck": true,
+
+    "moduleResolution": "node"
+  }
+}

Alguns ficheiros não foram mostrados porque muitos ficheiros mudaram neste diff