Skip to content

Commit e67d13c

Browse files
authored
Merge pull request #55 from akesser/master
Add support for srcset
2 parents a6ae756 + 9075dc3 commit e67d13c

File tree

3 files changed

+79
-14
lines changed

3 files changed

+79
-14
lines changed

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,15 @@ npm i -D html-loader
2525

2626
By default every local `<img src="image.png">` is required (`require('./image.png')`). You may need to specify loaders for images in your configuration (recommended `file-loader` or `url-loader`).
2727

28-
You can specify which tag-attribute combination should be processed by this loader via the query parameter `attrs`. Pass an array or a space-separated list of `<tag>:<attribute>` combinations. (Default: `attrs=img:src`)
28+
Also every `<img srcset="..."`> is converted to `require` statements. For example
29+
``` html
30+
<img src="image.jpg" srcset="image.jpg 1x, [email protected] 2x">
31+
```
32+
is converted to
33+
``` javascript
34+
"<img src=\"" + require("./image.jpg") + "\" srcset=\"" + require("./image.jpg") + " 1x," + require("./[email protected]") + " 2x \">"
35+
```
36+
You can specify which tag-attribute combination should be processed by this loader via the query parameter `attrs`. Pass an array or a space-separated list of `<tag>:<attribute>` combinations. (Default: `attrs=[img:src, img:srcset]`)
2937

3038
To completely disable tag-attribute processing (for instance, if you're handling image loading on the client side) you can pass in `attrs=false`.
3139

index.js

Lines changed: 49 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ function getLoaderConfig(context) {
2626
module.exports = function(content) {
2727
this.cacheable && this.cacheable();
2828
var config = getLoaderConfig(this);
29-
var attributes = ["img:src"];
29+
var attributes = ["img:src", "img:srcset"];
3030
if(config.attrs !== undefined) {
3131
if(typeof config.attrs === "string")
3232
attributes = config.attrs.split(" ");
@@ -38,27 +38,56 @@ module.exports = function(content) {
3838
throw new Error("Invalid value to config parameter attrs");
3939
}
4040
var root = config.root;
41-
var links = attrParse(content, function(tag, attr) {
41+
var rawLinks = attrParse(content, function(tag, attr) {
4242
return attributes.indexOf(tag + ":" + attr) >= 0;
4343
});
44+
var links = [];
45+
rawLinks.forEach(function (link) {
46+
var length = link.length;
47+
var start = link.start;
48+
var valueList = link.value.split(",");
49+
valueList.forEach(function (newLink) {
50+
var trimmed = newLink.trim();
51+
var cLength = newLink.length;
52+
var spacePos = trimmed.indexOf(" ");
53+
var spaceStart = newLink.indexOf(trimmed);
54+
var len = cLength+ spaceStart;
55+
if (-1 != spacePos) {
56+
len = spacePos + spaceStart;
57+
trimmed = trimmed.substring(0,spacePos);
58+
}
59+
links.push({start: start, length: len , value: trimmed});
60+
start += cLength+1;
61+
});
62+
});
4463
links.reverse();
4564
var data = {};
4665
content = [content];
4766
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-
}
67+
var newValue = link.value.split(",");
68+
var newValue = newValue.map(function (value) {
69+
var valueArray = value.trim().split(" ");
70+
var obj = {
71+
value: valueArray.shift(),
72+
additional: valueArray,
73+
};
74+
if(!loaderUtils.isUrlRequest(obj.value, root)) return;
75+
var uri = url.parse(obj.value);
76+
if (uri.hash !== null && uri.hash !== undefined) {
77+
obj.hash = uri.hash;
78+
uri.hash = null;
79+
obj.value = uri.format();
80+
}
81+
return obj;
82+
});
5683

5784
do {
5885
var ident = randomIdent();
5986
} while(data[ident]);
60-
data[ident] = link.value;
87+
data[ident] = newValue;
6188
var x = content.pop();
89+
90+
6291
content.push(x.substr(link.start + link.length));
6392
content.push(ident);
6493
content.push(x.substr(0, link.start));
@@ -95,9 +124,16 @@ module.exports = function(content) {
95124
} else {
96125
content = JSON.stringify(content);
97126
}
98-
99127
return "module.exports = " + content.replace(/xxxHTMLLINKxxx[0-9\.]+xxx/g, function(match) {
100128
if(!data[match]) return match;
101-
return '" + require(' + JSON.stringify(loaderUtils.urlToRequest(data[match], root)) + ') + "';
129+
return data[match].reduce(function (pV,cV, index, array) {
130+
131+
var hash = cV.hash || "";
132+
var additional = cV.additional.length != 0 ? " " + cV.additional.join(" ") : "";
133+
if (index != array.length -1) {
134+
additional += ",";
135+
}
136+
return pV + '" + require(' + JSON.stringify(loaderUtils.urlToRequest(cV.value, root)) + ') + "' + hash + additional;
137+
},"");
102138
}) + ";";
103139
}

test/loaderTest.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,27 @@ describe("loader", function() {
2929
'module.exports = "Text <script src=\\"" + require("./script.js") + "\\"><img src=\\"" + require("./image.png") + "\\">";'
3030
);
3131
});
32+
it("should handle srcset-attrubute by default", function ()
33+
{
34+
loader.call({
35+
},'Text <img srcset="image.png 1x">').should.be.eql(
36+
'module.exports = "Text <img srcset=\\"" + require("./image.png") + " 1x\\">";'
37+
)
38+
});
39+
it("should handle srcset-attrubute with comma seperated list", function ()
40+
{
41+
loader.call({
42+
},'Text <img srcset="image.png 1x,[email protected] 2x">').should.be.eql(
43+
'module.exports = "Text <img srcset=\\"" + require("./image.png") + " 1x,\" + require("./[email protected]") + " 2x\\">";'
44+
)
45+
});
46+
it("should handle srcset-attrubute with comma seperated list, independend of spaces in list", function ()
47+
{
48+
loader.call({
49+
},'Text <img srcset="image.png 1x, [email protected] 2x">').should.be.eql(
50+
'module.exports = "Text <img srcset=\\"" + require("./image.png") + " 1x,\" + require("./[email protected]") + " 2x\\">";'
51+
)
52+
});
3253
it("should not make bad things with templates", function() {
3354
loader.call({}, '<h3>#{number} {customer}</h3>\n<p> {title} </p>').should.be.eql(
3455
'module.exports = "<h3>#{number} {customer}</h3>\\n<p> {title} </p>";'

0 commit comments

Comments
 (0)