UNPKG

2.94 kBJavaScriptView Raw
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
4*/
5var htmlMinifier = require("html-minifier");
6var attrParse = require("./lib/attributesParser");
7var loaderUtils = require("loader-utils");
8var url = require("url");
9var assign = require("object-assign");
10var compile = require("es6-templates").compile;
11
12function randomIdent() {
13 return "xxxHTMLLINKxxx" + Math.random() + Math.random() + "xxx";
14}
15
16function getLoaderConfig(context) {
17 var query = loaderUtils.parseQuery(context.query);
18 var configKey = query.config || 'htmlLoader';
19 var config = context.options && context.options.hasOwnProperty(configKey) ? context.options[configKey] : {};
20
21 delete query.config;
22
23 return assign(query, config);
24}
25
26module.exports = function(content) {
27 this.cacheable && this.cacheable();
28 var config = getLoaderConfig(this);
29 var attributes = ["img:src"];
30 if(config.attrs !== undefined) {
31 if(typeof config.attrs === "string")
32 attributes = config.attrs.split(" ");
33 else if(Array.isArray(config.attrs))
34 attributes = config.attrs;
35 else if(config.attrs === false)
36 attributes = [];
37 else
38 throw new Error("Invalid value to config parameter attrs");
39 }
40 var root = config.root;
41 var links = attrParse(content, function(tag, attr) {
42 return attributes.indexOf(tag + ":" + attr) >= 0;
43 });
44 links.reverse();
45 var data = {};
46 content = [content];
47 links.forEach(function(link) {
48 if(!loaderUtils.isUrlRequest(link.value, root)) return;
49
50 var uri = url.parse(link.value);
51 if (uri.hash !== null && uri.hash !== undefined) {
52 uri.hash = null;
53 link.value = uri.format();
54 link.length = link.value.length;
55 }
56
57 do {
58 var ident = randomIdent();
59 } while(data[ident]);
60 data[ident] = link.value;
61 var x = content.pop();
62 content.push(x.substr(link.start + link.length));
63 content.push(ident);
64 content.push(x.substr(0, link.start));
65 });
66 content.reverse();
67 content = content.join("");
68 if(typeof config.minimize === "boolean" ? config.minimize : this.minimize) {
69 var minimizeOptions = assign({}, config);
70
71 [
72 "removeComments",
73 "removeCommentsFromCDATA",
74 "removeCDATASectionsFromCDATA",
75 "collapseWhitespace",
76 "conservativeCollapse",
77 "removeAttributeQuotes",
78 "useShortDoctype",
79 "keepClosingSlash",
80 "minifyJS",
81 "minifyCSS",
82 "removeScriptTypeAttributes",
83 "removeStyleTypeAttributes",
84 ].forEach(function(name) {
85 if(typeof minimizeOptions[name] === "undefined") {
86 minimizeOptions[name] = true;
87 }
88 });
89
90 content = htmlMinifier.minify(content, minimizeOptions);
91 }
92
93 if(config.interpolate) {
94 content = compile('`' + content + '`').code;
95 } else {
96 content = JSON.stringify(content);
97 }
98
99 return "module.exports = " + content.replace(/xxxHTMLLINKxxx[0-9\.]+xxx/g, function(match) {
100 if(!data[match]) return match;
101 return '" + require(' + JSON.stringify(loaderUtils.urlToRequest(data[match], root)) + ') + "';
102 }) + ";";
103}