form.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. // Converse.js (A browser based XMPP chat client)
  2. // http://conversejs.org
  3. //
  4. // This is the utilities module.
  5. //
  6. // Copyright (c) 2013-2018, Jan-Carel Brand <jc@opkode.com>
  7. // Licensed under the Mozilla Public License (MPLv2)
  8. //
  9. /*global define, escape, Jed */
  10. (function (root, factory) {
  11. define([
  12. "sizzle",
  13. "../lodash.noconflict",
  14. "./core",
  15. "../templates/field.html",
  16. "../templates/select_option.html",
  17. "../templates/form_select.html",
  18. "../templates/form_textarea.html",
  19. "../templates/form_checkbox.html",
  20. "../templates/form_username.html",
  21. "../templates/form_input.html",
  22. "../templates/form_captcha.html",
  23. "../templates/form_url.html",
  24. ], factory);
  25. }(this, function (
  26. sizzle,
  27. _,
  28. u,
  29. tpl_field,
  30. tpl_select_option,
  31. tpl_form_select,
  32. tpl_form_textarea,
  33. tpl_form_checkbox,
  34. tpl_form_username,
  35. tpl_form_input,
  36. tpl_form_captcha,
  37. tpl_form_url
  38. ) {
  39. "use strict";
  40. var XFORM_TYPE_MAP = {
  41. 'text-private': 'password',
  42. 'text-single': 'text',
  43. 'fixed': 'label',
  44. 'boolean': 'checkbox',
  45. 'hidden': 'hidden',
  46. 'jid-multi': 'textarea',
  47. 'list-single': 'dropdown',
  48. 'list-multi': 'dropdown'
  49. };
  50. u.webForm2xForm = function (field) {
  51. /* Takes an HTML DOM and turns it into an XForm field.
  52. *
  53. * Parameters:
  54. * (DOMElement) field - the field to convert
  55. */
  56. let value;
  57. if (field.getAttribute('type') === 'checkbox') {
  58. value = field.checked && 1 || 0;
  59. } else if (field.tagName == "TEXTAREA") {
  60. value = _.filter(field.value.split('\n'), _.trim);
  61. } else if (field.tagName == "SELECT") {
  62. value = u.getSelectValues(field);
  63. } else {
  64. value = field.value;
  65. }
  66. return u.stringToNode(
  67. tpl_field({
  68. 'name': field.getAttribute('name'),
  69. 'value': value
  70. })
  71. );
  72. };
  73. u.xForm2webForm = function (field, stanza, domain) {
  74. /* Takes a field in XMPP XForm (XEP-004: Data Forms) format
  75. * and turns it into an HTML field.
  76. *
  77. * Returns either text or a DOM element (which is not ideal, but fine
  78. * for now).
  79. *
  80. * Parameters:
  81. * (XMLElement) field - the field to convert
  82. */
  83. if (field.getAttribute('type')) {
  84. if (field.getAttribute('type') === 'list-single' ||
  85. field.getAttribute('type') === 'list-multi') {
  86. const values = _.map(
  87. u.queryChildren(field, 'value'),
  88. _.partial(_.get, _, 'textContent')
  89. );
  90. const options = _.map(
  91. u.queryChildren(field, 'option'),
  92. function (option) {
  93. const value = _.get(option.querySelector('value'), 'textContent');
  94. return tpl_select_option({
  95. 'value': value,
  96. 'label': option.getAttribute('label'),
  97. 'selected': _.includes(values, value),
  98. 'required': !_.isNil(field.querySelector('required'))
  99. })
  100. }
  101. );
  102. return tpl_form_select({
  103. 'id': u.getUniqueId(),
  104. 'name': field.getAttribute('var'),
  105. 'label': field.getAttribute('label'),
  106. 'options': options.join(''),
  107. 'multiple': (field.getAttribute('type') === 'list-multi'),
  108. 'required': !_.isNil(field.querySelector('required'))
  109. });
  110. } else if (field.getAttribute('type') === 'fixed') {
  111. const text = _.get(field.querySelector('value'), 'textContent');
  112. return '<p class="form-help">'+text+'</p>';
  113. } else if (field.getAttribute('type') === 'jid-multi') {
  114. return tpl_form_textarea({
  115. 'name': field.getAttribute('var'),
  116. 'label': field.getAttribute('label') || '',
  117. 'value': _.get(field.querySelector('value'), 'textContent'),
  118. 'required': !_.isNil(field.querySelector('required'))
  119. });
  120. } else if (field.getAttribute('type') === 'boolean') {
  121. return tpl_form_checkbox({
  122. 'id': u.getUniqueId(),
  123. 'name': field.getAttribute('var'),
  124. 'label': field.getAttribute('label') || '',
  125. 'checked': _.get(field.querySelector('value'), 'textContent') === "1" && 'checked="1"' || '',
  126. 'required': !_.isNil(field.querySelector('required'))
  127. });
  128. } else if (field.getAttribute('var') === 'url') {
  129. return tpl_form_url({
  130. 'label': field.getAttribute('label') || '',
  131. 'value': _.get(field.querySelector('value'), 'textContent')
  132. });
  133. } else if (field.getAttribute('var') === 'username') {
  134. return tpl_form_username({
  135. 'domain': ' @'+domain,
  136. 'name': field.getAttribute('var'),
  137. 'type': XFORM_TYPE_MAP[field.getAttribute('type')],
  138. 'label': field.getAttribute('label') || '',
  139. 'value': _.get(field.querySelector('value'), 'textContent'),
  140. 'required': !_.isNil(field.querySelector('required'))
  141. });
  142. } else {
  143. return tpl_form_input({
  144. 'id': u.getUniqueId(),
  145. 'label': field.getAttribute('label') || '',
  146. 'name': field.getAttribute('var'),
  147. 'placeholder': null,
  148. 'required': !_.isNil(field.querySelector('required')),
  149. 'type': XFORM_TYPE_MAP[field.getAttribute('type')],
  150. 'value': _.get(field.querySelector('value'), 'textContent')
  151. });
  152. }
  153. } else {
  154. if (field.getAttribute('var') === 'ocr') { // Captcha
  155. const uri = field.querySelector('uri');
  156. const el = sizzle('data[cid="'+uri.textContent.replace(/^cid:/, '')+'"]', stanza)[0];
  157. return tpl_form_captcha({
  158. 'label': field.getAttribute('label'),
  159. 'name': field.getAttribute('var'),
  160. 'data': _.get(el, 'textContent'),
  161. 'type': uri.getAttribute('type'),
  162. 'required': !_.isNil(field.querySelector('required'))
  163. });
  164. }
  165. }
  166. }
  167. return u;
  168. }));