186 lines
4.9 KiB
JavaScript
186 lines
4.9 KiB
JavaScript
|
"use strict";
|
||
|
|
||
|
Object.defineProperty(exports, "__esModule", {
|
||
|
value: true
|
||
|
});
|
||
|
exports.default = void 0;
|
||
|
|
||
|
var _parse = require("parse5");
|
||
|
|
||
|
var _utils = require("../utils");
|
||
|
|
||
|
var _default = options => function process(html) {
|
||
|
const sources = [];
|
||
|
const document = (0, _parse.parse)(html, {
|
||
|
sourceCodeLocationInfo: true,
|
||
|
scriptingEnabled: options.sources.scriptingEnabled
|
||
|
});
|
||
|
let needIgnore = false;
|
||
|
(0, _utils.traverse)(document, node => {
|
||
|
const {
|
||
|
tagName,
|
||
|
attrs: attributes,
|
||
|
sourceCodeLocation
|
||
|
} = node;
|
||
|
|
||
|
if (node.nodeName === "#comment") {
|
||
|
const match = node.data.match(_utils.webpackIgnoreCommentRegexp);
|
||
|
|
||
|
if (match) {
|
||
|
needIgnore = match[2] === "true";
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (!tagName) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (needIgnore) {
|
||
|
needIgnore = false;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
attributes.forEach(attribute => {
|
||
|
let {
|
||
|
name
|
||
|
} = attribute;
|
||
|
name = attribute.prefix ? `${attribute.prefix}:${name}` : name;
|
||
|
const handlers = new Map([...(options.sources.list.get("*") || new Map()), ...(options.sources.list.get(tagName.toLowerCase()) || new Map())]);
|
||
|
|
||
|
if (handlers.size === 0) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
const handler = handlers.get(name.toLowerCase());
|
||
|
|
||
|
if (!handler) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (handler.filter && !handler.filter(tagName, name, attributes, options.resourcePath)) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
const attributeAndValue = html.slice(sourceCodeLocation.attrs[name].startOffset, sourceCodeLocation.attrs[name].endOffset);
|
||
|
const isValueQuoted = attributeAndValue[attributeAndValue.length - 1] === '"' || attributeAndValue[attributeAndValue.length - 1] === "'";
|
||
|
const valueStartOffset = sourceCodeLocation.attrs[name].startOffset + attributeAndValue.indexOf(attribute.value);
|
||
|
const valueEndOffset = sourceCodeLocation.attrs[name].endOffset - (isValueQuoted ? 1 : 0);
|
||
|
const optionsForTypeFn = {
|
||
|
tag: tagName,
|
||
|
startTag: {
|
||
|
startOffset: sourceCodeLocation.startTag.startOffset,
|
||
|
endOffset: sourceCodeLocation.startTag.endOffset
|
||
|
},
|
||
|
endTag: sourceCodeLocation.endTag ? {
|
||
|
startOffset: sourceCodeLocation.endTag.startOffset,
|
||
|
endOffset: sourceCodeLocation.endTag.endOffset
|
||
|
} : // eslint-disable-next-line no-undefined
|
||
|
undefined,
|
||
|
attributes,
|
||
|
attribute: name,
|
||
|
attributePrefix: attribute.prefix,
|
||
|
attributeNamespace: attribute.namespace,
|
||
|
attributeStartOffset: sourceCodeLocation.attrs[name].startOffset,
|
||
|
attributeEndOffset: sourceCodeLocation.attrs[name].endOffset,
|
||
|
value: attribute.value,
|
||
|
isValueQuoted,
|
||
|
valueEndOffset,
|
||
|
valueStartOffset,
|
||
|
html
|
||
|
};
|
||
|
let result;
|
||
|
|
||
|
try {
|
||
|
result = handler.type(optionsForTypeFn);
|
||
|
} catch (error) {
|
||
|
options.errors.push(error);
|
||
|
}
|
||
|
|
||
|
result = Array.isArray(result) ? result : [result];
|
||
|
|
||
|
for (const source of result) {
|
||
|
if (!source) {
|
||
|
// eslint-disable-next-line no-continue
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
sources.push({ ...source,
|
||
|
name,
|
||
|
isValueQuoted
|
||
|
});
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
const urlFilter = (0, _utils.getFilter)(options.sources.urlFilter);
|
||
|
const imports = new Map();
|
||
|
const replacements = new Map();
|
||
|
let offset = 0;
|
||
|
|
||
|
for (const source of sources) {
|
||
|
const {
|
||
|
name,
|
||
|
value,
|
||
|
isValueQuoted,
|
||
|
format,
|
||
|
runtime,
|
||
|
startOffset,
|
||
|
endOffset
|
||
|
} = source;
|
||
|
let request = value;
|
||
|
|
||
|
if (!urlFilter(name, value, options.resourcePath)) {
|
||
|
// eslint-disable-next-line no-continue
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
let hash;
|
||
|
const indexHash = request.lastIndexOf("#");
|
||
|
|
||
|
if (indexHash >= 0) {
|
||
|
hash = request.substring(indexHash);
|
||
|
request = request.substring(0, indexHash);
|
||
|
}
|
||
|
|
||
|
request = (0, _utils.requestify)(options.context, request);
|
||
|
let importName = imports.get(request);
|
||
|
|
||
|
if (!importName) {
|
||
|
importName = `___HTML_LOADER_IMPORT_${imports.size}___`;
|
||
|
imports.set(request, importName);
|
||
|
options.imports.push({
|
||
|
format,
|
||
|
importName,
|
||
|
request
|
||
|
});
|
||
|
}
|
||
|
|
||
|
const replacementKey = JSON.stringify({
|
||
|
request,
|
||
|
isValueQuoted,
|
||
|
hash
|
||
|
});
|
||
|
let replacementName = replacements.get(replacementKey);
|
||
|
|
||
|
if (!replacementName) {
|
||
|
replacementName = `___HTML_LOADER_REPLACEMENT_${replacements.size}___`;
|
||
|
replacements.set(replacementKey, replacementName);
|
||
|
options.replacements.push({
|
||
|
replacementName,
|
||
|
importName,
|
||
|
hash,
|
||
|
isValueQuoted,
|
||
|
runtime
|
||
|
});
|
||
|
} // eslint-disable-next-line no-param-reassign
|
||
|
|
||
|
|
||
|
html = html.slice(0, startOffset + offset) + replacementName + html.slice(endOffset + offset);
|
||
|
offset += startOffset + replacementName.length - endOffset;
|
||
|
}
|
||
|
|
||
|
return html;
|
||
|
};
|
||
|
|
||
|
exports.default = _default;
|