utils.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. (function (root, factory) {
  2. define(['converse', 'es6-promise', 'mock', 'wait-until-promise'], factory);
  3. }(this, function (converse_api, Promise, mock, waitUntilPromise) {
  4. var _ = converse_api.env._;
  5. var $msg = converse_api.env.$msg;
  6. var $pres = converse_api.env.$pres;
  7. var $iq = converse_api.env.$iq;
  8. var Strophe = converse_api.env.Strophe;
  9. var u = converse_api.env.utils;
  10. var utils = {};
  11. if (typeof window.Promise === 'undefined') {
  12. waitUntilPromise.setPromiseImplementation(Promise);
  13. }
  14. utils.waitUntil = waitUntilPromise.default;
  15. utils.waitUntilFeatureSupportConfirmed = function (_converse, feature_name) {
  16. var IQ_disco, stanza;
  17. return utils.waitUntil(function () {
  18. IQ_disco = _.filter(_converse.connection.IQ_stanzas, function (iq) {
  19. return iq.nodeTree.querySelector('query[xmlns="http://jabber.org/protocol/disco#info"]');
  20. }).pop();
  21. return !_.isUndefined(IQ_disco);
  22. }, 300).then(function () {
  23. var info_IQ_id = IQ_disco.nodeTree.getAttribute('id');
  24. stanza = $iq({
  25. 'type': 'result',
  26. 'from': 'localhost',
  27. 'to': 'dummy@localhost/resource',
  28. 'id': info_IQ_id
  29. }).c('query', {'xmlns': 'http://jabber.org/protocol/disco#info'})
  30. .c('feature', {'var': feature_name});
  31. _converse.connection._dataRecv(utils.createRequest(stanza));
  32. });
  33. }
  34. utils.createRequest = function (iq) {
  35. iq = typeof iq.tree == "function" ? iq.tree() : iq;
  36. var req = new Strophe.Request(iq, function() {});
  37. req.getResponse = function () {
  38. var env = new Strophe.Builder('env', {type: 'mock'}).tree();
  39. env.appendChild(iq);
  40. return env;
  41. };
  42. return req;
  43. };
  44. utils.closeAllChatBoxes = function (converse) {
  45. var i, chatbox;
  46. for (i=converse.chatboxes.models.length-1; i>-1; i--) {
  47. chatbox = converse.chatboxes.models[i];
  48. converse.chatboxviews.get(chatbox.get('id')).close();
  49. }
  50. return this;
  51. };
  52. utils.openControlBox = function () {
  53. var toggle = document.querySelector(".toggle-controlbox");
  54. if (!u.isVisible(document.querySelector("#controlbox"))) {
  55. if (!u.isVisible(toggle)) {
  56. u.removeClass('hidden', toggle);
  57. }
  58. toggle.click();
  59. }
  60. return this;
  61. };
  62. utils.closeControlBox = function () {
  63. var controlbox = document.querySelector("#controlbox");
  64. if (u.isVisible(controlbox)) {
  65. var button = controlbox.querySelector(".close-chatbox-button");
  66. if (!_.isNull(button)) {
  67. button.click();
  68. }
  69. }
  70. return this;
  71. };
  72. utils.openContactsPanel = function (converse) {
  73. this.openControlBox(converse);
  74. var cbview = converse.chatboxviews.get('controlbox');
  75. cbview.el.querySelector('#controlbox-tabs li:first-child a').click();
  76. };
  77. utils.openRoomsPanel = function (converse) {
  78. utils.openControlBox();
  79. var cbview = converse.chatboxviews.get('controlbox');
  80. cbview.el.querySelector('#controlbox-tabs li:last-child a').click();
  81. };
  82. utils.openChatBoxes = function (converse, amount) {
  83. var i = 0, jid, views = [];
  84. for (i; i<amount; i++) {
  85. jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@localhost';
  86. views[i] = converse.roster.get(jid).trigger("open");
  87. }
  88. return views;
  89. };
  90. utils.openChatBoxFor = function (converse, jid) {
  91. return converse.roster.get(jid).trigger("open");
  92. };
  93. utils.openChatRoom = function (_converse, room, server, nick) {
  94. // Opens a new chatroom
  95. this.openControlBox(_converse);
  96. this.openRoomsPanel(_converse);
  97. var roomspanel = _converse.chatboxviews.get('controlbox').roomspanel;
  98. roomspanel.el.querySelector('input.new-chatroom-name').value = room;
  99. roomspanel.el.querySelector('input.new-chatroom-server').value = server;
  100. roomspanel.el.querySelector('form input[type="submit"]').click();
  101. this.closeControlBox(_converse);
  102. };
  103. utils.openAndEnterChatRoom = function (converse, room, server, nick) {
  104. return new Promise(function (resolve, reject) {
  105. sinon.spy(converse.connection, 'sendIQ');
  106. utils.openChatRoom(converse, room, server);
  107. var view = converse.chatboxviews.get((room+'@'+server).toLowerCase());
  108. // We pretend this is a new room, so no disco info is returned.
  109. var IQ_id = converse.connection.sendIQ.firstCall.returnValue;
  110. var features_stanza = $iq({
  111. 'from': room+'@'+server,
  112. 'id': IQ_id,
  113. 'to': nick+'@'+server+'/desktop',
  114. 'type': 'error'
  115. }).c('error', {'type': 'cancel'})
  116. .c('item-not-found', {'xmlns': "urn:ietf:params:xml:ns:xmpp-stanzas"});
  117. converse.connection._dataRecv(utils.createRequest(features_stanza));
  118. utils.waitUntil(function () {
  119. return converse.connection.sendIQ.secondCall;
  120. }).then(function () {
  121. // The XMPP server returns the reserved nick for this user.
  122. IQ_id = converse.connection.sendIQ.secondCall.returnValue;
  123. var stanza = $iq({
  124. 'type': 'result',
  125. 'id': IQ_id,
  126. 'from': view.model.get('jid'),
  127. 'to': converse.connection.jid
  128. }).c('query', {'xmlns': 'http://jabber.org/protocol/disco#info', 'node': 'x-roomuser-item'})
  129. .c('identity', {'category': 'conference', 'name': nick, 'type': 'text'});
  130. converse.connection._dataRecv(utils.createRequest(stanza));
  131. // The user has just entered the room (because join was called)
  132. // and receives their own presence from the server.
  133. // See example 24: http://xmpp.org/extensions/xep-0045.html#enter-pres
  134. var presence = $pres({
  135. to: converse.connection.jid,
  136. from: room+'@'+server+'/'+nick,
  137. id: 'DC352437-C019-40EC-B590-AF29E879AF97'
  138. }).c('x').attrs({xmlns:'http://jabber.org/protocol/muc#user'})
  139. .c('item').attrs({
  140. affiliation: 'member',
  141. jid: converse.bare_jid,
  142. role: 'participant'
  143. }).up()
  144. .c('status').attrs({code:'110'});
  145. converse.connection._dataRecv(utils.createRequest(presence));
  146. converse.connection.sendIQ.restore();
  147. resolve();
  148. });
  149. });
  150. };
  151. utils.clearBrowserStorage = function () {
  152. window.localStorage.clear();
  153. window.sessionStorage.clear();
  154. return this;
  155. };
  156. utils.clearChatBoxMessages = function (converse, jid) {
  157. var view = converse.chatboxviews.get(jid);
  158. view.el.querySelector('.chat-content').innerHTML = '';
  159. view.model.messages.reset();
  160. view.model.messages.browserStorage._clear();
  161. };
  162. utils.createContacts = function (converse, type, length) {
  163. /* Create current (as opposed to requesting or pending) contacts
  164. * for the user's roster.
  165. *
  166. * These contacts are not grouped. See below.
  167. */
  168. var names, jid, subscription, requesting, ask;
  169. if (type === 'requesting') {
  170. names = mock.req_names;
  171. subscription = 'none';
  172. requesting = true;
  173. ask = null;
  174. } else if (type === 'pending') {
  175. names = mock.pend_names;
  176. subscription = 'none';
  177. requesting = false;
  178. ask = 'subscribe';
  179. } else if (type === 'current') {
  180. names = mock.cur_names;
  181. subscription = 'both';
  182. requesting = false;
  183. ask = null;
  184. } else if (type === 'all') {
  185. this.createContacts(converse, 'current')
  186. .createContacts(converse, 'requesting')
  187. .createContacts(converse, 'pending');
  188. return this;
  189. } else {
  190. throw Error("Need to specify the type of contact to create");
  191. }
  192. if (typeof length === 'undefined') {
  193. length = names.length;
  194. }
  195. for (var i=0; i<length; i++) {
  196. jid = names[i].replace(/ /g,'.').toLowerCase() + '@localhost';
  197. if (!converse.roster.get(jid)) {
  198. converse.roster.create({
  199. 'ask': ask,
  200. 'fullname': names[i],
  201. 'jid': jid,
  202. 'requesting': requesting,
  203. 'subscription': subscription
  204. });
  205. }
  206. }
  207. return this;
  208. };
  209. utils.createGroupedContacts = function (converse) {
  210. /* Create grouped contacts
  211. */
  212. var i=0, j=0;
  213. _.each(_.keys(mock.groups), function (name) {
  214. j = i;
  215. for (i=j; i<j+mock.groups[name]; i++) {
  216. converse.roster.create({
  217. jid: mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@localhost',
  218. subscription: 'both',
  219. ask: null,
  220. groups: name === 'ungrouped'? [] : [name],
  221. fullname: mock.cur_names[i]
  222. });
  223. }
  224. });
  225. };
  226. utils.createChatMessage = function (_converse, sender_jid, message) {
  227. return $msg({
  228. from: sender_jid,
  229. to: _converse.connection.jid,
  230. type: 'chat',
  231. id: (new Date()).getTime()
  232. })
  233. .c('body').t(message).up()
  234. .c('active', {'xmlns': Strophe.NS.CHATSTATES}).tree();
  235. }
  236. utils.sendMessage = function (chatboxview, message) {
  237. chatboxview.el.querySelector('.chat-textarea').value = message;
  238. chatboxview.keyPressed({
  239. target: chatboxview.el.querySelector('textarea.chat-textarea'),
  240. preventDefault: _.noop,
  241. keyCode: 13
  242. });
  243. };
  244. return utils;
  245. }));