|
|
- /*
- MIT License http://www.opensource.org/licenses/mit-license.php
- Author Tobias Koppers @sokra
- */
- var htmlMinifier = require("html-minifier");
- var attrParse = require("./lib/attributesParser");
- var loaderUtils = require("loader-utils");
- var url = require("url");
- var assign = require("object-assign");
- var compile = require("es6-templates").compile;
-
- function randomIdent() {
- return "xxxHTMLLINKxxx" + Math.random() + Math.random() + "xxx";
- }
-
- function getLoaderConfig(context) {
- var query = loaderUtils.getOptions(context) || {};
- var configKey = query.config || 'htmlLoader';
- var config = context.options && context.options.hasOwnProperty(configKey) ? context.options[configKey] : {};
-
- delete query.config;
-
- return assign(query, config);
- }
-
- module.exports = function(content) {
- this.cacheable && this.cacheable();
- var config = getLoaderConfig(this);
- var attributes = ["img:src"];
- if(config.attrs !== undefined) {
- if(typeof config.attrs === "string")
- attributes = config.attrs.split(" ");
- else if(Array.isArray(config.attrs))
- attributes = config.attrs;
- else if(config.attrs === false)
- attributes = [];
- else
- throw new Error("Invalid value to config parameter attrs");
- }
- var root = config.root;
- var links = attrParse(content, function(tag, attr) {
- var res = attributes.find(function(a) {
- if (a.charAt(0) === ':') {
- return attr === a.slice(1);
- } else {
- return (tag + ":" + attr) === a;
- }
- });
- return !!res;
- });
- links.reverse();
- var data = {};
- content = [content];
- links.forEach(function(link) {
- if(!loaderUtils.isUrlRequest(link.value, root)) return;
-
- if (link.value.indexOf('mailto:') > -1 ) return;
-
- var uri = url.parse(link.value);
- if (uri.hash !== null && uri.hash !== undefined) {
- uri.hash = null;
- link.value = uri.format();
- link.length = link.value.length;
- }
-
- do {
- var ident = randomIdent();
- } while(data[ident]);
- data[ident] = link.value;
- var x = content.pop();
- content.push(x.substr(link.start + link.length));
- content.push(ident);
- content.push(x.substr(0, link.start));
- });
- content.reverse();
- content = content.join("");
-
- if (config.interpolate === 'require'){
-
- var reg = /\$\{require\([^)]*\)\}/g;
- var result;
- var reqList = [];
- while(result = reg.exec(content)){
- reqList.push({
- length : result[0].length,
- start : result.index,
- value : result[0]
- })
- }
- reqList.reverse();
- content = [content];
- reqList.forEach(function(link) {
- var x = content.pop();
- do {
- var ident = randomIdent();
- } while(data[ident]);
- data[ident] = link.value.substring(11,link.length - 3)
- content.push(x.substr(link.start + link.length));
- content.push(ident);
- content.push(x.substr(0, link.start));
- });
- content.reverse();
- content = content.join("");
- }
-
- if(typeof config.minimize === "boolean" ? config.minimize : this.minimize) {
- var minimizeOptions = assign({}, config);
-
- [
- "removeComments",
- "removeCommentsFromCDATA",
- "removeCDATASectionsFromCDATA",
- "collapseWhitespace",
- "conservativeCollapse",
- "removeAttributeQuotes",
- "useShortDoctype",
- "keepClosingSlash",
- "minifyJS",
- "minifyCSS",
- "removeScriptTypeAttributes",
- "removeStyleTypeAttributes",
- ].forEach(function(name) {
- if(typeof minimizeOptions[name] === "undefined") {
- minimizeOptions[name] = true;
- }
- });
-
- content = htmlMinifier.minify(content, minimizeOptions);
- }
-
- if(config.interpolate && config.interpolate !== 'require') {
- // Double escape quotes so that they are not unescaped completely in the template string
- content = content.replace(/\\"/g, "\\\\\"");
- content = content.replace(/\\'/g, "\\\\\'");
- content = compile('`' + content + '`').code;
- } else {
- content = JSON.stringify(content);
- }
-
- var exportsString = "module.exports = ";
- if (config.exportAsDefault) {
- exportsString = "exports.default = ";
-
- } else if (config.exportAsEs6Default) {
- exportsString = "export default ";
- }
-
- return exportsString + content.replace(/xxxHTMLLINKxxx[0-9\.]+xxx/g, function(match) {
- if(!data[match]) return match;
-
- var urlToRequest;
-
- if (config.interpolate === 'require') {
- urlToRequest = data[match];
- } else {
- urlToRequest = loaderUtils.urlToRequest(data[match], root);
- }
-
- return '" + require(' + JSON.stringify(urlToRequest) + ') + "';
- }) + ";";
-
- }
|