1 /** 2 * Validator for W3C Standard Engine 3 */ 4 xq.ValidatorW3 = xq.Class(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 = xq.getElementsByClassName(rdom.getRoot(), "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 = xq.getElementsByClassName(rdom.getRoot(), "underline"); 46 for(var i = 0; i < underlines.length; i++) { 47 if(["EM", "I"].indexOf(underlines[i].nodeName) != -1) 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 = xq.$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