Skip to content
Merged
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
43 changes: 43 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,49 @@ module.exports = {
};
```

If the tag name is not specified it will process all the tags.

> You can use your custom filter to specify html elements to be processed.

For example:

**webpack.config.js**

```js
module.exports = {
module: {
rules: [
{
test: /\.html$/i,
loader: 'html-loader',
options: {
attributes: {
list: [
{
// Attribute name
attribute: 'src',
// Type of processing, can be `src` or `scrset`
type: 'src',
// Allow to filter some attributes (optional)
filter: (tag, attribute, attributes, resourcePath) => {
// The `tag` argument contains a name of the HTML tag.
// The `attribute` argument contains a name of the HTML attribute.
// The `attributes` argument contains all attributes of the tag.
// The `resourcePath` argument contains a path to the loaded HTML file.

// choose all HTML tags except img tag
return tag.toLowerCase() !== 'img';
},
},
],
},
},
},
],
},
};
```

#### `urlFilter`

Type: `Function`
Expand Down
2 changes: 1 addition & 1 deletion src/options.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"instanceof": "Function"
}
},
"required": ["tag", "attribute", "type"],
"required": ["attribute", "type"],
"additionalProperties": false
},
"AttributeList": {
Expand Down
4 changes: 3 additions & 1 deletion src/plugins/source-plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,9 @@ export default (options) =>
const getAttribute = (tag, attribute, attributes, resourcePath) => {
return attributeList.find(
(element) =>
element.tag.toLowerCase() === tag.toLowerCase() &&
(typeof element.tag === 'undefined' ||
(typeof element.tag !== 'undefined' &&
element.tag.toLowerCase() === tag.toLowerCase())) &&
element.attribute.toLowerCase() === attribute.toLowerCase() &&
(element.filter
? element.filter(tag, attribute, attributes, resourcePath)
Expand Down
632 changes: 632 additions & 0 deletions test/__snapshots__/attributes-option.test.js.snap

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions test/__snapshots__/validate-options.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ exports[`validate options should throw an error on the "attributes" option with
- options.attributes.list should be an non-empty array."
`;

exports[`validate options should throw an error on the "attributes" option with "{"list":[{"tag":"","attribute":"src","type":"src"}]}" value 1`] = `
"Invalid options object. HTML Loader has been initialized using an options object that does not match the API schema.
- options.attributes.list[0].tag should be an non-empty string."
`;

exports[`validate options should throw an error on the "attributes" option with "{"list":[{"tag":"img","attribute":"src","type":"src","filter":"test"}]}" value 1`] = `
"Invalid options object. HTML Loader has been initialized using an options object that does not match the API schema.
- options.attributes.list[0].filter should be an instance of function."
Expand Down
46 changes: 46 additions & 0 deletions test/attributes-option.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,52 @@ describe("'attributes' option", () => {
expect(getErrors(stats)).toMatchSnapshot('errors');
});

it('should handle all src attributes in all HTML tags when tag is undefined', async () => {
const compiler = getCompiler('simple.js', {
attributes: {
list: [
{
attribute: 'src',
type: 'src',
},
],
},
});
const stats = await compile(compiler);

expect(getModuleSource('./simple.html', stats)).toMatchSnapshot('module');
expect(
execute(readAsset('main.bundle.js', compiler, stats))
).toMatchSnapshot('result');
expect(getWarnings(stats)).toMatchSnapshot('warnings');
expect(getErrors(stats)).toMatchSnapshot('errors');
});

it('should handle all src attributes in all HTML tags except img (testing filter option) tag is undefined', async () => {
const compiler = getCompiler('simple.js', {
attributes: {
list: [
{
attribute: 'src',
type: 'src',
// eslint-disable-next-line no-unused-vars
filter: (tag, attribute, attributes) => {
return tag.toLowerCase() !== 'img';
},
},
],
},
});
const stats = await compile(compiler);

expect(getModuleSource('./simple.html', stats)).toMatchSnapshot('module');
expect(
execute(readAsset('main.bundle.js', compiler, stats))
).toMatchSnapshot('result');
expect(getWarnings(stats)).toMatchSnapshot('warnings');
expect(getErrors(stats)).toMatchSnapshot('errors');
});

it('should work by default with CommonJS module syntax', async () => {
const compiler = getCompiler(
'simple.js',
Expand Down
17 changes: 17 additions & 0 deletions test/validate-options.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ describe('validate options', () => {
success: [
true,
false,
{
list: [
{
attribute: 'src',
type: 'src',
},
],
},
{
list: [
{
Expand Down Expand Up @@ -72,6 +80,15 @@ describe('validate options', () => {
},
],
},
{
list: [
{
tag: '',
attribute: 'src',
type: 'src',
},
],
},
{
list: [
{
Expand Down