From 11662db3af8f59e98c9fbd0563118d3b4e91a009 Mon Sep 17 00:00:00 2001 From: Yanis Wang Date: Wed, 7 Oct 2015 18:07:05 +0800 Subject: [PATCH] add inline rules readme --- README.md | 11 +++++++++-- bin/htmlhint | 8 ++++---- lib/htmlhint.js | 2 +- src/core.js | 4 ++-- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index d5a66fd0f..50c4110bc 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Quick start htmlhint --help htmlhint test.html -2. result +2. results test.html L5 | @@ -35,7 +35,7 @@ Quick start 3. config rules - search `.htmlhintrc` file in current directory and all parents directory: + search `.htmlhintrc` file in current directory and all parent directorys: htmlhint htmlhint test.html @@ -48,6 +48,13 @@ Quick start htmlhint --rules tag-pair,id-class-value=underline test.html + Inline rules in `test.html`: + + + + + ... + Guide ======================= diff --git a/bin/htmlhint b/bin/htmlhint index b7c9d4db0..71dc36086 100755 --- a/bin/htmlhint +++ b/bin/htmlhint @@ -22,15 +22,15 @@ function map(val) { program.on('--help', function(){ console.log(' Examples:'); console.log(''); - console.log(' htmlhint -l'); - console.log(' htmlhint -r tag-pair,id-class-value=underline test.html'); - console.log(' htmlhint -c .htmlhintrc test.html'); + console.log(' htmlhint --list'); + console.log(' htmlhint --rules tag-pair,id-class-value=underline test.html'); + console.log(' htmlhint --config .htmlhintrc test.html'); console.log(''); }); program .version(pkg.version) - .usage('[options] ') + .usage(' [options]') .option('-l, --list', 'show all of the rules available.') .option('-c, --config ', 'custom configuration file.') .option('-r, --rules ', 'set all of the rules available.', map) diff --git a/lib/htmlhint.js b/lib/htmlhint.js index ad9666d73..57a6a90f6 100644 --- a/lib/htmlhint.js +++ b/lib/htmlhint.js @@ -5,4 +5,4 @@ * (c) 2015 Yanis Wang . * MIT Licensed */ -var HTMLHint=function(e){var t={};return t.version="0.9.8",t.rules={},t.defaultRuleset={"tagname-lowercase":!0,"attr-lowercase":!0,"attr-value-double-quotes":!0,"doctype-first":!0,"tag-pair":!0,"spec-char-escape":!0,"id-unique":!0,"src-not-empty":!0,"attr-no-duplication":!0,"title-require":!0},t.addRule=function(e){t.rules[e.id]=e},t.verify=function(a,n){a=a.replace(/^\s*/i,function(t,a){return n===e&&(n={}),a.replace(/(?:^|,)\s*([^:]+)\s*:\s*([^,\s]+)/g,function(e,t,a){"false"===a?a=!1:"true"===a&&(a=!0),n[t]=a}),""}),(n===e||0===Object.keys(n).length)&&(n=t.defaultRuleset);var i,r=new HTMLParser,s=new t.Reporter(a.split(/\r?\n/),n),o=t.rules;for(var l in n)i=o[l],i!==e&&n[l]!==!1&&i.init(r,s,n[l]);return r.parse(a),s.messages},t}();"object"==typeof exports&&exports&&(exports.HTMLHint=HTMLHint),function(e){var t=function(){var e=this;e._init.apply(e,arguments)};t.prototype={_init:function(e,t){var a=this;a.lines=e,a.ruleset=t,a.messages=[]},error:function(e,t,a,n,i){this.report("error",e,t,a,n,i)},warn:function(e,t,a,n,i){this.report("warning",e,t,a,n,i)},info:function(e,t,a,n,i){this.report("info",e,t,a,n,i)},report:function(e,t,a,n,i,r){var s=this;s.messages.push({type:e,message:t,raw:r,evidence:s.lines[a-1],line:a,col:n,rule:{id:i.id,description:i.description,link:"https://github.com/yaniswang/HTMLHint/wiki/"+i.id}})}},e.Reporter=t}(HTMLHint);var HTMLParser=function(e){var t=function(){var e=this;e._init.apply(e,arguments)};return t.prototype={_init:function(){var e=this;e._listeners={},e._mapCdataTags=e.makeMap("script,style"),e._arrBlocks=[]},makeMap:function(e){for(var t={},a=e.split(","),n=0;a.length>n;n++)t[a[n]]=!0;return t},parse:function(t){function a(t,a,n,i){var r=n-b+1;i===e&&(i={}),i.raw=a,i.pos=n,i.line=w,i.col=r,L.push(i),c.fire(t,i);for(var s;s=m.exec(a);)w++,b=n+m.lastIndex}var n,i,r,s,o,l,d,u,c=this,f=c._mapCdataTags,g=/<(?:\/([^\s>]+)\s*|!--([\s\S]*?)--|!([^>]*?)|([\w\-:]+)((?:\s+[\w\-:]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s"'>]*))?)*?)\s*(\/?))>/g,h=/\s*([\w\-:]+)(?:\s*=\s*(?:(")([^"]*)"|(')([^']*)'|([^\s"'>]*)))?/g,m=/\r?\n/g,p=0,v=0,b=0,w=1,L=c._arrBlocks;for(c.fire("start",{pos:0,line:1,col:1});n=g.exec(t);)if(i=n.index,i>p&&(u=t.substring(p,i),o?d.push(u):a("text",u,p)),p=g.lastIndex,!(r=n[1])||(o&&r===o&&(u=d.join(""),a("cdata",u,v,{tagName:o,attrs:l}),o=null,l=null,d=null),o))if(o)d.push(n[0]);else if(r=n[4]){s=[];for(var T,H=n[5],y=0;T=h.exec(H);){var x=T[1],M=T[2]?T[2]:T[4]?T[4]:"",N=T[3]?T[3]:T[5]?T[5]:T[6]?T[6]:"";s.push({name:x,value:N,quote:M,index:T.index,raw:T[0]}),y+=T[0].length}y===H.length?(a("tagstart",n[0],i,{tagName:r,attrs:s,close:n[6]}),f[r]&&(o=r,l=s.concat(),d=[],v=p)):a("text",n[0],i)}else(n[2]||n[3])&&a("comment",n[0],i,{content:n[2]||n[3],"long":n[2]?!0:!1});else a("tagend",n[0],i,{tagName:r});t.length>p&&(u=t.substring(p,t.length),a("text",u,p)),c.fire("end",{pos:p,line:w,col:p-b+1})},addListener:function(t,a){for(var n,i=this._listeners,r=t.split(/[,\s]/),s=0,o=r.length;o>s;s++)n=r[s],i[n]===e&&(i[n]=[]),i[n].push(a)},fire:function(t,a){a===e&&(a={}),a.type=t;var n=this,i=[],r=n._listeners[t],s=n._listeners.all;r!==e&&(i=i.concat(r)),s!==e&&(i=i.concat(s));for(var o=0,l=i.length;l>o;o++)i[o].call(n,a)},removeListener:function(t,a){var n=this._listeners[t];if(n!==e)for(var i=0,r=n.length;r>i;i++)if(n[i]===a){n.splice(i,1);break}},fixPos:function(e,t){var a,n=e.raw.substr(0,t),i=n.split(/\r?\n/),r=i.length-1,s=e.line;return r>0?(s+=r,a=i[r].length+1):a=e.col+t,{line:s,col:a}},getMapAttrs:function(e){for(var t,a={},n=0,i=e.length;i>n;n++)t=e[n],a[t.name]=t.value;return a}},t}();"object"==typeof exports&&exports&&(exports.HTMLParser=HTMLParser),HTMLHint.addRule({id:"alt-require",description:"The alt attribute of an element must be present and alt attribute of area[href] and input[type=image] must have a value.",init:function(e,t){var a=this;e.addListener("tagstart",function(n){var i,r=n.tagName.toLowerCase(),s=e.getMapAttrs(n.attrs),o=n.col+r.length+1;"img"!==r||"alt"in s?("area"===r&&"href"in s||"input"===r&&"image"===s.type)&&("alt"in s&&""!==s.alt||(i="area"===r?"area[href]":"input[type=image]",t.warn("The alt attribute of "+i+" must have a value.",n.line,o,a,n.raw))):t.warn("An alt attribute must be present on elements.",n.line,o,a,n.raw)})}}),HTMLHint.addRule({id:"attr-lowercase",description:"All attribute names must be in lowercase.",init:function(e,t){var a=this;e.addListener("tagstart",function(e){for(var n,i=e.attrs,r=e.col+e.tagName.length+1,s=0,o=i.length;o>s;s++){n=i[s];var l=n.name;l!==l.toLowerCase()&&t.error("The attribute name of [ "+l+" ] must be in lowercase.",e.line,r+n.index,a,n.raw)}})}}),HTMLHint.addRule({id:"attr-no-duplication",description:"Elements cannot have duplicate attributes.",init:function(e,t){var a=this;e.addListener("tagstart",function(e){for(var n,i,r=e.attrs,s=e.col+e.tagName.length+1,o={},l=0,d=r.length;d>l;l++)n=r[l],i=n.name,o[i]===!0&&t.error("Duplicate of attribute name [ "+n.name+" ] was found.",e.line,s+n.index,a,n.raw),o[i]=!0})}}),HTMLHint.addRule({id:"attr-unsafe-chars",description:"Attribute values cannot contain unsafe chars.",init:function(e,t){var a=this;e.addListener("tagstart",function(e){for(var n,i=e.attrs,r=e.col+e.tagName.length+1,s=/[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/,o=0,l=i.length;l>o;o++)n=i[o],s.test(n.value)===!0&&t.warn("The value of attribute [ "+n.name+" ] cannot contain an unsafe char.",e.line,r+n.index,a,n.raw)})}}),HTMLHint.addRule({id:"attr-value-double-quotes",description:"Attribute values must be in double quotes.",init:function(e,t){var a=this;e.addListener("tagstart",function(e){for(var n,i=e.attrs,r=e.col+e.tagName.length+1,s=0,o=i.length;o>s;s++)n=i[s],(""!==n.value&&'"'!==n.quote||""===n.value&&"'"===n.quote)&&t.error("The value of attribute [ "+n.name+" ] must be in double quotes.",e.line,r+n.index,a,n.raw)})}}),HTMLHint.addRule({id:"attr-value-not-empty",description:"All attributes must have values.",init:function(e,t){var a=this;e.addListener("tagstart",function(e){for(var n,i=e.attrs,r=e.col+e.tagName.length+1,s=0,o=i.length;o>s;s++)n=i[s],""===n.quote&&""===n.value&&t.warn("The attribute [ "+n.name+" ] must have a value.",e.line,r+n.index,a,n.raw)})}}),HTMLHint.addRule({id:"csslint",description:"Scan css with csslint.",init:function(e,t,a){var n=this;e.addListener("cdata",function(e){if("style"===e.tagName.toLowerCase()){var i;if(i="object"==typeof exports&&require?require("csslint").CSSLint.verify:CSSLint.verify,void 0!==a){var r=e.line-1,s=e.col-1;try{var o=i(e.raw,a).messages;o.forEach(function(e){var a=e.line;t["warning"===e.type?"warn":"error"]("["+e.rule.id+"] "+e.message,r+a,(1===a?s:0)+e.col,n,e.evidence)})}catch(l){}}}})}}),HTMLHint.addRule({id:"doctype-first",description:"Doctype must be declared first.",init:function(e,t){var a=this,n=function(i){"start"===i.type||"text"===i.type&&/^\s*$/.test(i.raw)||(("comment"!==i.type&&i.long===!1||/^DOCTYPE\s+/i.test(i.content)===!1)&&t.error("Doctype must be declared first.",i.line,i.col,a,i.raw),e.removeListener("all",n))};e.addListener("all",n)}}),HTMLHint.addRule({id:"doctype-html5",description:'Invalid doctype. Use: ""',init:function(e,t){function a(e){e.long===!1&&"doctype html"!==e.content.toLowerCase()&&t.warn('Invalid doctype. Use: ""',e.line,e.col,i,e.raw)}function n(){e.removeListener("comment",a),e.removeListener("tagstart",n)}var i=this;e.addListener("all",a),e.addListener("tagstart",n)}}),HTMLHint.addRule({id:"head-script-disabled",description:"The