html-minifier
Advanced tools
Comparing version 0.5.0 to 0.5.1
{ | ||
"name": "html-minifier", | ||
"description": "HTML minifier with lint-like capabilities.", | ||
"version": "0.5.0", | ||
"version": "0.5.1", | ||
"keywords": ["html", "minifier", "lint"], | ||
@@ -22,3 +22,3 @@ "url" : "http://github.com/kangax/html-minifier", | ||
"type": "MIT", | ||
"url": "https://github.com/kangax/html-minifier/blob/gh-pages/src/license.txt" | ||
"url": "https://github.com/kangax/html-minifier/blob/gh-pages/LICENSE" | ||
}], | ||
@@ -33,3 +33,3 @@ "repository": "git://github.com/kangax/html-minifier", | ||
"scripts": { | ||
"test": "node test.js" | ||
"test": "jshint src/htmlminifier.js src/htmllint.js && cat src/htmlparser.js src/htmlminifier.js src/htmllint.js > dist/all.js && node test.js" | ||
}, | ||
@@ -41,3 +41,3 @@ "devDependencies": { | ||
}, | ||
"main": "./src/htmlminifier.js" | ||
"main": "./dist/all.js" | ||
} |
@@ -15,3 +15,3 @@ /*! | ||
function isDeprecatedElement(tag) { | ||
return (/^(?:applet|basefont|center|dir|font|isindex|menu|s|strike|u)$/).test(tag); | ||
return (/^(?:applet|basefont|center|dir|font|isindex|s|strike|u)$/).test(tag); | ||
} | ||
@@ -18,0 +18,0 @@ function isEventAttribute(attrName) { |
/*! | ||
* HTMLMinifier v0.5.0 | ||
* HTMLMinifier v0.5.1 | ||
* http://kangax.github.com/html-minifier/ | ||
@@ -30,5 +30,5 @@ * | ||
function trimWhitespace(str) { | ||
var trimWhitespace = function(str) { | ||
return str.replace(/^\s+/, '').replace(/\s+$/, ''); | ||
} | ||
}; | ||
if (String.prototype.trim) { | ||
@@ -44,2 +44,24 @@ trimWhitespace = function(str) { | ||
function collapseWhitespaceSmart(str, prevTag, nextTag) { | ||
// array of tags that will maintain a single space outside of them | ||
var tags = ['a', 'b', 'big', 'button', 'em', 'font','i', 'img', 'mark', 's', 'small', 'span', 'strike', 'strong', 'sub', 'sup', 'tt', 'u']; | ||
if (prevTag && (prevTag.substr(0,1) !== '/' | ||
|| ( prevTag.substr(0,1) === '/' && tags.indexOf(prevTag.substr(1)) === -1))) { | ||
str = str.replace(/^\s+/, ''); | ||
} | ||
if (nextTag && (nextTag.substr(0,1) === '/' | ||
|| ( nextTag.substr(0,1) !== '/' && tags.indexOf(nextTag) === -1))) { | ||
str = str.replace(/\s+$/, ''); | ||
} | ||
if (prevTag && nextTag) { | ||
// strip non space whitespace then compress spaces to one | ||
return str.replace(/[\t\n\r]+/g, '').replace(/[ ]+/g, ' '); | ||
} | ||
return str; | ||
} | ||
function isConditionalComment(text) { | ||
@@ -140,3 +162,3 @@ return ((/\[if[^\]]+\]/).test(text) || (/\s*(<!\[endif\])$/).test(text)); | ||
(tag === 'col' && attrName === 'span') || | ||
((tag === 'th' || tag == 'td') && (attrName === 'rowspan' || attrName === 'colspan')) | ||
((tag === 'th' || tag === 'td') && (attrName === 'rowspan' || attrName === 'colspan')) | ||
); | ||
@@ -267,3 +289,3 @@ } | ||
return false; | ||
} | ||
}; | ||
} | ||
@@ -287,3 +309,3 @@ } | ||
lint = options.lint, | ||
t = new Date() | ||
t = new Date(); | ||
@@ -299,3 +321,3 @@ function _canCollapseWhitespace(tag, attrs) { | ||
HTMLParser(value, { | ||
start: function( tag, attrs, unary ) { | ||
start: function( tag, attrs ) { | ||
tag = tag.toLowerCase(); | ||
@@ -331,7 +353,7 @@ currentTag = tag; | ||
if (stackNoTrimWhitespace.length && | ||
tag == stackNoTrimWhitespace[stackNoTrimWhitespace.length - 1]) { | ||
tag === stackNoTrimWhitespace[stackNoTrimWhitespace.length - 1]) { | ||
stackNoTrimWhitespace.pop(); | ||
} | ||
if (stackNoCollapseWhitespace.length && | ||
tag == stackNoCollapseWhitespace[stackNoCollapseWhitespace.length - 1]) { | ||
tag === stackNoCollapseWhitespace[stackNoCollapseWhitespace.length - 1]) { | ||
stackNoCollapseWhitespace.pop(); | ||
@@ -360,3 +382,3 @@ } | ||
}, | ||
chars: function( text ) { | ||
chars: function( text, prevTag, nextTag ) { | ||
if (currentTag === 'script' || currentTag === 'style') { | ||
@@ -372,3 +394,3 @@ if (options.removeCommentsFromCDATA) { | ||
if (!stackNoTrimWhitespace.length && _canTrimWhitespace(currentTag, currentAttrs)) { | ||
text = trimWhitespace(text); | ||
text = (prevTag || nextTag) ? collapseWhitespaceSmart(text, prevTag, nextTag) : trimWhitespace(text); | ||
} | ||
@@ -402,3 +424,3 @@ if (!stackNoCollapseWhitespace.length && _canCollapseWhitespace(currentTag, currentAttrs)) { | ||
results.push.apply(results, buffer) | ||
results.push.apply(results, buffer); | ||
var str = results.join(''); | ||
@@ -405,0 +427,0 @@ log('minified in: ' + (new Date() - t) + 'ms'); |
@@ -31,6 +31,6 @@ /* | ||
var startTag = /^<([\w:-]+)((?:\s*[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/, | ||
endTag = /^<\/(\w+)[^>]*>/, | ||
endTag = /^<\/([\w:-]+)[^>]*>/, | ||
attr = /([\w:-]+)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g, | ||
doctype = /^<!DOCTYPE [^>]+>/i; | ||
// Empty Elements - HTML 4.01 | ||
@@ -54,7 +54,7 @@ var empty = makeMap("area,base,basefont,br,col,frame,hr,img,input,isindex,link,meta,param,embed"); | ||
var special = makeMap("script,style"); | ||
var reCache = { }, stackedTag, re; | ||
var HTMLParser = global.HTMLParser = function( html, handler ) { | ||
var index, chars, match, stack = [], last = html; | ||
var index, chars, match, stack = [], last = html, prevTag, nextTag; | ||
stack.last = function(){ | ||
@@ -73,3 +73,3 @@ return this[ this.length - 1 ]; | ||
index = html.indexOf("-->"); | ||
if ( index >= 0 ) { | ||
@@ -87,20 +87,22 @@ if ( handler.comment ) | ||
chars = false; | ||
// end tag | ||
} 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; | ||
} | ||
// start tag | ||
} 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; | ||
@@ -112,15 +114,29 @@ } | ||
index = html.indexOf("<"); | ||
var text = index < 0 ? html : html.substring( 0, index ); | ||
html = index < 0 ? "" : html.substring( index ); | ||
// next tag | ||
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 ); | ||
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) { | ||
@@ -146,3 +162,3 @@ if (stackedTag !== 'script' && stackedTag !== 'style') { | ||
} | ||
// Clean up any remaining tags | ||
@@ -152,7 +168,2 @@ parseEndTag(); | ||
function parseStartTag( tag, tagName, rest, unary ) { | ||
if ( block[ tagName ] ) { | ||
while ( stack.last() && inline[ stack.last() ] ) { | ||
parseEndTag( "", stack.last() ); | ||
} | ||
} | ||
@@ -167,6 +178,6 @@ if ( closeSelf[ tagName ] && stack.last() == tagName ) { | ||
stack.push( tagName ); | ||
if ( handler.start ) { | ||
var attrs = []; | ||
rest.replace(attr, function(match, name) { | ||
@@ -183,3 +194,3 @@ var value = arguments[2] ? arguments[2] : | ||
}); | ||
if ( handler.start ) | ||
@@ -194,3 +205,3 @@ handler.start( tagName, attrs, unary ); | ||
var pos = 0; | ||
// Find the closest opened tag of the same type | ||
@@ -201,3 +212,3 @@ else | ||
break; | ||
if ( pos >= 0 ) { | ||
@@ -208,3 +219,3 @@ // Close all the open elements, up the stack | ||
handler.end( stack[ i ] ); | ||
// Remove the open elements from the stack | ||
@@ -215,13 +226,13 @@ 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 ? "/" : "") + ">"; | ||
@@ -239,10 +250,10 @@ }, | ||
}); | ||
return results; | ||
}; | ||
global.HTMLtoDOM = function( html, doc ) { | ||
// There can be only one of these elements | ||
var one = makeMap("html,head,body,title"); | ||
// Enforce a structure for the document | ||
@@ -253,3 +264,3 @@ var structure = { | ||
}; | ||
if ( !doc ) { | ||
@@ -262,3 +273,3 @@ if ( typeof DOMDocument != "undefined" ) | ||
doc = new ActiveXObject("Msxml.DOMDocument"); | ||
} else | ||
@@ -268,7 +279,7 @@ doc = doc.ownerDocument || | ||
doc; | ||
var elems = [], | ||
documentElement = doc.documentElement || | ||
doc.getDocumentElement && doc.getDocumentElement(); | ||
// If we're dealing with an empty document then we | ||
@@ -284,3 +295,3 @@ // need to pre-populate it with the HTML document structure | ||
})(); | ||
// Find all the unique elements | ||
@@ -290,7 +301,7 @@ if ( doc.getElementsByTagName ) | ||
one[ i ] = doc.getElementsByTagName( i )[0]; | ||
// If we're working with a document, inject contents into | ||
// the body element | ||
var curParentNode = one.body; | ||
HTMLParser( html, { | ||
@@ -304,14 +315,14 @@ start: function( tagName, attrs, unary ) { | ||
} | ||
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 ) { | ||
@@ -324,3 +335,3 @@ elems.push( elem ); | ||
elems.length -= 1; | ||
// Init the new parentNode | ||
@@ -336,3 +347,3 @@ curParentNode = elems[ elems.length - 1 ]; | ||
}); | ||
return doc; | ||
@@ -349,2 +360,2 @@ }; | ||
} | ||
})(typeof exports === 'undefined' ? this : exports); | ||
})(typeof exports === 'undefined' ? this : exports); |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
1
32524
8
778