1 |
|
2 |
|
3 |
|
4 |
|
5 | var htmlMinifier = require("html-minifier");
|
6 | var attrParse = require("./lib/attributesParser");
|
7 | var loaderUtils = require("loader-utils");
|
8 | var url = require("url");
|
9 | var assign = require("object-assign");
|
10 | var compile = require("es6-templates").compile;
|
11 |
|
12 | function randomIdent() {
|
13 | return "xxxHTMLLINKxxx" + Math.random() + Math.random() + "xxx";
|
14 | }
|
15 |
|
16 | function 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 |
|
26 | module.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 | }
|