converse-api.js 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. // Converse.js (A browser based XMPP chat client)
  2. // http://conversejs.org
  3. //
  4. // Copyright (c) 2012-2016, Jan-Carel Brand <jc@opkode.com>
  5. // Licensed under the Mozilla Public License (MPLv2)
  6. //
  7. /*global define */
  8. (function (root, factory) {
  9. define("converse-api", [
  10. "jquery",
  11. "underscore",
  12. "moment_with_locales",
  13. "strophe",
  14. "utils",
  15. "converse-core"
  16. ],
  17. factory);
  18. }(this, function ($, _, moment, strophe, utils, converse) {
  19. var Strophe = strophe.Strophe;
  20. return {
  21. 'initialize': function (settings, callback) {
  22. return converse.initialize(settings, callback);
  23. },
  24. 'log': converse.log,
  25. 'connection': {
  26. 'connected': function () {
  27. return converse.connection && converse.connection.connected || false;
  28. },
  29. 'disconnect': function () {
  30. converse.connection.disconnect();
  31. },
  32. },
  33. 'user': {
  34. 'jid': function () {
  35. return converse.connection.jid;
  36. },
  37. 'login': function (credentials) {
  38. converse.initConnection();
  39. converse.logIn(credentials);
  40. },
  41. 'logout': function () {
  42. converse.logOut();
  43. },
  44. 'status': {
  45. 'get': function () {
  46. return converse.xmppstatus.get('status');
  47. },
  48. 'set': function (value, message) {
  49. var data = {'status': value};
  50. if (!_.contains(_.keys(converse.STATUS_WEIGHTS), value)) {
  51. throw new Error('Invalid availability value. See https://xmpp.org/rfcs/rfc3921.html#rfc.section.2.2.2.1');
  52. }
  53. if (typeof message === "string") {
  54. data.status_message = message;
  55. }
  56. converse.xmppstatus.sendPresence(value);
  57. converse.xmppstatus.save(data);
  58. },
  59. 'message': {
  60. 'get': function () {
  61. return converse.xmppstatus.get('status_message');
  62. },
  63. 'set': function (stat) {
  64. converse.xmppstatus.save({'status_message': stat});
  65. }
  66. }
  67. },
  68. },
  69. 'settings': {
  70. 'get': function (key) {
  71. if (_.contains(Object.keys(converse.default_settings), key)) {
  72. return converse[key];
  73. }
  74. },
  75. 'set': function (key, val) {
  76. var o = {};
  77. if (typeof key === "object") {
  78. _.extend(converse, _.pick(key, Object.keys(converse.default_settings)));
  79. } else if (typeof key === "string") {
  80. o[key] = val;
  81. _.extend(converse, _.pick(o, Object.keys(converse.default_settings)));
  82. }
  83. }
  84. },
  85. 'contacts': {
  86. 'get': function (jids) {
  87. var _transform = function (jid) {
  88. var contact = converse.roster.get(Strophe.getBareJidFromJid(jid));
  89. if (contact) {
  90. return contact.attributes;
  91. }
  92. return null;
  93. };
  94. if (typeof jids === "undefined") {
  95. jids = converse.roster.pluck('jid');
  96. } else if (typeof jids === "string") {
  97. return _transform(jids);
  98. }
  99. return _.map(jids, _transform);
  100. },
  101. 'add': function (jid, name) {
  102. if (typeof jid !== "string" || jid.indexOf('@') < 0) {
  103. throw new TypeError('contacts.add: invalid jid');
  104. }
  105. converse.roster.addAndSubscribe(jid, _.isEmpty(name)? jid: name);
  106. }
  107. },
  108. 'chats': {
  109. 'open': function (jids) {
  110. var chatbox;
  111. if (typeof jids === "undefined") {
  112. converse.log("chats.open: You need to provide at least one JID", "error");
  113. return null;
  114. } else if (typeof jids === "string") {
  115. chatbox = converse.wrappedChatBox(
  116. converse.chatboxes.getChatBox(jids, true).trigger('show')
  117. );
  118. return chatbox;
  119. }
  120. return _.map(jids, function (jid) {
  121. chatbox = converse.wrappedChatBox(
  122. converse.chatboxes.getChatBox(jid, true).trigger('show')
  123. );
  124. return chatbox;
  125. });
  126. },
  127. 'get': function (jids) {
  128. if (typeof jids === "undefined") {
  129. var result = [];
  130. converse.chatboxes.each(function (chatbox) {
  131. // FIXME: Leaky abstraction from MUC. We need to add a
  132. // base type for chat boxes, and check for that.
  133. if (chatbox.get('type') !== 'chatroom') {
  134. result.push(converse.wrappedChatBox(chatbox));
  135. }
  136. });
  137. return result;
  138. } else if (typeof jids === "string") {
  139. return converse.wrappedChatBox(converse.chatboxes.getChatBox(jids));
  140. }
  141. return _.map(jids,
  142. _.partial(
  143. _.compose(
  144. converse.wrappedChatBox.bind(converse), converse.chatboxes.getChatBox.bind(converse.chatboxes)
  145. ), _, true
  146. )
  147. );
  148. }
  149. },
  150. 'tokens': {
  151. 'get': function (id) {
  152. if (!converse.expose_rid_and_sid || typeof converse.connection === "undefined") {
  153. return null;
  154. }
  155. if (id.toLowerCase() === 'rid') {
  156. return converse.connection.rid || converse.connection._proto.rid;
  157. } else if (id.toLowerCase() === 'sid') {
  158. return converse.connection.sid || converse.connection._proto.sid;
  159. }
  160. }
  161. },
  162. 'listen': {
  163. 'once': function (evt, handler, context) {
  164. converse.once(evt, handler, context);
  165. },
  166. 'on': function (evt, handler, context) {
  167. converse.on(evt, handler, context);
  168. },
  169. 'not': function (evt, handler) {
  170. converse.off(evt, handler);
  171. },
  172. 'stanza': function (name, options, handler) {
  173. if (typeof options === 'function') {
  174. handler = options;
  175. options = {};
  176. } else {
  177. options = options || {};
  178. }
  179. converse.connection.addHandler(
  180. handler,
  181. options.ns,
  182. name,
  183. options.type,
  184. options.id,
  185. options.from,
  186. options
  187. );
  188. },
  189. },
  190. 'send': function (stanza) {
  191. converse.connection.send(stanza);
  192. },
  193. 'plugins': {
  194. 'add': function (name, plugin) {
  195. plugin.__name__ = name;
  196. converse.pluggable.plugins[name] = plugin;
  197. },
  198. 'remove': function (name) {
  199. delete converse.plugins[name];
  200. },
  201. 'override': function (name, value) {
  202. /* Helper method for overriding methods and attributes directly on the
  203. * converse object. For Backbone objects, use instead the 'extend'
  204. * method.
  205. *
  206. * If a method is overridden, then the original method will still be
  207. * available via the __super__ attribute.
  208. *
  209. * name: The attribute being overridden.
  210. * value: The value of the attribute being overridden.
  211. */
  212. converse._overrideAttribute(name, value);
  213. },
  214. 'extend': function (obj, attributes) {
  215. /* Helper method for overriding or extending Converse's Backbone Views or Models
  216. *
  217. * When a method is overriden, the original will still be available
  218. * on the __super__ attribute of the object being overridden.
  219. *
  220. * obj: The Backbone View or Model
  221. * attributes: A hash of attributes, such as you would pass to Backbone.Model.extend or Backbone.View.extend
  222. */
  223. converse._extendObject(obj, attributes);
  224. }
  225. },
  226. 'env': {
  227. '$build': strophe.$build,
  228. '$iq': strophe.$iq,
  229. '$msg': strophe.$msg,
  230. '$pres': strophe.$pres,
  231. 'Strophe': strophe.Strophe,
  232. 'b64_sha1': strophe.SHA1.b64_sha1,
  233. '_': _,
  234. 'jQuery': $,
  235. 'moment': moment,
  236. 'utils': utils
  237. }
  238. };
  239. }));