You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

267 lines
6.3 KiB

1 year ago
  1. /**
  2. * validate.js
  3. *
  4. * Released under LGPL License.
  5. * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
  6. *
  7. * License: http://www.tinymce.com/license
  8. * Contributing: http://www.tinymce.com/contributing
  9. */
  10. /**
  11. // String validation:
  12. if (!Validator.isEmail('myemail'))
  13. alert('Invalid email.');
  14. // Form validation:
  15. var f = document.forms['myform'];
  16. if (!Validator.isEmail(f.myemail))
  17. alert('Invalid email.');
  18. */
  19. var Validator = {
  20. isEmail : function (s) {
  21. return this.test(s, '^[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+@[-!#$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+\.[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+$');
  22. },
  23. isAbsUrl : function (s) {
  24. return this.test(s, '^(news|telnet|nttp|file|http|ftp|https)://[-A-Za-z0-9\\.]+\\/?.*$');
  25. },
  26. isSize : function (s) {
  27. return this.test(s, '^[0-9.]+(%|in|cm|mm|em|ex|pt|pc|px)?$');
  28. },
  29. isId : function (s) {
  30. return this.test(s, '^[A-Za-z_]([A-Za-z0-9_])*$');
  31. },
  32. isEmpty : function (s) {
  33. var nl, i;
  34. if (s.nodeName == 'SELECT' && s.selectedIndex < 1) {
  35. return true;
  36. }
  37. if (s.type == 'checkbox' && !s.checked) {
  38. return true;
  39. }
  40. if (s.type == 'radio') {
  41. for (i = 0, nl = s.form.elements; i < nl.length; i++) {
  42. if (nl[i].type == "radio" && nl[i].name == s.name && nl[i].checked) {
  43. return false;
  44. }
  45. }
  46. return true;
  47. }
  48. return new RegExp('^\\s*$').test(s.nodeType == 1 ? s.value : s);
  49. },
  50. isNumber : function (s, d) {
  51. return !isNaN(s.nodeType == 1 ? s.value : s) && (!d || !this.test(s, '^-?[0-9]*\\.[0-9]*$'));
  52. },
  53. test : function (s, p) {
  54. s = s.nodeType == 1 ? s.value : s;
  55. return s == '' || new RegExp(p).test(s);
  56. }
  57. };
  58. var AutoValidator = {
  59. settings : {
  60. id_cls : 'id',
  61. int_cls : 'int',
  62. url_cls : 'url',
  63. number_cls : 'number',
  64. email_cls : 'email',
  65. size_cls : 'size',
  66. required_cls : 'required',
  67. invalid_cls : 'invalid',
  68. min_cls : 'min',
  69. max_cls : 'max'
  70. },
  71. init : function (s) {
  72. var n;
  73. for (n in s) {
  74. this.settings[n] = s[n];
  75. }
  76. },
  77. validate : function (f) {
  78. var i, nl, s = this.settings, c = 0;
  79. nl = this.tags(f, 'label');
  80. for (i = 0; i < nl.length; i++) {
  81. this.removeClass(nl[i], s.invalid_cls);
  82. nl[i].setAttribute('aria-invalid', false);
  83. }
  84. c += this.validateElms(f, 'input');
  85. c += this.validateElms(f, 'select');
  86. c += this.validateElms(f, 'textarea');
  87. return c == 3;
  88. },
  89. invalidate : function (n) {
  90. this.mark(n.form, n);
  91. },
  92. getErrorMessages : function (f) {
  93. var nl, i, s = this.settings, field, msg, values, messages = [], ed = tinyMCEPopup.editor;
  94. nl = this.tags(f, "label");
  95. for (i = 0; i < nl.length; i++) {
  96. if (this.hasClass(nl[i], s.invalid_cls)) {
  97. field = document.getElementById(nl[i].getAttribute("for"));
  98. values = { field: nl[i].textContent };
  99. if (this.hasClass(field, s.min_cls, true)) {
  100. message = ed.getLang('invalid_data_min');
  101. values.min = this.getNum(field, s.min_cls);
  102. } else if (this.hasClass(field, s.number_cls)) {
  103. message = ed.getLang('invalid_data_number');
  104. } else if (this.hasClass(field, s.size_cls)) {
  105. message = ed.getLang('invalid_data_size');
  106. } else {
  107. message = ed.getLang('invalid_data');
  108. }
  109. message = message.replace(/{\#([^}]+)\}/g, function (a, b) {
  110. return values[b] || '{#' + b + '}';
  111. });
  112. messages.push(message);
  113. }
  114. }
  115. return messages;
  116. },
  117. reset : function (e) {
  118. var t = ['label', 'input', 'select', 'textarea'];
  119. var i, j, nl, s = this.settings;
  120. if (e == null) {
  121. return;
  122. }
  123. for (i = 0; i < t.length; i++) {
  124. nl = this.tags(e.form ? e.form : e, t[i]);
  125. for (j = 0; j < nl.length; j++) {
  126. this.removeClass(nl[j], s.invalid_cls);
  127. nl[j].setAttribute('aria-invalid', false);
  128. }
  129. }
  130. },
  131. validateElms : function (f, e) {
  132. var nl, i, n, s = this.settings, st = true, va = Validator, v;
  133. nl = this.tags(f, e);
  134. for (i = 0; i < nl.length; i++) {
  135. n = nl[i];
  136. this.removeClass(n, s.invalid_cls);
  137. if (this.hasClass(n, s.required_cls) && va.isEmpty(n)) {
  138. st = this.mark(f, n);
  139. }
  140. if (this.hasClass(n, s.number_cls) && !va.isNumber(n)) {
  141. st = this.mark(f, n);
  142. }
  143. if (this.hasClass(n, s.int_cls) && !va.isNumber(n, true)) {
  144. st = this.mark(f, n);
  145. }
  146. if (this.hasClass(n, s.url_cls) && !va.isAbsUrl(n)) {
  147. st = this.mark(f, n);
  148. }
  149. if (this.hasClass(n, s.email_cls) && !va.isEmail(n)) {
  150. st = this.mark(f, n);
  151. }
  152. if (this.hasClass(n, s.size_cls) && !va.isSize(n)) {
  153. st = this.mark(f, n);
  154. }
  155. if (this.hasClass(n, s.id_cls) && !va.isId(n)) {
  156. st = this.mark(f, n);
  157. }
  158. if (this.hasClass(n, s.min_cls, true)) {
  159. v = this.getNum(n, s.min_cls);
  160. if (isNaN(v) || parseInt(n.value) < parseInt(v)) {
  161. st = this.mark(f, n);
  162. }
  163. }
  164. if (this.hasClass(n, s.max_cls, true)) {
  165. v = this.getNum(n, s.max_cls);
  166. if (isNaN(v) || parseInt(n.value) > parseInt(v)) {
  167. st = this.mark(f, n);
  168. }
  169. }
  170. }
  171. return st;
  172. },
  173. hasClass : function (n, c, d) {
  174. return new RegExp('\\b' + c + (d ? '[0-9]+' : '') + '\\b', 'g').test(n.className);
  175. },
  176. getNum : function (n, c) {
  177. c = n.className.match(new RegExp('\\b' + c + '([0-9]+)\\b', 'g'))[0];
  178. c = c.replace(/[^0-9]/g, '');
  179. return c;
  180. },
  181. addClass : function (n, c, b) {
  182. var o = this.removeClass(n, c);
  183. n.className = b ? c + (o !== '' ? (' ' + o) : '') : (o !== '' ? (o + ' ') : '') + c;
  184. },
  185. removeClass : function (n, c) {
  186. c = n.className.replace(new RegExp("(^|\\s+)" + c + "(\\s+|$)"), ' ');
  187. return n.className = c !== ' ' ? c : '';
  188. },
  189. tags : function (f, s) {
  190. return f.getElementsByTagName(s);
  191. },
  192. mark : function (f, n) {
  193. var s = this.settings;
  194. this.addClass(n, s.invalid_cls);
  195. n.setAttribute('aria-invalid', 'true');
  196. this.markLabels(f, n, s.invalid_cls);
  197. return false;
  198. },
  199. markLabels : function (f, n, ic) {
  200. var nl, i;
  201. nl = this.tags(f, "label");
  202. for (i = 0; i < nl.length; i++) {
  203. if (nl[i].getAttribute("for") == n.id || nl[i].htmlFor == n.id) {
  204. this.addClass(nl[i], ic);
  205. }
  206. }
  207. return null;
  208. }
  209. };