Converse converse.js

Source: headless/shared/api/public.js

  1. import ConnectionFeedback from './../connection/feedback.js';
  2. import URI from 'urijs';
  3. import _converse from '../_converse.js';
  4. import dayjs from 'dayjs';
  5. import i18n from '../i18n';
  6. import log from '../../log.js';
  7. import sizzle from 'sizzle';
  8. import u, { setUnloadEvent } from '../../utils/core.js';
  9. import { ANONYMOUS, CHAT_STATES, KEYCODES, VERSION_NAME } from '../constants.js';
  10. import { Collection } from "@converse/skeletor/src/collection";
  11. import { Model } from '@converse/skeletor/src/model.js';
  12. import { Strophe, $build, $iq, $msg, $pres } from 'strophe.js';
  13. import { TimeoutError } from '../errors.js';
  14. import { filesize } from 'filesize';
  15. import { html } from 'lit';
  16. import { initAppSettings } from '../settings/utils.js';
  17. import { sprintf } from 'sprintf-js';
  18. import { stx } from '../../utils/stanza.js';
  19. import {
  20. cleanup,
  21. initClientConfig,
  22. initPlugins,
  23. initSessionStorage,
  24. registerGlobalEventHandlers,
  25. } from '../../utils/init.js';
  26. /**
  27. * ### The Public API
  28. *
  29. * This namespace contains public API methods which are are
  30. * accessible on the global `converse` object.
  31. * They are public, because any JavaScript in the
  32. * page can call them. Public methods therefore don’t expose any sensitive
  33. * or closured data. To do that, you’ll need to create a plugin, which has
  34. * access to the private API method.
  35. *
  36. * @global
  37. * @namespace converse
  38. */
  39. export const converse = Object.assign(window.converse || {}, {
  40. CHAT_STATES,
  41. keycodes: KEYCODES,
  42. /**
  43. * Public API method which initializes Converse.
  44. * This method must always be called when using Converse.
  45. * @async
  46. * @memberOf converse
  47. * @method initialize
  48. * @param { object } config A map of [configuration-settings](https://conversejs.org/docs/html/configuration.html#configuration-settings).
  49. * @example
  50. * converse.initialize({
  51. * auto_list_rooms: false,
  52. * auto_subscribe: false,
  53. * bosh_service_url: 'https://bind.example.com',
  54. * hide_muc_server: false,
  55. * i18n: 'en',
  56. * play_sounds: true,
  57. * show_controlbox_by_default: true,
  58. * debug: false,
  59. * roster_groups: true
  60. * });
  61. */
  62. async initialize (settings) {
  63. const { api } = _converse;
  64. await cleanup(_converse);
  65. setUnloadEvent();
  66. initAppSettings(settings);
  67. _converse.strict_plugin_dependencies = settings.strict_plugin_dependencies; // Needed by pluggable.js
  68. log.setLogLevel(api.settings.get("loglevel"));
  69. if (api.settings.get("authentication") === ANONYMOUS) {
  70. if (api.settings.get("auto_login") && !api.settings.get('jid')) {
  71. throw new Error("Config Error: you need to provide the server's " +
  72. "domain via the 'jid' option when using anonymous " +
  73. "authentication with auto_login.");
  74. }
  75. }
  76. _converse.router.route(
  77. /^converse\?loglevel=(debug|info|warn|error|fatal)$/, 'loglevel',
  78. l => log.setLogLevel(l)
  79. );
  80. _converse.connfeedback = new ConnectionFeedback();
  81. /* When reloading the page:
  82. * For new sessions, we need to send out a presence stanza to notify
  83. * the server/network that we're online.
  84. * When re-attaching to an existing session we don't need to again send out a presence stanza,
  85. * because it's as if "we never left" (see onConnectStatusChanged).
  86. * https://github.com/conversejs/converse.js/issues/521
  87. */
  88. _converse.send_initial_presence = true;
  89. await initSessionStorage(_converse);
  90. await initClientConfig(_converse);
  91. await i18n.initialize();
  92. initPlugins(_converse);
  93. // Register all custom elements
  94. // XXX: api.elements is defined in the UI part of Converse, outside of @converse/headless.
  95. // This line should probably be moved to the UI code as part of a larger refactoring.
  96. api.elements?.register();
  97. registerGlobalEventHandlers(_converse);
  98. try {
  99. !History.started && _converse.router.history.start();
  100. } catch (e) {
  101. log.error(e);
  102. }
  103. const plugins = _converse.pluggable.plugins
  104. if (api.settings.get("auto_login") || api.settings.get("keepalive") && plugins['converse-bosh']?.enabled()) {
  105. await api.user.login(null, null, true);
  106. }
  107. /**
  108. * Triggered once converse.initialize has finished.
  109. * @event _converse#initialized
  110. */
  111. api.trigger('initialized');
  112. if (_converse.isTestEnv()) {
  113. return _converse;
  114. }
  115. },
  116. /**
  117. * Exposes methods for adding and removing plugins. You'll need to write a plugin
  118. * if you want to have access to the private API methods defined further down below.
  119. *
  120. * For more information on plugins, read the documentation on [writing a plugin](/docs/html/plugin_development.html).
  121. * @namespace plugins
  122. * @memberOf converse
  123. */
  124. plugins: {
  125. /**
  126. * Registers a new plugin.
  127. * @method converse.plugins.add
  128. * @param { string } name The name of the plugin
  129. * @param { object } plugin The plugin object
  130. * @example
  131. * const plugin = {
  132. * initialize: function () {
  133. * // Gets called as soon as the plugin has been loaded.
  134. *
  135. * // Inside this method, you have access to the private
  136. * // API via `_covnerse.api`.
  137. *
  138. * // The private _converse object contains the core logic
  139. * // and data-structures of Converse.
  140. * }
  141. * }
  142. * converse.plugins.add('myplugin', plugin);
  143. */
  144. add (name, plugin) {
  145. plugin.__name__ = name;
  146. if (_converse.pluggable.plugins[name] !== undefined) {
  147. throw new TypeError(
  148. `Error: plugin with name "${name}" has already been ` + 'registered!'
  149. );
  150. } else {
  151. _converse.pluggable.plugins[name] = plugin;
  152. }
  153. }
  154. },
  155. /**
  156. * Utility methods and globals from bundled 3rd party libraries.
  157. * @typedef ConverseEnv
  158. * @property { Error } converse.env.TimeoutError
  159. * @property { function } converse.env.$build - Creates a Strophe.Builder, for creating stanza objects.
  160. * @property { function } converse.env.$iq - Creates a Strophe.Builder with an <iq/> element as the root.
  161. * @property { function } converse.env.$msg - Creates a Strophe.Builder with an <message/> element as the root.
  162. * @property { function } converse.env.$pres - Creates a Strophe.Builder with an <presence/> element as the root.
  163. * @property { function } converse.env.Promise - The Promise implementation used by Converse.
  164. * @property { function } converse.env.Strophe - The [Strophe](http://strophe.im/strophejs) XMPP library used by Converse.
  165. * @property { function } converse.env.f - And instance of Lodash with its methods wrapped to produce immutable auto-curried iteratee-first data-last methods.
  166. * @property { function } converse.env.sizzle - [Sizzle](https://sizzlejs.com) CSS selector engine.
  167. * @property { function } converse.env.sprintf
  168. * @property { object } converse.env._ - The instance of [lodash-es](http://lodash.com) used by Converse.
  169. * @property { object } converse.env.dayjs - [DayJS](https://github.com/iamkun/dayjs) date manipulation library.
  170. * @property { object } converse.env.utils - Module containing common utility methods used by Converse.
  171. * @memberOf converse
  172. */
  173. 'env': {
  174. $build,
  175. $iq,
  176. $msg,
  177. $pres,
  178. 'utils': u,
  179. Collection,
  180. Model,
  181. Promise,
  182. Strophe,
  183. TimeoutError,
  184. URI,
  185. VERSION_NAME,
  186. dayjs,
  187. filesize,
  188. html,
  189. log,
  190. sizzle,
  191. sprintf,
  192. stx,
  193. u,
  194. }
  195. });