Add initial TypeScript support and declaration files

This commit is contained in:
JC Brand 2023-02-23 07:03:50 +01:00
parent 05c5cd1046
commit 3530ccc35d
46 changed files with 1450 additions and 284 deletions

View File

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

View File

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

View File

@ -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 dist:: node_modules src/* | dist/website.css dist/website.min.css
npm run headless npm run headless
npm run build npm run build
make types
.PHONY: install .PHONY: install
install:: dist install:: dist
@ -208,6 +209,10 @@ install:: dist
cdn:: node_modules cdn:: node_modules
npm run cdn npm run cdn
.PHONY: types
types:: node_modules
npm run types
######################################################################## ########################################################################
## Tests ## Tests

1189
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -15,6 +15,7 @@
"dist/", "dist/",
"docs/**/*.md", "docs/**/*.md",
"docs/**/*.rst", "docs/**/*.rst",
"sass/**/*.scss",
"src/**/*.html", "src/**/*.html",
"src/**/*.js", "src/**/*.js",
"src/**/*.json", "src/**/*.json",
@ -36,7 +37,9 @@
"nodeps": "webpack --config webpack/webpack.nodeps.js", "nodeps": "webpack --config webpack/webpack.nodeps.js",
"prepare": "npm run lerna && npm run build", "prepare": "npm run lerna && npm run build",
"serve": "webpack serve --config webpack/webpack.serve.js", "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": { "repository": {
"type": "git", "type": "git",
@ -65,9 +68,9 @@
"devDependencies": { "devDependencies": {
"@babel/cli": "^7.17.10", "@babel/cli": "^7.17.10",
"@babel/core": "^7.18.5", "@babel/core": "^7.18.5",
"@babel/eslint-parser": "^7.18.9",
"@babel/preset-env": "^7.18.2", "@babel/preset-env": "^7.18.2",
"@converse/headless": "file:src/headless", "@converse/headless": "file:src/headless",
"@typescript-eslint/eslint-plugin": "^5.48.0",
"autoprefixer": "^10.4.5", "autoprefixer": "^10.4.5",
"babel-loader": "^9.1.0", "babel-loader": "^9.1.0",
"bootstrap.native-loader": "2.0.0", "bootstrap.native-loader": "2.0.0",
@ -98,6 +101,9 @@
"sass": "^1.51.0", "sass": "^1.51.0",
"sass-loader": "^13.1.0", "sass-loader": "^13.1.0",
"style-loader": "^3.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": "^5.72.0",
"webpack-cli": "^4.7.2", "webpack-cli": "^4.7.2",
"webpack-dev-server": "^4.8.1", "webpack-dev-server": "^4.8.1",

View File

@ -410,7 +410,7 @@ export const api = _converse.api = {
/** /**
* Allows you to send XML stanzas. * Allows you to send XML stanzas.
* @method _converse.api.send * @method _converse.api.send
* @param {XMLElement} stanza * @param { Element } stanza
* @return {void} * @return {void}
* @example * @example
* const msg = converse.env.$msg({ * const msg = converse.env.$msg({
@ -443,8 +443,8 @@ export const api = _converse.api = {
/** /**
* Send an IQ stanza * Send an IQ stanza
* @method _converse.api.sendIQ * @method _converse.api.sendIQ
* @param {XMLElement} stanza * @param { Element } stanza
* @param {Integer} [timeout=_converse.STANZA_TIMEOUT] * @param { number } [timeout=_converse.STANZA_TIMEOUT]
* @param { Boolean } [reject=true] - Whether an error IQ should cause the promise * @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. * to be rejected. If `false`, the promise will resolve instead of being rejected.
* @returns {Promise} A promise which resolves (or potentially rejected) once we * @returns {Promise} A promise which resolves (or potentially rejected) once we
@ -500,9 +500,6 @@ _converse.ConnectionFeedback = Model.extend({
}); });
export const converse = window.converse || {};
/** /**
* ### The Public API * ### The Public API
* *
@ -516,7 +513,7 @@ export const converse = window.converse || {};
* @global * @global
* @namespace converse * @namespace converse
*/ */
Object.assign(converse, { export const converse = Object.assign(window.converse || {}, {
CHAT_STATES, CHAT_STATES,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -100,7 +100,7 @@ export async function handleMAMResult (model, result, query, options, should_pag
/** /**
* @typedef { Object } MAMOptions * @typedef { Object } MAMOptions
* A map of MAM related options that may be passed to fetchArchivedMessages * 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" * Defaults to "archived_messages_page_size"
* @param { string } [options.after] - The XEP-0359 stanza ID of a message * @param { string } [options.after] - The XEP-0359 stanza ID of a message
* after which messages should be returned. Implies forward paging. * 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. * 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 { MAMOptions } [options]
* @param { ('forwards'|'backwards'|null)} [should_page=null] - Determines whether * @param { ('forwards'|'backwards'|null)} [should_page=null] - Determines whether
* this function should recursively page through the entire result set if a limited * this function should recursively page through the entire result set if a limited

View File

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

View File

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

View File

@ -85,7 +85,7 @@ export async function openChatRoom (jid, settings) {
* See XEP-0249: Direct MUC invitations. * See XEP-0249: Direct MUC invitations.
* @private * @private
* @method _converse.ChatRoom#onDirectMUCInvitation * @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) { export async function onDirectMUCInvitation (message) {
const x_el = sizzle('x[xmlns="jabber:x:conference"]', message).pop(), const x_el = sizzle('x[xmlns="jabber:x:conference"]', message).pop(),

View File

@ -10,7 +10,7 @@ export default {
* @method api.ping * @method api.ping
* @param { String } [jid] - The JID of the service to 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. * 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; * milliseconds to wait for a response. The default is 10000;
* @returns { Boolean | null } * @returns { Boolean | null }
* Whether the pinged entity responded with a non-error IQ stanza. * Whether the pinged entity responded with a non-error IQ stanza.

View File

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

View File

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

View File

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

View File

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

View File

@ -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 * [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 } [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 { 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 { number } [index=0] - The index of the results page to return.
* @property { Integer } [max] - The maximum number of items to return. * @property { number } [max] - The maximum number of items to return.
*/ */
const RSM_QUERY_PARAMETERS = ['after', 'before', 'index', 'max']; 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. * 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} * The element is constructed based on the {@link module:converse-rsm~RSMQueryParameters}
* that are set on this RSM instance. * that are set on this RSM instance.
* @returns { XMLElement } * @returns { Element }
*/ */
toXML () { toXML () {
const xml = $build('set', {xmlns: Strophe.NS.RSM}); const xml = $build('set', {xmlns: Strophe.NS.RSM});

View File

@ -256,7 +256,7 @@ u.stringToElement = function (s) {
* Checks whether the DOM element matches the given selector. * Checks whether the DOM element matches the given selector.
* @private * @private
* @method u#matchesSelector * @method u#matchesSelector
* @param { DOMElement } el - The DOM element * @param { Element } el - The DOM element
* @param { String } selector - The selector * @param { String } selector - The selector
*/ */
u.matchesSelector = function (el, 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. * Returns a list of children of the DOM element that match the selector.
* @private * @private
* @method u#queryChildren * @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 * @param { String } selector - the selector they should be matched against
*/ */
u.queryChildren = function (el, selector) { u.queryChildren = function (el, selector) {
@ -395,7 +395,7 @@ u.siblingIndex = function (el) {
* Returns the current word being written in the input element * Returns the current word being written in the input element
* @method u#getCurrentWord * @method u#getCurrentWord
* @param { HTMLElement } input - The HTMLElement in which text is being entered * @param { HTMLElement } input - The HTMLElement in which text is being entered
* @param {integer} [index] - An optional rightmost boundary index. If given, the text * @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. * 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. * differentiate between words.

View File

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

View File

@ -53,7 +53,7 @@ export default class MessageForm extends ElementView {
* should be replaced. If set to `true`, the entire textarea will * should be replaced. If set to `true`, the entire textarea will
* be replaced with the new value. If set to a string, then only * be replaced with the new value. If set to a string, then only
* that string will be replaced *if* a position is also specified. * 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. * replaced with the new value.
*/ */
insertIntoTextArea (value, replace = false, correcting = false, position) { insertIntoTextArea (value, replace = false, correcting = false, position) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2,20 +2,42 @@ import { api } from "@converse/headless/core";
const registry = {}; const registry = {};
function define (name, constructor) { /**
this.registry[name] = constructor; * The "elements" namespace groups methods relevant to registering custom
} * HTML elements.
* @namespace api.elements
* @memberOf api
*/
api.elements = {
registry,
function 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 => { Object.keys(registry).forEach(name => {
if (!customElements.get(name)) { if (!customElements.get(name)) {
customElements.define(name, registry[name]) customElements.define(name, registry[name])
} }
}); });
} }
api.elements = {
registry,
define,
register
} }

View File

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

View File

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

31
tsconfig.json Normal file
View File

@ -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"
}
}