Skip to content

Commit

Permalink
feat: include type for tags
Browse files Browse the repository at this point in the history
  • Loading branch information
evilebottnawi committed Aug 11, 2020
1 parent ddad9f2 commit 9e3a780
Show file tree
Hide file tree
Showing 12 changed files with 555 additions and 503 deletions.
17 changes: 8 additions & 9 deletions src/index.js
Expand Up @@ -47,9 +47,8 @@ export default async function htmlLoader(content) {
const { html, messages } = pluginRunner(plugins).process(content);

const errors = [];
const importedMessages = [];
const replaceableMessages = [];
const exportedMessages = [];
const imports = [];
const replacements = [];

for (const message of messages) {
// eslint-disable-next-line default-case
Expand All @@ -58,10 +57,10 @@ export default async function htmlLoader(content) {
errors.push(message.value);
break;
case 'import':
importedMessages.push(message.value);
imports.push(message.value);
break;
case 'replacer':
replaceableMessages.push(message.value);
case 'replacement':
replacements.push(message.value);
break;
}
}
Expand All @@ -71,9 +70,9 @@ export default async function htmlLoader(content) {
}

const codeOptions = { ...options, loaderContext: this };
const importCode = getImportCode(html, importedMessages, codeOptions);
const moduleCode = getModuleCode(html, replaceableMessages, codeOptions);
const exportCode = getExportCode(html, exportedMessages, codeOptions);
const importCode = getImportCode(html, imports, codeOptions);
const moduleCode = getModuleCode(html, replacements, codeOptions);
const exportCode = getExportCode(html, codeOptions);

return `${importCode}${moduleCode}${exportCode}`;
}
2 changes: 1 addition & 1 deletion src/options.json
Expand Up @@ -13,7 +13,7 @@
"minLength": 1
},
"type": {
"enum": ["src", "srcset"]
"enum": ["src", "srcset", "include"]
},
"filter": {
"instanceof": "Function"
Expand Down
9 changes: 4 additions & 5 deletions src/plugins/source-plugin.js
Expand Up @@ -201,17 +201,16 @@ export default (options) =>
return { key, name };
}

// TODO rename
name = `___HTML_LOADER_REPLACER_${replacements.size}___`;
name = `___HTML_LOADER_REPLACEMENT_${replacements.size}___`;
replacements.set(key, name);

result.messages.push({
type: 'replacer',
type: 'replacement',
value: {
type: 'source',
hash,
importName: importItem.name,
replacerName: name,
replacementName: name,
unquoted,
},
});
Expand Down Expand Up @@ -330,7 +329,7 @@ export default (options) =>

