diff --git a/README.md b/README.md
index eb8b7b13..8a5781f6 100644
--- a/README.md
+++ b/README.md
@@ -41,10 +41,10 @@ module.exports = {
rules: [
{
test: /\.html$/i,
- loader: 'html-loader',
- },
- ],
- },
+ loader: 'html-loader'
+ }
+ ]
+ }
};
```
@@ -96,11 +96,11 @@ module.exports = {
loader: 'html-loader',
options: {
// Disables attributes processing
- attributes: false,
- },
- },
- ],
- },
+ attributes: false
+ }
+ }
+ ]
+ }
};
```
@@ -121,25 +121,29 @@ module.exports = {
options: {
attributes: {
list: [
+ {
+ tag: 'style', // all tags with style attribute
+ type: 'src'
+ },
{
tag: 'img',
attribute: 'src',
- type: 'src',
+ type: 'src'
},
{
tag: 'img',
attribute: 'srcset',
- type: 'srcset',
+ type: 'srcset'
},
{
tag: 'img',
attribute: 'data-src',
- type: 'src',
+ type: 'src'
},
{
tag: 'img',
attribute: 'data-srcset',
- type: 'srcset',
+ type: 'srcset'
},
{
tag: 'link',
@@ -158,8 +162,8 @@ module.exports = {
}
return true;
- },
- },
+ }
+ }
// More attributes
],
urlFilter: (attribute, value, resourcePath) => {
@@ -173,12 +177,12 @@ module.exports = {
return true;
},
- root: '.',
- },
- },
- },
- ],
- },
+ root: '.'
+ }
+ }
+ }
+ ]
+ }
};
```
@@ -209,7 +213,7 @@ module.exports = {
// Attribute name
attribute: 'src',
// Type of processing, can be `src` or `scrset`
- type: 'src',
+ type: 'src'
},
{
// Tag name
@@ -217,17 +221,17 @@ module.exports = {
// Attribute name
attribute: 'srcset',
// Type of processing, can be `src` or `scrset`
- type: 'srcset',
+ type: 'srcset'
},
{
tag: 'img',
attribute: 'data-src',
- type: 'src',
+ type: 'src'
},
{
tag: 'img',
attribute: 'data-srcset',
- type: 'srcset',
+ type: 'srcset'
},
{
// Tag name
@@ -259,14 +263,14 @@ module.exports = {
}
return true;
- },
- },
- ],
- },
- },
- },
- ],
- },
+ }
+ }
+ ]
+ }
+ }
+ }
+ ]
+ }
};
```
@@ -302,14 +306,14 @@ module.exports = {
// choose all HTML tags except img tag
return tag.toLowerCase() !== 'img';
- },
- },
- ],
- },
- },
- },
- ],
- },
+ }
+ }
+ ]
+ }
+ }
+ }
+ ]
+ }
};
```
@@ -340,12 +344,12 @@ module.exports = {
}
return true;
- },
- },
- },
- },
- ],
- },
+ }
+ }
+ }
+ }
+ ]
+ }
};
```
@@ -368,12 +372,12 @@ module.exports = {
loader: 'html-loader',
options: {
attributes: {
- root: '.',
- },
- },
- },
- ],
- },
+ root: '.'
+ }
+ }
+ }
+ ]
+ }
};
```
@@ -417,7 +421,7 @@ module.exports = {
try {
result = Handlebars.compile(content)({
firstname: 'Value',
- lastname: 'OtherValue',
+ lastname: 'OtherValue'
});
} catch (error) {
loaderContext.emitError(error);
@@ -426,11 +430,11 @@ module.exports = {
}
return result;
- },
- },
- },
- ],
- },
+ }
+ }
+ }
+ ]
+ }
};
```
@@ -456,7 +460,7 @@ module.exports = {
try {
result = await Handlebars.compile(content)({
firstname: 'Value',
- lastname: 'OtherValue',
+ lastname: 'OtherValue'
});
} catch (error) {
await loaderContext.emitError(error);
@@ -465,11 +469,11 @@ module.exports = {
}
return result;
- },
- },
- },
- ],
- },
+ }
+ }
+ }
+ ]
+ }
};
```
@@ -505,11 +509,11 @@ module.exports = {
test: /\.html$/i,
loader: 'html-loader',
options: {
- minimize: true,
- },
- },
- ],
- },
+ minimize: true
+ }
+ }
+ ]
+ }
};
```
@@ -533,12 +537,12 @@ module.exports = {
options: {
minimize: {
removeComments: false,
- collapseWhitespace: false,
- },
- },
- },
- ],
- },
+ collapseWhitespace: false
+ }
+ }
+ }
+ ]
+ }
};
```
@@ -562,11 +566,11 @@ module.exports = {
test: /\.html$/i,
loader: 'html-loader',
options: {
- esModule: true,
- },
- },
- ],
- },
+ esModule: true
+ }
+ }
+ ]
+ }
};
```
@@ -581,12 +585,12 @@ module.exports = {
module: {
rules: [
{ test: /\.jpg$/, loader: 'file-loader' },
- { test: /\.png$/, loader: 'url-loader' },
- ],
+ { test: /\.png$/, loader: 'url-loader' }
+ ]
},
output: {
- publicPath: 'http://cdn.example.com/[hash]/',
- },
+ publicPath: 'http://cdn.example.com/[hash]/'
+ }
};
```
@@ -667,28 +671,28 @@ module.exports = {
rules: [
{
test: /\.html$/i,
- use: ['file-loader?name=[name].[ext]', 'extract-loader', 'html-loader'],
+ use: ['file-loader?name=[name].[ext]', 'extract-loader', 'html-loader']
},
{
test: /\.js$/i,
exclude: /\.file.js$/i,
- loader: 'babel-loader',
+ loader: 'babel-loader'
},
{
test: /\.file.js$/i,
- loader: 'file-loader',
+ loader: 'file-loader'
},
{
test: /\.css$/i,
exclude: /\.file.css$/i,
- loader: 'css-loader',
+ loader: 'css-loader'
},
{
test: /\.file.css$/i,
- loader: 'file-loader',
- },
- ],
- },
+ loader: 'file-loader'
+ }
+ ]
+ }
};
```
@@ -749,7 +753,7 @@ module.exports = {
try {
result = Handlebars.compile(content)({
firstname: 'Value',
- lastname: 'OtherValue',
+ lastname: 'OtherValue'
});
} catch (error) {
loaderContext.emitError(error);
@@ -758,11 +762,11 @@ module.exports = {
}
return result;
- },
- },
- },
- ],
- },
+ }
+ }
+ }
+ ]
+ }
};
```
@@ -793,7 +797,9 @@ module.exports = {
let result;
try {
- result = posthtml().use(plugin).process(content, { sync: true });
+ result = posthtml()
+ .use(plugin)
+ .process(content, { sync: true });
} catch (error) {
loaderContext.emitError(error);
@@ -801,11 +807,11 @@ module.exports = {
}
return result.html;
- },
- },
- },
- ],
- },
+ }
+ }
+ }
+ ]
+ }
};
```
@@ -832,10 +838,10 @@ module.exports = {
rules: [
{
test: /\.html$/i,
- use: ['file-loader?name=[name].[ext]', 'extract-loader', 'html-loader'],
- },
- ],
- },
+ use: ['file-loader?name=[name].[ext]', 'extract-loader', 'html-loader']
+ }
+ ]
+ }
};
```
diff --git a/src/plugins/source-plugin.js b/src/plugins/source-plugin.js
index 9bc9b0d8..b37cd539 100644
--- a/src/plugins/source-plugin.js
+++ b/src/plugins/source-plugin.js
@@ -368,7 +368,6 @@ function parseSrc(input) {
while (isASCIIWhitespace(value.substring(value.length - 1, value.length))) {
value = value.substring(0, value.length - 1);
}
-
if (!value) {
throw new Error('Must be non-empty');
}
@@ -388,30 +387,34 @@ function getAttributeValue(attributes, name) {
}
const defaultAttributes = [
+ {
+ attribute: 'style',
+ type: 'src'
+ },
{
tag: 'audio',
attribute: 'src',
- type: 'src',
+ type: 'src'
},
{
tag: 'embed',
attribute: 'src',
- type: 'src',
+ type: 'src'
},
{
tag: 'img',
attribute: 'src',
- type: 'src',
+ type: 'src'
},
{
tag: 'img',
attribute: 'srcset',
- type: 'srcset',
+ type: 'srcset'
},
{
tag: 'input',
attribute: 'src',
- type: 'src',
+ type: 'src'
},
{
tag: 'link',
@@ -424,53 +427,54 @@ const defaultAttributes = [
if (
attributes.type &&
- getAttributeValue(attributes, 'type').trim().toLowerCase() !==
- 'text/css'
+ getAttributeValue(attributes, 'type')
+ .trim()
+ .toLowerCase() !== 'text/css'
) {
return false;
}
return true;
- },
+ }
},
{
tag: 'object',
attribute: 'data',
- type: 'src',
+ type: 'src'
},
{
tag: 'script',
attribute: 'src',
- type: 'src',
+ type: 'src'
},
{
tag: 'source',
attribute: 'src',
- type: 'src',
+ type: 'src'
},
{
tag: 'source',
attribute: 'srcset',
- type: 'srcset',
+ type: 'srcset'
},
{
tag: 'track',
attribute: 'src',
- type: 'src',
+ type: 'src'
},
{
tag: 'video',
attribute: 'poster',
- type: 'src',
+ type: 'src'
},
{
tag: 'video',
attribute: 'src',
- type: 'src',
- },
+ type: 'src'
+ }
];
-export default (options) =>
+export default options =>
function process(html, result) {
let attributeList;
let maybeUrlFilter;
@@ -488,12 +492,12 @@ export default (options) =>
}
const sources = [];
- const urlFilter = getFilter(maybeUrlFilter, (value) =>
+ const urlFilter = getFilter(maybeUrlFilter, value =>
isUrlRequest(value, root)
);
const getAttribute = (tag, attribute, attributes, resourcePath) => {
return attributeList.find(
- (element) =>
+ element =>
(typeof element.tag === 'undefined' ||
(typeof element.tag !== 'undefined' &&
element.tag.toLowerCase() === tag.toLowerCase())) &&
@@ -516,11 +520,11 @@ export default (options) =>
this.attributesMeta[name] = { startIndex, unquoted };
},
onopentag(tag, attributes) {
- Object.keys(attributes).forEach((attribute) => {
+ Object.keys(attributes).forEach(attribute => {
const value = attributes[attribute];
const {
startIndex: valueStartIndex,
- unquoted,
+ unquoted
} = this.attributesMeta[attribute];
const foundAttribute = getAttribute(
@@ -549,13 +553,13 @@ export default (options) =>
parser.startIndex,
parser.endIndex,
html
- ),
+ )
});
return;
}
- sourceSet.forEach((sourceItem) => {
+ sourceSet.forEach(sourceItem => {
const { source } = sourceItem;
if (!urlFilter(attribute, source.value, resourcePath)) {
@@ -582,11 +586,49 @@ export default (options) =>
parser.startIndex,
parser.endIndex,
html
- ),
+ )
});
return;
}
+ if (attribute.toLowerCase() === 'style') {
+ const urlSources = [];
+
+ source.value.split('url(').forEach((urlSource, index) => {
+ /* Ignoring first index because the first is just the css propertie for example:
+ [0:'background-image: ', 1:'
+ "image.png");\ntext-align: center;text-decoration: overline; color:red;background-image:',
+ '"image.png")']*/
+
+ if (index !== 0) {
+ // removing the rest of the url value ');....' and removing single and douple quotations
+ urlSource = urlSource
+ .substring(0, urlSource.indexOf(')'))
+ .replace(/["']/g, '');
+ urlSources.push(urlSource);
+ }
+ });
+ let currIndex = 0;
+
+ urlSources.forEach(urlSource => {
+ if (!urlFilter(attribute, urlSource, resourcePath)) {
+ return;
+ }
+
+ // currIndex to indicate to the current urlSource
+ const sourceStartIndex = source.value.indexOf(
+ urlSource,
+ currIndex
+ );
+
+ const startIndex = valueStartIndex + sourceStartIndex;
+ // incrementing currIndex so we can go to the next urlSource
+ currIndex = sourceStartIndex + 1;
+
+ sources.push({ startIndex, value: urlSource, unquoted });
+ });
+ return;
+ }
if (!urlFilter(attribute, source.value, resourcePath)) {
return;
@@ -602,16 +644,16 @@ export default (options) =>
onerror(error) {
result.messages.push({
type: 'error',
- value: error,
+ value: error
});
- },
+ }
},
{
decodeEntities: false,
lowerCaseTags: false,
lowerCaseAttributeNames: false,
recognizeCDATA: true,
- recognizeSelfClosing: true,
+ recognizeSelfClosing: true
}
);
@@ -647,15 +689,15 @@ export default (options) =>
value: {
type: 'source',
source: importKey,
- importName,
- },
+ importName
+ }
});
}
const replacerKey = JSON.stringify({
importKey,
unquoted,
- hash,
+ hash
});
let replacerName = replacersMap.get(replacerKey);
@@ -670,8 +712,8 @@ export default (options) =>
hash,
importName,
replacerName,
- unquoted,
- },
+ unquoted
+ }
});
}
diff --git a/test/__snapshots__/attributes-option.test.js.snap b/test/__snapshots__/attributes-option.test.js.snap
index c6061e9e..148b9a53 100644
--- a/test/__snapshots__/attributes-option.test.js.snap
+++ b/test/__snapshots__/attributes-option.test.js.snap
@@ -760,7 +760,7 @@ var ___HTML_LOADER_REPLACER_4___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___H
var ___HTML_LOADER_REPLACER_5___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_5___);
var ___HTML_LOADER_REPLACER_6___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_6___);
var ___HTML_LOADER_REPLACER_7___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_7___);
-var code = \\"\\\\n\\\\n
My First Heading
\\\\nMy first paragraph.
\\\\nAn Unordered HTML List
\\\\n\\\\n\\\\n - Coffee
\\\\n - Tea
\\\\n - Milk
\\\\n
\\\\n\\\\nAn Ordered HTML List
\\\\n\\\\n\\\\n - Coffee
\\\\n - Tea
\\\\n - Milk
\\\\n
\\\\n\\\\n\\\\n\\\\n\\\\n\\\\nFoo
\\\\n\\\\n\\\\nBAR
\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n
\\\\n
\\\\n
\\\\n
\\\\n
\\\\n
\\\\n
\\\\n
\\\\n
\\\\n
\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n
\\\\n\\\\n\\\\n\\\\n
\\\\n
\\\\n
\\\\n
\\\\n
\\\\n
\\\\n
\\\\n
\\\\n
\\\\n
\\\\n
\\\\n
\\\\n
\\\\n\\\\n\\\\n \\\\n \\\\n
\\\\n\\\\n\\\\n\\\\n\\\\n