Bläddra i källkod

bugfix: dragresize resistance not applied

When you're resizing, there should be some resistance around the default
height/view and it should snap to those defaults when you're within a
threshold. This makes it easier to resize a chat back to its original
dimensions.

This commit fixes that feature again.

It also refactors dragresize to be a mixin function instead of modifying
the prototype.
JC Brand 1 månad sedan
förälder
incheckning
c19ab2bd63

+ 1 - 1
CHANGES.md

@@ -2,6 +2,7 @@
 
 ## 11.0.1 (2025-06-09)
 
+- #2938: Add a service discovery browser
 - #3672: Images not rendering
 - #3676: Flyout box is not positioned correctly on mobile devices in "overlayed" mode
 - #3689: Chat view not accesible for certain widths in "fullscreen" mode
@@ -11,7 +12,6 @@
 - Properly handle OGP metadata that doesn't have an image
 - Fix TypeError which prevents logging out
 - Fix auto zoom in when input message in ios safari
-- Add a service discovery browser to the settings modal
 - Add a modal to view blocked XMPP addresses
 - Check for PubSub `config-node-max` feature before using the `max` value
 

+ 0 - 33
src/headless/types/log.d.ts

@@ -1,33 +0,0 @@
-export namespace LEVELS {
-    let debug: number;
-    let info: number;
-    let warn: number;
-    let error: number;
-    let fatal: number;
-}
-declare namespace _default {
-    /**
-     * The the log-level, which determines how verbose the logging is.
-     * @method log#setLogLevel
-     * @param {keyof LEVELS} level - The loglevel which allows for filtering of log messages
-     */
-    function setLogLevel(level: "debug" | "error" | "info" | "warn" | "fatal"): void;
-    /**
-     * Logs messages to the browser's developer console.
-     * Available loglevels are 0 for 'debug', 1 for 'info', 2 for 'warn',
-     * 3 for 'error' and 4 for 'fatal'.
-     * When using the 'error' or 'warn' loglevels, a full stacktrace will be
-     * logged as well.
-     * @method log#log
-     * @param {string|Element|Error} message - The message to be logged
-     * @param {string} level - The loglevel which allows for filtering of log messages
-     */
-    function log(message: string | Element | Error, level: string, style?: string): void;
-    function debug(message: any, style: any): void;
-    function error(message: any, style: any): void;
-    function info(message: any, style: any): void;
-    function warn(message: any, style: any): void;
-    function fatal(message: any, style: any): void;
-}
-export default _default;
-//# sourceMappingURL=log.d.ts.map

+ 0 - 7
src/headless/types/plugins/chat/types.d.ts

@@ -1,7 +0,0 @@
-export type Reference = {
-    begin: number;
-    end: number;
-    type: string;
-    uri: string;
-};
-//# sourceMappingURL=types.d.ts.map

+ 1 - 1
src/headless/types/shared/constants.d.ts

@@ -1,5 +1,5 @@
 export const BOSH_WAIT: 59;
