Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,16 @@ npm i -D html-loader

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`).

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`)
Also every `<img srcset="..."`> is converted to `require` statements. For example
``` html
<img src="image.jpg" srcset="image.jpg 1x, image@2x.jpg 2x">
```
is converted to
``` javascript
"<img src=\"" + require("./image.jpg") + "\" srcset=\"" + require("./image.jpg") + " 1x, " + require("./image@2x.jpg") + " 2x \">"
```

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]`). The srcset-specific qualifiers such as `100w` or `3x` are supported in any processed attribute.

If you use `<custom-elements>`, and lots of them make use of a `custom-src` attribute, you don't have to specify each combination `<tag>:<attribute>`: just specify an empty tag like `attrs=:custom-src` and it will match every element.

Expand Down
2 changes: 1 addition & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ function getLoaderConfig(context) {
module.exports = function(content) {
this.cacheable && this.cacheable();
var config = getLoaderConfig(this);
var attributes = ["img:src"];
var attributes = ["img:src", "img:srcset"];
if(config.attrs !== undefined) {
if(typeof config.attrs === "string")
attributes = config.attrs.split(" ");
Expand Down
14 changes: 9 additions & 5 deletions lib/attributesParser.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,18 @@
Author Tobias Koppers @sokra
*/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move this into its own folder && file => ./lib/attrs/srcset.js and require('./attrs/srcset.js') it

var Parser = require("fastparse");
var srcset = require("./attrs/srcset");

var processMatch = function(match, strUntilValue, name, value, index) {
if(!this.isRelevantTagAttr(this.currentTag, name)) return;
this.results.push({
start: index + strUntilValue.length,
length: value.length,
value: value
});

// tag might reference several images via srcset syntax
var start = index + strUntilValue.length;
var subMatches = srcset.split(start, value);

for (var i = 0; i < subMatches.length; ++i) {
this.results.push(subMatches[i]);
}
};

var parser = new Parser({
Expand Down
41 changes: 41 additions & 0 deletions lib/attrs/srcset.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
var SRCSET_REGEXP = /(\s+(\d+w))?(\s+(\d+x))?\s*$/;

function split(start, value) {
var matches = [];

// allow to load several urls in srcsets, separated by commas
var subMatches = value.split(/,/);

for(var i = 0; i < subMatches.length; ++i) {
var subMatch = {
start: start,
value: subMatches[i],
length: subMatches[i].length
};
// save position of the next match
var next = start + subMatch.length + 1;

// remove initial spacing
var space = /^\s+/.exec(subMatch.value);
if(space) {
subMatch.value = subMatch.value.substr(space[0].length)
}

// remove srcset qualifiers (2x, 110w, etc.) at the end
var qualifier = SRCSET_REGEXP.exec(subMatch.value);
if(qualifier) {
var qualifierLength = qualifier[0].length;
subMatch.length -= qualifierLength;
subMatch.value = subMatch.value.substr(0, subMatch.value.length - qualifierLength);
}

matches.push(subMatch);
start = next;
}

return matches;
}

module.exports = {
split: split
};
22 changes: 21 additions & 1 deletion test/loaderTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,31 @@ var should = require("should");
var loader = require("../");

describe("loader", function() {
it("should convert to requires", function() {
it("should convert src to requires", function() {
loader.call({}, 'Text <img src="image.png"><img src="~bootstrap-img"> Text').should.be.eql(
'module.exports = "Text <img src=\\"" + require("./image.png") + "\\"><img src=\\"" + require("bootstrap-img") + "\\"> Text";'
);
});
it("should convert srcset to requires", function() {
loader.call({}, 'Text <img srcset="image@2x.png 2x, ~bootstrap-img 3x"> Text').should.be.eql(
'module.exports = "Text <img srcset=\\"" + require("./image@2x.png") + " 2x," + require("bootstrap-img") + " 3x\\"> Text";'
);
});
it("should support both src srcset on a same element", function() {
loader.call({}, 'Text <img src="image.png" srcset="image@2x.png 2x, ~bootstrap-img 3x"> Text').should.be.eql(
'module.exports = "Text <img src=\\"" + require("./image.png") + "\\" srcset=\\"" + require("./image@2x.png") + " 2x," + require("bootstrap-img") + " 3x\\"> Text";'
);
});
it("should support multiple srcset qualifiers on a same element", function() {
loader.call({}, 'Text <img srcset="image-300w@2x.png 300w 2x, image@2x.png 2x"> Text').should.be.eql(
'module.exports = "Text <img srcset=\\"" + require("./image-300w@2x.png") + " 300w 2x," + require("./image@2x.png") + " 2x\\"> Text";'
);
});
it("should normalize spacing between entries of a srcset attribute", function() {
loader.call({}, 'Text <img srcset="image.png 1x, image@2x.png 300w 2x, image@3x.png 3x"> Text').should.be.eql(
'module.exports = "Text <img srcset=\\"" + require("./image.png") + " 1x," + require("./image@2x.png") + " 300w 2x," + require("./image@3x.png") + " 3x\\"> Text";'
);
});
it("should accept attrs from query", function() {
loader.call({
query: "?attrs=script:src"
Expand Down
Loading