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