Switch to Grunt.
authorXhmikosR <xhmikosr@users.sourceforge.net>
Tue, 28 Jan 2014 08:09:08 +0000 (10:09 +0200)
committerXhmikosR <xhmikosr@users.sourceforge.net>
Tue, 18 Feb 2014 06:19:48 +0000 (08:19 +0200)
13 files changed:
.travis.yml
Gruntfile.js [new file with mode: 0644]
README.md
_config.yml
dist/all.min.js [deleted file]
dist/htmlminifier.js [moved from dist/all.js with 99% similarity]
dist/htmlminifier.min.js [new file with mode: 0644]
index.html
package.json
tests/index.html
tests/lint-tests.html
tests/lint.js
tests/minifier.js

index 0cc3ae1..f36d554 100644 (file)
@@ -7,5 +7,7 @@ node_js:
 branches:
   only:
     - gh-pages
+before_script:
+  - npm install -g grunt-cli
 before_install:
  - '[ "${TRAVIS_NODE_VERSION}" = "0.6" ] && npm conf set strict-ssl false || true'
diff --git a/Gruntfile.js b/Gruntfile.js
new file mode 100644 (file)
index 0000000..ff55b14
--- /dev/null
@@ -0,0 +1,71 @@
+'use strict';
+
+module.exports = function(grunt) {
+
+    // Project configuration.
+    grunt.initConfig({
+
+        jshint: {
+            options: {
+                jshintrc: '.jshintrc'
+            },
+            gruntfile: {
+                src: 'Gruntfile.js'
+            },
+            src: {
+                src: ['src/**/*.js']
+            },
+            //tests: {
+            //    src: ['tests/**/*.js']
+            //},
+            //web: {
+            //    src: ['master.js']
+            //}
+        },
+
+        concat: {
+            js: {
+                src: ['src/htmlparser.js',
+                      'src/htmlminifier.js',
+                      'src/htmllint.js'],
+                dest: 'dist/htmlminifier.js'
+            }
+        },
+
+        uglify: {
+            options: {
+                compress: true,
+                mangle: true,
+                preserveComments: false,
+                report: 'min'
+            },
+            minify: {
+                files: {
+                    'dist/htmlminifier.min.js': '<%= concat.js.dest %>'
+                }
+            }
+        }
+
+
+    });
+
+    require('load-grunt-tasks')(grunt, { scope: 'devDependencies' });
+    require('time-grunt')(grunt);
+
+    grunt.registerTask('build', [
+        'concat'
+    ]);
+
+    grunt.registerTask('dist', [
+        'concat',
+        'uglify'
+    ]);
+
+    grunt.registerTask('test', [
+        'concat',
+        'jshint'
+    ]);
+
+    grunt.registerTask('default', 'test');
+
+};
index 93724bd..8c6a5f0 100644 (file)
--- a/README.md
+++ b/README.md
@@ -27,34 +27,6 @@ Installing with [npm](https://github.com/isaacs/npm):
 npm install html-minifier
 ```
 
-Linting:
-
-```
-npm run lint
-```
-
-Building distribution:
-
-```
-npm run build
-```
-
-Minifiying distribution:
-
-```
-npm run minify
-```
-
-Building & minifying distrubution:
-
-```
-npm run dist
-```
-
-Testing locally:
-
-```
-npm test
-```
+**TO BE FILLED**
 
 [![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/kangax/html-minifier/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
index 490a4b8..39bdd9f 100644 (file)
@@ -2,7 +2,7 @@ exclude:
 - "node_modules"
 - "src"
 - "v8"
+- "Gruntfile.js"
 - "package.json"
 - "README.md"
 - "test.js"
-
diff --git a/dist/all.min.js b/dist/all.min.js
deleted file mode 100644 (file)
index 8f0fd76..0000000
+++ /dev/null
@@ -1 +0,0 @@
-(function(global){var startTag=/^<([\w:-]+)((?:\s*[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/,endTag=/^<\/([\w:-]+)[^>]*>/,endingSlash=/\/>$/,attr=/([\w:-]+)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g,doctype=/^<!DOCTYPE [^>]+>/i,startIgnore=/<(%|\?)/,endIgnore=/(%|\?)>/;var empty=makeMap("area,base,basefont,br,col,frame,hr,img,input,isindex,link,meta,param,embed");var inline=makeMap("a,abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,code,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var");var closeSelf=makeMap("colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr,source");var fillAttrs=makeMap("checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected");var special=makeMap("script,style");var reCache={},stackedTag,reStackedTag,tagMatch;var HTMLParser=global.HTMLParser=function(html,handler){var index,chars,match,stack=[],last=html,prevTag,nextTag;stack.last=function(){return this[this.length-1]};while(html){chars=true;if(!stack.last()||!special[stack.last()]){if(html.indexOf("<!--")===0){index=html.indexOf("-->");if(index>=0){if(handler.comment)handler.comment(html.substring(4,index));html=html.substring(index+3);chars=false}}else if(html.search(startIgnore)===0){index=html.search(endIgnore);if(index>=0){handler.ignore&&handler.ignore(html.substring(0,index+2));html=html.substring(index+2);chars=false}}else if(match=doctype.exec(html)){if(handler.doctype)handler.doctype(match[0]);html=html.substring(match[0].length);chars=false}else if(html.indexOf("</")===0){match=html.match(endTag);if(match){html=html.substring(match[0].length);match[0].replace(endTag,parseEndTag);prevTag="/"+match[1];chars=false}}else if(html.indexOf("<")===0){match=html.match(startTag);if(match){html=html.substring(match[0].length);match[0].replace(startTag,parseStartTag);prevTag=match[1];chars=false}}if(chars){index=html.indexOf("<");var text=index<0?html:html.substring(0,index);html=index<0?"":html.substring(index);tagMatch=html.match(startTag);if(tagMatch){nextTag=tagMatch[1]}else{tagMatch=html.match(endTag);if(tagMatch){nextTag="/"+tagMatch[1]}else{nextTag=""}}if(handler.chars)handler.chars(text,prevTag,nextTag)}}else{stackedTag=stack.last().toLowerCase();reStackedTag=reCache[stackedTag]||(reCache[stackedTag]=new RegExp("([\\s\\S]*?)</"+stackedTag+"[^>]*>","i"));html=html.replace(reStackedTag,function(all,text){if(stackedTag!=="script"&&stackedTag!=="style"){text=text.replace(/<!--([\s\S]*?)-->/g,"$1").replace(/<!\[CDATA\[([\s\S]*?)\]\]>/g,"$1")}if(handler.chars)handler.chars(text);return""});parseEndTag("",stackedTag)}if(html===last)throw"Parse Error: "+html;last=html}parseEndTag();function parseStartTag(tag,tagName,rest,unary){var unarySlash=false;while(!handler.html5&&stack.last()&&inline[stack.last()]){parseEndTag("",stack.last())}if(closeSelf[tagName]&&stack.last()===tagName){parseEndTag("",tagName)}unary=empty[tagName]||!!unary;if(!unary){stack.push(tagName)}else{unarySlash=tag.match(endingSlash)}if(handler.start){var attrs=[];rest.replace(attr,function(match,name){var value=arguments[2]?arguments[2]:arguments[3]?arguments[3]:arguments[4]?arguments[4]:fillAttrs[name]?name:"";attrs.push({name:name,value:value,escaped:value.replace(/(^|[^\\])"/g,"$1&quot;")})});if(handler.start)handler.start(tagName,attrs,unary,unarySlash)}}function parseEndTag(tag,tagName){var pos;if(!tagName)pos=0;else for(pos=stack.length-1;pos>=0;pos--)if(stack[pos]===tagName)break;if(pos>=0){for(var i=stack.length-1;i>=pos;i--)if(handler.end)handler.end(stack[i]);stack.length=pos}}};global.HTMLtoXML=function(html){var results="";HTMLParser(html,{start:function(tag,attrs,unary){results+="<"+tag;for(var i=0;i<attrs.length;i++)results+=" "+attrs[i].name+'="'+attrs[i].escaped+'"';results+=(unary?"/":"")+">"},end:function(tag){results+="</"+tag+">"},chars:function(text){results+=text},comment:function(text){results+="<!--"+text+"-->"},ignore:function(text){results+=text}});return results};global.HTMLtoDOM=function(html,doc){var one=makeMap("html,head,body,title");var structure={link:"head",base:"head"};if(!doc){if(typeof DOMDocument!=="undefined")doc=new DOMDocument;else if(typeof document!=="undefined"&&document.implementation&&document.implementation.createDocument)doc=document.implementation.createDocument("","",null);else if(typeof ActiveX!=="undefined")doc=new ActiveXObject("Msxml.DOMDocument")}else doc=doc.ownerDocument||doc.getOwnerDocument&&doc.getOwnerDocument()||doc;var elems=[],documentElement=doc.documentElement||doc.getDocumentElement&&doc.getDocumentElement();if(!documentElement&&doc.createElement)(function(){var html=doc.createElement("html");var head=doc.createElement("head");head.appendChild(doc.createElement("title"));html.appendChild(head);html.appendChild(doc.createElement("body"));doc.appendChild(html)})();if(doc.getElementsByTagName)for(var i in one)one[i]=doc.getElementsByTagName(i)[0];var curParentNode=one.body;HTMLParser(html,{start:function(tagName,attrs,unary){if(one[tagName]){curParentNode=one[tagName];return}var elem=doc.createElement(tagName);for(var attr in attrs)elem.setAttribute(attrs[attr].name,attrs[attr].value);if(structure[tagName]&&typeof one[structure[tagName]]!=="boolean")one[structure[tagName]].appendChild(elem);else if(curParentNode&&curParentNode.appendChild)curParentNode.appendChild(elem);if(!unary){elems.push(elem);curParentNode=elem}},end:function(){elems.length-=1;curParentNode=elems[elems.length-1]},chars:function(text){curParentNode.appendChild(doc.createTextNode(text))},comment:function(){},ignore:function(){}});return doc};function makeMap(str){var obj={},items=str.split(",");for(var i=0;i<items.length;i++){obj[items[i]]=true;obj[items[i].toUpperCase()]=true}return obj}})(typeof exports==="undefined"?this:exports);(function(global){var log,HTMLParser;if(global.console&&global.console.log){log=function(message){global.console.log(message)}}else{log=function(){}}if(global.HTMLParser){HTMLParser=global.HTMLParser}else if(typeof require==="function"){HTMLParser=require("./htmlparser").HTMLParser}var trimWhitespace=function(str){return str.replace(/^\s+/,"").replace(/\s+$/,"")};if(String.prototype.trim){trimWhitespace=function(str){return str.trim()}}function collapseWhitespace(str){return str.replace(/\s+/g," ")}function collapseWhitespaceSmart(str,prevTag,nextTag){var tags=["a","abbr","acronym","b","bdi","bdo","big","button","cite","code","del","dfn","em","font","i","ins","kbd","mark","q","rt","rp","s","samp","small","span","strike","strong","sub","sup","time","tt","u","var"];if(prevTag&&prevTag!=="img"&&(prevTag.substr(0,1)!=="/"||prevTag.substr(0,1)==="/"&&tags.indexOf(prevTag.substr(1))===-1)){str=str.replace(/^\s+/,"")}if(nextTag&&nextTag!=="img"&&(nextTag.substr(0,1)==="/"||nextTag.substr(0,1)!=="/"&&tags.indexOf(nextTag)===-1)){str=str.replace(/\s+$/,"")}if(prevTag&&nextTag){return str.replace(/[\t\n\r]+/g," ").replace(/[ ]+/g," ")}return str}function isConditionalComment(text){return/\[if[^\]]+\]/.test(text)||/\s*(<!\[endif\])$/.test(text)}function isIgnoredComment(text){return/^!/.test(text)}function isEventAttribute(attrName){return/^on[a-z]+/.test(attrName)}function canRemoveAttributeQuotes(value){return/^[^\x20\t\n\f\r"'`=<>]+$/.test(value)&&!/\/$/.test(value)&&!/\/$/.test(value)}function attributesInclude(attributes,attribute){for(var i=attributes.length;i--;){if(attributes[i].name.toLowerCase()===attribute){return true}}return false}function isAttributeRedundant(tag,attrName,attrValue,attrs){attrValue=trimWhitespace(attrValue.toLowerCase());return tag==="script"&&attrName==="language"&&attrValue==="javascript"||tag==="form"&&attrName==="method"&&attrValue==="get"||tag==="input"&&attrName==="type"&&attrValue==="text"||tag==="script"&&attrName==="charset"&&!attributesInclude(attrs,"src")||tag==="a"&&attrName==="name"&&attributesInclude(attrs,"id")||tag==="area"&&attrName==="shape"&&attrValue==="rect"}function isScriptTypeAttribute(tag,attrName,attrValue){return tag==="script"&&attrName==="type"&&trimWhitespace(attrValue.toLowerCase())==="text/javascript"}function isStyleLinkTypeAttribute(tag,attrName,attrValue){return(tag==="style"||tag==="link")&&attrName==="type"&&trimWhitespace(attrValue.toLowerCase())==="text/css"}function isBooleanAttribute(attrName){return/^(?:allowfullscreen|async|autofocus|checked|compact|declare|default|defer|disabled|formnovalidate|hidden|inert|ismap|itemscope|multiple|muted|nohref|noresize|noshade|novalidate|nowrap|open|readonly|required|reversed|seamless|selected|sortable|truespeed|typemustmatch)$/.test(attrName)}function isUriTypeAttribute(attrName,tag){return/^(?:a|area|link|base)$/.test(tag)&&attrName==="href"||tag==="img"&&/^(?:src|longdesc|usemap)$/.test(attrName)||tag==="object"&&/^(?:classid|codebase|data|usemap)$/.test(attrName)||tag==="q"&&attrName==="cite"||tag==="blockquote"&&attrName==="cite"||(tag==="ins"||tag==="del")&&attrName==="cite"||tag==="form"&&attrName==="action"||tag==="input"&&(attrName==="src"||attrName==="usemap")||tag==="head"&&attrName==="profile"||tag==="script"&&(attrName==="src"||attrName==="for")}function isNumberTypeAttribute(attrName,tag){return/^(?:a|area|object|button)$/.test(tag)&&attrName==="tabindex"||tag==="input"&&(attrName==="maxlength"||attrName==="tabindex")||tag==="select"&&(attrName==="size"||attrName==="tabindex")||tag==="textarea"&&/^(?:rows|cols|tabindex)$/.test(attrName)||tag==="colgroup"&&attrName==="span"||tag==="col"&&attrName==="span"||(tag==="th"||tag==="td")&&(attrName==="rowspan"||attrName==="colspan")}function cleanAttributeValue(tag,attrName,attrValue){if(isEventAttribute(attrName)){return trimWhitespace(attrValue).replace(/^javascript:\s*/i,"").replace(/\s*;$/,"")}else if(attrName==="class"){return collapseWhitespace(trimWhitespace(attrValue))}else if(isUriTypeAttribute(attrName,tag)||isNumberTypeAttribute(attrName,tag)){return trimWhitespace(attrValue)}else if(attrName==="style"){return trimWhitespace(attrValue).replace(/\s*;\s*$/,"")}return attrValue}function cleanConditionalComment(comment){return comment.replace(/^(\[[^\]]+\]>)\s*/,"$1").replace(/\s*(<!\[endif\])$/,"$1")}function removeCDATASections(text){return text.replace(/^(?:\s*\/\*\s*<!\[CDATA\[\s*\*\/|\s*\/\/\s*<!\[CDATA\[.*)/,"").replace(/(?:\/\*\s*\]\]>\s*\*\/|\/\/\s*\]\]>)\s*$/,"")}var reStartDelimiter={script:/^\s*(?:\/\/)?\s*<!--.*\n?/,style:/^\s*<!--\s*/};var reEndDelimiter={script:/\s*(?:\/\/)?\s*-->\s*$/,style:/\s*-->\s*$/};function removeComments(text,tag){return text.replace(reStartDelimiter[tag],"").replace(reEndDelimiter[tag],"")}function isOptionalTag(tag){return/^(?:html|t?body|t?head|tfoot|tr|td|th|option|source)$/.test(tag)}var reEmptyAttribute=new RegExp("^(?:class|id|style|title|lang|dir|on(?:focus|blur|change|click|dblclick|mouse("+"?:down|up|over|move|out)|key(?:press|down|up)))$");function canDeleteEmptyAttribute(tag,attrName,attrValue){var isValueEmpty=/^(["'])?\s*\1$/.test(attrValue);if(isValueEmpty){return tag==="input"&&attrName==="value"||reEmptyAttribute.test(attrName)}return false}function canRemoveElement(tag){return tag!=="textarea"}function canCollapseWhitespace(tag){return!/^(?:script|style|pre|textarea)$/.test(tag)}function canTrimWhitespace(tag){return!/^(?:pre|textarea)$/.test(tag)}function normalizeAttribute(attr,attrs,tag,options){var attrName=options.caseSensitive?attr.name:attr.name.toLowerCase(),attrValue=attr.escaped,attrFragment;if(options.removeRedundantAttributes&&isAttributeRedundant(tag,attrName,attrValue,attrs)||options.removeScriptTypeAttributes&&isScriptTypeAttribute(tag,attrName,attrValue)||options.removeStyleLinkTypeAttributes&&isStyleLinkTypeAttribute(tag,attrName,attrValue)){return""}attrValue=cleanAttributeValue(tag,attrName,attrValue);if(!options.removeAttributeQuotes||!canRemoveAttributeQuotes(attrValue)){attrValue='"'+attrValue+'"'}if(options.removeEmptyAttributes&&canDeleteEmptyAttribute(tag,attrName,attrValue)){return""}if(options.collapseBooleanAttributes&&isBooleanAttribute(attrName)){attrFragment=attrName}else{attrFragment=attrName+"="+attrValue}return" "+attrFragment}function setDefaultTesters(options){var defaultTesters=["canCollapseWhitespace","canTrimWhitespace"];for(var i=0,len=defaultTesters.length;i<len;i++){if(!options[defaultTesters[i]]){options[defaultTesters[i]]=function(){return false}}}}function minify(value,options){options=options||{};value=trimWhitespace(value);setDefaultTesters(options);var results=[],buffer=[],currentChars="",currentTag="",currentAttrs=[],stackNoTrimWhitespace=[],stackNoCollapseWhitespace=[],lint=options.lint,t=new Date;function _canCollapseWhitespace(tag,attrs){return canCollapseWhitespace(tag)||options.canTrimWhitespace(tag,attrs)}function _canTrimWhitespace(tag,attrs){return canTrimWhitespace(tag)||options.canTrimWhitespace(tag,attrs)}HTMLParser(value,{html5:typeof options.html5!=="undefined"?options.html5:true,start:function(tag,attrs,unary,unarySlash){tag=tag.toLowerCase();currentTag=tag;currentChars="";currentAttrs=attrs;if(options.collapseWhitespace){if(!_canTrimWhitespace(tag,attrs)){stackNoTrimWhitespace.push(tag)}if(!_canCollapseWhitespace(tag,attrs)){stackNoCollapseWhitespace.push(tag)}}buffer.push("<",tag);lint&&lint.testElement(tag);for(var i=0,len=attrs.length;i<len;i++){lint&&lint.testAttribute(tag,attrs[i].name.toLowerCase(),attrs[i].escaped);buffer.push(normalizeAttribute(attrs[i],attrs,tag,options))}buffer.push((unarySlash&&options.keepClosingSlash?"/":"")+">")},end:function(tag){if(options.collapseWhitespace){if(stackNoTrimWhitespace.length&&tag===stackNoTrimWhitespace[stackNoTrimWhitespace.length-1]){stackNoTrimWhitespace.pop()}if(stackNoCollapseWhitespace.length&&tag===stackNoCollapseWhitespace[stackNoCollapseWhitespace.length-1]){stackNoCollapseWhitespace.pop()}}var isElementEmpty=currentChars===""&&tag===currentTag;if(options.removeEmptyElements&&isElementEmpty&&canRemoveElement(tag)){buffer.splice(buffer.lastIndexOf("<"));return}else if(options.removeOptionalTags&&isOptionalTag(tag)){return}else{buffer.push("</",tag.toLowerCase(),">");results.push.apply(results,buffer)}buffer.length=0;currentChars=""},chars:function(text,prevTag,nextTag){if(currentTag==="script"||currentTag==="style"){if(options.removeCommentsFromCDATA){text=removeComments(text,currentTag)}if(options.removeCDATASectionsFromCDATA){text=removeCDATASections(text)}}if(options.collapseWhitespace){if(!stackNoTrimWhitespace.length){text=prevTag||nextTag?collapseWhitespaceSmart(text,prevTag,nextTag):trimWhitespace(text)}if(!stackNoCollapseWhitespace.length){text=collapseWhitespace(text)}}currentChars=text;lint&&lint.testChars(text);buffer.push(text)},comment:function(text){if(options.removeComments){if(isConditionalComment(text)){text="<!--"+cleanConditionalComment(text)+"-->"}else if(isIgnoredComment(text)){text="<!--"+text+"-->"}else{text=""}}else{text="<!--"+text+"-->"}buffer.push(text)},ignore:function(text){buffer.push(options.removeIgnored?"":text)},doctype:function(doctype){buffer.push(options.useShortDoctype?"<!DOCTYPE html>":collapseWhitespace(doctype))}});results.push.apply(results,buffer);var str=results.join("");log("minified in: "+(new Date-t)+"ms");return str}if(typeof exports!=="undefined"){exports.minify=minify}else{global.minify=minify}})(this);(function(global){function isPresentationalElement(tag){return/^(?:b|i|big|small|hr|blink|marquee)$/.test(tag)}function isDeprecatedElement(tag){return/^(?:applet|basefont|center|dir|font|isindex|s|strike|u)$/.test(tag)}function isEventAttribute(attrName){return/^on[a-z]+/.test(attrName)}function isStyleAttribute(attrName){return"style"===attrName.toLowerCase()}function isDeprecatedAttribute(tag,attrName){return attrName==="align"&&/^(?:caption|applet|iframe|img|imput|object|legend|table|hr|div|h[1-6]|p)$/.test(tag)||attrName==="alink"&&tag==="body"||attrName==="alt"&&tag==="applet"||attrName==="archive"&&tag==="applet"||attrName==="background"&&tag==="body"||attrName==="bgcolor"&&/^(?:table|t[rdh]|body)$/.test(tag)||attrName==="border"&&/^(?:img|object)$/.test(tag)||attrName==="clear"&&tag==="br"||attrName==="code"&&tag==="applet"||attrName==="codebase"&&tag==="applet"||attrName==="color"&&/^(?:base(?:font)?)$/.test(tag)||attrName==="compact"&&/^(?:dir|[dou]l|menu)$/.test(tag)||attrName==="face"&&/^base(?:font)?$/.test(tag)||attrName==="height"&&/^(?:t[dh]|applet)$/.test(tag)||attrName==="hspace"&&/^(?:applet|img|object)$/.test(tag)||attrName==="language"&&tag==="script"||attrName==="link"&&tag==="body"||attrName==="name"&&tag==="applet"||attrName==="noshade"&&tag==="hr"||attrName==="nowrap"&&/^t[dh]$/.test(tag)||attrName==="object"&&tag==="applet"||attrName==="prompt"&&tag==="isindex"||attrName==="size"&&/^(?:hr|font|basefont)$/.test(tag)||attrName==="start"&&tag==="ol"||attrName==="text"&&tag==="body"||attrName==="type"&&/^(?:li|ol|ul)$/.test(tag)||attrName==="value"&&tag==="li"||attrName==="version"&&tag==="html"||attrName==="vlink"&&tag==="body"||attrName==="vspace"&&/^(?:applet|img|object)$/.test(tag)||attrName==="width"&&/^(?:hr|td|th|applet|pre)$/.test(tag)}function isInaccessibleAttribute(attrName,attrValue){return attrName==="href"&&/^\s*javascript\s*:\s*void\s*(\s+0|\(\s*0\s*\))\s*$/i.test(attrValue)}function Lint(){this.log=[];this._lastElement=null;this._isElementRepeated=false}Lint.prototype.testElement=function(tag){if(isDeprecatedElement(tag)){this.log.push('<li>Found <span class="deprecated-element">deprecated</span> <strong><code>&lt;'+tag+"&gt;</code></strong> element</li>")}else if(isPresentationalElement(tag)){this.log.push('<li>Found <span class="presentational-element">presentational</span> <strong><code>&lt;'+tag+"&gt;</code></strong> element</li>")}else{this.checkRepeatingElement(tag)}};Lint.prototype.checkRepeatingElement=function(tag){if(tag==="br"&&this._lastElement==="br"){this._isElementRepeated=true}else if(this._isElementRepeated){this._reportRepeatingElement();this._isElementRepeated=false}this._lastElement=tag};Lint.prototype._reportRepeatingElement=function(){this.log.push("<li>Found <code>&lt;br></code> sequence. Try replacing it with styling.</li>")};Lint.prototype.testAttribute=function(tag,attrName,attrValue){if(isEventAttribute(attrName)){this.log.push('<li>Found <span class="event-attribute">event attribute</span> (<strong>',attrName,"</strong>) on <strong><code>&lt;"+tag+"&gt;</code></strong> element</li>")}else if(isDeprecatedAttribute(tag,attrName)){this.log.push('<li>Found <span class="deprecated-attribute">deprecated</span> <strong>'+attrName+"</strong> attribute on <strong><code>&lt;",tag,"&gt;</code></strong> element</li>")}else if(isStyleAttribute(attrName)){this.log.push('<li>Found <span class="style-attribute">style attribute</span> on <strong><code>&lt;',tag,"&gt;</code></strong> element</li>")}else if(isInaccessibleAttribute(attrName,attrValue)){this.log.push('<li>Found <span class="inaccessible-attribute">inaccessible attribute</span> '+"(on <strong><code>&lt;",tag,"&gt;</code></strong> element)</li>")}};Lint.prototype.testChars=function(chars){this._lastElement="";if(/(&nbsp;\s*){2,}/.test(chars)){this.log.push("<li>Found repeating <strong><code>&amp;nbsp;</code></strong> sequence. Try replacing it with styling.</li>")}};Lint.prototype.test=function(tag,attrName,attrValue){this.testElement(tag);this.testAttribute(tag,attrName,attrValue)};Lint.prototype.populate=function(writeToElement){if(this._isElementRepeated){this._reportRepeatingElement()}var report;if(this.log.length&&writeToElement){report="<ol>"+this.log.join("")+"</ol>";writeToElement.innerHTML=report}};global.HTMLLint=Lint})(typeof exports==="undefined"?this:exports);
\ No newline at end of file
similarity index 99%
rename from dist/all.js
rename to dist/htmlminifier.js
index e2c8a08..355c015 100644 (file)
     return obj;
   }
 })(typeof exports === 'undefined' ? this : exports);