-export const VERSION_NAME: "v11.0.0";
+export const VERSION_NAME: "v11.0.1";
 export const PRES_SHOW_VALUES: string[];
 export const PRES_TYPE_VALUES: string[];
 export namespace STATUS_WEIGHTS {

+ 4 - 3
src/plugins/chatview/chat.js

@@ -2,15 +2,16 @@ import { _converse, api, constants } from '@converse/headless';
 import 'plugins/chatview/heading.js';
 import 'plugins/chatview/bottom-panel.js';
 import BaseChatView from 'shared/chat/baseview.js';
-import tplChat from './templates/chat.js';
 import { __ } from 'i18n';
+import DragResizable from 'plugins/dragresize/mixin.js';
+import tplChat from './templates/chat.js';
 
 const { ACTIVE } = constants;
 
 /**
  * The view of an open/ongoing chat conversation.
  */
-export default class ChatView extends BaseChatView {
+export default class ChatView extends DragResizable(BaseChatView) {
     length = 200;
 
     async initialize() {
@@ -52,6 +53,6 @@ export default class ChatView extends BaseChatView {
         this.model.clearUnreadMsgCounter();
         this.maybeFocus();
     }
-}
+};
 
 api.elements.define('converse-chat', ChatView);

+ 1 - 1
src/plugins/chatview/index.js

@@ -26,7 +26,7 @@ converse.plugins.add('converse-chatview', {
      *
      * NB: These plugins need to have already been loaded via require.js.
      */
-    dependencies: ['converse-chatboxviews', 'converse-chat', 'converse-disco', 'converse-modal'],
+    dependencies: ['converse-dragresize', 'converse-chatboxviews', 'converse-chat', 'converse-disco', 'converse-modal'],
 
     initialize () {
         /* The initialize function gets called as soon as the plugin is

+ 2 - 1
src/plugins/controlbox/controlbox.js

@@ -1,6 +1,7 @@
 import { _converse, api, constants, u } from '@converse/headless';
 import { CustomElement } from 'shared/components/element.js';
 import { MOBILE_CUTOFF } from 'shared/constants.js';
+import DragResizable from 'plugins/dragresize/mixin.js';
 import tplControlbox from './templates/controlbox.js';
 import './navbar.js';
 
@@ -13,7 +14,7 @@ const { LOGOUT } = constants;
  * In `overlayed` `view_mode` it's a box like the chat boxes, in `fullscreen`
  * `view_mode` it's a left-aligned sidebar.
  */
-class ControlBoxView extends CustomElement {
+class ControlBoxView extends DragResizable(CustomElement) {
     initialize() {
         this.setModel();
         const { chatboxviews } = _converse.state;

+ 0 - 1
src/plugins/disco-views/disco-browser.js

@@ -37,7 +37,6 @@ class DiscoBrowser extends CustomElement {
      */
     queryEntity(ev) {
         ev.preventDefault();
-        debugger;
         const form = /** @type {HTMLFormElement} */ (ev.target);
         const data = new FormData(form);
         this._entity_jids = [/** @type {string} */ (data.get('entity_jid')).trim()];

+ 2 - 4
src/plugins/dragresize/components/dragresize.js

@@ -1,11 +1,9 @@
 import { api } from '@converse/headless';
 import { CustomElement } from 'shared/components/element.js';
-import tplDragresize from "../templates/dragresize.js";
-
+import tplDragresize from '../templates/dragresize.js';
 
 class ConverseDragResize extends CustomElement {
-
-    render () {
+    render() {
         return tplDragresize();
     }
 }

+ 0 - 24
src/plugins/dragresize/index.js

@@ -1,45 +1,21 @@
 import './components/dragresize.js';
 import {
     shouldDestroyOnClose,
-    initializeDragResize,
     dragresizeOverIframeHandler,
     registerGlobalEventHandlers,
     unregisterGlobalEventHandlers,
 } from './utils.js';
-import DragResizableMixin from './mixin.js';
 import { _converse, api, converse } from '@converse/headless';
 
 converse.plugins.add('converse-dragresize', {
-    /* Plugin dependencies are other plugins which might be
-     * overridden or relied upon, and therefore need to be loaded before
-     * this plugin.
-     */
-    dependencies: ['converse-chatview', 'converse-headlines-view', 'converse-muc-views'],
-
-    enabled() {
-        return api.settings.get('view_mode') == 'overlayed';
-    },
-
     initialize() {
-        /* The initialize function gets called as soon as the plugin is
-         * loaded by converse.js's plugin machinery.
-         */
         api.settings.extend({
             allow_dragresize: true,
             dragresize_top_margin: 0,
         });
 
-        Object.assign(_converse.exports.ChatView?.prototype ?? {}, DragResizableMixin);
-        Object.assign(_converse.exports.MUCView?.prototype ?? {}, DragResizableMixin);
-        Object.assign(_converse.exports.HeadlinesFeedView?.prototype ?? {}, DragResizableMixin);
-        Object.assign(_converse.exports.ControlBoxView?.prototype ?? {}, DragResizableMixin);
-
-        api.listen.on('headlinesFeedInitialized', initializeDragResize);
-        api.listen.on('chatBoxInitialized', initializeDragResize);
-        api.listen.on('chatRoomInitialized', initializeDragResize);
         api.listen.on('registeredGlobalEventHandlers', registerGlobalEventHandlers);
         api.listen.on('unregisteredGlobalEventHandlers', unregisterGlobalEventHandlers);
-        api.listen.on('beforeShowingChatView', (view) => view.initDragResize().setDimensions());
         api.listen.on('startDiagonalResize', dragresizeOverIframeHandler);
         api.listen.on('startHorizontalResize', dragresizeOverIframeHandler);
         api.listen.on('startVerticalResize', dragresizeOverIframeHandler);

+ 135 - 105
src/plugins/dragresize/mixin.js

@@ -1,127 +1,157 @@
-import debounce from 'lodash-es/debounce';
-import { api } from '@converse/headless';
 import log from '@converse/log';
+import { api, u } from '@converse/headless';
 import { applyDragResistance, getResizingDirection } from './utils.js';
 
-const DragResizableMixin = {
-    initDragResize() {
-        const debouncedSetDimensions = debounce(() => this.setDimensions());
-        window.addEventListener('resize', debouncedSetDimensions);
-        this.listenTo(this.model, 'destroy', () => window.removeEventListener('resize', debouncedSetDimensions));
+/**
+ * @template {import('shared/components/types').CustomElementExtender} T
+ * @param {T} BaseCustomElement
+ */
+export default function DragResizable(BaseCustomElement) {
+    return class DragResizableElement extends BaseCustomElement {
+        /**
+         * @param {any[]} args
+         */
+        constructor(...args) {
+            super(args);
+            this.model = null;
+            api.settings.listen.on('change:view_mode', () => this.initDragResize());
+        }
 
-        // Determine and store the default box size.
-        // We need this information for the drag-resizing feature.
-        const flyout = this.querySelector('.box-flyout');
-        const style = window.getComputedStyle(flyout);
+        /**
+         * Called when the element's properties change.
+         * @param {import('lit').PropertyValues} changed
+         */
+        updated(changed) {
+            super.updated(changed);
+            if (changed.has('model') && this.model) {
+                this.initDragResize();
+            }
+        }
 
-        if (this.model.get('height') === undefined) {
-            const height = parseInt(style.height.replace(/px$/, ''), 10);
-            const width = parseInt(style.width.replace(/px$/, ''), 10);
-            this.model.set('height', height);
-            this.model.set('default_height', height);
-            this.model.set('width', width);
-            this.model.set('default_width', width);
+        initDragResize() {
+            if (api.settings.get('view_mode') == 'overlayed') {
+                this.setupDragResize();
+            }
         }
-        const min_width = style['min-width'];
-        const min_height = style['min-height'];
-        this.model.set('min_width', min_width.endsWith('px') ? Number(min_width.replace(/px$/, '')) : 0);
-        this.model.set('min_height', min_height.endsWith('px') ? Number(min_height.replace(/px$/, '')) : 0);
-        // Initialize last known mouse position
-        this.prev_pageY = 0;
-        this.prev_pageX = 0;
-        if (api.connection.get()?.connected) {
+
+        setupDragResize() {
+            const debouncedSetDimensions = u.debounce(() => this.setDimensions(), 250);
+            window.addEventListener('resize', debouncedSetDimensions);
+            this.listenTo(this.model, 'destroy', () => window.removeEventListener('resize', debouncedSetDimensions));
+
+            const flyout = /** @type {HTMLElement} */ (this.querySelector('.box-flyout'));
+            this.model.set(this.getDefaultDimensions());
+
+            const style = window.getComputedStyle(flyout);
+            const min_width = style['min-width'];
+            const min_height = style['min-height'];
+            this.model.set('min_width', min_width.endsWith('px') ? Number(min_width.replace(/px$/, '')) : 0);
+            this.model.set('min_height', min_height.endsWith('px') ? Number(min_height.replace(/px$/, '')) : 0);
+
+            // Initialize last known mouse position
+            this.prev_pageY = 0;
+            this.prev_pageX = 0;
             this.height = this.model.get('height');
             this.width = this.model.get('width');
+            return this;
         }
-        return this;
-    },
-
-    /**
-     * @param {MouseEvent} ev
-     */
-    resizeChatBox(ev) {
-        let diff;
-        const direction = getResizingDirection();
-        if (direction.indexOf('top') === 0) {
-            const margin = api.settings.get('dragresize_top_margin') ?? 0;
-            const max_height = window.innerHeight - margin;
-            diff = ev.pageY - this.prev_pageY;
-
-            if (diff) {
-                const new_height = this.height - diff;
-                log.debug('------------');
-                log.debug(`window.innerHeight: ${window.innerHeight}`);
-                log.debug(`max_height: ${max_height}`);
-                log.debug(`new_height: ${new_height}`);
-                log.debug(`diff: ${diff}`);
 
-                this.height =
-                    this.height - diff > (this.model.get('min_height') || 0)
-                        ? (new_height <= max_height ? new_height : max_height)
-                        : this.model.get('min_height');
-                this.prev_pageY = ev.pageY;
-                this.setChatBoxHeight(this.height);
+        /**
+         * Returns the default height and width of a chat, i.e. what it
+         * would have been if it wasn't resized.
+         * @returns {{ default_height: number, default_width: number }}
+         */
+        getDefaultDimensions() {
+            const flyout = /** @type {HTMLElement} */ (this.querySelector('.box-flyout'));
+            if (!this.model.get('height') && !this.model.get('width')) {
+                const style = window.getComputedStyle(flyout);
+                return {
+                    default_height: parseInt(style.height.replace(/px$/, ''), 10),
+                    default_width: parseInt(style.width.replace(/px$/, ''), 10),
+                };
+            } else {
+                const style = flyout.getAttribute('style');
+                flyout.removeAttribute('style');
+                const dimensions = {
+                    default_height: flyout.offsetHeight,
+                    default_width: flyout.offsetWidth,
+                };
+                flyout.setAttribute('style', style);
+                return dimensions;
             }
         }
-        if (direction.includes('left')) {
-            diff = this.prev_pageX - ev.pageX;
-            if (diff) {
-                this.width =
-                    this.width + diff > (this.model.get('min_width') || 0)
-                        ? this.width + diff
-                        : this.model.get('min_width');
-                this.prev_pageX = ev.pageX;
-                this.setChatBoxWidth(this.width);
+
+        setDimensions() {
+            if (api.settings.get('view_mode') === 'overlayed') {
+                this.setChatBoxWidth(this.model.get('width'));
+                this.setChatBoxHeight(this.model.get('height'));
             }
         }
-    },
 
-    setDimensions() {
-        // Make sure the chat box has the right height and width.
-        this.adjustToViewport();
-        this.setChatBoxWidth(this.model.get('width'));
-        if (api.settings.get('view_mode') === 'overlayed') {
-            this.setChatBoxHeight(this.model.get('height'));
-        }
-    },
+        /**
+         * @param {MouseEvent} ev
+         */
+        resizeChatBox(ev) {
+            let diff;
+            const direction = getResizingDirection();
+            if (direction.indexOf('top') === 0) {
+                const margin = api.settings.get('dragresize_top_margin') ?? 0;
+                const max_height = window.innerHeight - margin;
+                diff = ev.pageY - this.prev_pageY;
 
-    /**
-     * @param {number} height
-     */
-    setChatBoxHeight(height) {
-        const flyout_el = this.querySelector('.box-flyout');
-        if (flyout_el !== null) {
-            flyout_el.style.height = height ? applyDragResistance(height, this.model.get('default_height')) + 'px' : '';
-        }
-    },
+                if (diff) {
+                    const new_height = this.height - diff;
+                    log.debug('------------');
+                    log.debug(`window.innerHeight: ${window.innerHeight}`);
+                    log.debug(`max_height: ${max_height}`);
+                    log.debug(`new_height: ${new_height}`);
+                    log.debug(`diff: ${diff}`);
 
-    /**
-     * @param {number} width
-     */
-    setChatBoxWidth(width) {
-        const style_width = width ? applyDragResistance(width, this.model.get('default_width')) + 'px' : '';
-        this.style.width = style_width;
-        const flyout_el = this.querySelector('.box-flyout');
-        if (flyout_el !== null) {
-            flyout_el.style.width = style_width;
+                    this.height =
+                        this.height - diff > (this.model.get('min_height') || 0)
+                            ? new_height <= max_height
+                                ? new_height
+                                : max_height
+                            : this.model.get('min_height');
+                    this.prev_pageY = ev.pageY;
+                    this.setChatBoxHeight(this.height);
+                }
+            }
+            if (direction.includes('left')) {
+                diff = this.prev_pageX - ev.pageX;
+                if (diff) {
+                    this.width =
+                        this.width + diff > (this.model.get('min_width') || 0)
+                            ? this.width + diff
+                            : this.model.get('min_width');
+                    this.prev_pageX = ev.pageX;
+                    this.setChatBoxWidth(this.width);
+                }
+            }
         }
-    },
 
-    adjustToViewport() {
-        /* Event handler called when viewport gets resized. We remove
-         * custom width/height from chat boxes.
+        /**
+         * @param {number} height
          */
-        const viewport_width = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
-        const viewport_height = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
-        if (viewport_width <= 480) {
-            this.model.set('height', undefined);
-            this.model.set('width', undefined);
-        } else if (viewport_width <= this.model.get('width')) {
-            this.model.set('width', undefined);
-        } else if (viewport_height <= this.model.get('height')) {
-            this.model.set('height', undefined);
+        setChatBoxHeight(height) {
+            const flyout_el = /** @type {HTMLElement} */ (this.querySelector('.box-flyout'));
+            if (flyout_el !== null) {
+                flyout_el.style.height = height
+                    ? applyDragResistance(height, this.model.get('default_height')) + 'px'
+                    : '';
+            }
         }
-    },
-};
 
-export default DragResizableMixin;
+        /**
+         * @param {number} width
+         */
+        setChatBoxWidth(width) {
+            const style_width = width ? applyDragResistance(width, this.model.get('default_width')) + 'px' : '';
+            this.style.width = style_width;
+            const flyout_el = /** @type {HTMLElement} */ (this.querySelector('.box-flyout'));
+            if (flyout_el !== null) {
+                flyout_el.style.width = style_width;
+            }
+        }
+    };
+}

+ 8 - 19
src/plugins/dragresize/utils.js

@@ -39,18 +39,6 @@ export function dragresizeOverIframeHandler(e) {
     }
 }
 
-/**
- * @param {import('@converse/headless/types/shared/chatbox').default} model
- */
-export function initializeDragResize(model) {
-    const height = model.get('height');
-    const width = model.get('width');
-    u.safeSave(model, {
-        'height': applyDragResistance(height, model.get('default_height')),
-        'width': applyDragResistance(width, model.get('default_width')),
-    });
-}
-
 /**
  * @typedef {Object} ResizingData
  * @property {HTMLElement} chatbox
@@ -175,14 +163,15 @@ export function onMouseUp(ev) {
         return true;
     }
     ev.preventDefault();
-    const height = applyDragResistance(resizing.chatbox.height, resizing.chatbox.model.get('default_height'));
-    const width = applyDragResistance(resizing.chatbox.width, resizing.chatbox.model.get('default_width'));
-    if (api.connection.connected()) {
-        resizing.chatbox.model.save({ height });
-        resizing.chatbox.model.save({ width });
+    const default_width = resizing.chatbox.model.get('default_width');
+    const default_height = resizing.chatbox.model.get('default_height');
+    const height = applyDragResistance(resizing.chatbox.height, default_height);
+    const width = applyDragResistance(resizing.chatbox.width, default_width);
+
+    if (height !== default_height || width !== default_width) {
+        u.safeSave(resizing.chatbox.model, { height, width });
     } else {
-        resizing.chatbox.model.set({ height });
-        resizing.chatbox.model.set({ width });
+        u.safeSave(resizing.chatbox.model, { height: undefined, width: undefined });
     }
     delete resizing.chatbox;
     delete resizing.direction;

+ 1 - 1
src/plugins/headlines-view/index.js

@@ -23,7 +23,7 @@ converse.plugins.add('converse-headlines-view', {
      *
      * NB: These plugins need to have already been loaded by the bundler
      */
-    dependencies: ['converse-headlines', 'converse-chatview'],
+    dependencies: ['converse-headlines', 'converse-dragresize', 'converse-chatview'],
 
     initialize () {
         const exports =  {

+ 3 - 2
src/plugins/headlines-view/view.js

@@ -1,8 +1,9 @@
-import BaseChatView from 'shared/chat/baseview.js';
 import { _converse, api } from '@converse/headless';
+import BaseChatView from 'shared/chat/baseview.js';
+import DragResizable from 'plugins/dragresize/mixin.js';
 import tplHeadlines from './templates/headlines.js';
 
-class HeadlinesFeedView extends BaseChatView {
+class HeadlinesFeedView extends DragResizable(BaseChatView) {
     async initialize() {
         const { chatboxviews, chatboxes } = _converse.state;
         chatboxviews.add(this.jid, this);

+ 12 - 0
src/plugins/muc-views/chatarea.js

@@ -34,6 +34,18 @@ export default class MUCChatArea extends CustomElement {
         return this.model ? tplMUCChatarea(this) : '';
     }
 
+    /**
+     * Called when the element's properties change.
+     * @param {import('lit').PropertyValues} changed
+     */
+    updated(changed) {
+        super.updated(changed);
+        if (changed.has('jid') && this.model && this.jid !== this.model.get('jid')) {
+            this.stopListening();
+            this.initialize();
+        }
+    }
+
     /**
      * @param {MediaQueryListEvent} [event]
      */

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

@@ -32,7 +32,7 @@ converse.plugins.add('converse-muc-views', {
      * If the setting "strict_plugin_dependencies" is set to true,
      * an error will be raised if the plugin is not found.
      */
-    dependencies: ['converse-modal', 'converse-controlbox', 'converse-chatview'],
+    dependencies: ['converse-modal', 'converse-dragresize', 'converse-controlbox', 'converse-chatview'],
 
     initialize () {
         const { _converse } = this;

+ 9 - 8
src/plugins/muc-views/muc.js

@@ -1,21 +1,22 @@
 import { _converse, api, converse } from '@converse/headless';
 import BaseChatView from 'shared/chat/baseview.js';
+import DragResizable from 'plugins/dragresize/mixin.js';
 import tplMuc from './templates/muc.js';
 
+export default class MUCView extends DragResizable(BaseChatView) {
+    length = 300;
+    is_chatroom = true;
 
-export default class MUCView extends BaseChatView {
-    length = 300
-    is_chatroom = true
-
-    async initialize () {
+    async initialize() {
         this.model = await api.rooms.get(this.jid);
         _converse.state.chatboxviews.add(this.jid, this);
+
         this.setAttribute('id', this.model.get('box_id'));
 
         this.listenTo(this.model.session, 'change:connection_status', this.onConnectionStatusChanged);
         this.listenTo(this.model.session, 'change:view', () => this.requestUpdate());
 
-        document.addEventListener('visibilitychange',  () => this.onWindowStateChanged());
+        document.addEventListener('visibilitychange', () => this.onWindowStateChanged());
 
         this.onConnectionStatusChanged();
         this.model.maybeShow();
@@ -28,11 +29,11 @@ export default class MUCView extends BaseChatView {
         api.trigger('chatRoomViewInitialized', this);
     }
 
-    render () {
+    render() {
         return tplMuc(this);
     }
 
-    onConnectionStatusChanged () {
+    onConnectionStatusChanged() {
         const conn_status = this.model.session.get('connection_status');
         if (conn_status === converse.ROOMSTATUS.CONNECTING) {
             this.model.session.save({

+ 2 - 3
src/plugins/muc-views/tests/component.js

@@ -37,13 +37,12 @@ describe("The <converse-muc> component", function () {
     }));
 
     it("will update correctly when the jid property changes",
-            mock.initConverse([], {'auto_insert': false}, async function (_converse) {
+            mock.initConverse([], { auto_insert: false}, async function (_converse) {
 
         const { api } = _converse;
         const muc_jid = 'lounge@montague.lit';
         const nick = 'romeo';
 
-
         const muc_creation_promise = api.rooms.open(muc_jid, {nick, 'hidden': true}, false);
         await mock.waitForMUCDiscoInfo(_converse, muc_jid, []);
         await mock.receiveOwnMUCPresence(_converse, muc_jid, nick);
@@ -87,7 +86,7 @@ describe("The <converse-muc> component", function () {
         await mock.returnMemberLists(_converse, muc2_jid, [], all_affiliations);
         await model.messages.fetched;
 
-        model2.sendMessage({'body': 'hello from the bar!'});
+        model2.sendMessage({ body: 'hello from the bar!' });
         muc_el.setAttribute('jid', muc2_jid);
 
         await u.waitUntil(() => muc_el.querySelector('converse-chat-message-body').textContent.trim() === 'hello from the bar!');

+ 9 - 5
src/shared/chat/baseview.js

@@ -1,5 +1,5 @@
-import { CustomElement } from '../components/element.js';
 import { _converse, api, constants } from '@converse/headless';
+import { CustomElement } from '../components/element.js';
 import { MOBILE_CUTOFF } from 'shared/constants.js';
 import { onScrolledDown } from './utils.js';
 
@@ -9,6 +9,7 @@ export default class BaseChatView extends CustomElement {
     static get properties() {
         return {
             jid: { type: String },
+            model: { state: true },
         };
     }
 
@@ -31,12 +32,15 @@ export default class BaseChatView extends CustomElement {
         this.viewportMediaQuery.removeEventListener('change', this.renderOnViewportChange);
     }
 
-    updated() {
-        if (this.model && this.jid !== this.model.get('jid')) {
+    /**
+     * Called when the element's properties change.
+     * @param {import('lit').PropertyValues} changed
+     */
+    updated(changed) {
+        super.updated(changed);
+        if (changed.has('jid') && this.model && this.jid !== this.model.get('jid')) {
             this.stopListening();
             _converse.state.chatboxviews.remove(this.model.get('jid'), this);
-            delete this.model;
-            this.requestUpdate();
             this.initialize();
         }
     }

+ 1 - 6
src/shared/chat/chat-content.js

@@ -16,11 +16,6 @@ const WINDOW_SIZE = 100;
  * gets updated as the user scrolls up and down.
  */
 export default class ChatContent extends CustomElement {
-    /**
-     * @typedef {import('../../plugins/chatview/chat.js').default} ChatView
-     * @typedef {import('../../plugins/muc-views/muc.js').default} MUCView
-     * @typedef {import('../../plugins/muc-views/occupant').default} MUCOccupantView
-     */
     constructor() {
         super();
         this.model = null;
@@ -103,7 +98,7 @@ export default class ChatContent extends CustomElement {
     #markScrolled(ev) {
         let scrolled = true;
 
-        const el = /** @type {ChatView|MUCView|MUCOccupantView} */ (ev.target);
+        const el = /** @type {HTMLElement} */ (ev.target);
         const is_at_bottom = Math.floor(el.scrollTop) === 0;
         const is_at_top =
             Math.ceil(el.clientHeight - el.scrollTop) >= el.scrollHeight - Math.ceil(el.scrollHeight / 20);

+ 7 - 1
src/shared/components/types.ts

@@ -1,2 +1,8 @@
+import { CustomElement } from './element.js';
 
-export type ObservableProperty = 'once'|'always'|null;
+export type ObservableProperty = 'once' | 'always' | null;
+
+// Represents the class that will be extended via a mixin.
+type Constructor<T = {}> = new (...args: any[]) => T;
+
+export type CustomElementExtender = Constructor<CustomElement>;

+ 402 - 1
src/types/plugins/chatview/chat.d.ts

@@ -1,7 +1,407 @@
+declare const ChatView_base: {
+    new (...args: any[]): {
+        model: any;
+        updated(changed: import("lit").PropertyValues): void;
+        initDragResize(): void;
+        setupDragResize(): any;
+        prev_pageY: number;
+        prev_pageX: number;
+        height: any;
+        width: any;
+        getDefaultDimensions(): {
+            default_height: number;
+            default_width: number;
+        };
+        setDimensions(): void;
+        resizeChatBox(ev: MouseEvent): void;
+        setChatBoxHeight(height: number): void;
+        setChatBoxWidth(width: number): void;
+        createRenderRoot(): any;
+        initialize(): any;
+        connectedCallback(): any;
+        disconnectedCallback(): void;
+        on(name: string, callback: (event: any, model: import("@converse/skeletor").Model, collection: import("@converse/skeletor").Collection, options? /**
+         * Triggered once the {@link ChatView} has been initialized
+         * @event _converse#chatBoxViewInitialized
+         * @type {ChatView}
+         * @example _converse.api.listen.on('chatBoxViewInitialized', view => { ... });
+         */: Record<string, any>) => any, context: any): any;
+        _events: any;
+        _listeners: {};
+        listenTo(obj: any, name: string, callback?: (event: any, model: import("@converse/skeletor").Model, collection: import("@converse/skeletor").Collection, options?: Record<string, any>) => any): any;
+        _listeningTo: {};
+        _listenId: any;
+        off(name: string, callback: (event: any, model: import("@converse/skeletor").Model, collection: import("@converse/skeletor").Collection, options?: Record<string, any>) => any, context?: any): any;
+        stopListening(obj?: any, name?: string, callback?: (event: any, model: import("@converse/skeletor").Model, collection: import("@converse/skeletor").Collection, options?: Record<string, any>) => any): any;
+        once(name: string, callback: (event: any, model: import("@converse/skeletor").Model, collection: import("@converse/skeletor").Collection, options?: Record<string, any>) => any, context: any): any;
+        listenToOnce(obj: any, name: string, callback?: (event: any, model: import("@converse/skeletor").Model, collection: import("@converse/skeletor").Collection, options?: Record<string, any>) => any): any;
+        trigger(name: string, ...args: any[]): any;
+        readonly renderOptions: import("lit-html").RenderOptions;
+        __childPart: any;
+        update(changedProperties: import("lit").PropertyValues): void;
+        render(): unknown;
+        __instanceProperties?: any;
+        readonly renderRoot: HTMLElement | DocumentFragment;
+        __updatePromise: any;
+        isUpdatePending: boolean;
+        hasUpdated: boolean;
+        __defaultValues?: any;
+        __reflectingProperties?: any;
+        __reflectingProperty: any;
+        __controllers?: any;
+        __initialize: any;
+        addController(controller: import("lit").ReactiveController): void;
+        removeController(controller: import("lit").ReactiveController): void;
+        __saveInstanceProperties: any;
+        enableUpdating(_requestedUpdate: boolean): void;
+        attributeChangedCallback(name: string, _old: string | null, value: string | null): void;
+        __propertyToAttribute: any;
+        requestUpdate(name?: PropertyKey, oldValue?: unknown, options?: import("lit").PropertyDeclaration): void;
+        __enqueueUpdate: any;
+        scheduleUpdate(): void | Promise<unknown>;
+        performUpdate(): void;
+        willUpdate(_changedProperties: import("lit").PropertyValues): void;
+        __markUpdated: any;
+        readonly updateComplete: Promise<boolean>;
+        getUpdateComplete(): Promise<boolean>;
+        shouldUpdate(_changedProperties: import("lit").PropertyValues): boolean;
+        firstUpdated(_changedProperties: import("lit").PropertyValues): void;
+        accessKey: string;
+        readonly accessKeyLabel: string;
+        autocapitalize: string;
+        dir: string;
+        draggable: boolean;
+        hidden: boolean;
+        inert: boolean;
+        innerText: string;
+        lang: string;
+        readonly offsetHeight: number;
+        readonly offsetLeft: number;
+        readonly offsetParent: Element | null;
+        readonly offsetTop: number;
+        readonly offsetWidth: number;
+        outerText: string;
+        popover: string | null;
+        spellcheck: boolean;
+        title: string;
+        translate: boolean;
+        attachInternals(): ElementInternals;
+        click(): void;
+        hidePopover(): void;
+        showPopover(): void;
+        togglePopover(force?: boolean): boolean;
+        addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
+        addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
+        removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
+        removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
+        readonly attributes: NamedNodeMap;
+        readonly classList: DOMTokenList;
+        className: string;
+        readonly clientHeight: number;
+        readonly clientLeft: number;
+        readonly clientTop: number;
+        readonly clientWidth: number;
+        id: string;
+        innerHTML: string;
+        readonly localName: string;
+        readonly namespaceURI: string | null;
+        onfullscreenchange: (this: Element, ev: Event) => any;
+        onfullscreenerror: (this: Element, ev: Event) => any;
+        outerHTML: string;
+        readonly ownerDocument: Document;
+        readonly part: DOMTokenList;
+        readonly prefix: string | null;
+        readonly scrollHeight: number;
+        scrollLeft: number;
+        scrollTop: number;
+        readonly scrollWidth: number;
+        readonly shadowRoot: ShadowRoot | null;
+        slot: string;
+        readonly tagName: string;
+        attachShadow(init: ShadowRootInit): ShadowRoot;
+        checkVisibility(options?: CheckVisibilityOptions): boolean;
+        closest<K extends keyof HTMLElementTagNameMap>(selector: K): HTMLElementTagNameMap[K];
+        closest<K extends keyof SVGElementTagNameMap>(selector: K): SVGElementTagNameMap[K];
+        closest<K extends keyof MathMLElementTagNameMap>(selector: K): MathMLElementTagNameMap[K];
+        closest<E extends Element = Element>(selectors: string): E;
+        computedStyleMap(): StylePropertyMapReadOnly;
+        getAttribute(qualifiedName: string): string | null;
+        getAttributeNS(namespace: string | null, localName: string): string | null;
+        getAttributeNames(): string[];
+        getAttributeNode(qualifiedName: string): Attr | null;
+        getAttributeNodeNS(namespace: string | null, localName: string): Attr | null;
+        getBoundingClientRect(): DOMRect;
+        getClientRects(): DOMRectList;
+        getElementsByClassName(classNames: string): HTMLCollectionOf<Element>;
+        getElementsByTagName<K extends keyof HTMLElementTagNameMap>(qualifiedName: K): HTMLCollectionOf<HTMLElementTagNameMap[K]>;
+        getElementsByTagName<K extends keyof SVGElementTagNameMap>(qualifiedName: K): HTMLCollectionOf<SVGElementTagNameMap[K]>;
+        getElementsByTagName<K extends keyof MathMLElementTagNameMap>(qualifiedName: K): HTMLCollectionOf<MathMLElementTagNameMap[K]>;
+        getElementsByTagName<K extends keyof HTMLElementDeprecatedTagNameMap>(qualifiedName: K): HTMLCollectionOf<HTMLElementDeprecatedTagNameMap[K]>;
+        getElementsByTagName(qualifiedName: string): HTMLCollectionOf<Element>;
+        getElementsByTagNameNS(namespaceURI: "http://www.w3.org/1999/xhtml", localName: string): HTMLCollectionOf<HTMLElement>;
+        getElementsByTagNameNS(namespaceURI: "http://www.w3.org/2000/svg", localName: string): HTMLCollectionOf<SVGElement>;
+        getElementsByTagNameNS(namespaceURI: "http://www.w3.org/1998/Math/MathML", localName: string): HTMLCollectionOf<MathMLElement>;
+        getElementsByTagNameNS(namespace: string | null, localName: string): HTMLCollectionOf<Element>;
+        getHTML(options?: GetHTMLOptions): string;
+        hasAttribute(qualifiedName: string): boolean;
+        hasAttributeNS(namespace: string | null, localName: string): boolean;
+        hasAttributes(): boolean;
+        hasPointerCapture(pointerId: number): boolean;
+        insertAdjacentElement(where: InsertPosition, element: Element): Element | null;
+        insertAdjacentHTML(position: InsertPosition, string: string): void;
+        insertAdjacentText(where: InsertPosition, data: string): void;
+        matches(selectors: string): boolean;
+        releasePointerCapture(pointerId: number): void;
+        removeAttribute(qualifiedName: string): void;
+        removeAttributeNS(namespace: string | null, localName: string): void;
+        removeAttributeNode(attr: Attr): Attr;
+        requestFullscreen(options?: FullscreenOptions): Promise<void>;
+        requestPointerLock(options?: PointerLockOptions): Promise<void>;
+        scroll(options?: ScrollToOptions): void;
+        scroll(x: number, y: number): void;
+        scrollBy(options?: ScrollToOptions): void;
+        scrollBy(x: number, y: number): void;
+        scrollIntoView(arg?: boolean | ScrollIntoViewOptions): void;
+        scrollTo(options?: ScrollToOptions): void;
+        scrollTo(x: number, y: number): void;
+        setAttribute(qualifiedName: string, value: string): void;
+        setAttributeNS(namespace: string | null, qualifiedName: string, value: string): void;
+        setAttributeNode(attr: Attr): Attr | null;
+        setAttributeNodeNS(attr: Attr): Attr | null;
+        setHTMLUnsafe(html: string): void;
+        setPointerCapture(pointerId: number): void;
+        toggleAttribute(qualifiedName: string, force?: boolean): boolean;
+        webkitMatchesSelector(selectors: string): boolean;
+        readonly baseURI: string;
+        readonly childNodes: NodeListOf<ChildNode>;
+        readonly firstChild: ChildNode | null;
+        readonly isConnected: boolean;
+        readonly lastChild: ChildNode | null;
+        readonly nextSibling: ChildNode | null;
+        readonly nodeName: string;
+        readonly nodeType: number;
+        nodeValue: string | null;
+        readonly parentElement: HTMLElement | null;
+        readonly parentNode: ParentNode | null;
+        readonly previousSibling: ChildNode | null;
+        textContent: string | null;
+        appendChild<T extends Node>(node: T): T;
+        cloneNode(deep?: boolean): Node;
+        compareDocumentPosition(other: Node): number;
+        contains(other: Node | null): boolean;
+        getRootNode(options?: GetRootNodeOptions): Node;
+        hasChildNodes(): boolean;
+        insertBefore<T extends Node>(node: T, child: Node | null): T;
+        isDefaultNamespace(namespace: string | null): boolean;
+        isEqualNode(otherNode: Node | null): boolean;
+        isSameNode(otherNode: Node | null): boolean;
+        lookupNamespaceURI(prefix: string | null): string | null;
+        lookupPrefix(namespace: string | null): string | null;
+        normalize(): void;
+        removeChild<T extends Node>(child: T): T;
+        replaceChild<T extends Node>(node: Node, child: T): T;
+        readonly ELEMENT_NODE: 1;
+        readonly ATTRIBUTE_NODE: 2;
+        readonly TEXT_NODE: 3;
+        readonly CDATA_SECTION_NODE: 4;
+        readonly ENTITY_REFERENCE_NODE: 5;
+        readonly ENTITY_NODE: 6;
+        readonly PROCESSING_INSTRUCTION_NODE: 7;
+        readonly COMMENT_NODE: 8;
+        readonly DOCUMENT_NODE: 9;
+        readonly DOCUMENT_TYPE_NODE: 10;
+        readonly DOCUMENT_FRAGMENT_NODE: 11;
+        readonly NOTATION_NODE: 12;
+        readonly DOCUMENT_POSITION_DISCONNECTED: 1;
+        readonly DOCUMENT_POSITION_PRECEDING: 2;
+        readonly DOCUMENT_POSITION_FOLLOWING: 4;
+        readonly DOCUMENT_POSITION_CONTAINS: 8;
+        readonly DOCUMENT_POSITION_CONTAINED_BY: 16;
+        readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: 32;
+        dispatchEvent(event: Event): boolean;
+        ariaAtomic: string | null;
+        ariaAutoComplete: string | null;
+        ariaBrailleLabel: string | null;
+        ariaBrailleRoleDescription: string | null;
+        ariaBusy: string | null;
+        ariaChecked: string | null;
+        ariaColCount: string | null;
+        ariaColIndex: string | null;
+        ariaColSpan: string | null;
+        ariaCurrent: string | null;
+        ariaDescription: string | null;
+        ariaDisabled: string | null;
+        ariaExpanded: string | null;
+        ariaHasPopup: string | null;
+        ariaHidden: string | null;
+        ariaInvalid: string | null;
+        ariaKeyShortcuts: string | null;
+        ariaLabel: string | null;
+        ariaLevel: string | null;
+        ariaLive: string | null;
+        ariaModal: string | null;
+        ariaMultiLine: string | null;
+        ariaMultiSelectable: string | null;
+        ariaOrientation: string | null;
+        ariaPlaceholder: string | null;
+        ariaPosInSet: string | null;
+        ariaPressed: string | null;
+        ariaReadOnly: string | null;
+        ariaRequired: string | null;
+        ariaRoleDescription: string | null;
+        ariaRowCount: string | null;
+        ariaRowIndex: string | null;
+        ariaRowSpan: string | null;
+        ariaSelected: string | null;
+        ariaSetSize: string | null;
+        ariaSort: string | null;
+        ariaValueMax: string | null;
+        ariaValueMin: string | null;
+        ariaValueNow: string | null;
+        ariaValueText: string | null;
+        role: string | null;
+        animate(keyframes: Keyframe[] | PropertyIndexedKeyframes | null, options?: number | KeyframeAnimationOptions): Animation;
+        getAnimations(options?: GetAnimationsOptions): Animation[];
+        after(...nodes: (Node | string)[]): void;
+        before(...nodes: (Node | string)[]): void;
+        remove(): void;
+        replaceWith(...nodes: (Node | string)[]): void;
+        readonly nextElementSibling: Element | null;
+        readonly previousElementSibling: Element | null;
+        readonly childElementCount: number;
+        readonly children: HTMLCollection;
+        readonly firstElementChild: Element | null;
+        readonly lastElementChild: Element | null;
+        append(...nodes: (Node | string)[]): void;
+        prepend(...nodes: (Node | string)[]): void;
+        querySelector<K extends keyof HTMLElementTagNameMap>(selectors: K): HTMLElementTagNameMap[K] | null;
+        querySelector<K extends keyof SVGElementTagNameMap>(selectors: K): SVGElementTagNameMap[K] | null;
+        querySelector<K extends keyof MathMLElementTagNameMap>(selectors: K): MathMLElementTagNameMap[K] | null;
+        querySelector<K extends keyof HTMLElementDeprecatedTagNameMap>(selectors: K): HTMLElementDeprecatedTagNameMap[K] | null;
+        querySelector<E extends Element = Element>(selectors: string): E | null;
+        querySelectorAll<K extends keyof HTMLElementTagNameMap>(selectors: K): NodeListOf<HTMLElementTagNameMap[K]>;
+        querySelectorAll<K extends keyof SVGElementTagNameMap>(selectors: K): NodeListOf<SVGElementTagNameMap[K]>;
+        querySelectorAll<K extends keyof MathMLElementTagNameMap>(selectors: K): NodeListOf<MathMLElementTagNameMap[K]>;
+        querySelectorAll<K extends keyof HTMLElementDeprecatedTagNameMap>(selectors: K): NodeListOf<HTMLElementDeprecatedTagNameMap[K]>;
+        querySelectorAll<E extends Element = Element>(selectors: string): NodeListOf<E>;
+        replaceChildren(...nodes: (Node | string)[]): void;
+        readonly assignedSlot: HTMLSlotElement | null;
+        readonly attributeStyleMap: StylePropertyMap;
+        readonly style: CSSStyleDeclaration;
+        contentEditable: string;
+        enterKeyHint: string;
+        inputMode: string;
+        readonly isContentEditable: boolean;
+        onabort: ((this: GlobalEventHandlers, ev: UIEvent) => any) | null;
+        onanimationcancel: ((this: GlobalEventHandlers, ev: AnimationEvent) => any) | null;
+        onanimationend: ((this: GlobalEventHandlers, ev: AnimationEvent) => any) | null;
+        onanimationiteration: ((this: GlobalEventHandlers, ev: AnimationEvent) => any) | null;
+        onanimationstart: ((this: GlobalEventHandlers, ev: AnimationEvent) => any) | null;
+        onauxclick: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onbeforeinput: ((this: GlobalEventHandlers, ev: InputEvent) => any) | null;
+        onbeforetoggle: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onblur: ((this: GlobalEventHandlers, ev: FocusEvent) => any) | null;
+        oncancel: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        oncanplay: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        oncanplaythrough: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onchange: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onclick: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onclose: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        oncontextlost: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        oncontextmenu: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        oncontextrestored: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        oncopy: ((this: GlobalEventHandlers, ev: ClipboardEvent) => any) | null;
+        oncuechange: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        oncut: ((this: GlobalEventHandlers, ev: ClipboardEvent) => any) | null;
+        ondblclick: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        ondrag: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null;
+        ondragend: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null;
+        ondragenter: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null;
+        ondragleave: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null;
+        ondragover: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null;
+        ondragstart: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null;
+        ondrop: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null;
+        ondurationchange: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onemptied: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onended: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onerror: OnErrorEventHandler;
+        onfocus: ((this: GlobalEventHandlers, ev: FocusEvent) => any) | null;
+        onformdata: ((this: GlobalEventHandlers, ev: FormDataEvent) => any) | null;
+        ongotpointercapture: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        oninput: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        oninvalid: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onkeydown: ((this: GlobalEventHandlers, ev: KeyboardEvent) => any) | null;
+        onkeypress: ((this: GlobalEventHandlers, ev: KeyboardEvent) => any) | null;
+        onkeyup: ((this: GlobalEventHandlers, ev: KeyboardEvent) => any) | null;
+        onload: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onloadeddata: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onloadedmetadata: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onloadstart: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onlostpointercapture: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onmousedown: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onmouseenter: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onmouseleave: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onmousemove: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onmouseout: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onmouseover: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onmouseup: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onpaste: ((this: GlobalEventHandlers, ev: ClipboardEvent) => any) | null;
+        onpause: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onplay: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onplaying: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onpointercancel: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onpointerdown: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onpointerenter: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onpointerleave: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onpointermove: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onpointerout: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onpointerover: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onpointerup: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onprogress: ((this: GlobalEventHandlers, ev: ProgressEvent) => any) | null;
+        onratechange: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onreset: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onresize: ((this: GlobalEventHandlers, ev: UIEvent) => any) | null;
+        onscroll: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onscrollend: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onsecuritypolicyviolation: ((this: GlobalEventHandlers, ev: SecurityPolicyViolationEvent) => any) | null;
+        onseeked: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onseeking: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onselect: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onselectionchange: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onselectstart: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onslotchange: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onstalled: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onsubmit: ((this: GlobalEventHandlers, ev: SubmitEvent) => any) | null;
+        onsuspend: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        ontimeupdate: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        ontoggle: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        ontouchcancel?: ((this: GlobalEventHandlers, ev: TouchEvent) => any) | null | undefined;
+        ontouchend?: ((this: GlobalEventHandlers, ev: TouchEvent) => any) | null | undefined;
+        ontouchmove?: ((this: GlobalEventHandlers, ev: TouchEvent) => any) | null | undefined;
+        ontouchstart?: ((this: GlobalEventHandlers, ev: TouchEvent) => any) | null | undefined;
+        ontransitioncancel: ((this: GlobalEventHandlers, ev: TransitionEvent) => any) | null;
+        ontransitionend: ((this: GlobalEventHandlers, ev: TransitionEvent) => any) | null;
+        ontransitionrun: ((this: GlobalEventHandlers, ev: TransitionEvent) => any) | null;
+        ontransitionstart: ((this: GlobalEventHandlers, ev: TransitionEvent) => any) | null;
+        onvolumechange: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onwaiting: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onwebkitanimationend: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onwebkitanimationiteration: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onwebkitanimationstart: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onwebkittransitionend: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onwheel: ((this: GlobalEventHandlers, ev: WheelEvent) => any) | null;
+        autofocus: boolean;
+        readonly dataset: DOMStringMap;
+        nonce?: string;
+        tabIndex: number;
+        blur(): void;
+        focus(options?: FocusOptions): void;
+    };
+} & typeof BaseChatView;
 /**
  * The view of an open/ongoing chat conversation.
  */
-export default class ChatView extends BaseChatView {
+export default class ChatView extends ChatView_base {
     length: number;
     initialize(): Promise<void>;
     render(): import("lit-html").TemplateResult<1>;
@@ -9,4 +409,5 @@ export default class ChatView extends BaseChatView {
     afterShown(): void;
 }
 import BaseChatView from 'shared/chat/baseview.js';
+export {};
 //# sourceMappingURL=chat.d.ts.map

+ 396 - 2
src/types/plugins/controlbox/controlbox.d.ts

@@ -1,4 +1,399 @@
 export default ControlBoxView;
+declare const ControlBoxView_base: {
+    new (...args: any[]): {
+        model: any;
+        updated(changed: import("lit").PropertyValues): void;
+        initDragResize(): void;
+        setupDragResize(): any;
+        prev_pageY: number;
+        prev_pageX: number;
+        height: any;
+        width: any;
+        getDefaultDimensions(): {
+            default_height: number;
+            default_width: number;
+        };
+        setDimensions(): void;
+        resizeChatBox(ev: MouseEvent): void;
+        setChatBoxHeight(height: number): void;
+        setChatBoxWidth(width: number): void;
+        createRenderRoot(): any;
+        initialize(): any;
+        connectedCallback(): any;
+        disconnectedCallback(): void;
+        on(name: string, callback: (event: any, model: import("@converse/skeletor").Model, collection: import("@converse/skeletor").Collection, options?: Record<string, any>) => any, context: any): any;
+        _events: any;
+        _listeners: {};
+        listenTo(obj: any, name: string, callback?: (event: any, model: import("@converse/skeletor").Model, collection: import("@converse/skeletor").Collection, options?: Record<string, any>) => any): any;
+        _listeningTo: {};
+        _listenId: any;
+        off(name: string, callback: (event: any, model: import("@converse/skeletor").Model, collection: import("@converse/skeletor").Collection, options?: Record<string, any>) => any, context?: any): any;
+        stopListening(obj?: any, name?: string, callback?: (event: any, model: import("@converse/skeletor").Model, collection: import("@converse/skeletor").Collection, options?: Record<string, any>) => any): any;
+        once(name: string, callback: (event: any, model: import("@converse/skeletor").Model, collection: import("@converse/skeletor").Collection, options?: Record<string, any>) => any, context: any): any;
+        listenToOnce(obj: any, name: string, callback?: (event: any, model: import("@converse/skeletor").Model, collection: import("@converse/skeletor").Collection, options?: Record<string, any>) => any): any;
+        trigger(name: string, ...args: any[]): any;
+        readonly renderOptions: import("lit-html").RenderOptions;
+        __childPart: any;
+        update(changedProperties: import("lit").PropertyValues): void;
+        render(): unknown;
+        __instanceProperties?: any;
+        readonly renderRoot: HTMLElement | DocumentFragment;
+        __updatePromise: any;
+        isUpdatePending: boolean;
+        hasUpdated: boolean;
+        __defaultValues?: any;
+        __reflectingProperties?: any;
+        __reflectingProperty: any;
+        __controllers?: any;
+        __initialize: any;
+        addController(controller: import("lit").ReactiveController): void;
+        removeController(controller: import("lit").ReactiveController): void;
+        __saveInstanceProperties: any;
+        enableUpdating(_requestedUpdate: boolean): void;
+        attributeChangedCallback(name: string, _old: string | null, value: string | null): void;
+        __propertyToAttribute: any;
+        requestUpdate(name?: PropertyKey, oldValue?: unknown, options?: import("lit").PropertyDeclaration): void;
+        __enqueueUpdate: any;
+        scheduleUpdate(): void | Promise<unknown>;
+        performUpdate(): void;
+        willUpdate(_changedProperties: import("lit").PropertyValues): void;
+        __markUpdated: any;
+        readonly updateComplete: Promise<boolean>;
+        getUpdateComplete(): Promise<boolean>;
+        shouldUpdate(_changedProperties: import("lit").PropertyValues): boolean;
+        firstUpdated(_changedProperties: import("lit").PropertyValues): void;
+        accessKey: string;
+        readonly accessKeyLabel: string;
+        autocapitalize: string;
+        dir: string;
+        draggable: boolean;
+        hidden: boolean;
+        inert: boolean;
+        innerText: string;
+        lang: string;
+        readonly offsetHeight: number;
+        readonly offsetLeft: number;
+        readonly offsetParent: Element | null;
+        readonly offsetTop: number;
+        readonly offsetWidth: number;
+        outerText: string;
+        popover: string | null;
+        spellcheck: boolean;
+        title: string;
+        translate: boolean;
+        attachInternals(): ElementInternals;
+        click(): void;
+        hidePopover(): void;
+        showPopover(): void;
+        togglePopover(force?: boolean): boolean;
+        addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
+        addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
+        removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
+        removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
+        readonly attributes: NamedNodeMap;
+        readonly classList: DOMTokenList;
+        className: string;
+        readonly clientHeight: number;
+        readonly clientLeft: number;
+        readonly clientTop: number;
+        readonly clientWidth: number;
+        id: string;
+        innerHTML: string;
+        readonly localName: string;
+        readonly namespaceURI: string | null;
+        onfullscreenchange: (this: Element, ev: Event) => any;
+        onfullscreenerror: (this: Element, ev: Event) => any;
+        outerHTML: string;
+        readonly ownerDocument: Document;
+        readonly part: DOMTokenList;
+        readonly prefix: string | null;
+        readonly scrollHeight: number;
+        scrollLeft: number;
+        scrollTop: number;
+        readonly scrollWidth: number;
+        readonly shadowRoot: ShadowRoot | null;
+        slot: string;
+        readonly tagName: string;
+        attachShadow(init: ShadowRootInit): ShadowRoot;
+        checkVisibility(options?: CheckVisibilityOptions): boolean;
+        closest<K extends keyof HTMLElementTagNameMap>(selector: K): HTMLElementTagNameMap[K];
+        closest<K extends keyof SVGElementTagNameMap>(selector: K): SVGElementTagNameMap[K];
+        closest<K extends keyof MathMLElementTagNameMap>(selector: K): MathMLElementTagNameMap[K];
+        closest<E extends Element = Element>(selectors: string): E;
+        computedStyleMap(): StylePropertyMapReadOnly;
+        getAttribute(qualifiedName: string): string | null;
+        getAttributeNS(namespace: string | null, localName: string): string | null;
+        getAttributeNames(): string[];
+        getAttributeNode(qualifiedName: string): Attr | null;
+        getAttributeNodeNS(namespace: string | null, localName: string): Attr | null;
+        getBoundingClientRect(): DOMRect;
+        getClientRects(): DOMRectList;
+        getElementsByClassName(classNames: string): HTMLCollectionOf<Element>;
+        getElementsByTagName<K extends keyof HTMLElementTagNameMap>(qualifiedName: K): HTMLCollectionOf<HTMLElementTagNameMap[K]>;
+        getElementsByTagName<K extends keyof SVGElementTagNameMap>(qualifiedName: K): HTMLCollectionOf<SVGElementTagNameMap[K]>;
+        getElementsByTagName<K extends keyof MathMLElementTagNameMap>(qualifiedName: K): HTMLCollectionOf<MathMLElementTagNameMap[K]>;
+        getElementsByTagName<K extends keyof HTMLElementDeprecatedTagNameMap>(qualifiedName: K): HTMLCollectionOf<HTMLElementDeprecatedTagNameMap[K]>;
+        getElementsByTagName(qualifiedName: string): HTMLCollectionOf<Element>;
+        getElementsByTagNameNS(namespaceURI: "http://www.w3.org/1999/xhtml", localName: string): HTMLCollectionOf<HTMLElement>;
+        getElementsByTagNameNS(namespaceURI: "http://www.w3.org/2000/svg", localName: string): HTMLCollectionOf<SVGElement>;
+        getElementsByTagNameNS(namespaceURI: "http://www.w3.org/1998/Math/MathML", localName: string): HTMLCollectionOf<MathMLElement>;
+        getElementsByTagNameNS(namespace: string | null, localName: string): HTMLCollectionOf<Element>;
+        getHTML(options?: GetHTMLOptions): string;
+        hasAttribute(qualifiedName: string): boolean;
+        hasAttributeNS(namespace: string | null, localName: string): boolean;
+        hasAttributes(): boolean;
+        hasPointerCapture(pointerId: number): boolean;
+        insertAdjacentElement(where: InsertPosition, element: Element): Element | null;
+        insertAdjacentHTML(position: InsertPosition, string: string): void;
+        insertAdjacentText(where: InsertPosition, data: string): void;
+        matches(selectors: string): boolean;
+        releasePointerCapture(pointerId: number): void;
+        removeAttribute(qualifiedName: string): void;
+        removeAttributeNS(namespace: string | null, localName: string): void;
+        removeAttributeNode(attr: Attr): Attr;
+        requestFullscreen(options?: FullscreenOptions): Promise<void>;
+        requestPointerLock(options?: PointerLockOptions): Promise<void>;
+        scroll(options?: ScrollToOptions): void;
+        scroll(x: number, y: number): void;
+        scrollBy(options?: ScrollToOptions): void;
+        scrollBy(x: number, y: number): void;
+        scrollIntoView(arg?: boolean | ScrollIntoViewOptions): void;
+        scrollTo(options?: ScrollToOptions): void;
+        scrollTo(x: number, y: number): void;
+        setAttribute(qualifiedName: string, value: string): void;
+        setAttributeNS(namespace: string | null, qualifiedName: string, value: string): void;
+        setAttributeNode(attr: Attr): Attr | null;
+        setAttributeNodeNS(attr: Attr): Attr | null;
+        setHTMLUnsafe(html: string): void;
+        setPointerCapture(pointerId: number): void;
+        toggleAttribute(qualifiedName: string, force?: boolean): boolean;
+        webkitMatchesSelector(selectors: string): boolean;
+        readonly baseURI: string;
+        readonly childNodes: NodeListOf<ChildNode>;
+        readonly firstChild: ChildNode | null;
+        readonly isConnected: boolean;
+        readonly lastChild: ChildNode | null;
+        readonly nextSibling: ChildNode | null;
+        readonly nodeName: string;
+        readonly nodeType: number;
+        nodeValue: string | null;
+        readonly parentElement: HTMLElement | null;
+        readonly parentNode: ParentNode | null;
+        readonly previousSibling: ChildNode | null;
+        textContent: string | null;
+        appendChild<T extends Node>(node: T): T;
+        cloneNode(deep?: boolean): Node;
+        compareDocumentPosition(other: Node): number;
+        contains(other: Node | null): boolean;
+        getRootNode(options?: GetRootNodeOptions): Node;
+        hasChildNodes(): boolean;
+        insertBefore<T extends Node>(node: T, child: Node | null): T;
+        isDefaultNamespace(namespace: string | null): boolean;
+        isEqualNode(otherNode: Node | null): boolean;
+        isSameNode(otherNode: Node | null): boolean;
+        lookupNamespaceURI(prefix: string | null): string | null;
+        lookupPrefix(namespace: string | null): string | null;
+        normalize(): void;
+        removeChild<T extends Node>(child: T): T;
+        replaceChild<T extends Node>(node: Node, child: T): T;
+        readonly ELEMENT_NODE: 1;
+        readonly ATTRIBUTE_NODE: 2;
+        readonly TEXT_NODE: 3;
+        readonly CDATA_SECTION_NODE: 4;
+        readonly ENTITY_REFERENCE_NODE: 5;
+        readonly ENTITY_NODE: 6;
+        readonly PROCESSING_INSTRUCTION_NODE: 7;
+        readonly COMMENT_NODE: 8;
+        readonly DOCUMENT_NODE: 9;
+        readonly DOCUMENT_TYPE_NODE: 10;
+        readonly DOCUMENT_FRAGMENT_NODE: 11;
+        readonly NOTATION_NODE: 12;
+        readonly DOCUMENT_POSITION_DISCONNECTED: 1;
+        readonly DOCUMENT_POSITION_PRECEDING: 2;
+        readonly DOCUMENT_POSITION_FOLLOWING: 4;
+        readonly DOCUMENT_POSITION_CONTAINS: 8;
+        readonly DOCUMENT_POSITION_CONTAINED_BY: 16;
+        readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: 32;
+        dispatchEvent(event: Event): boolean;
+        ariaAtomic: string | null;
+        ariaAutoComplete: string | null;
+        ariaBrailleLabel: string | null;
+        ariaBrailleRoleDescription: string | null;
+        ariaBusy: string | null;
+        ariaChecked: string | null;
+        ariaColCount: string | null;
+        ariaColIndex: string | null;
+        ariaColSpan: string | null;
+        ariaCurrent: string | null;
+        ariaDescription: string | null;
+        ariaDisabled: string | null;
+        ariaExpanded: string | null;
+        ariaHasPopup: string | null;
+        ariaHidden: string | null;
+        ariaInvalid: string | null;
+        ariaKeyShortcuts: string | null;
+        ariaLabel: string | null;
+        ariaLevel: string | null;
+        ariaLive: string | null;
+        ariaModal: string | null;
+        ariaMultiLine: string | null;
+        ariaMultiSelectable: string | null;
+        ariaOrientation: string | null;
+        ariaPlaceholder: string | null;
+        ariaPosInSet: string | null;
+        ariaPressed: string | null;
+        ariaReadOnly: string | null;
+        ariaRequired: string | null;
+        ariaRoleDescription: string | null;
+        ariaRowCount: string | null;
+        ariaRowIndex: string | null;
+        ariaRowSpan: string | null;
+        ariaSelected: string | null;
+        ariaSetSize: string | null;
+        ariaSort: string | null;
+        ariaValueMax: string | null;
+        ariaValueMin: string | null;
+        ariaValueNow: string | null;
+        ariaValueText: string | null;
+        role: string | null;
+        animate(keyframes: Keyframe[] | PropertyIndexedKeyframes | null, options?: number | KeyframeAnimationOptions): Animation;
+        getAnimations(options?: GetAnimationsOptions): Animation[];
+        after(...nodes: (Node | string)[]): void;
+        before(...nodes: (Node | string)[]): void;
+        remove(): void;
+        replaceWith(...nodes: (Node | string)[]): void;
+        readonly nextElementSibling: Element | null;
+        readonly previousElementSibling: Element | null;
+        readonly childElementCount: number;
+        readonly children: HTMLCollection;
+        readonly firstElementChild: Element | null;
+        readonly lastElementChild: Element | null;
+        append(...nodes: (Node | string)[]): void;
+        prepend(...nodes: (Node | string)[]): void;
+        querySelector<K extends keyof HTMLElementTagNameMap>(selectors: K): HTMLElementTagNameMap[K] | null;
+        querySelector<K extends keyof SVGElementTagNameMap>(selectors: K): SVGElementTagNameMap[K] | null;
+        querySelector<K extends keyof MathMLElementTagNameMap>(selectors: K): MathMLElementTagNameMap[K] | null;
+        querySelector<K extends keyof HTMLElementDeprecatedTagNameMap>(selectors: K): HTMLElementDeprecatedTagNameMap[K] | null;
+        querySelector<E extends Element = Element>(selectors: string): E | null;
+        querySelectorAll<K extends keyof HTMLElementTagNameMap>(selectors: K): NodeListOf<HTMLElementTagNameMap[K]>;
+        querySelectorAll<K extends keyof SVGElementTagNameMap>(selectors: K): NodeListOf<SVGElementTagNameMap[K]>;
+        querySelectorAll<K extends keyof MathMLElementTagNameMap>(selectors: K): NodeListOf<MathMLElementTagNameMap[K]>;
+        querySelectorAll<K extends keyof HTMLElementDeprecatedTagNameMap>(selectors: K): NodeListOf<HTMLElementDeprecatedTagNameMap[K]>;
+        querySelectorAll<E extends Element = Element>(selectors: string): NodeListOf<E>;
+        replaceChildren(...nodes: (Node | string)[]): void;
+        readonly assignedSlot: HTMLSlotElement | null;
+        readonly attributeStyleMap: StylePropertyMap;
+        readonly style: CSSStyleDeclaration;
+        contentEditable: string;
+        enterKeyHint: string;
+        inputMode: string;
+        readonly isContentEditable: boolean;
+        onabort: ((this: GlobalEventHandlers, ev: UIEvent) => any) | null;
+        onanimationcancel: ((this: GlobalEventHandlers, ev: AnimationEvent) => any) | null;
+        onanimationend: ((this: GlobalEventHandlers, ev: AnimationEvent) => any) | null;
+        onanimationiteration: ((this: GlobalEventHandlers, ev: AnimationEvent) => any) | null;
+        onanimationstart: ((this: GlobalEventHandlers, ev: AnimationEvent) => any) | null;
+        onauxclick: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onbeforeinput: ((this: GlobalEventHandlers, ev: InputEvent) => any) | null;
+        onbeforetoggle: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onblur: ((this: GlobalEventHandlers, ev: FocusEvent) => any) | null;
+        oncancel: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        oncanplay: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        oncanplaythrough: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onchange: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onclick: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onclose: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        oncontextlost: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        oncontextmenu: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        oncontextrestored: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        oncopy: ((this: GlobalEventHandlers, ev: ClipboardEvent) => any) | null;
+        oncuechange: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        oncut: ((this: GlobalEventHandlers, ev: ClipboardEvent) => any) | null;
+        ondblclick: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        ondrag: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null;
+        ondragend: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null;
+        ondragenter: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null;
+        ondragleave: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null;
+        ondragover: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null;
+        ondragstart: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null;
+        ondrop: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null;
+        ondurationchange: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onemptied: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onended: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onerror: OnErrorEventHandler;
+        onfocus: ((this: GlobalEventHandlers, ev: FocusEvent) => any) | null;
+        onformdata: ((this: GlobalEventHandlers, ev: FormDataEvent) => any) | null;
+        ongotpointercapture: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        oninput: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        oninvalid: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onkeydown: ((this: GlobalEventHandlers, ev: KeyboardEvent) => any) | null;
+        onkeypress: ((this: GlobalEventHandlers, ev: KeyboardEvent) => any) | null;
+        onkeyup: ((this: GlobalEventHandlers, ev: KeyboardEvent) => any) | null;
+        onload: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onloadeddata: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onloadedmetadata: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onloadstart: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onlostpointercapture: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onmousedown: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onmouseenter: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onmouseleave: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onmousemove: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onmouseout: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onmouseover: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onmouseup: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onpaste: ((this: GlobalEventHandlers, ev: ClipboardEvent) => any) | null;
+        onpause: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onplay: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onplaying: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onpointercancel: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onpointerdown: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onpointerenter: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onpointerleave: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onpointermove: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onpointerout: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onpointerover: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onpointerup: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onprogress: ((this: GlobalEventHandlers, ev: ProgressEvent) => any) | null;
+        onratechange: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onreset: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onresize: ((this: GlobalEventHandlers, ev: UIEvent) => any) | null;
+        onscroll: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onscrollend: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onsecuritypolicyviolation: ((this: GlobalEventHandlers, ev: SecurityPolicyViolationEvent) => any) | null;
+        onseeked: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onseeking: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onselect: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onselectionchange: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onselectstart: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onslotchange: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onstalled: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onsubmit: ((this: GlobalEventHandlers, ev: SubmitEvent) => any) | null;
+        onsuspend: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        ontimeupdate: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        ontoggle: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        ontouchcancel?: ((this: GlobalEventHandlers, ev: TouchEvent) => any) | null | undefined;
+        ontouchend?: ((this: GlobalEventHandlers, ev: TouchEvent) => any) | null | undefined;
+        ontouchmove?: ((this: GlobalEventHandlers, ev: TouchEvent) => any) | null | undefined;
+        ontouchstart?: ((this: GlobalEventHandlers, ev: TouchEvent) => any) | null | undefined;
+        ontransitioncancel: ((this: GlobalEventHandlers, ev: TransitionEvent) => any) | null;
+        ontransitionend: ((this: GlobalEventHandlers, ev: TransitionEvent) => any) | null;
+        ontransitionrun: ((this: GlobalEventHandlers, ev: TransitionEvent) => any) | null;
+        ontransitionstart: ((this: GlobalEventHandlers, ev: TransitionEvent) => any) | null;
+        onvolumechange: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onwaiting: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onwebkitanimationend: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onwebkitanimationiteration: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onwebkitanimationstart: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onwebkittransitionend: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onwheel: ((this: GlobalEventHandlers, ev: WheelEvent) => any) | null;
+        autofocus: boolean;
+        readonly dataset: DOMStringMap;
+        nonce?: string;
+        tabIndex: number;
+        blur(): void;
+        focus(options?: FocusOptions): void;
+    };
+} & typeof CustomElement;
 /**
  * The ControlBox is the section of the chat that contains the open groupchats,
  * bookmarks and roster.
@@ -6,13 +401,12 @@ export default ControlBoxView;
  * In `overlayed` `view_mode` it's a box like the chat boxes, in `fullscreen`
  * `view_mode` it's a left-aligned sidebar.
  */
-declare class ControlBoxView extends CustomElement {
+declare class ControlBoxView extends ControlBoxView_base {
     initialize(): void;
     viewportMediaQuery: MediaQueryList;
     renderOnViewportChange: () => void;
     connectedCallback(): void;
     setModel(): void;
-    model: any;
     render(): import("lit-html").TemplateResult<1> | "";
     close(ev: any): this;
 }

+ 404 - 21
src/types/plugins/dragresize/mixin.d.ts

@@ -1,12 +1,35 @@
-export default DragResizableMixin;
-declare namespace DragResizableMixin {
-    function initDragResize(): {
-        initDragResize(): any;
+/**
+ * @template {import('shared/components/types').CustomElementExtender} T
+ * @param {T} BaseCustomElement
+ */
+export default function DragResizable<T extends import("shared/components/types").CustomElementExtender>(BaseCustomElement: T): {
+    new (...args: any[]): {
+        model: any;
+        /**
+         * Called when the element's properties change.
+         * @param {import('lit').PropertyValues} changed
+         */
+        updated(changed: import("lit").PropertyValues): void;
+        initDragResize(): void;
+        setupDragResize(): any;
+        prev_pageY: number;
+        prev_pageX: number;
+        height: any;
+        width: any;
+        /**
+         * Returns the default height and width of a chat, i.e. what it
+         * would have been if it wasn't resized.
+         * @returns {{ default_height: number, default_width: number }}
+         */
+        getDefaultDimensions(): {
+            default_height: number;
+            default_width: number;
+        };
+        setDimensions(): void;
         /**
          * @param {MouseEvent} ev
          */
         resizeChatBox(ev: MouseEvent): void;
-        setDimensions(): void;
         /**
          * @param {number} height
          */
@@ -15,21 +38,381 @@ declare namespace DragResizableMixin {
          * @param {number} width
          */
         setChatBoxWidth(width: number): void;
-        adjustToViewport(): void;
+        createRenderRoot(): any;
+        initialize(): any;
+        connectedCallback(): any;
+        disconnectedCallback(): void;
+        on(name: string, callback: (event: any, model: import("@converse/skeletor").Model, collection: import("@converse/skeletor").Collection, options?: Record<string, any>) => any, context: any): any;
+        _events: any;
+        _listeners: {};
+        listenTo(obj: any, name: string, callback?: (event: any, model: import("@converse/skeletor").Model, collection: import("@converse/skeletor").Collection, options?: Record<string, any>) => any): any;
+        _listeningTo: {};
+        _listenId: any;
+        off(name: string, callback: (event: any, model: import("@converse/skeletor").Model, collection: import("@converse/skeletor").Collection, options?: Record<string, any>) => any, context?: any): any;
+        stopListening(obj?: any, name?: string, callback?: (event: any, model: import("@converse/skeletor").Model, collection: import("@converse/skeletor").Collection, options?: Record<string, any>) => any): any;
+        once(name: string, callback: (event: any, model: import("@converse/skeletor").Model, collection: import("@converse/skeletor").Collection, options?: Record<string, any>) => any, context: any): any;
+        listenToOnce(obj: any, name: string, callback?: (event: any, model: import("@converse/skeletor").Model, collection: import("@converse/skeletor").Collection, options?: Record<string, any>) => any): any;
+        trigger(name: string, ...args: any[]): any;
+        readonly renderOptions: import("lit-html").RenderOptions;
+        __childPart: any;
+        update(changedProperties: import("lit").PropertyValues): void;
+        render(): unknown;
+        __instanceProperties?: any;
+        readonly renderRoot: HTMLElement | DocumentFragment;
+        __updatePromise: any;
+        isUpdatePending: boolean;
+        hasUpdated: boolean;
+        __defaultValues?: any;
+        __reflectingProperties?: any;
+        __reflectingProperty: any;
+        __controllers?: any;
+        __initialize: any;
+        addController(controller: import("lit").ReactiveController): void;
+        removeController(controller: import("lit").ReactiveController): void;
+        __saveInstanceProperties: any;
+        enableUpdating(_requestedUpdate: boolean): void;
+        attributeChangedCallback(name: string, _old: string | null, value: string | null): void;
+        __propertyToAttribute: any;
+        requestUpdate(name?: PropertyKey, oldValue?: unknown, options?: import("lit").PropertyDeclaration): void;
+        __enqueueUpdate: any;
+        scheduleUpdate(): void | Promise<unknown>;
+        performUpdate(): void;
+        willUpdate(_changedProperties: import("lit").PropertyValues): void;
+        __markUpdated: any;
+        readonly updateComplete: Promise<boolean>;
+        getUpdateComplete(): Promise<boolean>;
+        shouldUpdate(_changedProperties: import("lit").PropertyValues): boolean;
+        firstUpdated(_changedProperties: import("lit").PropertyValues): void;
+        accessKey: string;
+        readonly accessKeyLabel: string;
+        autocapitalize: string;
+        dir: string;
+        draggable: boolean;
+        hidden: boolean;
+        inert: boolean;
+        innerText: string;
+        lang: string;
+        readonly offsetHeight: number;
+        readonly offsetLeft: number;
+        readonly offsetParent: Element | null;
+        readonly offsetTop: number;
+        readonly offsetWidth: number;
+        outerText: string;
+        popover: string | null;
+        spellcheck: boolean;
+        title: string;
+        translate: boolean;
+        attachInternals(): ElementInternals;
+        click(): void;
+        hidePopover(): void;
+        showPopover(): void;
+        togglePopover(force?: boolean): boolean;
+        addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
+        addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
+        removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
+        removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
+        readonly attributes: NamedNodeMap;
+        readonly classList: DOMTokenList;
+        className: string;
+        readonly clientHeight: number;
+        readonly clientLeft: number;
+        readonly clientTop: number;
+        readonly clientWidth: number;
+        id: string;
+        innerHTML: string;
+        readonly localName: string;
+        readonly namespaceURI: string | null;
+        onfullscreenchange: (this: Element, ev: Event) => any;
+        onfullscreenerror: (this: Element, ev: Event) => any;
+        outerHTML: string;
+        readonly ownerDocument: Document;
+        readonly part: DOMTokenList;
+        readonly prefix: string | null;
+        readonly scrollHeight: number;
+        scrollLeft: number;
+        scrollTop: number;
+        readonly scrollWidth: number;
+        readonly shadowRoot: ShadowRoot | null;
+        slot: string;
+        readonly tagName: string;
+        attachShadow(init: ShadowRootInit): ShadowRoot;
+        checkVisibility(options?: CheckVisibilityOptions): boolean;
+        closest<K extends keyof HTMLElementTagNameMap>(selector: K): HTMLElementTagNameMap[K];
+        closest<K extends keyof SVGElementTagNameMap>(selector: K): SVGElementTagNameMap[K];
+        closest<K extends keyof MathMLElementTagNameMap>(selector: K): MathMLElementTagNameMap[K];
+        closest<E extends Element = Element>(selectors: string): E;
+        computedStyleMap(): StylePropertyMapReadOnly;
+        getAttribute(qualifiedName: string): string | null;
+        getAttributeNS(namespace: string | null, localName: string): string | null;
+        getAttributeNames(): string[];
+        getAttributeNode(qualifiedName: string): Attr | null;
+        getAttributeNodeNS(namespace: string | null, localName: string): Attr | null;
+        getBoundingClientRect(): DOMRect;
+        getClientRects(): DOMRectList;
+        getElementsByClassName(classNames: string): HTMLCollectionOf<Element>;
+        getElementsByTagName<K extends keyof HTMLElementTagNameMap>(qualifiedName: K): HTMLCollectionOf<HTMLElementTagNameMap[K]>;
+        getElementsByTagName<K extends keyof SVGElementTagNameMap>(qualifiedName: K): HTMLCollectionOf<SVGElementTagNameMap[K]>;
+        getElementsByTagName<K extends keyof MathMLElementTagNameMap>(qualifiedName: K): HTMLCollectionOf<MathMLElementTagNameMap[K]>;
+        getElementsByTagName<K extends keyof HTMLElementDeprecatedTagNameMap>(qualifiedName: K): HTMLCollectionOf<HTMLElementDeprecatedTagNameMap[K]>;
+        getElementsByTagName(qualifiedName: string): HTMLCollectionOf<Element>;
+        getElementsByTagNameNS(namespaceURI: "http://www.w3.org/1999/xhtml", localName: string): HTMLCollectionOf<HTMLElement>;
+        getElementsByTagNameNS(namespaceURI: "http://www.w3.org/2000/svg", localName: string): HTMLCollectionOf<SVGElement>;
+        getElementsByTagNameNS(namespaceURI: "http://www.w3.org/1998/Math/MathML", localName: string): HTMLCollectionOf<MathMLElement>;
+        getElementsByTagNameNS(namespace: string | null, localName: string): HTMLCollectionOf<Element>;
+        getHTML(options?: GetHTMLOptions): string;
+        hasAttribute(qualifiedName: string): boolean;
+        hasAttributeNS(namespace: string | null, localName: string): boolean;
+        hasAttributes(): boolean;
+        hasPointerCapture(pointerId: number): boolean;
+        insertAdjacentElement(where: InsertPosition, element: Element): Element | null;
+        insertAdjacentHTML(position: InsertPosition, string: string): void;
+        insertAdjacentText(where: InsertPosition, data: string): void;
+        matches(selectors: string): boolean;
+        releasePointerCapture(pointerId: number): void;
+        removeAttribute(qualifiedName: string): void;
+        removeAttributeNS(namespace: string | null, localName: string): void;
+        removeAttributeNode(attr: Attr): Attr;
+        requestFullscreen(options?: FullscreenOptions): Promise<void>;
+        requestPointerLock(options?: PointerLockOptions): Promise<void>;
+        scroll(options?: ScrollToOptions): void;
+        scroll(x: number, y: number): void;
+        scrollBy(options?: ScrollToOptions): void;
+        scrollBy(x: number, y: number): void;
+        scrollIntoView(arg?: boolean | ScrollIntoViewOptions): void;
+        scrollTo(options?: ScrollToOptions): void;
+        scrollTo(x: number, y: number): void;
+        setAttribute(qualifiedName: string, value: string): void;
+        setAttributeNS(namespace: string | null, qualifiedName: string, value: string): void;
+        setAttributeNode(attr: Attr): Attr | null;
+        setAttributeNodeNS(attr: Attr): Attr | null;
+        setHTMLUnsafe(html: string): void;
+        setPointerCapture(pointerId: number): void;
+        toggleAttribute(qualifiedName: string, force?: boolean): boolean;
+        webkitMatchesSelector(selectors: string): boolean;
+        readonly baseURI: string;
+        readonly childNodes: NodeListOf<ChildNode>;
+        readonly firstChild: ChildNode | null;
+        readonly isConnected: boolean;
+        readonly lastChild: ChildNode | null;
+        readonly nextSibling: ChildNode | null;
+        readonly nodeName: string;
+        readonly nodeType: number;
+        nodeValue: string | null;
+        readonly parentElement: HTMLElement | null;
+        readonly parentNode: ParentNode | null;
+        readonly previousSibling: ChildNode | null;
+        textContent: string | null;
+        appendChild<T_1 extends Node>(node: T_1): T_1;
+        cloneNode(deep?: boolean): Node;
+        compareDocumentPosition(other: Node): number;
+        contains(other: Node | null): boolean;
+        getRootNode(options?: GetRootNodeOptions): Node;
+        hasChildNodes(): boolean;
+        insertBefore<T_1 extends Node>(node: T_1, child: Node | null): T_1;
+        isDefaultNamespace(namespace: string | null): boolean;
+        isEqualNode(otherNode: Node | null): boolean;
+        isSameNode(otherNode: Node | null): boolean;
+        lookupNamespaceURI(prefix: string | null): string | null;
+        lookupPrefix(namespace: string | null): string | null;
+        normalize(): void;
+        removeChild<T_1 extends Node>(child: T_1): T_1;
+        replaceChild<T_1 extends Node>(node: Node, child: T_1): T_1;
+        readonly ELEMENT_NODE: 1;
+        readonly ATTRIBUTE_NODE: 2;
+        readonly TEXT_NODE: 3;
+        readonly CDATA_SECTION_NODE: 4;
+        readonly ENTITY_REFERENCE_NODE: 5;
+        readonly ENTITY_NODE: 6;
+        readonly PROCESSING_INSTRUCTION_NODE: 7;
+        readonly COMMENT_NODE: 8;
+        readonly DOCUMENT_NODE: 9;
+        readonly DOCUMENT_TYPE_NODE: 10;
+        readonly DOCUMENT_FRAGMENT_NODE: 11;
+        readonly NOTATION_NODE: 12;
+        readonly DOCUMENT_POSITION_DISCONNECTED: 1;
+        readonly DOCUMENT_POSITION_PRECEDING: 2;
+        readonly DOCUMENT_POSITION_FOLLOWING: 4;
+        readonly DOCUMENT_POSITION_CONTAINS: 8;
+        readonly DOCUMENT_POSITION_CONTAINED_BY: 16;
+        readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: 32;
+        dispatchEvent(event: Event): boolean;
+        ariaAtomic: string | null;
+        ariaAutoComplete: string | null;
+        ariaBrailleLabel: string | null;
+        ariaBrailleRoleDescription: string | null;
+        ariaBusy: string | null;
+        ariaChecked: string | null;
+        ariaColCount: string | null;
+        ariaColIndex: string | null;
+        ariaColSpan: string | null;
+        ariaCurrent: string | null;
+        ariaDescription: string | null;
+        ariaDisabled: string | null;
+        ariaExpanded: string | null;
+        ariaHasPopup: string | null;
+        ariaHidden: string | null;
+        ariaInvalid: string | null;
+        ariaKeyShortcuts: string | null;
+        ariaLabel: string | null;
+        ariaLevel: string | null;
+        ariaLive: string | null;
+        ariaModal: string | null;
+        ariaMultiLine: string | null;
+        ariaMultiSelectable: string | null;
+        ariaOrientation: string | null;
+        ariaPlaceholder: string | null;
+        ariaPosInSet: string | null;
+        ariaPressed: string | null;
+        ariaReadOnly: string | null;
+        ariaRequired: string | null;
+        ariaRoleDescription: string | null;
+        ariaRowCount: string | null;
+        ariaRowIndex: string | null;
+        ariaRowSpan: string | null;
+        ariaSelected: string | null;
+        ariaSetSize: string | null;
+        ariaSort: string | null;
+        ariaValueMax: string | null;
+        ariaValueMin: string | null;
+        ariaValueNow: string | null;
+        ariaValueText: string | null;
+        role: string | null;
+        animate(keyframes: Keyframe[] | PropertyIndexedKeyframes | null, options?: number | KeyframeAnimationOptions): Animation;
+        getAnimations(options?: GetAnimationsOptions): Animation[];
+        after(...nodes: (Node | string)[]): void;
+        before(...nodes: (Node | string)[]): void;
+        remove(): void;
+        replaceWith(...nodes: (Node | string)[]): void;
+        readonly nextElementSibling: Element | null;
+        readonly previousElementSibling: Element | null;
+        readonly childElementCount: number;
+        readonly children: HTMLCollection;
+        readonly firstElementChild: Element | null;
+        readonly lastElementChild: Element | null;
+        append(...nodes: (Node | string)[]): void;
+        prepend(...nodes: (Node | string)[]): void;
+        querySelector<K extends keyof HTMLElementTagNameMap>(selectors: K): HTMLElementTagNameMap[K] | null;
+        querySelector<K extends keyof SVGElementTagNameMap>(selectors: K): SVGElementTagNameMap[K] | null;
+        querySelector<K extends keyof MathMLElementTagNameMap>(selectors: K): MathMLElementTagNameMap[K] | null;
+        querySelector<K extends keyof HTMLElementDeprecatedTagNameMap>(selectors: K): HTMLElementDeprecatedTagNameMap[K] | null;
+        querySelector<E extends Element = Element>(selectors: string): E | null;
+        querySelectorAll<K extends keyof HTMLElementTagNameMap>(selectors: K): NodeListOf<HTMLElementTagNameMap[K]>;
+        querySelectorAll<K extends keyof SVGElementTagNameMap>(selectors: K): NodeListOf<SVGElementTagNameMap[K]>;
+        querySelectorAll<K extends keyof MathMLElementTagNameMap>(selectors: K): NodeListOf<MathMLElementTagNameMap[K]>;
+        querySelectorAll<K extends keyof HTMLElementDeprecatedTagNameMap>(selectors: K): NodeListOf<HTMLElementDeprecatedTagNameMap[K]>;
+        querySelectorAll<E extends Element = Element>(selectors: string): NodeListOf<E>;
+        replaceChildren(...nodes: (Node | string)[]): void;
+        readonly assignedSlot: HTMLSlotElement | null;
+        readonly attributeStyleMap: StylePropertyMap;
+        readonly style: CSSStyleDeclaration;
+        contentEditable: string;
+        enterKeyHint: string;
+        inputMode: string;
+        readonly isContentEditable: boolean;
+        onabort: ((this: GlobalEventHandlers, ev: UIEvent) => any) | null;
+        onanimationcancel: ((this: GlobalEventHandlers, ev: AnimationEvent) => any) | null;
+        onanimationend: ((this: GlobalEventHandlers, ev: AnimationEvent) => any) | null;
+        onanimationiteration: ((this: GlobalEventHandlers, ev: AnimationEvent) => any) | null;
+        onanimationstart: ((this: GlobalEventHandlers, ev: AnimationEvent) => any) | null;
+        onauxclick: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onbeforeinput: ((this: GlobalEventHandlers, ev: InputEvent) => any) | null;
+        onbeforetoggle: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onblur: ((this: GlobalEventHandlers, ev: FocusEvent) => any) | null;
+        oncancel: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        oncanplay: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        oncanplaythrough: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onchange: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onclick: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onclose: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        oncontextlost: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        oncontextmenu: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        oncontextrestored: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        oncopy: ((this: GlobalEventHandlers, ev: ClipboardEvent) => any) | null;
+        oncuechange: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        oncut: ((this: GlobalEventHandlers, ev: ClipboardEvent) => any) | null;
+        ondblclick: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        ondrag: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null;
+        ondragend: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null;
+        ondragenter: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null;
+        ondragleave: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null;
+        ondragover: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null;
+        ondragstart: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null;
+        ondrop: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null;
+        ondurationchange: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onemptied: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onended: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onerror: OnErrorEventHandler;
+        onfocus: ((this: GlobalEventHandlers, ev: FocusEvent) => any) | null;
+        onformdata: ((this: GlobalEventHandlers, ev: FormDataEvent) => any) | null;
+        ongotpointercapture: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        oninput: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        oninvalid: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onkeydown: ((this: GlobalEventHandlers, ev: KeyboardEvent) => any) | null;
+        onkeypress: ((this: GlobalEventHandlers, ev: KeyboardEvent) => any) | null;
+        onkeyup: ((this: GlobalEventHandlers, ev: KeyboardEvent) => any) | null;
+        onload: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onloadeddata: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onloadedmetadata: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onloadstart: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onlostpointercapture: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onmousedown: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onmouseenter: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onmouseleave: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onmousemove: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onmouseout: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onmouseover: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onmouseup: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onpaste: ((this: GlobalEventHandlers, ev: ClipboardEvent) => any) | null;
+        onpause: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onplay: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onplaying: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onpointercancel: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onpointerdown: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onpointerenter: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onpointerleave: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onpointermove: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onpointerout: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onpointerover: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onpointerup: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onprogress: ((this: GlobalEventHandlers, ev: ProgressEvent) => any) | null;
+        onratechange: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onreset: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onresize: ((this: GlobalEventHandlers, ev: UIEvent) => any) | null;
+        onscroll: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onscrollend: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onsecuritypolicyviolation: ((this: GlobalEventHandlers, ev: SecurityPolicyViolationEvent) => any) | null;
+        onseeked: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onseeking: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onselect: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onselectionchange: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onselectstart: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onslotchange: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onstalled: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onsubmit: ((this: GlobalEventHandlers, ev: SubmitEvent) => any) | null;
+        onsuspend: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        ontimeupdate: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        ontoggle: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        ontouchcancel?: ((this: GlobalEventHandlers, ev: TouchEvent) => any) | null | undefined;
+        ontouchend?: ((this: GlobalEventHandlers, ev: TouchEvent) => any) | null | undefined;
+        ontouchmove?: ((this: GlobalEventHandlers, ev: TouchEvent) => any) | null | undefined;
+        ontouchstart?: ((this: GlobalEventHandlers, ev: TouchEvent) => any) | null | undefined;
+        ontransitioncancel: ((this: GlobalEventHandlers, ev: TransitionEvent) => any) | null;
+        ontransitionend: ((this: GlobalEventHandlers, ev: TransitionEvent) => any) | null;
+        ontransitionrun: ((this: GlobalEventHandlers, ev: TransitionEvent) => any) | null;
+        ontransitionstart: ((this: GlobalEventHandlers, ev: TransitionEvent) => any) | null;
+        onvolumechange: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onwaiting: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onwebkitanimationend: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onwebkitanimationiteration: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onwebkitanimationstart: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onwebkittransitionend: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onwheel: ((this: GlobalEventHandlers, ev: WheelEvent) => any) | null;
+        autofocus: boolean;
+        readonly dataset: DOMStringMap;
+        nonce?: string;
+        tabIndex: number;
+        blur(): void;
+        focus(options?: FocusOptions): void;
     };
-    /**
-     * @param {MouseEvent} ev
-     */
-    function resizeChatBox(ev: MouseEvent): void;
-    function setDimensions(): void;
-    /**
-     * @param {number} height
-     */
-    function setChatBoxHeight(height: number): void;
-    /**
-     * @param {number} width
-     */
-    function setChatBoxWidth(width: number): void;
-    function adjustToViewport(): void;
-}
+} & T;
 //# sourceMappingURL=mixin.d.ts.map

+ 0 - 4
src/types/plugins/dragresize/utils.d.ts

@@ -7,10 +7,6 @@ export function unregisterGlobalEventHandlers(): void;
  * @param {Element} e - dragging node element.
  */
 export function dragresizeOverIframeHandler(e: Element): void;
-/**
- * @param {import('@converse/headless/types/shared/chatbox').default} model
- */
-export function initializeDragResize(model: import("@converse/headless/types/shared/chatbox").default): void;
 /**
  * @returns {string}
  */

+ 401 - 1
src/types/plugins/headlines-view/view.d.ts

@@ -1,5 +1,405 @@
 export default HeadlinesFeedView;
-declare class HeadlinesFeedView extends BaseChatView {
+declare const HeadlinesFeedView_base: {
+    new (...args: any[]): {
+        model: any;
+        updated(changed: import("lit").PropertyValues): void;
+        initDragResize(): void;
+        setupDragResize(): any;
+        prev_pageY: number;
+        prev_pageX: number;
+        height: any;
+        width: any;
+        getDefaultDimensions(): {
+            default_height: number;
+            default_width: number;
+        };
+        setDimensions(): void;
+        resizeChatBox(ev: MouseEvent): void;
+        setChatBoxHeight(height: number): void;
+        setChatBoxWidth(width: number): void;
+        createRenderRoot(): any;
+        initialize(): any;
+        connectedCallback(): any;
+        disconnectedCallback(): void;
+        on(name: string, callback: (event: any, model: import("@converse/skeletor" /**
+         * Triggered once the {@link HeadlinesFeedView} has been initialized
+         * @event _converse#headlinesBoxViewInitialized
+         * @type {HeadlinesFeedView}
+         * @example _converse.api.listen.on('headlinesBoxViewInitialized', view => { ... });
+         */).Model, collection: import("@converse/skeletor").Collection, options?: Record<string, any>) => any, context: any): any;
+        _events: any;
+        _listeners: {};
+        listenTo(obj: any, name: string, callback?: (event: any, model: import("@converse/skeletor").Model, collection: import("@converse/skeletor").Collection, options?: Record<string, any>) => any): any;
+        _listeningTo: {};
+        _listenId: any;
+        off(name: string, callback: (event: any, model: import("@converse/skeletor").Model, collection: import("@converse/skeletor").Collection, options?: Record<string, any>) => any, context?: any): any;
+        stopListening(obj?: any, name?: string, callback?: (event: any, model: import("@converse/skeletor").Model, collection: import("@converse/skeletor").Collection, options?: Record<string, any>) => any): any;
+        once(name: string, callback: (event: any, model: import("@converse/skeletor").Model, collection: import("@converse/skeletor").Collection, options?: Record<string, any>) => any, context: any): any;
+        listenToOnce(obj: any, name: string, callback?: (event: any, model: import("@converse/skeletor").Model, collection: import("@converse/skeletor").Collection, options?: Record<string, any>) => any): any;
+        trigger(name: string, ...args: any[]): any;
+        readonly renderOptions: import("lit-html").RenderOptions;
+        __childPart: any;
+        update(changedProperties: import("lit").PropertyValues): void;
+        render(): unknown;
+        __instanceProperties?: any;
+        readonly renderRoot: HTMLElement | DocumentFragment;
+        __updatePromise: any;
+        isUpdatePending: boolean;
+        hasUpdated: boolean;
+        __defaultValues?: any;
+        __reflectingProperties?: any;
+        __reflectingProperty: any;
+        __controllers?: any;
+        __initialize: any;
+        addController(controller: import("lit").ReactiveController): void;
+        removeController(controller: import("lit").ReactiveController): void;
+        __saveInstanceProperties: any;
+        enableUpdating(_requestedUpdate: boolean): void;
+        attributeChangedCallback(name: string, _old: string | null, value: string | null): void;
+        __propertyToAttribute: any;
+        requestUpdate(name?: PropertyKey, oldValue?: unknown, options?: import("lit").PropertyDeclaration): void;
+        __enqueueUpdate: any;
+        scheduleUpdate(): void | Promise<unknown>;
+        performUpdate(): void;
+        willUpdate(_changedProperties: import("lit").PropertyValues): void;
+        __markUpdated: any;
+        readonly updateComplete: Promise<boolean>;
+        getUpdateComplete(): Promise<boolean>;
+        shouldUpdate(_changedProperties: import("lit").PropertyValues): boolean;
+        firstUpdated(_changedProperties: import("lit").PropertyValues): void;
+        accessKey: string;
+        readonly accessKeyLabel: string;
+        autocapitalize: string;
+        dir: string;
+        draggable: boolean;
+        hidden: boolean;
+        inert: boolean;
+        innerText: string;
+        lang: string;
+        readonly offsetHeight: number;
+        readonly offsetLeft: number;
+        readonly offsetParent: Element | null;
+        readonly offsetTop: number;
+        readonly offsetWidth: number;
+        outerText: string;
+        popover: string | null;
+        spellcheck: boolean;
+        title: string;
+        translate: boolean;
+        attachInternals(): ElementInternals;
+        click(): void;
+        hidePopover(): void;
+        showPopover(): void;
+        togglePopover(force?: boolean): boolean;
+        addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
+        addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
+        removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
+        removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
+        readonly attributes: NamedNodeMap;
+        readonly classList: DOMTokenList;
+        className: string;
+        readonly clientHeight: number;
+        readonly clientLeft: number;
+        readonly clientTop: number;
+        readonly clientWidth: number;
+        id: string;
+        innerHTML: string;
+        readonly localName: string;
+        readonly namespaceURI: string | null;
+        onfullscreenchange: (this: Element, ev: Event) => any;
+        onfullscreenerror: (this: Element, ev: Event) => any;
+        outerHTML: string;
+        readonly ownerDocument: Document;
+        readonly part: DOMTokenList;
+        readonly prefix: string | null;
+        readonly scrollHeight: number;
+        scrollLeft: number;
+        scrollTop: number;
+        readonly scrollWidth: number;
+        readonly shadowRoot: ShadowRoot | null;
+        slot: string;
+        readonly tagName: string;
+        attachShadow(init: ShadowRootInit): ShadowRoot;
+        checkVisibility(options?: CheckVisibilityOptions): boolean;
+        closest<K extends keyof HTMLElementTagNameMap>(selector: K): HTMLElementTagNameMap[K];
+        closest<K extends keyof SVGElementTagNameMap>(selector: K): SVGElementTagNameMap[K];
+        closest<K extends keyof MathMLElementTagNameMap>(selector: K): MathMLElementTagNameMap[K];
+        closest<E extends Element = Element>(selectors: string): E;
+        computedStyleMap(): StylePropertyMapReadOnly;
+        getAttribute(qualifiedName: string): string | null;
+        getAttributeNS(namespace: string | null, localName: string): string | null;
+        getAttributeNames(): string[];
+        getAttributeNode(qualifiedName: string): Attr | null;
+        getAttributeNodeNS(namespace: string | null, localName: string): Attr | null;
+        getBoundingClientRect(): DOMRect;
+        getClientRects(): DOMRectList;
+        getElementsByClassName(classNames: string): HTMLCollectionOf<Element>;
+        getElementsByTagName<K extends keyof HTMLElementTagNameMap>(qualifiedName: K): HTMLCollectionOf<HTMLElementTagNameMap[K]>;
+        getElementsByTagName<K extends keyof SVGElementTagNameMap>(qualifiedName: K): HTMLCollectionOf<SVGElementTagNameMap[K]>;
+        getElementsByTagName<K extends keyof MathMLElementTagNameMap>(qualifiedName: K): HTMLCollectionOf<MathMLElementTagNameMap[K]>;
+        getElementsByTagName<K extends keyof HTMLElementDeprecatedTagNameMap>(qualifiedName: K): HTMLCollectionOf<HTMLElementDeprecatedTagNameMap[K]>;
+        getElementsByTagName(qualifiedName: string): HTMLCollectionOf<Element>;
+        getElementsByTagNameNS(namespaceURI: "http://www.w3.org/1999/xhtml", localName: string): HTMLCollectionOf<HTMLElement>;
+        getElementsByTagNameNS(namespaceURI: "http://www.w3.org/2000/svg", localName: string): HTMLCollectionOf<SVGElement>;
+        getElementsByTagNameNS(namespaceURI: "http://www.w3.org/1998/Math/MathML", localName: string): HTMLCollectionOf<MathMLElement>;
+        getElementsByTagNameNS(namespace: string | null, localName: string): HTMLCollectionOf<Element>;
+        getHTML(options?: GetHTMLOptions): string;
+        hasAttribute(qualifiedName: string): boolean;
+        hasAttributeNS(namespace: string | null, localName: string): boolean;
+        hasAttributes(): boolean;
+        hasPointerCapture(pointerId: number): boolean;
+        insertAdjacentElement(where: InsertPosition, element: Element): Element | null;
+        insertAdjacentHTML(position: InsertPosition, string: string): void;
+        insertAdjacentText(where: InsertPosition, data: string): void;
+        matches(selectors: string): boolean;
+        releasePointerCapture(pointerId: number): void;
+        removeAttribute(qualifiedName: string): void;
+        removeAttributeNS(namespace: string | null, localName: string): void;
+        removeAttributeNode(attr: Attr): Attr;
+        requestFullscreen(options?: FullscreenOptions): Promise<void>;
+        requestPointerLock(options?: PointerLockOptions): Promise<void>;
+        scroll(options?: ScrollToOptions): void;
+        scroll(x: number, y: number): void;
+        scrollBy(options?: ScrollToOptions): void;
+        scrollBy(x: number, y: number): void;
+        scrollIntoView(arg?: boolean | ScrollIntoViewOptions): void;
+        scrollTo(options?: ScrollToOptions): void;
+        scrollTo(x: number, y: number): void;
+        setAttribute(qualifiedName: string, value: string): void;
+        setAttributeNS(namespace: string | null, qualifiedName: string, value: string): void;
+        setAttributeNode(attr: Attr): Attr | null;
+        setAttributeNodeNS(attr: Attr): Attr | null;
+        setHTMLUnsafe(html: string): void;
+        setPointerCapture(pointerId: number): void;
+        toggleAttribute(qualifiedName: string, force?: boolean): boolean;
+        webkitMatchesSelector(selectors: string): boolean;
+        readonly baseURI: string;
+        readonly childNodes: NodeListOf<ChildNode>;
+        readonly firstChild: ChildNode | null;
+        readonly isConnected: boolean;
+        readonly lastChild: ChildNode | null;
+        readonly nextSibling: ChildNode | null;
+        readonly nodeName: string;
+        readonly nodeType: number;
+        nodeValue: string | null;
+        readonly parentElement: HTMLElement | null;
+        readonly parentNode: ParentNode | null;
+        readonly previousSibling: ChildNode | null;
+        textContent: string | null;
+        appendChild<T extends Node>(node: T): T;
+        cloneNode(deep?: boolean): Node;
+        compareDocumentPosition(other: Node): number;
+        contains(other: Node | null): boolean;
+        getRootNode(options?: GetRootNodeOptions): Node;
+        hasChildNodes(): boolean;
+        insertBefore<T extends Node>(node: T, child: Node | null): T;
+        isDefaultNamespace(namespace: string | null): boolean;
+        isEqualNode(otherNode: Node | null): boolean;
+        isSameNode(otherNode: Node | null): boolean;
+        lookupNamespaceURI(prefix: string | null): string | null;
+        lookupPrefix(namespace: string | null): string | null;
+        normalize(): void;
+        removeChild<T extends Node>(child: T): T;
+        replaceChild<T extends Node>(node: Node, child: T): T;
+        readonly ELEMENT_NODE: 1;
+        readonly ATTRIBUTE_NODE: 2;
+        readonly TEXT_NODE: 3;
+        readonly CDATA_SECTION_NODE: 4;
+        readonly ENTITY_REFERENCE_NODE: 5;
+        readonly ENTITY_NODE: 6;
+        readonly PROCESSING_INSTRUCTION_NODE: 7;
+        readonly COMMENT_NODE: 8;
+        readonly DOCUMENT_NODE: 9;
+        readonly DOCUMENT_TYPE_NODE: 10;
+        readonly DOCUMENT_FRAGMENT_NODE: 11;
+        readonly NOTATION_NODE: 12;
+        readonly DOCUMENT_POSITION_DISCONNECTED: 1;
+        readonly DOCUMENT_POSITION_PRECEDING: 2;
+        readonly DOCUMENT_POSITION_FOLLOWING: 4;
+        readonly DOCUMENT_POSITION_CONTAINS: 8;
+        readonly DOCUMENT_POSITION_CONTAINED_BY: 16;
+        readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: 32;
+        dispatchEvent(event: Event): boolean;
+        ariaAtomic: string | null;
+        ariaAutoComplete: string | null;
+        ariaBrailleLabel: string | null;
+        ariaBrailleRoleDescription: string | null;
+        ariaBusy: string | null;
+        ariaChecked: string | null;
+        ariaColCount: string | null;
+        ariaColIndex: string | null;
+        ariaColSpan: string | null;
+        ariaCurrent: string | null;
+        ariaDescription: string | null;
+        ariaDisabled: string | null;
+        ariaExpanded: string | null;
+        ariaHasPopup: string | null;
+        ariaHidden: string | null;
+        ariaInvalid: string | null;
+        ariaKeyShortcuts: string | null;
+        ariaLabel: string | null;
+        ariaLevel: string | null;
+        ariaLive: string | null;
+        ariaModal: string | null;
+        ariaMultiLine: string | null;
+        ariaMultiSelectable: string | null;
+        ariaOrientation: string | null;
+        ariaPlaceholder: string | null;
+        ariaPosInSet: string | null;
+        ariaPressed: string | null;
+        ariaReadOnly: string | null;
+        ariaRequired: string | null;
+        ariaRoleDescription: string | null;
+        ariaRowCount: string | null;
+        ariaRowIndex: string | null;
+        ariaRowSpan: string | null;
+        ariaSelected: string | null;
+        ariaSetSize: string | null;
+        ariaSort: string | null;
+        ariaValueMax: string | null;
+        ariaValueMin: string | null;
+        ariaValueNow: string | null;
+        ariaValueText: string | null;
+        role: string | null;
+        animate(keyframes: Keyframe[] | PropertyIndexedKeyframes | null, options?: number | KeyframeAnimationOptions): Animation;
+        getAnimations(options?: GetAnimationsOptions): Animation[];
+        after(...nodes: (Node | string)[]): void;
+        before(...nodes: (Node | string)[]): void;
+        remove(): void;
+        replaceWith(...nodes: (Node | string)[]): void;
+        readonly nextElementSibling: Element | null;
+        readonly previousElementSibling: Element | null;
+        readonly childElementCount: number;
+        readonly children: HTMLCollection;
+        readonly firstElementChild: Element | null;
+        readonly lastElementChild: Element | null;
+        append(...nodes: (Node | string)[]): void;
+        prepend(...nodes: (Node | string)[]): void;
+        querySelector<K extends keyof HTMLElementTagNameMap>(selectors: K): HTMLElementTagNameMap[K] | null;
+        querySelector<K extends keyof SVGElementTagNameMap>(selectors: K): SVGElementTagNameMap[K] | null;
+        querySelector<K extends keyof MathMLElementTagNameMap>(selectors: K): MathMLElementTagNameMap[K] | null;
+        querySelector<K extends keyof HTMLElementDeprecatedTagNameMap>(selectors: K): HTMLElementDeprecatedTagNameMap[K] | null;
+        querySelector<E extends Element = Element>(selectors: string): E | null;
+        querySelectorAll<K extends keyof HTMLElementTagNameMap>(selectors: K): NodeListOf<HTMLElementTagNameMap[K]>;
+        querySelectorAll<K extends keyof SVGElementTagNameMap>(selectors: K): NodeListOf<SVGElementTagNameMap[K]>;
+        querySelectorAll<K extends keyof MathMLElementTagNameMap>(selectors: K): NodeListOf<MathMLElementTagNameMap[K]>;
+        querySelectorAll<K extends keyof HTMLElementDeprecatedTagNameMap>(selectors: K): NodeListOf<HTMLElementDeprecatedTagNameMap[K]>;
+        querySelectorAll<E extends Element = Element>(selectors: string): NodeListOf<E>;
+        replaceChildren(...nodes: (Node | string)[]): void;
+        readonly assignedSlot: HTMLSlotElement | null;
+        readonly attributeStyleMap: StylePropertyMap;
+        readonly style: CSSStyleDeclaration;
+        contentEditable: string;
+        enterKeyHint: string;
+        inputMode: string;
+        readonly isContentEditable: boolean;
+        onabort: ((this: GlobalEventHandlers, ev: UIEvent) => any) | null;
+        onanimationcancel: ((this: GlobalEventHandlers, ev: AnimationEvent) => any) | null;
+        onanimationend: ((this: GlobalEventHandlers, ev: AnimationEvent) => any) | null;
+        onanimationiteration: ((this: GlobalEventHandlers, ev: AnimationEvent) => any) | null;
+        onanimationstart: ((this: GlobalEventHandlers, ev: AnimationEvent) => any) | null;
+        onauxclick: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onbeforeinput: ((this: GlobalEventHandlers, ev: InputEvent) => any) | null;
+        onbeforetoggle: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onblur: ((this: GlobalEventHandlers, ev: FocusEvent) => any) | null;
+        oncancel: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        oncanplay: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        oncanplaythrough: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onchange: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onclick: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onclose: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        oncontextlost: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        oncontextmenu: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        oncontextrestored: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        oncopy: ((this: GlobalEventHandlers, ev: ClipboardEvent) => any) | null;
+        oncuechange: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        oncut: ((this: GlobalEventHandlers, ev: ClipboardEvent) => any) | null;
+        ondblclick: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        ondrag: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null;
+        ondragend: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null;
+        ondragenter: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null;
+        ondragleave: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null;
+        ondragover: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null;
+        ondragstart: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null;
+        ondrop: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null;
+        ondurationchange: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onemptied: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onended: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onerror: OnErrorEventHandler;
+        onfocus: ((this: GlobalEventHandlers, ev: FocusEvent) => any) | null;
+        onformdata: ((this: GlobalEventHandlers, ev: FormDataEvent) => any) | null;
+        ongotpointercapture: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        oninput: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        oninvalid: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onkeydown: ((this: GlobalEventHandlers, ev: KeyboardEvent) => any) | null;
+        onkeypress: ((this: GlobalEventHandlers, ev: KeyboardEvent) => any) | null;
+        onkeyup: ((this: GlobalEventHandlers, ev: KeyboardEvent) => any) | null;
+        onload: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onloadeddata: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onloadedmetadata: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onloadstart: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onlostpointercapture: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onmousedown: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onmouseenter: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onmouseleave: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onmousemove: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onmouseout: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onmouseover: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onmouseup: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onpaste: ((this: GlobalEventHandlers, ev: ClipboardEvent) => any) | null;
+        onpause: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onplay: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onplaying: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onpointercancel: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onpointerdown: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onpointerenter: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onpointerleave: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onpointermove: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onpointerout: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onpointerover: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onpointerup: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onprogress: ((this: GlobalEventHandlers, ev: ProgressEvent) => any) | null;
+        onratechange: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onreset: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onresize: ((this: GlobalEventHandlers, ev: UIEvent) => any) | null;
+        onscroll: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onscrollend: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onsecuritypolicyviolation: ((this: GlobalEventHandlers, ev: SecurityPolicyViolationEvent) => any) | null;
+        onseeked: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onseeking: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onselect: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onselectionchange: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onselectstart: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onslotchange: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onstalled: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onsubmit: ((this: GlobalEventHandlers, ev: SubmitEvent) => any) | null;
+        onsuspend: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        ontimeupdate: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        ontoggle: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        ontouchcancel?: ((this: GlobalEventHandlers, ev: TouchEvent) => any) | null | undefined;
+        ontouchend?: ((this: GlobalEventHandlers, ev: TouchEvent) => any) | null | undefined;
+        ontouchmove?: ((this: GlobalEventHandlers, ev: TouchEvent) => any) | null | undefined;
+        ontouchstart?: ((this: GlobalEventHandlers, ev: TouchEvent) => any) | null | undefined;
+        ontransitioncancel: ((this: GlobalEventHandlers, ev: TransitionEvent) => any) | null;
+        ontransitionend: ((this: GlobalEventHandlers, ev: TransitionEvent) => any) | null;
+        ontransitionrun: ((this: GlobalEventHandlers, ev: TransitionEvent) => any) | null;
+        ontransitionstart: ((this: GlobalEventHandlers, ev: TransitionEvent) => any) | null;
+        onvolumechange: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onwaiting: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onwebkitanimationend: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onwebkitanimationiteration: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onwebkitanimationstart: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onwebkittransitionend: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onwheel: ((this: GlobalEventHandlers, ev: WheelEvent) => any) | null;
+        autofocus: boolean;
+        readonly dataset: DOMStringMap;
+        nonce?: string;
+        tabIndex: number;
+        blur(): void;
+        focus(options?: FocusOptions): void;
+    };
+} & typeof BaseChatView;
+declare class HeadlinesFeedView extends HeadlinesFeedView_base {
     initialize(): Promise<void>;
     render(): import("lit-html").TemplateResult<1>;
     /**

+ 397 - 1
src/types/plugins/muc-views/muc.d.ts

@@ -1,4 +1,399 @@
-export default class MUCView extends BaseChatView {
+declare const MUCView_base: {
+    new (...args: any[]): {
+        model: any;
+        updated(changed: import("lit").PropertyValues): void;
+        initDragResize(): void;
+        setupDragResize(): any;
+        prev_pageY: number;
+        prev_pageX: number;
+        height: any;
+        width: any;
+        getDefaultDimensions(): {
+            default_height: number;
+            default_width: number;
+        };
+        setDimensions(): void;
+        resizeChatBox(ev: MouseEvent): void;
+        setChatBoxHeight(height: number): void;
+        setChatBoxWidth(width: number): void;
+        createRenderRoot(): any;
+        initialize(): any;
+        connectedCallback(): any;
+        disconnectedCallback(): void;
+        on(name: string, callback: (event: any, model: import("@converse/skeletor").Model, collection: import("@converse/skeletor").Collection, options?: Record<string, any>) => any, context: any): any;
+        _events: any;
+        _listeners: {};
+        listenTo(obj: any, name: string, callback?: (event: any, model: import("@converse/skeletor").Model, collection: import("@converse/skeletor").Collection, options?: Record<string, any>) => any): any;
+        _listeningTo: {};
+        _listenId: any;
+        off(name: string, callback: (event: any, model: import("@converse/skeletor").Model, collection: import("@converse/skeletor").Collection, options?: Record<string, any>) => any, context?: any): any;
+        stopListening(obj?: any, name?: string, callback?: (event: any, model: import("@converse/skeletor").Model, collection: import("@converse/skeletor").Collection, options?: Record<string, any>) => any): any;
+        once(name: string, callback: (event: any, model: import("@converse/skeletor").Model, collection: import("@converse/skeletor").Collection, options?: Record<string, any>) => any, context: any): any;
+        listenToOnce(obj: any, name: string, callback?: (event: any, model: import("@converse/skeletor").Model, collection: import("@converse/skeletor").Collection, options?: Record<string, any>) => any): any;
+        trigger(name: string, ...args: any[]): any;
+        readonly renderOptions: import("lit-html").RenderOptions;
+        __childPart: any;
+        update(changedProperties: import("lit").PropertyValues): void;
+        render(): unknown;
+        __instanceProperties?: any;
+        readonly renderRoot: HTMLElement | DocumentFragment;
+        __updatePromise: any;
+        isUpdatePending: boolean;
+        hasUpdated: boolean;
+        __defaultValues?: any;
+        __reflectingProperties?: any;
+        __reflectingProperty: any;
+        __controllers?: any;
+        __initialize: any;
+        addController(controller: import("lit").ReactiveController): void;
+        removeController(controller: import("lit").ReactiveController): void;
+        __saveInstanceProperties: any;
+        enableUpdating(_requestedUpdate: boolean): void;
+        attributeChangedCallback(name: string, _old: string | null, value: string | null): void;
+        __propertyToAttribute: any;
+        requestUpdate(name?: PropertyKey, oldValue?: unknown, options?: import("lit").PropertyDeclaration): void;
+        __enqueueUpdate: any;
+        scheduleUpdate(): void | Promise<unknown>;
+        performUpdate(): void;
+        willUpdate(_changedProperties: import("lit").PropertyValues): void;
+        __markUpdated: any;
+        readonly updateComplete: Promise<boolean>;
+        getUpdateComplete(): Promise<boolean>;
+        shouldUpdate(_changedProperties: import("lit").PropertyValues): boolean;
+        firstUpdated(_changedProperties: import("lit").PropertyValues): void;
+        accessKey: string;
+        readonly accessKeyLabel: string;
+        autocapitalize: string;
+        dir: string;
+        draggable: boolean;
+        hidden: boolean;
+        inert: boolean;
+        innerText: string;
+        lang: string;
+        readonly offsetHeight: number;
+        readonly offsetLeft: number;
+        readonly offsetParent: Element | null;
+        readonly offsetTop: number;
+        readonly offsetWidth: number;
+        outerText: string;
+        popover: string | null;
+        spellcheck: boolean;
+        title: string;
+        translate: boolean;
+        attachInternals(): ElementInternals;
+        click(): void;
+        hidePopover(): void;
+        showPopover(): void;
+        togglePopover(force?: boolean): boolean;
+        addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
+        addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
+        removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
+        removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
+        readonly attributes: NamedNodeMap;
+        readonly classList: DOMTokenList;
+        className: string;
+        readonly clientHeight: number;
+        readonly clientLeft: number;
+        readonly clientTop: number;
+        readonly clientWidth: number;
+        id: string;
+        innerHTML: string;
+        readonly localName: string;
+        readonly namespaceURI: string | null;
+        onfullscreenchange: (this: Element, ev: Event) => any;
+        onfullscreenerror: (this: Element, ev: Event) => any;
+        outerHTML: string;
+        readonly ownerDocument: Document;
+        readonly part: DOMTokenList;
+        readonly prefix: string | null;
+        readonly scrollHeight: number;
+        scrollLeft: number;
+        scrollTop: number;
+        readonly scrollWidth: number;
+        readonly shadowRoot: ShadowRoot | null;
+        slot: string;
+        readonly tagName: string;
+        attachShadow(init: ShadowRootInit): ShadowRoot;
+        checkVisibility(options?: CheckVisibilityOptions): boolean;
+        closest<K extends keyof HTMLElementTagNameMap>(selector: K): HTMLElementTagNameMap[K];
+        closest<K extends keyof SVGElementTagNameMap>(selector: K): SVGElementTagNameMap[K];
+        closest<K extends keyof MathMLElementTagNameMap>(selector: K): MathMLElementTagNameMap[K];
+        closest<E extends Element = Element>(selectors: string): E;
+        computedStyleMap(): StylePropertyMapReadOnly;
+        getAttribute(qualifiedName: string): string | null;
+        getAttributeNS(namespace: string | null, localName: string): string | null;
+        getAttributeNames(): string[];
+        getAttributeNode(qualifiedName: string): Attr | null;
+        getAttributeNodeNS(namespace: string | null, localName: string): Attr | null;
+        getBoundingClientRect(): DOMRect;
+        getClientRects(): DOMRectList;
+        getElementsByClassName(classNames: string): HTMLCollectionOf<Element>;
+        getElementsByTagName<K extends keyof HTMLElementTagNameMap>(qualifiedName: K): HTMLCollectionOf<HTMLElementTagNameMap[K]>;
+        getElementsByTagName<K extends keyof SVGElementTagNameMap>(qualifiedName: K): HTMLCollectionOf<SVGElementTagNameMap[K]>;
+        getElementsByTagName<K extends keyof MathMLElementTagNameMap>(qualifiedName: K): HTMLCollectionOf<MathMLElementTagNameMap[K]>;
+        getElementsByTagName<K extends keyof HTMLElementDeprecatedTagNameMap>(qualifiedName: K): HTMLCollectionOf<HTMLElementDeprecatedTagNameMap[K]>;
+        getElementsByTagName(qualifiedName: string): HTMLCollectionOf<Element>;
+        getElementsByTagNameNS(namespaceURI: "http://www.w3.org/1999/xhtml", localName: string): HTMLCollectionOf<HTMLElement>;
+        getElementsByTagNameNS(namespaceURI: "http://www.w3.org/2000/svg", localName: string): HTMLCollectionOf<SVGElement>;
+        getElementsByTagNameNS(namespaceURI: "http://www.w3.org/1998/Math/MathML", localName: string): HTMLCollectionOf<MathMLElement>;
+        getElementsByTagNameNS(namespace: string | null, localName: string): HTMLCollectionOf<Element>;
+        getHTML(options?: GetHTMLOptions): string;
+        hasAttribute(qualifiedName: string): boolean;
+        hasAttributeNS(namespace: string | null, localName: string): boolean;
+        hasAttributes(): boolean;
+        hasPointerCapture(pointerId: number): boolean;
+        insertAdjacentElement(where: InsertPosition, element: Element): Element | null;
+        insertAdjacentHTML(position: InsertPosition, string: string): void;
+        insertAdjacentText(where: InsertPosition, data: string): void;
+        matches(selectors: string): boolean;
+        releasePointerCapture(pointerId: number): void;
+        removeAttribute(qualifiedName: string): void;
+        removeAttributeNS(namespace: string | null, localName: string): void;
+        removeAttributeNode(attr: Attr): Attr;
+        requestFullscreen(options?: FullscreenOptions): Promise<void>;
+        requestPointerLock(options?: PointerLockOptions): Promise<void>;
+        scroll(options?: ScrollToOptions): void;
+        scroll(x: number, y: number): void;
+        scrollBy(options?: ScrollToOptions): void;
+        scrollBy(x: number, y: number): void;
+        scrollIntoView(arg?: boolean | ScrollIntoViewOptions): void;
+        scrollTo(options?: ScrollToOptions): void;
+        scrollTo(x: number, y: number): void;
+        setAttribute(qualifiedName: string, value: string): void;
+        setAttributeNS(namespace: string | null, qualifiedName: string, value: string): void;
+        setAttributeNode(attr: Attr): Attr | null;
+        setAttributeNodeNS(attr: Attr): Attr | null;
+        setHTMLUnsafe(html: string): void;
+        setPointerCapture(pointerId: number): void;
+        toggleAttribute(qualifiedName: string, force?: boolean): boolean;
+        webkitMatchesSelector(selectors: string): boolean;
+        readonly baseURI: string;
+        readonly childNodes: NodeListOf<ChildNode>;
+        readonly firstChild: ChildNode | null;
+        readonly isConnected: boolean;
+        readonly lastChild: ChildNode | null;
+        readonly nextSibling: ChildNode | null;
+        readonly nodeName: string;
+        readonly nodeType: number;
+        nodeValue: string | null;
+        readonly parentElement: HTMLElement | null;
+        readonly parentNode: ParentNode | null;
+        readonly previousSibling: ChildNode | null;
+        textContent: string | null;
+        appendChild<T extends Node>(node: T): T;
+        cloneNode(deep?: boolean): Node;
+        compareDocumentPosition(other: Node): number;
+        contains(other: Node | null): boolean;
+        getRootNode(options?: GetRootNodeOptions): Node;
+        hasChildNodes(): boolean;
+        insertBefore<T extends Node>(node: T, child: Node | null): T;
+        isDefaultNamespace(namespace: string | null): boolean;
+        isEqualNode(otherNode: Node | null): boolean;
+        isSameNode(otherNode: Node | null): boolean;
+        lookupNamespaceURI(prefix: string | null): string | null;
+        lookupPrefix(namespace: string | null): string | null;
+        normalize(): void;
+        removeChild<T extends Node>(child: T): T;
+        replaceChild<T extends Node>(node: Node, child: T): T;
+        readonly ELEMENT_NODE: 1;
+        readonly ATTRIBUTE_NODE: 2;
+        readonly TEXT_NODE: 3;
+        readonly CDATA_SECTION_NODE: 4;
+        readonly ENTITY_REFERENCE_NODE: 5;
+        readonly ENTITY_NODE: 6;
+        readonly PROCESSING_INSTRUCTION_NODE: 7;
+        readonly COMMENT_NODE: 8;
+        readonly DOCUMENT_NODE: 9;
+        readonly DOCUMENT_TYPE_NODE: 10;
+        readonly DOCUMENT_FRAGMENT_NODE: 11;
+        readonly NOTATION_NODE: 12;
+        readonly DOCUMENT_POSITION_DISCONNECTED: 1;
+        readonly DOCUMENT_POSITION_PRECEDING: 2;
+        readonly DOCUMENT_POSITION_FOLLOWING: 4;
+        readonly DOCUMENT_POSITION_CONTAINS: 8;
+        readonly DOCUMENT_POSITION_CONTAINED_BY: 16;
+        readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: 32;
+        dispatchEvent(event: Event): boolean;
+        ariaAtomic: string | null;
+        ariaAutoComplete: string | null;
+        ariaBrailleLabel: string | null;
+        ariaBrailleRoleDescription: string | null;
+        ariaBusy: string | null;
+        ariaChecked: string | null;
+        ariaColCount: string | null;
+        ariaColIndex: string | null;
+        ariaColSpan: string | null;
+        ariaCurrent: string | null;
+        ariaDescription: string | null;
+        ariaDisabled: string | null;
+        ariaExpanded: string | null;
+        ariaHasPopup: string | null;
+        ariaHidden: string | null;
+        ariaInvalid: string | null;
+        ariaKeyShortcuts: string | null;
+        ariaLabel: string | null;
+        ariaLevel: string | null;
+        ariaLive: string | null;
+        ariaModal: string | null;
+        ariaMultiLine: string | null;
+        ariaMultiSelectable: string | null;
+        ariaOrientation: string | null;
+        ariaPlaceholder: string | null;
+        ariaPosInSet: string | null;
+        ariaPressed: string | null;
+        ariaReadOnly: string | null;
+        ariaRequired: string | null;
+        ariaRoleDescription: string | null;
+        ariaRowCount: string | null;
+        ariaRowIndex: string | null;
+        ariaRowSpan: string | null;
+        ariaSelected: string | null;
+        ariaSetSize: string | null;
+        ariaSort: string | null;
+        ariaValueMax: string | null;
+        ariaValueMin: string | null;
+        ariaValueNow: string | null;
+        ariaValueText: string | null;
+        role: string | null;
+        animate(keyframes: Keyframe[] | PropertyIndexedKeyframes | null, options?: number | KeyframeAnimationOptions): Animation;
+        getAnimations(options?: GetAnimationsOptions): Animation[];
+        after(...nodes: (Node | string)[]): void;
+        before(...nodes: (Node | string)[]): void;
+        remove(): void;
+        replaceWith(...nodes: (Node | string)[]): void;
+        readonly nextElementSibling: Element | null;
+        readonly previousElementSibling: Element | null;
+        readonly childElementCount: number;
+        readonly children: HTMLCollection;
+        readonly firstElementChild: Element | null;
+        readonly lastElementChild: Element | null;
+        append(...nodes: (Node | string)[]): void;
+        prepend(...nodes: (Node | string)[]): void;
+        querySelector<K extends keyof HTMLElementTagNameMap>(selectors: K): HTMLElementTagNameMap[K] | null;
+        querySelector<K extends keyof SVGElementTagNameMap>(selectors: K): SVGElementTagNameMap[K] | null;
+        querySelector<K extends keyof MathMLElementTagNameMap>(selectors: K): MathMLElementTagNameMap[K] | null;
+        querySelector<K extends keyof HTMLElementDeprecatedTagNameMap>(selectors: K): HTMLElementDeprecatedTagNameMap[K] | null;
+        querySelector<E extends Element = Element>(selectors: string): E | null;
+        querySelectorAll<K extends keyof HTMLElementTagNameMap>(selectors: K): NodeListOf<HTMLElementTagNameMap[K]>;
+        querySelectorAll<K extends keyof SVGElementTagNameMap>(selectors: K): NodeListOf<SVGElementTagNameMap[K]>;
+        querySelectorAll<K extends keyof MathMLElementTagNameMap>(selectors: K): NodeListOf<MathMLElementTagNameMap[K]>;
+        querySelectorAll<K extends keyof HTMLElementDeprecatedTagNameMap>(selectors: K): NodeListOf<HTMLElementDeprecatedTagNameMap[K]>;
+        querySelectorAll<E extends Element = Element>(selectors: string): NodeListOf<E>;
+        replaceChildren(...nodes: (Node | string)[]): void;
+        readonly assignedSlot: HTMLSlotElement | null;
+        readonly attributeStyleMap: StylePropertyMap;
+        readonly style: CSSStyleDeclaration;
+        contentEditable: string;
+        enterKeyHint: string;
+        inputMode: string;
+        readonly isContentEditable: boolean;
+        onabort: ((this: GlobalEventHandlers, ev: UIEvent) => any) | null;
+        onanimationcancel: ((this: GlobalEventHandlers, ev: AnimationEvent) => any) | null;
+        onanimationend: ((this: GlobalEventHandlers, ev: AnimationEvent) => any) | null;
+        onanimationiteration: ((this: GlobalEventHandlers, ev: AnimationEvent) => any) | null;
+        onanimationstart: ((this: GlobalEventHandlers, ev: AnimationEvent) => any) | null;
+        onauxclick: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onbeforeinput: ((this: GlobalEventHandlers, ev: InputEvent) => any) | null;
+        onbeforetoggle: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onblur: ((this: GlobalEventHandlers, ev: FocusEvent) => any) | null;
+        oncancel: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        oncanplay: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        oncanplaythrough: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onchange: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onclick: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onclose: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        oncontextlost: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        oncontextmenu: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        oncontextrestored: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        oncopy: ((this: GlobalEventHandlers, ev: ClipboardEvent) => any) | null;
+        oncuechange: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        oncut: ((this: GlobalEventHandlers, ev: ClipboardEvent) => any) | null;
+        ondblclick: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        ondrag: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null;
+        ondragend: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null;
+        ondragenter: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null;
+        ondragleave: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null;
+        ondragover: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null;
+        ondragstart: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null;
+        ondrop: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null;
+        ondurationchange: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onemptied: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onended: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onerror: OnErrorEventHandler;
+        onfocus: ((this: GlobalEventHandlers, ev: FocusEvent) => any) | null;
+        onformdata: ((this: GlobalEventHandlers, ev: FormDataEvent) => any) | null;
+        ongotpointercapture: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        oninput: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        oninvalid: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onkeydown: ((this: GlobalEventHandlers, ev: KeyboardEvent) => any) | null;
+        onkeypress: ((this: GlobalEventHandlers, ev: KeyboardEvent) => any) | null;
+        onkeyup: ((this: GlobalEventHandlers, ev: KeyboardEvent) => any) | null;
+        onload: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onloadeddata: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onloadedmetadata: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onloadstart: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onlostpointercapture: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onmousedown: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onmouseenter: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onmouseleave: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onmousemove: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onmouseout: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onmouseover: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onmouseup: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
+        onpaste: ((this: GlobalEventHandlers, ev: ClipboardEvent) => any) | null;
+        onpause: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onplay: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onplaying: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onpointercancel: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onpointerdown: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onpointerenter: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onpointerleave: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onpointermove: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onpointerout: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onpointerover: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onpointerup: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;
+        onprogress: ((this: GlobalEventHandlers, ev: ProgressEvent) => any) | null;
+        onratechange: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onreset: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onresize: ((this: GlobalEventHandlers, ev: UIEvent) => any) | null;
+        onscroll: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onscrollend: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onsecuritypolicyviolation: ((this: GlobalEventHandlers, ev: SecurityPolicyViolationEvent) => any) | null;
+        onseeked: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onseeking: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onselect: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onselectionchange: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onselectstart: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onslotchange: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onstalled: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onsubmit: ((this: GlobalEventHandlers, ev: SubmitEvent) => any) | null;
+        onsuspend: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        ontimeupdate: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        ontoggle: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        ontouchcancel?: ((this: GlobalEventHandlers, ev: TouchEvent) => any) | null | undefined;
+        ontouchend?: ((this: GlobalEventHandlers, ev: TouchEvent) => any) | null | undefined;
+        ontouchmove?: ((this: GlobalEventHandlers, ev: TouchEvent) => any) | null | undefined;
+        ontouchstart?: ((this: GlobalEventHandlers, ev: TouchEvent) => any) | null | undefined;
+        ontransitioncancel: ((this: GlobalEventHandlers, ev: TransitionEvent) => any) | null;
+        ontransitionend: ((this: GlobalEventHandlers, ev: TransitionEvent) => any) | null;
+        ontransitionrun: ((this: GlobalEventHandlers, ev: TransitionEvent) => any) | null;
+        ontransitionstart: ((this: GlobalEventHandlers, ev: TransitionEvent) => any) | null;
+        onvolumechange: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onwaiting: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onwebkitanimationend: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onwebkitanimationiteration: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onwebkitanimationstart: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onwebkittransitionend: ((this: GlobalEventHandlers, ev: Event) => any) | null;
+        onwheel: ((this: GlobalEventHandlers, ev: WheelEvent) => any) | null;
+        autofocus: boolean;
+        readonly dataset: DOMStringMap;
+        nonce?: string;
+        tabIndex: number;
+        blur(): void;
+        focus(options?: FocusOptions): void;
+    };
+} & typeof BaseChatView;
+export default class MUCView extends MUCView_base {
     length: number;
     is_chatroom: boolean;
     initialize(): Promise<void>;
@@ -6,4 +401,5 @@ export default class MUCView extends BaseChatView {
     onConnectionStatusChanged(): void;
 }
 import BaseChatView from 'shared/chat/baseview.js';
+export {};
 //# sourceMappingURL=muc.d.ts.map

+ 3 - 1
src/types/shared/chat/baseview.d.ts

@@ -3,13 +3,15 @@ export default class BaseChatView extends CustomElement {
         jid: {
             type: StringConstructor;
         };
+        model: {
+            state: boolean;
+        };
     };
     jid: any;
     model: any;
     viewportMediaQuery: MediaQueryList;
     renderOnViewportChange: () => void;
     connectedCallback(): void;
-    updated(): void;
     /**
      * @param {MouseEvent} ev
      */

+ 0 - 26
src/types/shared/components/disco-browser.d.ts

@@ -1,26 +0,0 @@
-export class DiscoBrowser extends CustomElement {
-    static get properties(): {
-        _entity_jid: {
-            type: StringConstructor;
-            state: boolean;
-        };
-    };
-    _entity_jid: any;
-    render(): import("lit-html").TemplateResult<1>;
-    /**
-     * @param {import('@converse/headless/types/plugins/disco/entity').default} i
-     */
-    renderItem(i: import("@converse/headless/types/plugins/disco/entity").default): import("lit-html").TemplateResult<1>;
-    /**
-     * @param {MouseEvent} ev
-     * @param {import('@converse/headless/types/plugins/disco/entity').default} identity
-     */
-    setEntityJID(ev: MouseEvent, identity: import("@converse/headless/types/plugins/disco/entity").default): void;
-    getDiscoInfo(): Promise<{
-        features: any;
-        identities: any;
-        items: any[];
-    }>;
-}
-import { CustomElement } from './element';
-//# sourceMappingURL=disco-browser.d.ts.map

+ 4 - 0
src/types/shared/components/types.d.ts

@@ -1,2 +1,6 @@
+import { CustomElement } from './element.js';
 export type ObservableProperty = 'once' | 'always' | null;
+type Constructor<T = {}> = new (...args: any[]) => T;
+export type CustomElementExtender = Constructor<CustomElement>;
+export {};
 //# sourceMappingURL=types.d.ts.map

+ 0 - 14
src/types/strophe-shims.d.ts

@@ -1,14 +0,0 @@
-export function getDummyXMLDOMDocument(): XMLDocument;
-export const WebSocket: {
-    new (url: string | URL, protocols?: string | string[]): WebSocket;
-    prototype: WebSocket;
-    readonly CONNECTING: 0;
-    readonly OPEN: 1;
-    readonly CLOSING: 2;
-    readonly CLOSED: 3;
-};
-export const DOMParser: {
-    new (): DOMParser;
-    prototype: DOMParser;
-};
-//# sourceMappingURL=strophe-shims.d.ts.map