plugin_development.rst 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. .. raw:: html
  2. <div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/theming.rst">Edit me on GitHub</a></div>
  3. Writing a converse.js plugin
  4. ============================
  5. .. contents:: Table of Contents
  6. :depth: 2
  7. :local:
  8. Introduction
  9. ------------
  10. Developers are able to extend and override the objects, functions and the
  11. Backbone models and views that make up converse.js by means of writing plugins.
  12. Converse.js uses `pluggable.js <https://github.com/jcbrand/pluggable.js/>`_ as
  13. its plugin architecture.
  14. To understand how this plugin architecture works, please read the
  15. `pluggable.js documentation <https://jcbrand.github.io/pluggable.js/>`_
  16. and to grok its inner workins, please refer to the `annotated source code
  17. <https://jcbrand.github.io/pluggable.js/docs/pluggable.html>`_.
  18. You register a converse.js plugin as follows:
  19. .. code-block:: javascript
  20. converse.plugins.add('myplugin', {
  21. // Your plugin code goes in here
  22. });
  23. Security and access to the inner workings
  24. -----------------------------------------
  25. The globally available ``converse`` object, which exposes the API methods, such
  26. as ``initialize`` and ``plugins.add``, is a wrapper that encloses and protects
  27. a sensitive inner object.
  28. This inner object contains all the Backbone models and views, as well as
  29. various other attributes and functions.
  30. Within a plugin, you will have access to this internal
  31. `"closured" <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures>`_
  32. converse object, which is normally not exposed in the global variable scope. The
  33. hiding of this inner object is due to the fact that it contains sensitive information,
  34. such as the user's JID and password (if they logged in manually). You should
  35. therefore make sure NOT to expose this object globally.
  36. An example plugin
  37. -----------------
  38. .. code-block:: javascript
  39. (function (root, factory) {
  40. if (typeof define === 'function' && define.amd) {
  41. // AMD. Register as a module called "myplugin"
  42. define("myplugin", ["converse"], factory);
  43. } else {
  44. // Browser globals. If you're not using a module loader such as require.js,
  45. // then this line below executes. Make sure that your plugin's <script> tag
  46. // appears after the one from converse.js.
  47. factory(converse);
  48. }
  49. }(this, function (converse_api) {
  50. // Commonly used utilities and variables can be found under the "env"
  51. // namespace of converse_api
  52. // Strophe methods for building stanzas
  53. var Strophe = converse_api.env.Strophe,
  54. $iq = converse_api.env.$iq,
  55. $msg = converse_api.env.$msg,
  56. $pres = converse_api.env.$pres,
  57. $build = converse_api.env.$build,
  58. b64_sha1 = converse_api.env.b64_sha1;
  59. // Other frequently used utilities
  60. var $ = converse_api.env.jQuery,
  61. _ = converse_api.env._,
  62. moment = converse_api.env.moment;
  63. // The following line registers your plugin.
  64. converse_api.plugins.add('myplugin', {
  65. initialize: function () {
  66. // Converse.js's plugin mechanism will call the initialize
  67. // method on any plugin (if it exists) as soon as the plugin has
  68. // been loaded.
  69. // Inside this method, you have access to the protected "inner"
  70. // converse object, from which you can get any configuration
  71. // options that the user might have passed in via
  72. // converse.initialize. These values are stored in the
  73. // "user_settings" attribute.
  74. // Let's assume the user might in a custom setting, like so:
  75. // converse.initialize({
  76. // "initialize_message": "My plugin has been initialized"
  77. // });
  78. //
  79. // Then we can alert that message, like so:
  80. alert(this.converse.user_settings.initialize_message);
  81. },
  82. myFunction: function () {
  83. // This is a function which does not override anything in
  84. // converse.js itself, but in which you still have access to
  85. // the protected "inner" converse object.
  86. var converse = this.converse;
  87. // Custom code comes here
  88. // ...
  89. },
  90. overrides: {
  91. // If you want to override some function or a Backbone model or
  92. // view defined inside converse, then you do that under this
  93. // "overrides" namespace.
  94. // For example, the inner protected *converse* object has a
  95. // method "onConnected". You can override that method as follows:
  96. onConnected: function () {
  97. // Overrides the onConnected method in converse.js
  98. // Top-level functions in "overrides" are bound to the
  99. // inner "converse" object.
  100. var converse = this;
  101. // Your custom code comes here.
  102. // ...
  103. // You can access the original function being overridden
  104. // via the __super__ attribute.
  105. // Make sure to pass on the arguments supplied to this
  106. // function and also to apply the proper "this" object.
  107. this.__super__.onConnected.apply(this, arguments);
  108. },
  109. XMPPStatus: {
  110. // Override converse.js's XMPPStatus Backbone model so that we can override the
  111. // function that sends out the presence stanza.
  112. sendPresence: function (type, status_message, jid) {
  113. // The "converse" object is available via the __super__
  114. // attribute.
  115. var converse = this.__super__.converse;
  116. // Custom code can come here
  117. // ...
  118. // You can call the original overridden method, by
  119. // accessing it via the __super__ attribute.
  120. // When calling it, you need to apply the proper
  121. // context as reference by the "this" variable.
  122. this.__super__.sendPresence.apply(this, arguments);
  123. }
  124. },
  125. }
  126. });
  127. }));