+
 /*!
  * HTMLMinifier v0.5.5
  * http://kangax.github.com/html-minifier/
   }
 
 }(this));
+
 /*!
  * HTMLLint (to be used in conjunction with HTMLMinifier)
  *
diff --git a/dist/htmlminifier.min.js b/dist/htmlminifier.min.js
new file mode 100644 (file)
index 0000000..fc50c6d
--- /dev/null
@@ -0,0 +1 @@
+!function(a){function b(a){for(var b={},c=a.split(","),d=0;d<c.length;d++)b[c[d]]=!0,b[c[d].toUpperCase()]=!0;return b}var c,d,e,f=/^<([\w:-]+)((?:\s*[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/,g=/^<\/([\w:-]+)[^>]*>/,h=/\/>$/,i=/([\w:-]+)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g,j=/^<!DOCTYPE [^>]+>/i,k=/<(%|\?)/,l=/(%|\?)>/,m=b("area,base,basefont,br,col,frame,hr,img,input,isindex,link,meta,param,embed"),n=b("a,abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,code,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var"),o=b("colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr,source"),p=b("checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected"),q=b("script,style"),r={},s=a.HTMLParser=function(a,b){function s(a,c,d,e){for(var f=!1;!b.html5&&z.last()&&n[z.last()];)t("",z.last());if(o[c]&&z.last()===c&&t("",c),e=m[c]||!!e,e?f=a.match(h):z.push(c),b.start){var g=[];d.replace(i,function(a,b){var c=arguments[2]?arguments[2]:arguments[3]?arguments[3]:arguments[4]?arguments[4]:p[b]?b:"";g.push({name:b,value:c,escaped:c.replace(/(^|[^\\])"/g,"$1&quot;")})}),b.start&&b.start(c,g,e,f)}}function t(a,c){var d;if(c)for(d=z.length-1;d>=0&&z[d]!==c;d--);else d=0;if(d>=0){for(var e=z.length-1;e>=d;e--)b.end&&b.end(z[e]);z.length=d}}var u,v,w,x,y,z=[],A=a;for(z.last=function(){return this[this.length-1]};a;){if(v=!0,z.last()&&q[z.last()])c=z.last().toLowerCase(),d=r[c]||(r[c]=new RegExp("([\\s\\S]*?)</"+c+"[^>]*>","i")),a=a.replace(d,function(a,d){return"script"!==c&&"style"!==c&&(d=d.replace(/<!--([\s\S]*?)-->/g,"$1").replace(/<!\[CDATA\[([\s\S]*?)\]\]>/g,"$1")),b.chars&&b.chars(d),""}),t("",c);else if(0===a.indexOf("<!--")?(u=a.indexOf("-->"),u>=0&&(b.comment&&b.comment(a.substring(4,u)),a=a.substring(u+3),v=!1)):0===a.search(k)?(u=a.search(l),u>=0&&(b.ignore&&b.ignore(a.substring(0,u+2)),a=a.substring(u+2),v=!1)):(w=j.exec(a))?(b.doctype&&b.doctype(w[0]),a=a.substring(w[0].length),v=!1):0===a.indexOf("</")?(w=a.match(g),w&&(a=a.substring(w[0].length),w[0].replace(g,t),x="/"+w[1],v=!1)):0===a.indexOf("<")&&(w=a.match(f),w&&(a=a.substring(w[0].length),w[0].replace(f,s),x=w[1],v=!1)),v){u=a.indexOf("<");var B=0>u?a:a.substring(0,u);a=0>u?"":a.substring(u),e=a.match(f),e?y=e[1]:(e=a.match(g),y=e?"/"+e[1]:""),b.chars&&b.chars(B,x,y)}if(a===A)throw"Parse Error: "+a;A=a}t()};a.HTMLtoXML=function(a){var b="";return s(a,{start:function(a,c,d){b+="<"+a;for(var e=0;e<c.length;e++)b+=" "+c[e].name+'="'+c[e].escaped+'"';b+=(d?"/":"")+">"},end:function(a){b+="</"+a+">"},chars:function(a){b+=a},comment:function(a){b+="<!--"+a+"-->"},ignore:function(a){b+=a}}),b},a.HTMLtoDOM=function(a,c){var d=b("html,head,body,title"),e={link:"head",base:"head"};c?c=c.ownerDocument||c.getOwnerDocument&&c.getOwnerDocument()||c:"undefined"!=typeof DOMDocument?c=new DOMDocument:"undefined"!=typeof document&&document.implementation&&document.implementation.createDocument?c=document.implementation.createDocument("","",null):"undefined"!=typeof ActiveX&&(c=new ActiveXObject("Msxml.DOMDocument"));var f=[],g=c.documentElement||c.getDocumentElement&&c.getDocumentElement();if(!g&&c.createElement&&function(){var a=c.createElement("html"),b=c.createElement("head");b.appendChild(c.createElement("title")),a.appendChild(b),a.appendChild(c.createElement("body")),c.appendChild(a)}(),c.getElementsByTagName)for(var h in d)d[h]=c.getElementsByTagName(h)[0];var i=d.body;return s(a,{start:function(a,b,g){if(d[a])return void(i=d[a]);var h=c.createElement(a);for(var j in b)h.setAttribute(b[j].name,b[j].value);e[a]&&"boolean"!=typeof d[e[a]]?d[e[a]].appendChild(h):i&&i.appendChild&&i.appendChild(h),g||(f.push(h),i=h)},end:function(){f.length-=1,i=f[f.length-1]},chars:function(a){i.appendChild(c.createTextNode(a))},comment:function(){},ignore:function(){}}),c}}("undefined"==typeof exports?this:exports),function(a){function b(a){return a.replace(/\s+/g," ")}function c(a,b,c){var d=["a","abbr","acronym","b","bdi","bdo","big","button","cite","code","del","dfn","em","font","i","ins","kbd","mark","q","rt","rp","s","samp","small","span","strike","strong","sub","sup","time","tt","u","var"];return b&&"img"!==b&&("/"!==b.substr(0,1)||"/"===b.substr(0,1)&&-1===d.indexOf(b.substr(1)))&&(a=a.replace(/^\s+/,"")),c&&"img"!==c&&("/"===c.substr(0,1)||"/"!==c.substr(0,1)&&-1===d.indexOf(c))&&(a=a.replace(/\s+$/,"")),b&&c?a.replace(/[\t\n\r]+/g," ").replace(/[ ]+/g," "):a}function d(a){return/\[if[^\]]+\]/.test(a)||/\s*(<!\[endif\])$/.test(a)}function e(a){return/^!/.test(a)}function f(a){return/^on[a-z]+/.test(a)}function g(a){return/^[^\x20\t\n\f\r"'`=<>]+$/.test(a)&&!/\/$/.test(a)&&!/\/$/.test(a)}function h(a,b){for(var c=a.length;c--;)if(a[c].name.toLowerCase()===b)return!0;return!1}function i(a,b,c,d){return c=C(c.toLowerCase()),"script"===a&&"language"===b&&"javascript"===c||"form"===a&&"method"===b&&"get"===c||"input"===a&&"type"===b&&"text"===c||"script"===a&&"charset"===b&&!h(d,"src")||"a"===a&&"name"===b&&h(d,"id")||"area"===a&&"shape"===b&&"rect"===c}function j(a,b,c){return"script"===a&&"type"===b&&"text/javascript"===C(c.toLowerCase())}function k(a,b,c){return("style"===a||"link"===a)&&"type"===b&&"text/css"===C(c.toLowerCase())}function l(a){return/^(?:allowfullscreen|async|autofocus|checked|compact|declare|default|defer|disabled|formnovalidate|hidden|inert|ismap|itemscope|multiple|muted|nohref|noresize|noshade|novalidate|nowrap|open|readonly|required|reversed|seamless|selected|sortable|truespeed|typemustmatch)$/.test(a)}function m(a,b){return/^(?:a|area|link|base)$/.test(b)&&"href"===a||"img"===b&&/^(?:src|longdesc|usemap)$/.test(a)||"object"===b&&/^(?:classid|codebase|data|usemap)$/.test(a)||"q"===b&&"cite"===a||"blockquote"===b&&"cite"===a||("ins"===b||"del"===b)&&"cite"===a||"form"===b&&"action"===a||"input"===b&&("src"===a||"usemap"===a)||"head"===b&&"profile"===a||"script"===b&&("src"===a||"for"===a)}function n(a,b){return/^(?:a|area|object|button)$/.test(b)&&"tabindex"===a||"input"===b&&("maxlength"===a||"tabindex"===a)||"select"===b&&("size"===a||"tabindex"===a)||"textarea"===b&&/^(?:rows|cols|tabindex)$/.test(a)||"colgroup"===b&&"span"===a||"col"===b&&"span"===a||("th"===b||"td"===b)&&("rowspan"===a||"colspan"===a)}function o(a,c,d){return f(c)?C(d).replace(/^javascript:\s*/i,"").replace(/\s*;$/,""):"class"===c?b(C(d)):m(c,a)||n(c,a)?C(d):"style"===c?C(d).replace(/\s*;\s*$/,""):d}function p(a){return a.replace(/^(\[[^\]]+\]>)\s*/,"$1").replace(/\s*(<!\[endif\])$/,"$1")}function q(a){return a.replace(/^(?:\s*\/\*\s*<!\[CDATA\[\s*\*\/|\s*\/\/\s*<!\[CDATA\[.*)/,"").replace(/(?:\/\*\s*\]\]>\s*\*\/|\/\/\s*\]\]>)\s*$/,"")}function r(a,b){return a.replace(D[b],"").replace(E[b],"")}function s(a){return/^(?:html|t?body|t?head|tfoot|tr|td|th|option|source)$/.test(a)}function t(a,b,c){var d=/^(["'])?\s*\1$/.test(c);return d?"input"===a&&"value"===b||F.test(b):!1}function u(a){return"textarea"!==a}function v(a){return!/^(?:script|style|pre|textarea)$/.test(a)}function w(a){return!/^(?:pre|textarea)$/.test(a)}function x(a,b,c,d){var e,f=d.caseSensitive?a.name:a.name.toLowerCase(),h=a.escaped;return d.removeRedundantAttributes&&i(c,f,h,b)||d.removeScriptTypeAttributes&&j(c,f,h)||d.removeStyleLinkTypeAttributes&&k(c,f,h)?"":(h=o(c,f,h),d.removeAttributeQuotes&&g(h)||(h='"'+h+'"'),d.removeEmptyAttributes&&t(c,f,h)?"":(e=d.collapseBooleanAttributes&&l(f)?f:f+"="+h," "+e))}function y(a){for(var b=["canCollapseWhitespace","canTrimWhitespace"],c=0,d=b.length;d>c;c++)a[b[c]]||(a[b[c]]=function(){return!1})}function z(a,f){function g(a,b){return v(a)||f.canTrimWhitespace(a,b)}function h(a,b){return w(a)||f.canTrimWhitespace(a,b)}f=f||{},a=C(a),y(f);var i=[],j=[],k="",l="",m=[],n=[],o=[],t=f.lint,z=new Date;B(a,{html5:"undefined"!=typeof f.html5?f.html5:!0,start:function(a,b,c,d){a=a.toLowerCase(),l=a,k="",m=b,f.collapseWhitespace&&(h(a,b)||n.push(a),g(a,b)||o.push(a)),j.push("<",a),t&&t.testElement(a);for(var e=0,i=b.length;i>e;e++)t&&t.testAttribute(a,b[e].name.toLowerCase(),b[e].escaped),j.push(x(b[e],b,a,f));j.push((d&&f.keepClosingSlash?"/":"")+">")},end:function(a){f.collapseWhitespace&&(n.length&&a===n[n.length-1]&&n.pop(),o.length&&a===o[o.length-1]&&o.pop());var b=""===k&&a===l;return f.removeEmptyElements&&b&&u(a)?void j.splice(j.lastIndexOf("<")):void(f.removeOptionalTags&&s(a)||(j.push("</",a.toLowerCase(),">"),i.push.apply(i,j),j.length=0,k=""))},chars:function(a,d,e){("script"===l||"style"===l)&&(f.removeCommentsFromCDATA&&(a=r(a,l)),f.removeCDATASectionsFromCDATA&&(a=q(a))),f.collapseWhitespace&&(n.length||(a=d||e?c(a,d,e):C(a)),o.length||(a=b(a))),k=a,t&&t.testChars(a),j.push(a)},comment:function(a){a=f.removeComments?d(a)?"<!--"+p(a)+"-->":e(a)?"<!--"+a+"-->":"":"<!--"+a+"-->",j.push(a)},ignore:function(a){j.push(f.removeIgnored?"":a)},doctype:function(a){j.push(f.useShortDoctype?"<!DOCTYPE html>":b(a))}}),i.push.apply(i,j);var D=i.join("");return A("minified in: "+(new Date-z)+"ms"),D}var A,B;A=a.console&&a.console.log?function(b){a.console.log(b)}:function(){},a.HTMLParser?B=a.HTMLParser:"function"==typeof require&&(B=require("./htmlparser").HTMLParser);var C=function(a){return a.replace(/^\s+/,"").replace(/\s+$/,"")};String.prototype.trim&&(C=function(a){return a.trim()});var D={script:/^\s*(?:\/\/)?\s*<!--.*\n?/,style:/^\s*<!--\s*/},E={script:/\s*(?:\/\/)?\s*-->\s*$/,style:/\s*-->\s*$/},F=new RegExp("^(?:class|id|style|title|lang|dir|on(?:focus|blur|change|click|dblclick|mouse(?:down|up|over|move|out)|key(?:press|down|up)))$");"undefined"!=typeof exports?exports.minify=z:a.minify=z}(this),function(a){function b(a){return/^(?:b|i|big|small|hr|blink|marquee)$/.test(a)}function c(a){return/^(?:applet|basefont|center|dir|font|isindex|s|strike|u)$/.test(a)}function d(a){return/^on[a-z]+/.test(a)}function e(a){return"style"===a.toLowerCase()}function f(a,b){return"align"===b&&/^(?:caption|applet|iframe|img|imput|object|legend|table|hr|div|h[1-6]|p)$/.test(a)||"alink"===b&&"body"===a||"alt"===b&&"applet"===a||"archive"===b&&"applet"===a||"background"===b&&"body"===a||"bgcolor"===b&&/^(?:table|t[rdh]|body)$/.test(a)||"border"===b&&/^(?:img|object)$/.test(a)||"clear"===b&&"br"===a||"code"===b&&"applet"===a||"codebase"===b&&"applet"===a||"color"===b&&/^(?:base(?:font)?)$/.test(a)||"compact"===b&&/^(?:dir|[dou]l|menu)$/.test(a)||"face"===b&&/^base(?:font)?$/.test(a)||"height"===b&&/^(?:t[dh]|applet)$/.test(a)||"hspace"===b&&/^(?:applet|img|object)$/.test(a)||"language"===b&&"script"===a||"link"===b&&"body"===a||"name"===b&&"applet"===a||"noshade"===b&&"hr"===a||"nowrap"===b&&/^t[dh]$/.test(a)||"object"===b&&"applet"===a||"prompt"===b&&"isindex"===a||"size"===b&&/^(?:hr|font|basefont)$/.test(a)||"start"===b&&"ol"===a||"text"===b&&"body"===a||"type"===b&&/^(?:li|ol|ul)$/.test(a)||"value"===b&&"li"===a||"version"===b&&"html"===a||"vlink"===b&&"body"===a||"vspace"===b&&/^(?:applet|img|object)$/.test(a)||"width"===b&&/^(?:hr|td|th|applet|pre)$/.test(a)}function g(a,b){return"href"===a&&/^\s*javascript\s*:\s*void\s*(\s+0|\(\s*0\s*\))\s*$/i.test(b)}function h(){this.log=[],this._lastElement=null,this._isElementRepeated=!1}h.prototype.testElement=function(a){c(a)?this.log.push('<li>Found <span class="deprecated-element">deprecated</span> <strong><code>&lt;'+a+"&gt;</code></strong> element</li>"):b(a)?this.log.push('<li>Found <span class="presentational-element">presentational</span> <strong><code>&lt;'+a+"&gt;</code></strong> element</li>"):this.checkRepeatingElement(a)},h.prototype.checkRepeatingElement=function(a){"br"===a&&"br"===this._lastElement?this._isElementRepeated=!0:this._isElementRepeated&&(this._reportRepeatingElement(),this._isElementRepeated=!1),this._lastElement=a},h.prototype._reportRepeatingElement=function(){this.log.push("<li>Found <code>&lt;br></code> sequence. Try replacing it with styling.</li>")},h.prototype.testAttribute=function(a,b,c){d(b)?this.log.push('<li>Found <span class="event-attribute">event attribute</span> (<strong>',b,"</strong>) on <strong><code>&lt;"+a+"&gt;</code></strong> element</li>"):f(a,b)?this.log.push('<li>Found <span class="deprecated-attribute">deprecated</span> <strong>'+b+"</strong> attribute on <strong><code>&lt;",a,"&gt;</code></strong> element</li>"):e(b)?this.log.push('<li>Found <span class="style-attribute">style attribute</span> on <strong><code>&lt;',a,"&gt;</code></strong> element</li>"):g(b,c)&&this.log.push('<li>Found <span class="inaccessible-attribute">inaccessible attribute</span> (on <strong><code>&lt;',a,"&gt;</code></strong> element)</li>")},h.prototype.testChars=function(a){this._lastElement="",/(&nbsp;\s*){2,}/.test(a)&&this.log.push("<li>Found repeating <strong><code>&amp;nbsp;</code></strong> sequence. Try replacing it with styling.</li>")},h.prototype.test=function(a,b,c){this.testElement(a),this.testAttribute(a,b,c)},h.prototype.populate=function(a){this._isElementRepeated&&this._reportRepeatingElement();var b;this.log.length&&a&&(b="<ol>"+this.log.join("")+"</ol>",a.innerHTML=b)},a.HTMLLint=h}("undefined"==typeof exports?this:exports);
\ No newline at end of file
index 9381db0..eb5d9cf 100644 (file)
         Source and bugtracker are <a href="http://github.com/kangax/html-minifier">hosted on Github</a>.
       </p>
     </div>
-    <script src="dist/all.min.js"></script>
+    <script src="dist/htmlminifier.min.js"></script>
     <script src="master.js"></script>
   </body>
 </html>
index 3fad664..031d868 100644 (file)
     "test": "tests"
   },
   "scripts": {
-    "build": "cat src/htmlparser.js src/htmlminifier.js src/htmllint.js > dist/all.js",
-    "dist": "npm run build && npm run minify",
-    "lint": "jshint src/htmlminifier.js src/htmllint.js",
-    "minify": "uglifyjs --output dist/all.min.js dist/all.js",
-    "test": "npm run lint && npm run build && node test.js"
+    "test": "grunt test && node test.js"
   },
   "devDependencies": {
-    "jshint": "2.4.x",
+    "grunt": "0.4.x",
+    "grunt-contrib-concat": "0.3.x",
+    "grunt-contrib-jshint": "0.8.x",
+    "grunt-contrib-qunit": "0.4.x",
+    "grunt-contrib-uglify": "0.3.x",
+    "load-grunt-tasks": "0.3.x",
     "qunit": "0.5.x",
-    "uglify-js": "2.4.x"
+    "time-grunt": "0.2.x"
   },