break;
}
case 'tag': {
case 'include': {
let source;

try {
Expand Down
20 changes: 10 additions & 10 deletions src/utils.js
Expand Up @@ -407,8 +407,8 @@ export function isProductionMode(loaderContext) {
return loaderContext.mode === 'production' || !loaderContext.mode;
}

export function getImportCode(html, importedMessages, codeOptions) {
if (importedMessages.length === 0) {
export function getImportCode(html, imports, codeOptions) {
if (imports.length === 0) {
return '';
}

Expand All @@ -422,7 +422,7 @@ export function getImportCode(html, importedMessages, codeOptions) {
? `import ${GET_SOURCE_FROM_IMPORT_NAME} from ${stringifiedHelperRequest};\n`
: `var ${GET_SOURCE_FROM_IMPORT_NAME} = require(${stringifiedHelperRequest});\n`;

for (const item of importedMessages) {
for (const item of imports) {
const { importName, source } = item;
const stringifiedSourceRequest = stringifyRequest(loaderContext, source);

Expand All @@ -434,7 +434,7 @@ export function getImportCode(html, importedMessages, codeOptions) {
return `// Imports\n${code}`;
}

export function getModuleCode(html, replaceableMessages) {
export function getModuleCode(html, replacements) {
let code = JSON.stringify(html)
// Invalid in JavaScript but valid HTML
.replace(/[\u2028\u2029]/g, (str) =>
Expand All @@ -443,27 +443,27 @@ export function getModuleCode(html, replaceableMessages) {

let replacersCode = '';

for (const item of replaceableMessages) {
const { importName, replacerName, unquoted, hash } = item;
for (const item of replacements) {
const { importName, replacementName, unquoted, hash } = item;

const getUrlOptions = []
.concat(hash ? [`hash: ${JSON.stringify(hash)}`] : [])
.concat(unquoted ? 'maybeNeedQuotes: true' : []);
const preparedOptions =
getUrlOptions.length > 0 ? `, { ${getUrlOptions.join(', ')} }` : '';

replacersCode += `var ${replacerName} = ${GET_SOURCE_FROM_IMPORT_NAME}(${importName}${preparedOptions});\n`;
replacersCode += `var ${replacementName} = ${GET_SOURCE_FROM_IMPORT_NAME}(${importName}${preparedOptions});\n`;

code = code.replace(
new RegExp(replacerName, 'g'),
() => `" + ${replacerName} + "`
new RegExp(replacementName, 'g'),
() => `" + ${replacementName} + "`
);
}

return `// Module\n${replacersCode}var code = ${code};\n`;
}

export function getExportCode(html, exportedMessages, codeOptions) {
export function getExportCode(html, codeOptions) {
if (codeOptions.esModule) {
return `// Exports\nexport default code;`;
}
Expand Down
475 changes: 259 additions & 216 deletions test/__snapshots__/attributes-option.test.js.snap

Large diffs are not rendered by default.

144 changes: 72 additions & 72 deletions test/__snapshots__/esModule-option.test.js.snap

Large diffs are not rendered by default.

52 changes: 26 additions & 26 deletions test/__snapshots__/loader.test.js.snap

Large diffs are not rendered by default.

292 changes: 146 additions & 146 deletions test/__snapshots__/minimize-option.test.js.snap

Large diffs are not rendered by default.

20 changes: 10 additions & 10 deletions test/__snapshots__/preprocessor-option.test.js.snap
Expand Up @@ -7,8 +7,8 @@ exports[`'process' option should work with Async "preprocessor" Function option:
var ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___ = require(\\"../../src/runtime/getUrl.js\\");
var ___HTML_LOADER_IMPORT_0___ = require(\\"./image.png\\");
// Module
var ___HTML_LOADER_REPLACER_0___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_0___);
var code = \\"<div>\\\\n <p>Alexander Krasnoyarov</p>\\\\n <img src=\\\\\\"\\" + ___HTML_LOADER_REPLACER_0___ + \\"\\\\\\" alt=\\\\\\"alt\\\\\\" />\\\\n<div>\\\\n\\";
var ___HTML_LOADER_REPLACEMENT_0___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_0___);
var code = \\"<div>\\\\n <p>Alexander Krasnoyarov</p>\\\\n <img src=\\\\\\"\\" + ___HTML_LOADER_REPLACEMENT_0___ + \\"\\\\\\" alt=\\\\\\"alt\\\\\\" />\\\\n<div>\\\\n\\";
// Exports
module.exports = code;"
`;
Expand All @@ -31,9 +31,9 @@ var ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___ = require(\\"../../src/runtime/getU
var ___HTML_LOADER_IMPORT_0___ = require(\\"./image.png.webp\\");
var ___HTML_LOADER_IMPORT_1___ = require(\\"./image.png\\");
// Module
var ___HTML_LOADER_REPLACER_0___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_0___);
var ___HTML_LOADER_REPLACER_1___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_1___);
var code = \\"<picture><source type=\\\\\\"image/webp\\\\\\" srcset=\\\\\\"\\" + ___HTML_LOADER_REPLACER_0___ + \\"\\\\\\"><img src=\\\\\\"\\" + ___HTML_LOADER_REPLACER_1___ + \\"\\\\\\"></picture>\\\\n\\";
var ___HTML_LOADER_REPLACEMENT_0___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_0___);
var ___HTML_LOADER_REPLACEMENT_1___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_1___);
var code = \\"<picture><source type=\\\\\\"image/webp\\\\\\" srcset=\\\\\\"\\" + ___HTML_LOADER_REPLACEMENT_0___ + \\"\\\\\\"><img src=\\\\\\"\\" + ___HTML_LOADER_REPLACEMENT_1___ + \\"\\\\\\"></picture>\\\\n\\";
// Exports
module.exports = code;"
`;
Expand All @@ -52,8 +52,8 @@ exports[`'process' option should work with the "preprocessor" option: module 1`]
var ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___ = require(\\"../../src/runtime/getUrl.js\\");
var ___HTML_LOADER_IMPORT_0___ = require(\\"./image.png\\");
// Module
var ___HTML_LOADER_REPLACER_0___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_0___);
var code = \\"<div>\\\\n <p>Alexander Krasnoyarov</p>\\\\n <img src=\\\\\\"\\" + ___HTML_LOADER_REPLACER_0___ + \\"\\\\\\" alt=\\\\\\"alt\\\\\\" />\\\\n<div>\\\\n\\";
var ___HTML_LOADER_REPLACEMENT_0___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_0___);
var code = \\"<div>\\\\n <p>Alexander Krasnoyarov</p>\\\\n <img src=\\\\\\"\\" + ___HTML_LOADER_REPLACEMENT_0___ + \\"\\\\\\" alt=\\\\\\"alt\\\\\\" />\\\\n<div>\\\\n\\";
// Exports
module.exports = code;"
`;
Expand All @@ -76,9 +76,9 @@ var ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___ = require(\\"../../src/runtime/getU
var ___HTML_LOADER_IMPORT_0___ = require(\\"./image.png.webp\\");
var ___HTML_LOADER_IMPORT_1___ = require(\\"./image.png\\");
// Module
var ___HTML_LOADER_REPLACER_0___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_0___);
var ___HTML_LOADER_REPLACER_1___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_1___);
var code = \\"<picture><source type=\\\\\\"image/webp\\\\\\" srcset=\\\\\\"\\" + ___HTML_LOADER_REPLACER_0___ + \\"\\\\\\"><img src=\\\\\\"\\" + ___HTML_LOADER_REPLACER_1___ + \\"\\\\\\"></picture>\\\\n\\";
var ___HTML_LOADER_REPLACEMENT_0___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_0___);
var ___HTML_LOADER_REPLACEMENT_1___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_1___);
var code = \\"<picture><source type=\\\\\\"image/webp\\\\\\" srcset=\\\\\\"\\" + ___HTML_LOADER_REPLACEMENT_0___ + \\"\\\\\\"><img src=\\\\\\"\\" + ___HTML_LOADER_REPLACEMENT_1___ + \\"\\\\\\"></picture>\\\\n\\";
// Exports
module.exports = code;"
`;
Expand Down
2 changes: 1 addition & 1 deletion test/__snapshots__/validate-options.test.js.snap
Expand Up @@ -33,7 +33,7 @@ exports[`validate options should throw an error on the "attributes" option with
exports[`validate options should throw an error on the "attributes" option with "{"list":[{"tag":"img","attribute":"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] misses the property 'type'. Should be:
\\"src\\" | \\"srcset\\""
\\"src\\" | \\"srcset\\" | \\"include\\""
`;
exports[`validate options should throw an error on the "attributes" option with "{"root":false}" value 1`] = `
Expand Down
22 changes: 16 additions & 6 deletions test/attributes-option.test.js
Expand Up @@ -23,23 +23,33 @@ describe("'attributes' option", () => {
expect(getErrors(stats)).toMatchSnapshot('errors');
});

it.skip('should handle the "include" type of tags', async () => {
const compiler = getCompiler('include.js');
it('should handle "src" and "srcset" tags correctly', async () => {
const compiler = getCompiler('sources.js');
const stats = await compile(compiler);

expect(getModuleSource('./include.html', stats)).toMatchSnapshot('module');
expect(getModuleSource('./sources.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 "src" and "srcset" tags correctly', async () => {
const compiler = getCompiler('sources.js');
it('should handle the "include" type of tags', async () => {
const compiler = getCompiler('include.js', {
attributes: {
list: [
{
tag: 'include',
attribute: 'src',
type: 'include',
},
],
},
});
const stats = await compile(compiler);

expect(getModuleSource('./sources.html', stats)).toMatchSnapshot('module');
expect(getModuleSource('./include.html', stats)).toMatchSnapshot('module');
expect(
execute(readAsset('main.bundle.js', compiler, stats))
).toMatchSnapshot('result');
Expand Down
3 changes: 2 additions & 1 deletion test/fixtures/include.html
Expand Up @@ -7,6 +7,7 @@
<li>Have I mentioned the beard?</li>
</ol>
BeforeFooterText<include src="./include-footer.html" />AfterFooterText
<div><include src="./include-content.html"></include></div>
<!--<div><include src="./include-content.html"></include></div>-->
TextBeforeOpenDiv<div>TextAfterOpenDiv<include src="./include-content.html" />TextBeforeCloseDiv</div>TextAfterCloseDiv
</article>
</div>

0 comments on commit 9e3a780

Please sign in to comment.