2
0

development.rst 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719
  1. .. raw:: html
  2. <div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/development.rst">Edit me on GitHub</a></div>
  3. .. _development:
  4. ===========
  5. Development
  6. ===========
  7. .. contents:: Table of Contents
  8. :depth: 2
  9. :local:
  10. If you want to work with the non-minified Javascript and CSS files you'll soon
  11. notice that there are references to a missing *components* folder. Please
  12. follow the instructions below to create this folder and fetch Converse's
  13. 3rd-party dependencies.
  14. .. note::
  15. Windows environment: We recommend installing the required tools using `Chocolatey <https://chocolatey.org/>`_
  16. You will need Node.js (nodejs.install), Git (git.install) and optionally to build using Makefile, GNU Make (make)
  17. If you have trouble setting up a development environment on Windows,
  18. please read `this post <http://librelist.com/browser//conversejs/2014/11/5/openfire-converse-and-visual-studio-questions/#b28387e7f8f126693b11598a8acbe810>`_
  19. in the mailing list.:
  20. Install the development and front-end dependencies
  21. ==================================================
  22. We use development tools (`Grunt <http://gruntjs.com>`_ and `Bower <http://bower.io>`_)
  23. which depend on Node.js and npm (the Node package manager).
  24. If you don't have Node.js installed, you can download and install the latest
  25. version `here <https://nodejs.org/download>`_.
  26. Also make sure you have ``Git`` installed. `Details <http://git-scm.com/book/en/Getting-Started-Installing-Git>`_.
  27. .. note::
  28. Windows users should use Chocolatey as recommended above.:
  29. .. note::
  30. Debian & Ubuntu users : apt-get install git npm nodejs-legacy
  31. Once you have *Node.js* and *git* installed, run the following command inside the Converse.js
  32. directory:
  33. ::
  34. make dev
  35. On Windows you need to specify Makefile.win to be used by running: ::
  36. make -f Makefile.win dev
  37. Or alternatively, if you don't have GNU Make:
  38. ::
  39. npm install
  40. bower update
  41. This will first install the Node.js development tools (like Grunt and Bower)
  42. and then use Bower to install all of Converse.js's front-end dependencies.
  43. The front-end dependencies are those javascript files on which
  44. Converse.js directly depends and which will be loaded in the browser.
  45. If you are curious to know what the different dependencies are:
  46. * Development dependencies:
  47. Take a look at whats under the *devDependencies* key in
  48. `package.json <https://github.com/jcbrand/converse.js/blob/master/package.json>`_.
  49. * Front-end dependencies:
  50. See *dependencies* in
  51. `bower.json <https://github.com/jcbrand/converse.js/blob/master/bower.json>`_.
  52. .. note::
  53. After running ```make dev```, you should now have a new directory *components*,
  54. which contains all the front-end dependencies of Converse.js.
  55. If this directory does NOT exist, something must have gone wrong.
  56. Double-check the output of ```make dev``` to see if there are any errors
  57. listed. For support, you can write to the mailing list: conversejs@librelist.com
  58. With AMD and require.js (recommended)
  59. =====================================
  60. Converse.js uses `require.js <http://requirejs.org>`_ to asynchronously load dependencies.
  61. If you want to develop or customize converse.js, you'll want to load the
  62. non-minified javascript files.
  63. Add the following two lines to the *<head>* section of your webpage:
  64. .. code-block:: html
  65. <link rel="stylesheet" type="text/css" media="screen" href="converse.css">
  66. <script data-main="main" src="components/requirejs/require.js"></script>
  67. require.js will then let the main.js file be parsed (because of the *data-main*
  68. attribute on the *script* tag), which will in turn cause converse.js to be
  69. parsed.
  70. Without AMD and require.js
  71. ==========================
  72. Converse.js can also be used without require.js. If you for some reason prefer
  73. to use it this way, please refer to
  74. `non_amd.html <https://github.com/jcbrand/converse.js/blob/master/non_amd.html>`_
  75. for an example of how and in what order all the Javascript files that converse.js
  76. depends on need to be loaded.
  77. Before submitting a pull request
  78. ================================
  79. Please follow the usual github workflow. Create your own local fork of this repository,
  80. make your changes and then submit a pull request.
  81. Before submitting a pull request
  82. --------------------------------
  83. Please read the `style guide </docs/html/style_guide.html>`_ and make sure that your code follows it.
  84. Add tests for your bugfix or feature
  85. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  86. Add a test for any bug fixed or feature added. We use Jasmine
  87. for testing.
  88. Take a look at `tests.html <https://github.com/jcbrand/converse.js/blob/master/tests.html>`_
  89. and the `spec files <https://github.com/jcbrand/converse.js/blob/master/tests.html>`_
  90. to see how tests are implemented.
  91. Check that the tests pass
  92. ~~~~~~~~~~~~~~~~~~~~~~~~~
  93. Check that all tests complete sucessfully.
  94. Run ``make check`` in your terminal or open `tests.html <https://github.com/jcbrand/converse.js/blob/master/tests.html>`_
  95. in your browser.
  96. Developer API
  97. =============
  98. .. note:: The API documented here is available in Converse.js 0.8.4 and higher.
  99. Earlier versions of Converse.js might have different API methods or none at all.
  100. In the Converse.js API, you traverse towards a logical grouping, from
  101. which you can then call certain standardised accessors and mutators, like::
  102. .get
  103. .set
  104. .add
  105. .remove
  106. This is done to increase readability and to allow intuitive method chaining.
  107. For example, to get a contact, you would do the following::
  108. converse.contacts.get('jid@example.com');
  109. To get multiple contacts, just pass in an array of jids::
  110. converse.contacts.get(['jid1@example.com', 'jid2@example.com']);
  111. To get all contacts, simply call ``get`` without any jids::
  112. converse.contacts.get();
  113. **Here follows now a breakdown of all API groupings and methods**:
  114. initialize
  115. ----------
  116. .. note:: This method is the one exception of a method which is not logically grouped
  117. as explained above.
  118. Initializes converse.js. This method must always be called when using
  119. converse.js.
  120. The `initialize` method takes a map (also called a hash or dictionary) of
  121. :ref:`configuration-variables`.
  122. Example:
  123. .. code-block:: javascript
  124. converse.initialize({
  125. allow_otr: true,
  126. auto_list_rooms: false,
  127. auto_subscribe: false,
  128. bosh_service_url: 'https://bind.example.com',
  129. hide_muc_server: false,
  130. i18n: locales['en'],
  131. keepalive: true,
  132. play_sounds: true,
  133. prebind: false,
  134. show_controlbox_by_default: true,
  135. debug: false,
  136. roster_groups: true
  137. });
  138. The "user" grouping
  139. -------------------
  140. This grouping collects API functions related to the current logged in user.
  141. logout
  142. ~~~~~~
  143. Log the user out of the current XMPP session.
  144. .. code-block:: javascript
  145. converse.user.logout();
  146. The "status" sub-grouping
  147. ~~~~~~~~~~~~~~~~~~~~~~~~~
  148. Set and get the user's chat status, also called their *availability*.
  149. get
  150. ^^^
  151. Return the current user's availability status:
  152. .. code-block:: javascript
  153. converse.user.status.get(); // Returns for example "dnd"
  154. set
  155. ^^^
  156. The user's status can be set to one of the following values:
  157. * **away**
  158. * **dnd**
  159. * **offline**
  160. * **online**
  161. * **unavailable**
  162. * **xa**
  163. For example:
  164. .. code-block:: javascript
  165. converse.user.status.set('dnd');
  166. Because the user's availability is often set together with a custom status
  167. message, this method also allows you to pass in a status message as a
  168. second parameter:
  169. .. code-block:: javascript
  170. converse.user.status.set('dnd', 'In a meeting');
  171. The "message" sub-grouping
  172. ^^^^^^^^^^^^^^^^^^^^^^^^^^
  173. The ``user.status.message`` sub-grouping exposes methods for setting and
  174. retrieving the user's custom status message.
  175. .. code-block:: javascript
  176. converse.user.status.message.set('In a meeting');
  177. converse.user.status.message.get(); // Returns "In a meeting"
  178. The "contacts" grouping
  179. -----------------------
  180. get
  181. ~~~
  182. This method is used to retrieve roster contacts.
  183. To get a single roster contact, call the method with the contact's JID (Jabber ID):
  184. .. code-block:: javascript
  185. converse.contacts.get('buddy@example.com')
  186. To get multiple contacts, pass in an array of JIDs:
  187. .. code-block:: javascript
  188. converse.contacts.get(['buddy1@example.com', 'buddy2@example.com'])
  189. To return all contacts, simply call ``get`` without any parameters:
  190. .. code-block:: javascript
  191. converse.contacts.get()
  192. The returned roster contact objects have these attributes:
  193. +----------------+-----------------------------------------------------------------------------------------------------------------+
  194. | Attribute | |
  195. +================+=================================================================================================================+
  196. | ask | If ask === 'subscribe', then we have asked this person to be our chat buddy. |
  197. +----------------+-----------------------------------------------------------------------------------------------------------------+
  198. | fullname | The person's full name. |
  199. +----------------+-----------------------------------------------------------------------------------------------------------------+
  200. | jid | The person's Jabber/XMPP username. |
  201. +----------------+-----------------------------------------------------------------------------------------------------------------+
  202. | requesting | If true, then this person is asking to be our chat buddy. |
  203. +----------------+-----------------------------------------------------------------------------------------------------------------+
  204. | subscription | The subscription state between the current user and this chat buddy. Can be `none`, `to`, `from` or `both`. |
  205. +----------------+-----------------------------------------------------------------------------------------------------------------+
  206. | id | A unique id, same as the jid. |
  207. +----------------+-----------------------------------------------------------------------------------------------------------------+
  208. | chat_status | The person's chat status. Can be `online`, `offline`, `busy`, `xa` (extended away) or `away`. |
  209. +----------------+-----------------------------------------------------------------------------------------------------------------+
  210. | user_id | The user id part of the JID (the part before the `@`). |
  211. +----------------+-----------------------------------------------------------------------------------------------------------------+
  212. | resources | The known resources for this chat buddy. Each resource denotes a separate and connected chat client. |
  213. +----------------+-----------------------------------------------------------------------------------------------------------------+
  214. | groups | The roster groups in which this chat buddy was placed. |
  215. +----------------+-----------------------------------------------------------------------------------------------------------------+
  216. | status | Their human readable custom status message. |
  217. +----------------+-----------------------------------------------------------------------------------------------------------------+
  218. | image_type | The image's file type. |
  219. +----------------+-----------------------------------------------------------------------------------------------------------------+
  220. | image | The Base64 encoded image data. |
  221. +----------------+-----------------------------------------------------------------------------------------------------------------+
  222. | url | The buddy's website URL, as specified in their VCard data. |
  223. +----------------+-----------------------------------------------------------------------------------------------------------------+
  224. | vcard_updated | When last the buddy's VCard was updated. |
  225. +----------------+-----------------------------------------------------------------------------------------------------------------+
  226. add
  227. ~~~
  228. Add a contact.
  229. Provide the JID of the contact you want to add:
  230. .. code-block:: javascript
  231. converse.contacts.add('buddy@example.com')
  232. You may also provide the fullname. If not present, we use the jid as fullname:
  233. .. code-block:: javascript
  234. converse.contacts.add('buddy@example.com', 'Buddy')
  235. The "chats" grouping
  236. --------------------
  237. get
  238. ~~~
  239. Returns an object representing a chat box.
  240. To return a single chat box, provide the JID of the contact you're chatting
  241. with in that chat box:
  242. .. code-block:: javascript
  243. converse.chats.get('buddy@example.com')
  244. To return an array of chat boxes, provide an array of JIDs:
  245. .. code-block:: javascript
  246. converse.chats.get(['buddy1@example.com', 'buddy2@example.com'])
  247. To return all open chat boxes, call the method without any JIDs::
  248. converse.chats.get()
  249. open
  250. ~~~~
  251. Opens a chat box and returns an object representing a chat box.
  252. To open a single chat box, provide the JID of the contact:
  253. .. code-block:: javascript
  254. converse.chats.open('buddy@example.com')
  255. To return an array of chat boxes, provide an array of JIDs:
  256. .. code-block:: javascript
  257. converse.chats.open(['buddy1@example.com', 'buddy2@example.com'])
  258. *The returned chat box object contains the following methods:*
  259. +-------------+------------------------------------------+
  260. | Method | Description |
  261. +=============+==========================================+
  262. | endOTR | End an OTR (Off-the-record) session. |
  263. +-------------+------------------------------------------+
  264. | get | Get an attribute (i.e. accessor). |
  265. +-------------+------------------------------------------+
  266. | initiateOTR | Start an OTR (off-the-record) session. |
  267. +-------------+------------------------------------------+
  268. | maximize | Minimize the chat box. |
  269. +-------------+------------------------------------------+
  270. | minimize | Maximize the chat box. |
  271. +-------------+------------------------------------------+
  272. | set | Set an attribute (i.e. mutator). |
  273. +-------------+------------------------------------------+
  274. | close | Close the chat box. |
  275. +-------------+------------------------------------------+
  276. | open | Opens the chat box. |
  277. +-------------+------------------------------------------+
  278. *The get and set methods can be used to retrieve and change the following attributes:*
  279. +-------------+-----------------------------------------------------+
  280. | Attribute | Description |
  281. +=============+=====================================================+
  282. | height | The height of the chat box. |
  283. +-------------+-----------------------------------------------------+
  284. | url | The URL of the chat box heading. |
  285. +-------------+-----------------------------------------------------+
  286. The "rooms" grouping
  287. --------------------
  288. get
  289. ~~~
  290. Returns an object representing a multi user chat box (room).
  291. Similar to chats.get API
  292. open
  293. ~~~~
  294. Opens a multi user chat box and returns an object representing it.
  295. Similar to chats.get API
  296. To open a single multi user chat box, provide the JID of the room:
  297. .. code-block:: javascript
  298. converse.rooms.open('group@muc.example.com')
  299. To return an array of rooms, provide an array of room JIDs:
  300. .. code-block:: javascript
  301. converse.rooms.open(['group1@muc.example.com', 'group2@muc.example.com'])
  302. To setup a custom nickname when joining the room, provide the optional nick argument:
  303. .. code-block:: javascript
  304. converse.rooms.open('group@muc.example.com', 'mycustomnick')
  305. The "settings" grouping
  306. -----------------------
  307. This grouping allows you to get or set the configuration settings of converse.js.
  308. get(key)
  309. ~~~~~~~~
  310. Returns the value of a configuration settings. For example:
  311. .. code-block:: javascript
  312. converse.settings.get("play_sounds"); // default value returned would be false;
  313. set(key, value) or set(object)
  314. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  315. Set one or many configuration settings. For example:
  316. .. code-block:: javascript
  317. converse.settings.set("play_sounds", true);
  318. or :
  319. .. code-block:: javascript
  320. converse.settings.set({
  321. "play_sounds", true,
  322. "hide_offline_users" true
  323. });
  324. Note, this is not an alternative to calling ``converse.initialize``, which still needs
  325. to be called. Generally, you'd use this method after converse.js is already
  326. running and you want to change the configuration on-the-fly.
  327. The "tokens" grouping
  328. ---------------------
  329. get
  330. ~~~
  331. Returns a token, either the RID or SID token depending on what's asked for.
  332. Example:
  333. .. code-block:: javascript
  334. converse.tokens.get('rid')
  335. The "listen" grouping
  336. ---------------------
  337. Converse.js emits events to which you can subscribe from your own Javascript.
  338. Concerning events, the following methods are available under the "listen"
  339. grouping:
  340. * **on(eventName, callback)**:
  341. Calling the ``on`` method allows you to subscribe to an event.
  342. Every time the event fires, the callback method specified by ``callback`` will be
  343. called.
  344. Parameters:
  345. * ``eventName`` is the event name as a string.
  346. * ``callback`` is the callback method to be called when the event is emitted.
  347. For example:
  348. .. code-block:: javascript
  349. converse.listen.on('message', function (event, messageXML) { ... });
  350. * **once(eventName, callback)**:
  351. Calling the ``once`` method allows you to listen to an event
  352. exactly once.
  353. Parameters:
  354. * ``eventName`` is the event name as a string.
  355. * ``callback`` is the callback method to be called when the event is emitted.
  356. For example:
  357. .. code-block:: javascript
  358. converse.listen.once('message', function (event, messageXML) { ... });
  359. * **not(eventName, callback)**
  360. To stop listening to an event, you can use the ``not`` method.
  361. Parameters:
  362. * ``eventName`` is the event name as a string.
  363. * ``callback`` refers to the function that is to be no longer executed.
  364. For example:
  365. .. code-block:: javascript
  366. converse.listen.not('message', function (event, messageXML) { ... });
  367. Events
  368. ======
  369. .. note:: see also the `"listen" grouping`_ API section above.
  370. Event Types
  371. -----------
  372. Here are the different events that are emitted:
  373. +---------------------------------+---------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------+
  374. | Event Type | When is it triggered? | Example |
  375. +=================================+===================================================================================================+======================================================================================================+
  376. | **initialized** | Once converse.js has been initialized. | ``converse.listen.on('initialized', function (event) { ... });`` |
  377. +---------------------------------+---------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------+
  378. | **ready** | After connection has been established and converse.js has got all its ducks in a row. | ``converse.listen.on('ready', function (event) { ... });`` |
  379. +---------------------------------+---------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------+
  380. | **reconnect** | After the connection has dropped. Converse.js will attempt to reconnect when not in prebind mode. | ``converse.listen.on('reconnect', function (event) { ... });`` |
  381. +---------------------------------+---------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------+
  382. | **message** | When a message is received. | ``converse.listen.on('message', function (event, messageXML) { ... });`` |
  383. +---------------------------------+---------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------+
  384. | **messageSend** | When a message will be sent out. | ``storage_memoryconverse.listen.on('messageSend', function (event, messageText) { ... });`` |
  385. +---------------------------------+---------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------+
  386. | **noResumeableSession** | When keepalive=true but there aren't any stored prebind tokens. | ``converse.listen.on('noResumeableSession', function (event) { ... });`` |
  387. +---------------------------------+---------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------+
  388. | **roster** | When the roster is updated. | ``converse.listen.on('roster', function (event, items) { ... });`` |
  389. +---------------------------------+---------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------+
  390. | **callButtonClicked** | When a call button (i.e. with class .toggle-call) on a chat box has been clicked. | ``converse.listen.on('callButtonClicked', function (event, connection, model) { ... });`` |
  391. +---------------------------------+---------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------+
  392. | **chatBoxOpened** | When a chat box has been opened. | ``converse.listen.on('chatBoxOpened', function (event, chatbox) { ... });`` |
  393. +---------------------------------+---------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------+
  394. | **chatRoomOpened** | When a chat room has been opened. | ``converse.listen.on('chatRoomOpened', function (event, chatbox) { ... });`` |
  395. +---------------------------------+---------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------+
  396. | **chatBoxClosed** | When a chat box has been closed. | ``converse.listen.on('chatBoxClosed', function (event, chatbox) { ... });`` |
  397. +---------------------------------+---------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------+
  398. | **chatBoxFocused** | When the focus has been moved to a chat box. | ``converse.listen.on('chatBoxFocused', function (event, chatbox) { ... });`` |
  399. +---------------------------------+---------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------+
  400. | **chatBoxToggled** | When a chat box has been minimized or maximized. | ``converse.listen.on('chatBoxToggled', function (event, chatbox) { ... });`` |
  401. +---------------------------------+---------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------+
  402. | **roomInviteSent** | After the user has sent out a direct invitation, to a roster contact, asking them to join a room. | ``converse.listen.on('roomInvite', function (event, roomview, invitee_jid, reason) { ... });`` |
  403. +---------------------------------+---------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------+
  404. | **roomInviteReceived** | After the user has sent out a direct invitation, to a roster contact, asking them to join a room. | ``converse.listen.on('roomInvite', function (event, roomview, invitee_jid, reason) { ... });`` |
  405. +---------------------------------+---------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------+
  406. | **statusChanged** | When own chat status has changed. | ``converse.listen.on('statusChanged', function (event, status) { ... });`` |
  407. +---------------------------------+---------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------+
  408. | **statusMessageChanged** | When own custom status message has changed. | ``converse.listen.on('statusMessageChanged', function (event, message) { ... });`` |
  409. +---------------------------------+---------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------+
  410. | **contactStatusChanged** | When a chat buddy's chat status has changed. | ``converse.listen.on('contactStatusChanged', function (event, buddy, status) { ... });`` |
  411. +---------------------------------+---------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------+
  412. | **contactStatusMessageChanged** | When a chat buddy's custom status message has changed. | ``converse.listen.on('contactStatusMessageChanged', function (event, buddy, messageText) { ... });`` |
  413. +---------------------------------+---------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------+
  414. Writing a converse.js plugin
  415. ============================
  416. Converse.js exposes a plugin mechanism which allows developers to extend and
  417. override its functionality.
  418. You register a plugin as follows:
  419. .. code-block:: javascript
  420. converse.plugins.add('myplugin', {
  421. // Your plugin code goes in here
  422. });
  423. Security and access to the inner workings
  424. -----------------------------------------
  425. The globally available ``converse`` object, which exposes the API methods, such
  426. as ``initialize`` and ``plugins.add``, is a wrapper that encloses and protects
  427. a sensitive inner object.
  428. This inner object contains all the Backbone models and views, as well as
  429. various other attributes and functions.
  430. Within a plugin, you will have access to this internal
  431. `"closured" <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures>`_
  432. converse object, which is normally not exposed in the global variable scope. The
  433. hiding of this inner object is due to the fact that it contains sensitive information,
  434. such as the user's JID and password (if they logged in manually). You should
  435. therefore make sure NOT to expose this object globally.
  436. An example plugin
  437. -----------------
  438. .. code-block:: javascript
  439. (function (root, factory) {
  440. if (typeof define === 'function' && define.amd) {
  441. define("myplugin", ["jquery", "strophe", "utils", "converse"], factory);
  442. }
  443. }(this, function ($, strophe, utils, converse_api) {
  444. // Wrap your UI strings with the __ function for translation support.
  445. var __ = $.proxy(utils.__, this);
  446. // Strophe methods for building stanzas
  447. var Strophe = strophe.Strophe;
  448. $iq = strophe.$iq;
  449. $msg = strophe.$msg;
  450. $build = strophe.$build;
  451. // The following line registers your plugin.
  452. converse_api.plugins.add('myplugin', {
  453. myFunction: function () {
  454. // This is a function which does not override anything in
  455. // converse.js itself, but in which you still have access to
  456. // the protected "inner" converse object.
  457. var converse = this.converse;
  458. // Custom code comes here
  459. // ...
  460. },
  461. overrides: {
  462. // If you want to override some function or a Backbone model or
  463. // view defined inside converse, then you do that under this
  464. // "overrides" namespace.
  465. // For example, the inner protected *converse* object has a
  466. // method "onConnected". You can override that method as follows:
  467. onConnected: function () {
  468. // Override the onConnected method in converse.js
  469. // You have access to the protected converse object via the
  470. // _super attribute.
  471. var converse = this._super.converse;
  472. // Your custom code comes here.
  473. // ...
  474. // You can access the original function being overridden
  475. // vai the _super attribute.
  476. this._super.onConnected();
  477. },
  478. XMPPStatus: {
  479. // Override converse.js's XMPPStatus Backbone model so that we can override the
  480. // function that sends out the presence stanza.
  481. sendPresence: function (type, status_message, jid) {
  482. var converse = this._super.converse;
  483. // Custom code can come here
  484. // ...
  485. this._super.sendPresence(type, status_message, jid);
  486. }
  487. },
  488. }
  489. });
  490. }));