-  "main": "./dist/all.js"
+  "main": "./dist/htmlminifier.js"
 }
index 866e595..ac00ac6 100644 (file)
@@ -5,7 +5,7 @@
     <title>HTML Minifier Tests</title>
     <link rel="stylesheet" href="http://oss.maxcdn.com/libs/qunit/1.13/qunit.min.css">
     <script src="http://oss.maxcdn.com/libs/qunit/1.13/qunit.min.js"></script>
-    <script src="../dist/all.js"></script>
+    <script src="../dist/htmlminifier.js"></script>
   </head>
   <body>
 
index ba04a56..1e19c97 100644 (file)
@@ -5,7 +5,7 @@
     <title>HTML Lint Tests</title>
     <link rel="stylesheet" href="http://oss.maxcdn.com/libs/qunit/1.13/qunit.min.css">
     <script src="http://oss.maxcdn.com/libs/qunit/1.13/qunit.min.js"></script>
-    <script src="../dist/all.js"></script>
+    <script src="../dist/htmlminifier.js"></script>
   </head>
   <body>
     <h1 id="qunit-header">HTML Lint</h1>
index 2ef0ccd..ad42462 100644 (file)
@@ -1,7 +1,7 @@
 (function(global){
 
-  var minify = global.minify || require('../dist/all.js').minify,
-      HTMLLint = HTMLLint || require('../dist/all.js').HTMLLint,
+  var minify = global.minify || require('../dist/htmlminifier.js').minify,
+      HTMLLint = HTMLLint || require('../dist/htmlminifier.js').HTMLLint,
       input,
       output,
       lint = new HTMLLint();
index 6ae76ec..0f2ce52 100644 (file)
@@ -1,6 +1,6 @@
 (function(global){
 
-  var minify = global.minify || require('../dist/all.js').minify,
+  var minify = global.minify || require('../dist/htmlminifier.js').minify,
       input,
       output;