diff --git a/src/htmlminifier.js b/src/htmlminifier.js
index 120e62b8..7e887f29 100644
--- a/src/htmlminifier.js
+++ b/src/htmlminifier.js
@@ -613,113 +613,107 @@ function identity(value) {
return value;
}
-function processOptions(options) {
- ['html5', 'includeAutoGeneratedTags'].forEach(function(key) {
- if (!(key in options)) {
- options[key] = true;
- }
- });
-
- if (typeof options.log !== 'function') {
- options.log = identity;
- }
-
- if (!options.canCollapseWhitespace) {
- options.canCollapseWhitespace = canCollapseWhitespace;
- }
- if (!options.canTrimWhitespace) {
- options.canTrimWhitespace = canTrimWhitespace;
- }
-
- if (!('ignoreCustomComments' in options)) {
- options.ignoreCustomComments = [/^!/];
- }
-
- if (!('ignoreCustomFragments' in options)) {
- options.ignoreCustomFragments = [
+function processOptions(values) {
+ var options = {
+ canCollapseWhitespace: canCollapseWhitespace,
+ canTrimWhitespace: canTrimWhitespace,
+ html5: true,
+ ignoreCustomComments: [/^!/],
+ ignoreCustomFragments: [
/<%[\s\S]*?%>/,
/<\?[\s\S]*?\?>/
- ];
- }
-
- if (!options.minifyURLs) {
- options.minifyURLs = identity;
- }
- if (typeof options.minifyURLs !== 'function') {
- var minifyURLs = options.minifyURLs;
- if (typeof minifyURLs === 'string') {
- minifyURLs = { site: minifyURLs };
- }
- else if (typeof minifyURLs !== 'object') {
- minifyURLs = {};
- }
- options.minifyURLs = function(text) {
- try {
- return RelateUrl.relate(text, minifyURLs);
- }
- catch (err) {
- options.log(err);
- return text;
+ ],
+ includeAutoGeneratedTags: true,
+ log: identity,
+ minifyCSS: identity,
+ minifyJS: identity,
+ minifyURLs: identity
+ };
+ Object.keys(values).forEach(function(key) {
+ var value = values[key];
+ if (key === 'log') {
+ if (typeof value === 'function') {
+ options.log = value;
}
- };
- }
-
- if (!options.minifyJS) {
- options.minifyJS = identity;
- }
- if (typeof options.minifyJS !== 'function') {
- var minifyJS = options.minifyJS;
- if (typeof minifyJS !== 'object') {
- minifyJS = {};
}
- (minifyJS.parse || (minifyJS.parse = {})).bare_returns = false;
- options.minifyJS = function(text, inline) {
- var start = text.match(/^\s*\s*$/, '') : text;
- minifyJS.parse.bare_returns = inline;
- var result = UglifyJS.minify(code, minifyJS);
- if (result.error) {
- options.log(result.error);
- return text;
+ else if (key === 'minifyCSS' && typeof value !== 'function') {
+ if (!value) {
+ return;
}
- return result.code.replace(/;$/, '');
- };
- }
-
- if (!options.minifyCSS) {
- options.minifyCSS = identity;
- }
- if (typeof options.minifyCSS !== 'function') {
- var minifyCSS = options.minifyCSS;
- if (typeof minifyCSS !== 'object') {
- minifyCSS = {};
- }
- options.minifyCSS = function(text, type) {
- text = text.replace(/(url\s*\(\s*)("|'|)(.*?)\2(\s*\))/ig, function(match, prefix, quote, url, suffix) {
- return prefix + quote + options.minifyURLs(url) + quote + suffix;
- });
- try {
- if (type === 'inline') {
- text = wrapInlineCSS(text);
- }
- else if (type === 'media') {
- text = wrapMediaQuery(text);
+ if (typeof value !== 'object') {
+ value = {};
+ }
+ options.minifyCSS = function(text, type) {
+ text = text.replace(/(url\s*\(\s*)("|'|)(.*?)\2(\s*\))/ig, function(match, prefix, quote, url, suffix) {
+ return prefix + quote + options.minifyURLs(url) + quote + suffix;
+ });
+ try {
+ if (type === 'inline') {
+ text = wrapInlineCSS(text);
+ }
+ else if (type === 'media') {
+ text = wrapMediaQuery(text);
+ }
+ text = new CleanCSS(value).minify(text).styles;
+ if (type === 'inline') {
+ text = unwrapInlineCSS(text);
+ }
+ else if (type === 'media') {
+ text = unwrapMediaQuery(text);
+ }
+ return text;
}
- text = new CleanCSS(minifyCSS).minify(text).styles;
- if (type === 'inline') {
- text = unwrapInlineCSS(text);
+ catch (err) {
+ options.log(err);
+ return text;
}
- else if (type === 'media') {
- text = unwrapMediaQuery(text);
+ };
+ }
+ else if (key === 'minifyJS' && typeof value !== 'function') {
+ if (!value) {
+ return;
+ }
+ if (typeof value !== 'object') {
+ value = {};
+ }
+ (value.parse || (value.parse = {})).bare_returns = false;
+ options.minifyJS = function(text, inline) {
+ var start = text.match(/^\s*\s*$/, '') : text;
+ value.parse.bare_returns = inline;
+ var result = UglifyJS.minify(code, value);
+ if (result.error) {
+ options.log(result.error);
+ return text;
}
- return text;
+ return result.code.replace(/;$/, '');
+ };
+ }
+ else if (key === 'minifyURLs' && typeof value !== 'function') {
+ if (!value) {
+ return;
}
- catch (err) {
- options.log(err);
- return text;
+ if (typeof value === 'string') {
+ value = { site: value };
}
- };
- }
+ else if (typeof value !== 'object') {
+ value = {};
+ }
+ options.minifyURLs = function(text) {
+ try {
+ return RelateUrl.relate(text, value);
+ }
+ catch (err) {
+ options.log(err);
+ return text;
+ }
+ };
+ }
+ else {
+ options[key] = value;
+ }
+ });
+ return options;
}
function uniqueId(value) {
@@ -817,9 +811,7 @@ function createSortFns(value, options, uidIgnore, uidAttr) {
}
function minify(value, options, partialMarkup) {
- options = options || {};
- var optionsStack = [];
- processOptions(options);
+ options = processOptions(options || {});
if (options.collapseWhitespace) {
value = collapseWhitespace(value, options, true, true);
}
@@ -850,22 +842,25 @@ function minify(value, options, partialMarkup) {
uidIgnore = uniqueId(value);
var pattern = new RegExp('^' + uidIgnore + '([0-9]+)$');
if (options.ignoreCustomComments) {
- options.ignoreCustomComments.push(pattern);
+ options.ignoreCustomComments = options.ignoreCustomComments.slice();
}
else {
- options.ignoreCustomComments = [pattern];
+ options.ignoreCustomComments = [];
}
+ options.ignoreCustomComments.push(pattern);
}
var token = '';
ignoredMarkupChunks.push(group1);
return token;
});
- function escapeFragments(text) {
- return text.replace(uidPattern, function(match, prefix, index) {
- var chunks = ignoredCustomMarkupChunks[+index];
- return chunks[1] + uidAttr + index + chunks[2];
- });
+ function escapeFragments(fn) {
+ return function(text, type) {
+ return fn(text.replace(uidPattern, function(match, prefix, index) {
+ var chunks = ignoredCustomMarkupChunks[+index];
+ return chunks[1] + uidAttr + index + chunks[2];
+ }), type);
+ };
}
var customFragments = options.ignoreCustomFragments.map(function(re) {
@@ -878,17 +873,11 @@ function minify(value, options, partialMarkup) {
if (!uidAttr) {
uidAttr = uniqueId(value);
uidPattern = new RegExp('(\\s*)' + uidAttr + '([0-9]+)(\\s*)', 'g');
- var minifyCSS = options.minifyCSS;
- if (minifyCSS) {
- options.minifyCSS = function(text, type) {
- return minifyCSS(escapeFragments(text), type);
- };
+ if (options.minifyCSS) {
+ options.minifyCSS = escapeFragments(options.minifyCSS);
}
- var minifyJS = options.minifyJS;
- if (minifyJS) {
- options.minifyJS = function(text, inline) {
- return minifyJS(escapeFragments(text), inline);
- };
+ if (options.minifyJS) {
+ options.minifyJS = escapeFragments(options.minifyJS);
}
}
var token = uidAttr + ignoredCustomMarkupChunks.length;
@@ -962,14 +951,9 @@ function minify(value, options, partialMarkup) {
var lowerTag = tag.toLowerCase();
if (lowerTag === 'svg') {
- optionsStack.push(options);
- var nextOptions = {};
- for (var key in options) {
- nextOptions[key] = options[key];
- }
- nextOptions.keepClosingSlash = true;
- nextOptions.caseSensitive = true;
- options = nextOptions;
+ options = Object.create(options);
+ options.keepClosingSlash = true;
+ options.caseSensitive = true;
}
tag = options.caseSensitive ? tag : lowerTag;
@@ -1055,7 +1039,7 @@ function minify(value, options, partialMarkup) {
end: function(tag, attrs, autoGenerated) {
var lowerTag = tag.toLowerCase();
if (lowerTag === 'svg') {
- options = optionsStack.pop();
+ options = Object.getPrototypeOf(options);
}
tag = options.caseSensitive ? tag : lowerTag;