development.rst 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  1. ===========
  2. Development
  3. ===========
  4. .. contents:: Table of Contents
  5. :depth: 2
  6. :local:
  7. If you want to work with the non-minified Javascript and CSS files you'll soon
  8. notice that there are references to a missing *components* folder. Please
  9. follow the instructions below to create this folder and fetch Converse's
  10. 3rd-party dependencies.
  11. .. note::
  12. If you have trouble setting up a development environment on Windows,
  13. please read `this post <http://librelist.com/browser//conversejs/2014/11/5/openfire-converse-and-visual-studio-questions/#b28387e7f8f126693b11598a8acbe810>`_
  14. in the mailing list.:
  15. Install the development and front-end dependencies
  16. ==================================================
  17. We use development tools (`Grunt <http://gruntjs.com>`_ and `Bower <http://bower.io>`_)
  18. which depend on Node.js and npm (the Node package manager).
  19. If you don't have Node.js installed, you can download and install the latest
  20. version `here <https://nodejs.org/download>`_.
  21. Also make sure you have ``Git`` installed. `Details <http://git-scm.com/book/en/Getting-Started-Installing-Git>`_.
  22. Once you have *Node.js* and *git* installed, run the following command inside the Converse.js
  23. directory:
  24. ::
  25. make dev
  26. Or alternatively, if you don't have GNU Make:
  27. ::
  28. npm install
  29. bower update
  30. This will first install the Node.js development tools (like Grunt and Bower)
  31. and then use Bower to install all of Converse.js's front-end dependencies.
  32. The front-end dependencies are those javascript files on which
  33. Converse.js directly depends and which will be loaded in the browser.
  34. If you are curious to know what the different dependencies are:
  35. * Development dependencies:
  36. Take a look at whats under the *devDependencies* key in
  37. `package.json <https://github.com/jcbrand/converse.js/blob/master/package.json>`_.
  38. * Front-end dependencies:
  39. See *dependencies* in
  40. `bower.json <https://github.com/jcbrand/converse.js/blob/master/bower.json>`_.
  41. .. note::
  42. After running ```make dev```, you should now have a new directory *components*,
  43. which contains all the front-end dependencies of Converse.js.
  44. If this directory does NOT exist, something must have gone wrong.
  45. Double-check the output of ```make dev``` to see if there are any errors
  46. listed. For support, you can write to the mailing list: conversejs@librelist.com
  47. With AMD and require.js (recommended)
  48. =====================================
  49. Converse.js uses `require.js <http://requirejs.org>`_ to asynchronously load dependencies.
  50. If you want to develop or customize converse.js, you'll want to load the
  51. non-minified javascript files.
  52. Add the following two lines to the *<head>* section of your webpage:
  53. .. code-block:: html
  54. <link rel="stylesheet" type="text/css" media="screen" href="converse.css">
  55. <script data-main="main" src="components/requirejs/require.js"></script>
  56. require.js will then let the main.js file be parsed (because of the *data-main*
  57. attribute on the *script* tag), which will in turn cause converse.js to be
  58. parsed.
  59. Without AMD and require.js
  60. ==========================
  61. Converse.js can also be used without require.js. If you for some reason prefer
  62. to use it this way, please refer to
  63. `non_amd.html <https://github.com/jcbrand/converse.js/blob/master/non_amd.html>`_
  64. for an example of how and in what order all the Javascript files that converse.js
  65. depends on need to be loaded.
  66. Before submitting a pull request
  67. ================================
  68. Add tests for your bugfix or feature
  69. ------------------------------------
  70. Add a test for any bug fixed or feature added. We use Jasmine
  71. for testing.
  72. Take a look at ``tests.html`` and ``spec/MainSpec.js`` to see how
  73. the tests are implemented.
  74. If you are unsure how to write tests, please
  75. `contact me <http://opkode.com/contact>`_ and I'll be happy to help.
  76. Check that the tests pass
  77. -------------------------
  78. Check that the Jasmine tests complete sucessfully. Open
  79. `tests.html <https://github.com/jcbrand/converse.js/blob/master/tests.html>`_
  80. in your browser, and the tests will run automatically.
  81. On the command line you can run:
  82. ::
  83. grunt test
  84. Check your code for errors or bad habits by running JSHint
  85. ----------------------------------------------------------
  86. `JSHint <http://jshint.com>`_ will do a static analysis of your code and hightlight potential errors
  87. and/or bad habits.
  88. ::
  89. grunt jshint
  90. You can run both the tests and jshint in one go by calling:
  91. ::
  92. grunt check
  93. Developer API
  94. =============
  95. .. note:: The API documented here is available in Converse.js 0.8.4 and higher.
  96. Earlier versions of Converse.js might have different API methods or none at all.
  97. In the Converse.js API, you traverse towards a logical grouping, from
  98. which you can then call certain standardised accessors and mutators, like::
  99. .get
  100. .set
  101. .add
  102. .all
  103. .remove
  104. This is done to increase readability and to allow intuitive method chaining.
  105. For example, to get a contact, you would do the following::
  106. converse.contacts.get('jid@example.com');
  107. To get multiple contacts, just pass in an array of jids::
  108. converse.contacts.get(['jid1@example.com', 'jid2@example.com']);
  109. **Here follows now a breakdown of all API groupings and methods**:
  110. initialize
  111. ----------
  112. .. note:: This method is the one exception of a method which is not logically grouped
  113. as explained above.
  114. Initializes converse.js. This method must always be called when using
  115. converse.js.
  116. The `initialize` method takes a map (also called a hash or dictionary) of
  117. :ref:`configuration-variables`.
  118. Example:
  119. .. code-block:: javascript
  120. converse.initialize({
  121. allow_otr: true,
  122. auto_list_rooms: false,
  123. auto_subscribe: false,
  124. bosh_service_url: 'https://bind.example.com',
  125. hide_muc_server: false,
  126. i18n: locales['en'],
  127. keepalive: true,
  128. play_sounds: true,
  129. prebind: false,
  130. show_controlbox_by_default: true,
  131. debug: false,
  132. roster_groups: true
  133. });
  134. "contacts" grouping
  135. -------------------
  136. get
  137. ~~~
  138. Returns a map of attributes for a given buddy (i.e. roster contact), specified
  139. by JID (Jabber ID).
  140. Example::
  141. converse.contacts.get('buddy@example.com')
  142. The map of attributes:
  143. +----------------+--------------------------------------------------------------------------------------------------------------------------------------+
  144. | Attribute | |
  145. +================+======================================================================================================================================+
  146. | ask | If ask === 'subscribe', then we have asked this person to be our chat buddy. |
  147. +----------------+--------------------------------------------------------------------------------------------------------------------------------------+
  148. | fullname | The person's full name. |
  149. +----------------+--------------------------------------------------------------------------------------------------------------------------------------+
  150. | jid | The person's Jabber/XMPP username. |
  151. +----------------+--------------------------------------------------------------------------------------------------------------------------------------+
  152. | requesting | If true, then this person is asking to be our chat buddy. |
  153. +----------------+--------------------------------------------------------------------------------------------------------------------------------------+
  154. | subscription | The subscription state between the current user and this chat buddy. Can be `none`, `to`, `from` or `both`. |
  155. +----------------+--------------------------------------------------------------------------------------------------------------------------------------+
  156. | id | A unique id, same as the jid. |
  157. +----------------+--------------------------------------------------------------------------------------------------------------------------------------+
  158. | chat_status | The person's chat status. Can be `online`, `offline`, `busy`, `xa` (extended away) or `away`. |
  159. +----------------+--------------------------------------------------------------------------------------------------------------------------------------+
  160. | user_id | The user id part of the JID (the part before the `@`). |
  161. +----------------+--------------------------------------------------------------------------------------------------------------------------------------+
  162. | resources | The known resources for this chat buddy. Each resource denotes a separate and connected chat client. |
  163. +----------------+--------------------------------------------------------------------------------------------------------------------------------------+
  164. | groups | The roster groups in which this chat buddy was placed. |
  165. +----------------+--------------------------------------------------------------------------------------------------------------------------------------+
  166. | status | Their human readable custom status message. |
  167. +----------------+--------------------------------------------------------------------------------------------------------------------------------------+
  168. | image_type | The image's file type. |
  169. +----------------+--------------------------------------------------------------------------------------------------------------------------------------+
  170. | image | The Base64 encoded image data. |
  171. +----------------+--------------------------------------------------------------------------------------------------------------------------------------+
  172. | url | The buddy's website URL, as specified in their VCard data. |
  173. +----------------+--------------------------------------------------------------------------------------------------------------------------------------+
  174. | vcard_updated | When last the buddy's VCard was updated. |
  175. +----------------+--------------------------------------------------------------------------------------------------------------------------------------+
  176. "chats" grouping
  177. ----------------
  178. get
  179. ~~~
  180. Returns an object/map representing a chat box (without opening or affecting that chat box).
  181. Example::
  182. converse.chats.get('buddy@example.com')
  183. *The returned chat box contains the following methods:*
  184. +-------------+------------------------------------------+
  185. | Method | Description |
  186. +=============+==========================================+
  187. | endOTR | End an OTR (Off-the-record) session. |
  188. +-------------+------------------------------------------+
  189. | get | Get an attribute (i.e. accessor). |
  190. +-------------+------------------------------------------+
  191. | initiateOTR | Start an OTR (off-the-record) session. |
  192. +-------------+------------------------------------------+
  193. | maximize | Minimize the chat box. |
  194. +-------------+------------------------------------------+
  195. | minimize | Maximize the chat box. |
  196. +-------------+------------------------------------------+
  197. | set | Set an attribute (i.e. mutator). |
  198. +-------------+------------------------------------------+
  199. *The get and set methods can be used to retrieve and change the following attributes:*
  200. +-------------+-----------------------------------------------------+
  201. | Attribute | Description |
  202. +=============+=====================================================+
  203. | height | The height of the chat box. |
  204. +-------------+-----------------------------------------------------+
  205. | url | The URL of the chat box heading. |
  206. +-------------+-----------------------------------------------------+
  207. "tokens" grouping
  208. -----------------
  209. get
  210. ~~~
  211. Returns a token, either the RID or SID token depending on what's asked for.
  212. Example::
  213. converse.tokens.get('rid')
  214. "listen" grouping
  215. -----------------
  216. Converse.js emits events to which you can subscribe from your own Javascript.
  217. Concerning events, the following methods are available under the "listen"
  218. grouping:
  219. * **on(eventName, callback)**:
  220. Calling the ``on`` method allows you to subscribe to an event.
  221. Every time the event fires, the callback method specified by ``callback`` will be
  222. called.
  223. Parameters:
  224. * ``eventName`` is the event name as a string.
  225. * ``callback`` is the callback method to be called when the event is emitted.
  226. For example::
  227. converse.listen.on('message', function (messageXML) { ... });
  228. * **once(eventName, callback)**:
  229. Calling the ``once`` method allows you to listen to an event
  230. exactly once.
  231. Parameters:
  232. * ``eventName`` is the event name as a string.
  233. * ``callback`` is the callback method to be called when the event is emitted.
  234. For example::
  235. converse.listen.once('message', function (messageXML) { ... });
  236. * **not(eventName, callback)**
  237. To stop listening to an event, you can use the ``not`` method.
  238. Parameters:
  239. * ``eventName`` is the event name as a string.
  240. * ``callback`` refers to the function that is to be no longer executed.
  241. For example::
  242. converse.listen.not('message', function (messageXML) { ... });
  243. Events
  244. ======
  245. .. note:: see also the `"listen" grouping`_ API section above.
  246. Event Types
  247. -----------
  248. Here are the different events that are emitted:
  249. +--------------------------------+---------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+
  250. | Event Type | When is it triggered? | Example |
  251. +================================+===================================================================================================+=========================================================================================+
  252. | **initialized** | Once converse.js has been initialized. | ``converse.on('initialized', function () { ... });`` |
  253. +--------------------------------+---------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+
  254. | **ready** | After connection has been established and converse.js has got all its ducks in a row. | ``converse.on('ready', function () { ... });`` |
  255. +--------------------------------+---------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+
  256. | **reconnect** | After the connection has dropped. Converse.js will attempt to reconnect when not in prebind mode. | ``converse.on('reconnect', function () { ... });`` |
  257. +--------------------------------+---------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+
  258. | **message** | When a message is received. | ``converse.on('message', function (messageXML) { ... });`` |
  259. +--------------------------------+---------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+
  260. | **messageSend** | When a message will be sent out. | ``converse.on('messageSend', function (messageText) { ... });`` |
  261. +--------------------------------+---------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+
  262. | **noResumeableSession** | When keepalive=true but there aren't any stored prebind tokens. | ``converse.on('noResumeableSession', function () { ... });`` |
  263. +--------------------------------+---------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+
  264. | **roster** | When the roster is updated. | ``converse.on('roster', function (items) { ... });`` |
  265. +--------------------------------+---------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+
  266. | **callButtonClicked** | When a call button (i.e. with class .toggle-call) on a chat box has been clicked. | ``converse.on('callButtonClicked', function (connection, model) { ... });`` |
  267. +--------------------------------+---------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+
  268. | **chatBoxOpened** | When a chat box has been opened. | ``converse.on('chatBoxOpened', function (chatbox) { ... });`` |
  269. +--------------------------------+---------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+
  270. | **chatRoomOpened** | When a chat room has been opened. | ``converse.on('chatRoomOpened', function (chatbox) { ... });`` |
  271. +--------------------------------+---------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+
  272. | **chatBoxClosed** | When a chat box has been closed. | ``converse.on('chatBoxClosed', function (chatbox) { ... });`` |
  273. +--------------------------------+---------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+
  274. | **chatBoxFocused** | When the focus has been moved to a chat box. | ``converse.on('chatBoxFocused', function (chatbox) { ... });`` |
  275. +--------------------------------+---------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+
  276. | **chatBoxToggled** | When a chat box has been minimized or maximized. | ``converse.on('chatBoxToggled', function (chatbox) { ... });`` |
  277. +--------------------------------+---------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+
  278. | **roomInviteSent** | After the user has sent out a direct invitation, to a roster contact, asking them to join a room. | ``converse.on('roomInvite', function (roomview, invitee_jid, reason) { ... });`` |
  279. +--------------------------------+---------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+
  280. | **roomInviteReceived** | After the user has sent out a direct invitation, to a roster contact, asking them to join a room. | ``converse.on('roomInvite', function (roomview, invitee_jid, reason) { ... });`` |
  281. +--------------------------------+---------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+
  282. | **statusChanged** | When own chat status has changed. | ``converse.on('statusChanged', function (status) { ... });`` |
  283. +--------------------------------+---------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+
  284. | **statusMessageChanged** | When own custom status message has changed. | ``converse.on('statusMessageChanged', function (message) { ... });`` |
  285. +--------------------------------+---------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+
  286. | **contactStatusChanged** | When a chat buddy's chat status has changed. | ``converse.on('contactStatusChanged', function (buddy, status) { ... });`` |
  287. +--------------------------------+---------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+
  288. | **contactStatusMessageChanged**| When a chat buddy's custom status message has changed. | ``converse.on('contactStatusMessageChanged', function (buddy, messageText) { ... });`` |
  289. +--------------------------------+---------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+