converse.js
Version:
Browser based XMPP chat client
197 lines (175 loc) • 6.28 kB
JavaScript
/**
* @typedef {module:shared-api-public.ConversePrivateGlobal} ConversePrivateGlobal
*/
import { sprintf } from 'sprintf-js';
import dayjs from 'dayjs';
import sizzle from 'sizzle';
import { Stanza, Strophe, $build, $iq, $msg, $pres, stx } from 'strophe.js';
import { Collection, Model } from "@converse/skeletor";
import { filesize } from 'filesize';
import { css, html, render, nothing } from 'lit';
import api from './index.js';
import _converse from '../_converse.js';
import i18n from '../i18n';
import log from "@converse/log";
import ConnectionFeedback from './../connection/feedback.js';
import u, { setLogLevelFromRoute } from '../../utils/index.js';
import { ANONYMOUS, CHAT_STATES, KEYCODES, VERSION_NAME } from '../constants.js';
import { isTestEnv } from '../../utils/session.js';
import { TimeoutError } from '../errors.js';
import { initAppSettings } from '../settings/utils.js';
import * as errors from '../errors.js';
_converse.api = api;
import {
cleanup,
initClientConfig,
initPlugins,
initSessionStorage,
registerGlobalEventHandlers,
} from '../../utils/init.js';
const env = /** @type {import('./types').ConverseEnv} */ {
$build,
$iq,
$msg,
$pres,
Collection,
Model,
Stanza,
Strophe,
TimeoutError,
VERSION_NAME,
css,
dayjs,
errors,
filesize,
html,
log,
nothing,
render,
sizzle,
sprintf,
stx,
u,
utils: u,
}
/**
* @typedef {Window & {converse: ConversePrivateGlobal} } window
*
* ### The Public API
*
* This namespace contains public API methods which are are
* accessible on the global `converse` object.
* They are public, because any JavaScript in the
* page can call them. Public methods therefore don’t expose any sensitive
* or closured data. To do that, you’ll need to create a plugin, which has
* access to the private API method.
*
* @global
* @namespace converse
*/
const converse = Object.assign(/** @type {ConversePrivateGlobal} */(window).converse || {}, {
CHAT_STATES,
keycodes: KEYCODES,
/**
* Public API method which initializes Converse.
* This method must always be called when using Converse.
* @async
* @memberOf converse
* @method initialize
* @param { object } settings A map of [configuration-settings](https://conversejs.org/docs/html/configuration.html#configuration-settings).
* @example
* converse.initialize({
* auto_list_rooms: false,
* auto_subscribe: false,
* bosh_service_url: 'https://bind.example.com',
* hide_muc_server: false,
* i18n: 'en',
* play_sounds: true,
* show_controlbox_by_default: true,
* debug: false,
* roster_groups: true
* });
*/
async initialize (settings) {
const { api } = _converse;
await cleanup(_converse);
initAppSettings(settings);
_converse.strict_plugin_dependencies = settings.strict_plugin_dependencies; // Needed by pluggable.js
log.setLogLevel(api.settings.get("loglevel"));
if (api.settings.get("authentication") === ANONYMOUS) {
if (api.settings.get("auto_login") && !api.settings.get('jid')) {
throw new Error("Config Error: you need to provide the server's " +
"domain via the 'jid' option when using anonymous " +
"authentication with auto_login.");
}
}
setLogLevelFromRoute();
addEventListener('hashchange', setLogLevelFromRoute);
const connfeedback = new ConnectionFeedback();
Object.assign(_converse, { connfeedback }); // XXX: DEPRECATED
Object.assign(_converse.state, { connfeedback });
_converse.env = env;
await initSessionStorage(_converse);
await initClientConfig(_converse);
await i18n.initialize();
initPlugins(_converse);
// Register all custom elements
// XXX: api.elements is defined in the UI part of Converse, outside of @converse/headless.
// This line should probably be moved to the UI code as part of a larger refactoring.
api.elements?.register();
registerGlobalEventHandlers(_converse);
const plugins = _converse.pluggable.plugins
if (api.settings.get("auto_login") || api.settings.get("keepalive") && plugins['converse-bosh']?.enabled()) {
await api.user.login(null, null, true);
}
/**
* Triggered once converse.initialize has finished.
* @event _converse#initialized
*/
api.trigger('initialized');
if (isTestEnv()) {
return _converse;
}
},
/**
* Exposes methods for adding and removing plugins. You'll need to write a plugin
* if you want to have access to the private API methods defined further down below.
*
* For more information on plugins, read the documentation on [writing a plugin](/docs/html/plugin_development.html).
* @namespace plugins
* @memberOf converse
*/
plugins: {
/**
* Registers a new plugin.
* @method converse.plugins.add
* @param { string } name The name of the plugin
* @param { object } plugin The plugin object
* @example
* const plugin = {
* initialize: function () {
* // Gets called as soon as the plugin has been loaded.
*
* // Inside this method, you have access to the private
* // API via `_covnerse.api`.
*
* // The private _converse object contains the core logic
* // and data-structures of Converse.
* }
* }
* converse.plugins.add('myplugin', plugin);
*/
add (name, plugin) {
plugin.__name__ = name;
if (_converse.pluggable.plugins[name] !== undefined) {
throw new TypeError(
`Error: plugin with name "${name}" has already been ` + 'registered!'
);
} else {
_converse.pluggable.plugins[name] = plugin;
}
}
},
env,
});
export default converse;