      1 /**
      2  * Validator for W3C Standard Engine
      3  */
      4 xq.ValidatorW3 = Class.create(xq.Validator, {
      5 	validate: function(element, fullValidation) {
      6 		element = element.cloneNode(true);
      7
      8 		var rdom = xq.RichDom.createInstance();
      9 		rdom.setRoot(element);
     10 		rdom.removePlaceHoldersAndEmptyNodes(element);
     11 		this.removeDangerousElements(element);
     12 		this.validateFontColor(element);
     13
     14 		var content = element.innerHTML;
     15
     16 		try {
     17 			content = this.replaceTag(content, "b", "strong");
     18 			content = this.replaceTag(content, "i", "em");
     19
     20 			content = this.validateStrike(content);
     21 			content = this.validateUnderline(content);
     22 			content = this.addNbspToEmptyBlocks(content);
     23
     24 			if(fullValidation) content = this.performFullValidation(content);
     25 		} catch(ignored) {}
     26
     27 		// insert newline between block-tags
     28 		var blocks = rdom.tree.getBlockTags().join("|");
     29 		var regex = new RegExp("</(" + blocks + ")>([^\n])", "img");
     30 		content = content.replace(regex, '</$1>\n$2');
     31
     32 		return content;
     33 	},
     34 	invalidate: function(element) {
     35 		var rdom = xq.RichDom.createInstance();
     36 		rdom.setRoot(element);
     37
     38 		// <span class="strike"> -> <strike>
     39 		var strikes = rdom.findByAttribute("class", "strike");
     40 		for(var i = 0; i < strikes.length; i++) {
     41 			if("SPAN" == strikes[i].nodeName) rdom.replaceTag("strike", strikes[i]).removeAttribute("class");
     42 		}
     43
     44 		// <em|i class="underline"> -> <u>
     45 		var underlines = rdom.findByAttribute("class", "underline");
     46 		for(var i = 0; i < underlines.length; i++) {
     47 			if(["EM", "I"].include(underlines[i].nodeName)) rdom.replaceTag("u", underlines[i]).removeAttribute("class");
     48 		}
     49
     50 		var content = rdom.getRoot().innerHTML;
     51
     52 		content = this.replaceTag(content, "strong", "b");
     53 		content = this.replaceTag(content, "em", "i");
     54 		content = this.removeComments(content);
     55 		content = this.replaceNbspToBr(content);
     56
     57 		return content;
     58 	},
     59
     60 	performFullValidation: function(content) {
     61 		content = this.validateSelfClosingTags(content);
     62 		content = this.applyWhitelist(content);
     63
     64 		if(this.urlValidationMode == 'relative') {
     65 			content = this.makeUrlsRelative(content);
     66 		} else if(this.urlValidationMode == 'host_relative') {
     67 			content = this.makeUrlsHostRelative(content);
     68 		} else if(this.urlValidationMode == 'absolute') {
     69 			content = this.makeUrlsAbsolute(content);
     70 		}
     71
     72 		return content;
     73 	},
     74
     75 	validateFontColor: function(element) {
     76 		var rdom = xq.RichDom.createInstance();
     77 		rdom.setRoot(element);
     78
     79 		var fonts = $A(element.getElementsByTagName('FONT')).reverse();
     80 		for(var i = 0; i < fonts.length; i++) {
     81 			var font = fonts[i];
     82 			var color = font.getAttribute('color');
     83
     84 			if(color) {
     85 				var span = rdom.replaceTag("span", font);
     86 				span.removeAttribute('color');
     87 				span.style.color = color;
     88 			}
     89 		}
     90 	},
     91
     92 	addNbspToEmptyBlocks: function(content) {
     93 		var blocks = new xq.DomTree().getBlockTags().join("|");
     94 		var regex = new RegExp("<(" + blocks + ")>\\s*?</(" + blocks + ")>", "img");
     95 		return content.replace(regex, '<$1> </$2>');
     96 	},
     97
     98 	replaceNbspToBr: function(content) {
     99 		var blocks = new xq.DomTree().getBlockTags().join("|");
    100 		var regex = new RegExp("<(" + blocks + ")>( )?</(" + blocks + ")>", "img");
    101 		var rdom = xq.RichDom.createInstance();
    102 		return content.replace(regex, '<$1>' + rdom.makePlaceHolderString() + '</$3>');
    103 	}
    104 });
    105