From c78c50f68490f8cbada7da7f3174464b3aba2206 Mon Sep 17 00:00:00 2001
From: zoltan-dulac <zoltan.dulac@gmail.com>
Date: Tue, 3 Jul 2012 16:05:17 -0400
Subject: [PATCH] Updated html5Forms.js to support extra CSS features:

---
 .DS_Store                                     | Bin 6148 -> 6148 bytes
 shared/js/html5Forms.js                       | 292 +++++++++++++++---
 .../weston.ruter.net/webforms2/webforms2.css  |   2 +-
 .../webforms2/webforms2_src.js                | 160 +++++++++-
 tests/html5Forms/css/basicForm.css            |   7 +
 5 files changed, 403 insertions(+), 58 deletions(-)

diff --git a/.DS_Store b/.DS_Store
index 0dacb722e15ca5040e389cb8d6b72d433d750777..2b4f49fde41c0cb1168d29a6eaeb7d3b74a772d9 100644
GIT binary patch
diff --git a/shared/js/html5Forms.js b/shared/js/html5Forms.js
index 54484d3..0c189a7 100644
--- a/shared/js/html5Forms.js
+++ b/shared/js/html5Forms.js
@@ -3,6 +3,7 @@ var html5Forms = new function () {
 	
 	var scriptNode = null,
 		scriptDir = null,
+		isScriptCompressed = false,
 		
 		// WebKit less than 534 doesn't show validation UI - we need to check for this (from http://stackoverflow.com/questions/6030522/html5-form-validation-modernizr-safari)
 		hasNativeBubbles = navigator.userAgent.indexOf('WebKit') < 0 || parseInt(navigator.userAgent.match(/AppleWebKit\/([^ ]*)/)[1].split('.')[0])  > 534,
@@ -19,6 +20,20 @@ var html5Forms = new function () {
 		return r;
 	}
 	
+	
+	me.start = function () {
+		
+		var split = navigator.userAgent.split('Firefox/');
+		
+		//Firefox 3.6 gives a wierd error when using the Twitter API
+		//unless you do this onload.
+		if (split.length>=1 && parseFloat(split[1]) <= 3.6) {
+			EventHelpers.addEvent(window, 'load', me.init);
+		} else {
+			me.init();
+		}
+	}
+	
 	me.init = function () {
 		var scriptNodes = document.getElementsByTagName('script');
 		
@@ -28,6 +43,9 @@ var html5Forms = new function () {
 			if (scriptNode.src.match('html5Forms(_src|-p|)\.js')) {
 				scriptNode = scriptNode;
 				scriptDir = getScriptDir();
+				if (scriptNode.src.indexOf('html5Forms-p.js') >= 0) {
+					isScriptCompressed = true;
+				}
 				break;
 			}
 		}
@@ -38,7 +56,7 @@ var html5Forms = new function () {
 				/* let's load the supporting scripts according to what is in data-webforms2-support */
 				var supportArray = scriptNode.getAttribute('data-webforms2-support');
 				var forceJSValidation = (scriptNode.getAttribute('data-webforms2-force-js-validation') == 'true');
-				
+				var turnOffValidation = (scriptNode.getAttribute('data-webforms2-turn-off-validation') == 'true');
 				if (!supportArray) {
 					return;
 				} else if (trim(supportArray) == 'all') {
@@ -58,16 +76,27 @@ var html5Forms = new function () {
 						
 						case "validation":
 						case "autofocus":
-							if (!Modernizr.input.required || hasBadValidationImplementation || forceJSValidation) {
-								
-								toLoad = toLoad.concat([  
-										scriptDir + '../../shared/js/weston.ruter.net/webforms2/webforms2_src.js']);
-								
-								if (supportReq == 'autofocus') {
-									loadHTML5Widgets = true;
+							if (turnOffValidation) {
+								//me.turnOffNativeValidation();
+								EventHelpers.addPageLoadEvent('html5Forms.turnOffNativeValidation')
+							} else {
+						
+								if (!Modernizr.input.required || hasBadValidationImplementation || forceJSValidation) {
+									
+									if (isScriptCompressed) {
+										toLoad = toLoad.concat([  
+											scriptDir + '../../shared/js/weston.ruter.net/webforms2/webforms2-p.js']);
+									} else {
+										toLoad = toLoad.concat([  
+											scriptDir + '../../shared/js/weston.ruter.net/webforms2/webforms2_src.js']);
+									}
+									
+									if (supportReq == 'autofocus') {
+										loadHTML5Widgets = true;
+									}
+									
 								}
-								
-							}	
+							}
 							break;
 						case "number":
 							if (!inputSupport.number) {
@@ -147,14 +176,14 @@ var html5Forms = new function () {
 					// allow browsers that don't need webforms2 to handle custom error messages populated
 					// in the data-errormessage attribute
 					if (document.addEventListener) {
-						document.addEventListener('DOMContentLoaded', handleCustomErrorMessages, false);
+						document.addEventListener('DOMContentLoaded', setupExtraFeatures, false);
 					}
 				} else {
 					yepnope({
 						load: toLoad,
 						complete: function (){
 							loadWidgets();
-							handleCustomErrorMessages();
+							setupExtraFeatures();
 						}
 					});
 				}
@@ -180,46 +209,133 @@ var html5Forms = new function () {
 			
 		}
 		
+		
+		
 		/*
 		 * This should work even when webforms2 is not loaded.
+		 * It sets up extra features for HTML5Forms like:
+		 * 1) Setting custom error messages on form elements.
+		 * 2) setting up isBlank and isBlurred classes.
+		 * 3) settung up form.wf2_submitAttempted
 		 */
-		function handleCustomErrorMessages() {
-			
+		function setupExtraFeatures() {
 			var nodeNames = ["input", "select", "textarea"];
 			for (var i=0; i<nodeNames.length; i++) {
 				var nodes = document.getElementsByTagName(nodeNames[i]);
 				
 				for (var j=0; j<nodes.length; j++) {
 					var node = nodes[j];
-					var message = me.getAttributeValue(node, 'data-errormessage');
-					if (message) {
-						if(document.addEventListener){
-							node.addEventListener('invalid', showCustomMessageEvent, false);
-							node.addEventListener('focus', showCustomMessageEvent, false);
-							
-							// Opera doesn't work well with this.
-							if (!window.opera) {
-								node.addEventListener('keypress', clearMessageIfValidEvent, false);
-							}
-							
-							node.addEventListener('input', clearMessageIfValidEvent, false);
-						} else {
-							var invalidEvent = ' this.setCustomValidity("' + message + '");';
-							if (node.oninvalid) {
-								node.oninvalid += invalidEvent;
-							} else {
-								node.oninvalid = invalidEvent;
-							}
-							node.oninvalid = new Function('event', node.oninvalid);
-							
-							// IE freaks a little on keypress here, so change to keydown.
-							node.attachEvent('onkeydown', clearMessageIfValidEvent);
-							node.attachEvent('oninput', clearMessageIfValidEvent); 
-						}
-						clearMessageIfValid(node);
+					setErrorMessageEvents(node);
+					setCustomClassesEvents(node);
+					setNodeClasses(node, true);
+				}
+				
+				if (i==0 && node.type=="submit") {
+					EventHelpers.addEvent(node, 'click', submitClickEvent);
+				}
+			}
 			
+			var forms = document.getElementsByTagName('form');
+			for (var i=0; i<forms.length; i++) {
+				EventHelpers.addEvent(forms[i], 'submit', submitEvent);
+			}
+		}
+		
+		function submitEvent(e) {
+			var target = EventHelpers.getEventTarget(e);
+			markSubmitAttempt(target);
+		}
+		
+		function submitClickEvent(e) {
+			var target = EventHelpers.getEventTarget(e);
+			markSubmitAttempt(target.form);
+		}
+		
+		function markSubmitAttempt(form) {
+			me.css.addClass(form, 'wf2_submitAttempted');
+		}
+		
+		function setCustomClassesEvents(node) {
+			EventHelpers.addEvent(node, 'keyup', nodeChangeEvent);
+			EventHelpers.addEvent(node, 'change', nodeChangeEvent);
+			EventHelpers.addEvent(node, 'blur', nodeBlurEvent);
+		}
+		
+		function nodeChangeEvent(e) {
+			var node = EventHelpers.getEventTarget(e);
+			setNodeClasses(node);
+		}
+		
+		function setNodeClasses(node, isLoadEvent) {	
+			if (node.value === '') {
+				
+				me.css.addClass(node, 'wf2_isBlank');
+				me.css.removeClass(node, 'wf2_notBlank');
+			} else {
+				me.css.addClass(node, 'wf2_notBlank');
+				me.css.removeClass(node, 'wf2_isBlank');
+			}
+			
+			if (isLoadEvent && node.nodeName == 'SELECT') {
+				node.setAttribute('data-wf2-initialvalue', node.value)
+			}
+			
+			if ((node.nodeName == 'SELECT' && me.getAttributeValue(node, 'data-wf2-initialvalue') != node.value)
+			    || (node.nodeName != 'SELECT' && me.getAttributeValue(node, 'value') != node.value)) {
+				me.css.removeClass(node, 'wf2_defaultValue');
+				me.css.addClass(node, 'wf2_notDefaultValue');
+			} else {
+				me.css.addClass(node, 'wf2_defaultValue');
+				me.css.removeClass(node, 'wf2_notDefaultValue');
+			}
+		}
+		
+		function nodeBlurEvent(e) {
+			var node = EventHelpers.getEventTarget(e);
+			
+			me.css.addClass(node, 'wf2_lostFocus');
+		}
+		
+		function setErrorMessageEvents(node) {
+			var message = me.getAttributeValue(node, 'data-errormessage');
+			if (message) {
+				if(document.addEventListener){
+					node.addEventListener('invalid', showCustomMessageEvent, false);
+					node.addEventListener('focus', showCustomMessageEvent, false);
+					
+					// Opera doesn't work well with this.
+					if (!window.opera) {
+						node.addEventListener('keypress', clearMessageIfValidEvent, false);
+					}
+					
+					node.addEventListener('input', clearMessageIfValidEvent, false);
+					
+					if (node.nodeName == 'SELECT') {
+						node.addEventListener('change', clearMessageIfValidEvent, false);
+						node.addEventListener('click', clearMessageIfValidEvent, false);
+					}
+				} else {
+					var invalidEvent = ' this.setCustomValidity("' + message + '");';
+					if (node.oninvalid) {
+						node.oninvalid += invalidEvent;
+					} else {
+						node.oninvalid = invalidEvent;
+					}
+					node.oninvalid = new Function('event', node.oninvalid);
+					
+					// IE freaks a little on keypress here, so change to keydown.
+					node.attachEvent('onkeydown', clearMessageIfValidEvent);
+					node.attachEvent('oninput', clearMessageIfValidEvent); 
+					
+					if (node.nodeName == 'SELECT') {
+						node.attachEvent('change', clearMessageIfValidEvent, false);
+						node.attachEvent('click', clearMessageIfValidEvent, false);
 					}
 				}
+				
+				
+				clearMessageIfValid(node);
+	
 			}
 		}
 		
@@ -264,6 +380,14 @@ var html5Forms = new function () {
 		
 	}
 	
+	me.turnOffNativeValidation = function () {
+			
+			var formNodes = document.getElementsByTagName('form');
+			for (var i=0; i<formNodes.length; i++) {
+				formNodes[i].setAttribute('novalidate', 'novalidate');
+			}
+		}
+	
 	var supportsOutput = function () {
 		var outputEl = document.createElement('output');
 		return (outputEl.value != undefined && (outputEl.onforminput !== undefined || outputEl.oninput !== undefined));
@@ -307,6 +431,91 @@ var html5Forms = new function () {
 		return str.replace(initWhitespaceRe, '')
 			.replace(endWhitespaceRe, '');
 	}  
+	
+	me.css = new function () {
+		var me = this;
+		
+		var blankRe = new RegExp('\\s');
+
+		/**
+		 * Generates a regular expression string that can be used to detect a class name
+		 * in a tag's class attribute.  It is used by a few methods, so I 
+		 * centralized it.
+		 * 
+		 * @param {String} className - a name of a CSS class.
+		 */
+		
+		function getClassReString(className) {
+			return '\\s'+className+'\\s|^' + className + '\\s|\\s' + className + '$|' + '^' + className +'$';
+		}
+		
+		function getClassPrefixReString(className) {
+			return '\\s'+className+'-[0-9a-zA-Z_]+\\s|^' + className + '[0-9a-zA-Z_]+\\s|\\s' + className + '[0-9a-zA-Z_]+$|' + '^' + className +'[0-9a-zA-Z_]+$';
+		}
+		
+		
+		/**
+		 * Make an HTML object be a member of a certain class.
+		 * 
+		 * @param {Object} obj - an HTML object
+		 * @param {String} className - a CSS class name.
+		 */
+		me.addClass = function (obj, className) {
+			
+			if (blankRe.test(className)) {
+				return;
+			}
+			
+			// only add class if the object is not a member of it yet.
+			if (!me.isMemberOfClass(obj, className)) {
+				obj.className += " " + className;
+			}
+			
+		}
+		
+		/**
+		 * Make an HTML object *not* be a member of a certain class.
+		 * 
+		 * @param {Object} obj - an HTML object
+		 * @param {Object} className - a CSS class name.
+		 */
+		me.removeClass = function (obj, className) {
+			
+			if (blankRe.test(className)) {
+				return; 
+			}
+			
+			
+			var re = new RegExp(getClassReString(className) , "g");
+			
+			var oldClassName = obj.className;
+		
+		
+			if (obj.className) {
+				obj.className = oldClassName.replace(re, ' ');
+			}
+		
+			
+		}
+		
+		/**
+		 * Determines if an HTML object is a member of a specific class.
+		 * @param {Object} obj - an HTML object.
+		 * @param {Object} className - the CSS class name.
+		 */
+		me.isMemberOfClass = function (obj, className) {
+			
+			if (blankRe.test(className))
+				return false;
+			
+			var re = new RegExp(getClassReString(className) , "g");
+		
+			return (re.test(obj.className));
+		
+		
+		}
+		
+	}
 
 }
 
@@ -337,6 +546,7 @@ var EventHelpers = new function(){
 		safariVer = parseFloat(safariVer[1]);
 	}
 	
+	
 	me.init = function () {
 		if (me.hasPageLoadHappened(arguments)) {
 			return;	
@@ -651,4 +861,4 @@ var EventHelpers = new function(){
     }
 }
 
-html5Forms.init();
+html5Forms.start();
diff --git a/shared/js/weston.ruter.net/webforms2/webforms2.css b/shared/js/weston.ruter.net/webforms2/webforms2.css
index 355089c..f4514d4 100644
--- a/shared/js/weston.ruter.net/webforms2/webforms2.css
+++ b/shared/js/weston.ruter.net/webforms2/webforms2.css
@@ -170,7 +170,7 @@ body.ie8 input.wf2_invalid {
 /* HTML5Widgets Placeholder text */
 .html5-hasPlaceholderText{font-family: "Arial", "Helvetica", sans-serif !important; color: #999999; font-style: italic}
 input::-webkit-input-placeholder {font-family: "Arial", "Helvetica", sans-serif; color: #999999; font-style: italic}
-input:-moz-placeholder {font-family: "Arial", "Helvetica", sans-serif; color: #999999; font-style: italic}
+input:-moz-placeholder, textarea:-moz-placeholder {font-family: "Arial", "Helvetica", sans-serif; color: #999999; font-style: italic !important}
 input:-ms-input-placeholder {font-family: "Arial", "Helvetica", sans-serif; color: #999999; font-style: italic}
 
 
diff --git a/shared/js/weston.ruter.net/webforms2/webforms2_src.js b/shared/js/weston.ruter.net/webforms2/webforms2_src.js
index 7938b4f..56c3f3e 100644
--- a/shared/js/weston.ruter.net/webforms2/webforms2_src.js
+++ b/shared/js/weston.ruter.net/webforms2/webforms2_src.js
@@ -136,6 +136,8 @@ $wf2 = {
 		for (var i=0; i<$wf2.callAfterDOMContentLoaded.length; i++) {
 			$wf2.callAfterDOMContentLoaded[i]();
 		}
+		
+		
 	},
 
 	
@@ -463,6 +465,10 @@ $wf2 = {
 		parent = (parent || document.documentElement);
 		var i,j, frm, frms = parent.getElementsByTagName('form');
 		for(i = 0; frm = frms[i]; i++){
+			
+			// use the native validation if the browser has it, unless 
+			// the form has a data-webforms2-force-js-validation attribute
+			// set to "true". 
 			if(frm.checkValidity && !$wf2.hasBadImplementation && $wf2.getAttributeValue(frm, 'data-webforms2-force-js-validation') != 'true') {
 				continue;
 			}
@@ -478,6 +484,23 @@ $wf2 = {
 		for(i = 0; ctrl = ctrls[i]; i++){
 			$wf2.applyValidityInterface(ctrl);
 			$wf2.updateValidityState(ctrl); //ctrl._updateValidityState();
+			
+			// add CSS focus-like support for IE7 and under
+			/*@cc_on
+			  
+			 	ctrl.attachEvent('onfocus', function (e) {
+			 		
+			 		$wf2.css.addClass(e.srcElement, 'wf2_focus');
+			 		
+			 	});
+			 	
+			 	ctrl.attachEvent('onblur', function (e) { 
+			 		
+			 		$wf2.css.removeClass(e.srcElement, 'wf2_focus')
+			 	});
+			 
+			  
+			 @*/
 		}
 		
 		//Autofocus **********************************************************
@@ -818,8 +841,10 @@ $wf2 = {
 		var doMaxLengthCheck = doCheckPrecision || node.nodeName.toLowerCase() == 'textarea'; //datetime, datetime-local, time, date, month, week, number, range, textarea
 		var doCheckRange = (doCheckPrecision || isFileInput); //datetime, datetime-local, time, date, month, week, number, range, file
 		var isRadioOrCheckbox = (type == 'radio' || type == 'checkbox');
+		var isSelect = (node.nodeName == 'SELECT');
 		var doRequiredCheck = (doMaxLengthCheck  || //datetime, datetime-local, time, date, month, week, number, range, textarea
 							   isFileInput       ||
+							   isSelect ||
 							   type == 'email'   ||
 							   type == 'url'     ||
 							   type == 'text'    ||
@@ -1152,17 +1177,46 @@ $wf2 = {
 		//customError -- The control was marked invalid from script. See the definition of the setCustomValiditiy() method.
 		//console.log('second: ', node.validity.stepMismatch)
 		node.validity.valid = !$wf2.hasInvalidState(node.validity);
+		var nextSib = (node.nextSibling);
+		if (nextSib && nextSib.nodeName != 'SPAN' && !$wf2.css.isMemberOfClass(nextSib, 'wf2-validityIndicator')) {
+			nextSib = null;
+		}
+		
 		if (node.validity.valid) {
 			$wf2.css.removeClass(node, 'wf2_invalid');
 			$wf2.css.addClass(node, 'wf2_valid');
+			
+			/*
+			 * If we have an .wf2-validityIndicator span after the input, mark these as well
+			 */
+			if (nextSib) {
+				$wf2.css.removeClass(nextSib, 'wf2_invalid');
+				$wf2.css.addClass(nextSib, 'wf2_valid');
+				//console.log('valid: ', nextSib.className);
+			}
+			
 			//node.className = node.className.replace(/\s?wf2_invalid/g, "") + ' wf2_valid';
-			//console.log('valid: ', node.className)
+			
 		} else { 
 			$wf2.css.removeClass(node, 'wf2_valid');
 			$wf2.css.addClass(node, 'wf2_invalid');
-			//node.className = node.className.replace(/\s?wf2_valid/g, "") + ' wf2_invalid';
-			//console.log('not valid: ', node.className, 'value:', node.value, 'wtfValue:', node.wf2Value)
+			
+			/*
+			 * If we have an .wf2-validityIndicator span after the input, mark these as well
+			 */
+			if (nextSib) {
+				$wf2.css.removeClass(nextSib, 'wf2_valid');
+				$wf2.css.addClass(nextSib, 'wf2_invalid');
+				//node.className = node.className.replace(/\s?wf2_valid/g, "") + ' wf2_invalid';
+				//console.log('not valid: ', nextSib.className, 'value:', node.value, 'wtfValue:', node.wf2Value)
+			}
+			
+			
 		}
+		
+		
+		
+		
 		if (isCustomErrorMessageSet) {
 			node.validationMessage = customErrorMessage;
 		}
@@ -1288,6 +1342,7 @@ $wf2 = {
 	/* updateValidityState: function (node) {
 		if (node.checkValidity()){
 			node.className = node.className.replace(/\s?wf2_invalid/, "");
+			
 		} else {
 			node.className += ' wf2_invalid';
 		}
@@ -1320,7 +1375,9 @@ $wf2 = {
 			$wf2.callAfterValidation[i](event, r);
 		}
 		
-		
+		// Finally .. set a class on the form to indicate that a form
+		// submit was attempted
+		$wf2.css.addClass(frm, 'wf2_submitAttempted');
 		
 		return r;
 	},
@@ -1515,11 +1572,14 @@ $wf2 = {
 		/* if(!target.className.match(/\bwf2_invalid\b/))
 			target.className += " wf2_invalid"; */
 		$wf2.css.addClass(target, 'wf2_invalid');
-			
-		if($wf2.indicatorIntervalId == null){
+		
+		
+		// WR: We removed the commented stuff below because it is not needed for the new validation routines.
+		/* if($wf2.indicatorIntervalId == null){
 			//var i = $wf2.invalidIndicators.length - 1;
 			$wf2.indicatorIntervalId = setInterval(function(){
 				var invalidIndicator;
+				
 				for(var i = 0; invalidIndicator = $wf2.invalidIndicators[i]; i++){
 					
 					if (!$wf2.css.isMemberOfClass(invalidIndicator.target, 'wf2_invalid')) {
@@ -1529,16 +1589,10 @@ $wf2 = {
 					}
 					
 					
-					/* 
-					if(!invalidIndicator.target.className.match(/\bwf2_invalid\b/)){
-						invalidIndicator.target.className += " wf2_invalid";
-					}
-					else {
-						invalidIndicator.target.className = invalidIndicator.target.className.replace(/\s?wf2_invalid/, "");
-					} */
+					
 				}
 				
-			}, 500);
+			}, 500); 
 			return;
 			// call routines other libraries have set to be run before
 			// validation.
@@ -1548,11 +1602,23 @@ $wf2 = {
 				}
 			}, 1);
 			$wf2.indicatorTimeoutId = setTimeout($wf2.clearInvalidIndicators, 4000);
-		}
+		}*/
 		
 	},
 
-	clearInvalidIndicators : function(){
+	clearInvalidIndicators : function(e){
+		
+		if (e.type == 'mousedown') {
+			var coords = $wf2.css.getMouseCoords(e),
+				browserWidth = $wf2.css.getWindowWidth(),
+				offset = (window.innerWidth )?16:0;
+				
+				if (coords.x >= browserWidth - offset) {
+					return;
+				}
+		}
+		
+		
 		clearTimeout($wf2.indicatorTimeoutId);
 		$wf2.indicatorTimeoutId = null;
 		clearInterval($wf2.indicatorIntervalId);
@@ -2318,6 +2384,36 @@ $wf2 = {
 			}
 		}
 		
+		/**
+		 * gets the current window's width.  
+		 * 
+		 * @author Peter-Paul Koch - http://www.quirksmode.org
+		 * @license see http://www.quirksmode.org/about/copyright.html
+		 * @return {int} - the window's width, in pixels.
+		 */
+		me.getWindowWidth = function (theWindow)
+		{
+			if (!theWindow) {
+				theWindow = window;
+			}
+			
+			var theDocument = theWindow.document;
+			
+			// all except IE
+			if (theWindow.innerWidth != null)  {
+				return theWindow.innerWidth;
+			// IE6 Strict mode
+			} else if (theDocument.documentElement && 
+					theDocument.documentElement.clientWidth ) {
+				return theDocument.documentElement.clientWidth;	
+			// IE strictly less than 6
+			} else if (theDocument.body != null) {
+				return theDocument.body.clientWidth;
+			} else {	
+				return null;
+			}
+		}
+		
 		/**
 		 * gets the current window's height.  
 		 * 
@@ -2347,6 +2443,38 @@ $wf2 = {
 				return null;
 			}
 		}
+		
+		me.getMouseCoords = function (e) {
+			if (!e) {
+				return;
+			}
+			// IE
+			if (e.clientX != null) {
+				return {
+					x: e.clientX,
+					y: e.clientY
+				}
+			
+			}
+			// NS4
+			else if (e.pageX != null) {
+				return {
+					x: e.pageX,
+					y: e.pageY
+				}
+			// W3C
+			}  else if (window.event != null && window.event.clientX != null 
+					&& document.body != null && 
+					document.body.scrollLeft != null) {
+				return {
+					x: window.event.clientX + document.body.scrollLeft,
+					y: window.event.clientY + document.body.scrollTop
+				}
+						
+			} else { 
+				return null;
+			}
+		}
 	}
 }; //End $wf2 = {
 
diff --git a/tests/html5Forms/css/basicForm.css b/tests/html5Forms/css/basicForm.css
index cf3e80a..18dc9f3 100644
--- a/tests/html5Forms/css/basicForm.css
+++ b/tests/html5Forms/css/basicForm.css
@@ -1,3 +1,10 @@
+/*
+ * This stylesheet, as well as the imported one, are for general styling
+ * and do not contain any form validation styling.
+ */
+
+
+
 @import url("http://www.useragentman.com/shared/css/useragentmanExample.css");
 body {
 	font-family: "Arial", sans-serif;
