191 lines
5.3 KiB
TypeScript
Raw Normal View History

2021-02-21 17:38:59 +01:00
import cheerio from "cheerio";
import {
replaceImportsFromStaticInJsCode,
replaceImportsInInlineCssCode,
2021-02-21 17:38:59 +01:00
generateCssCodeToDefineGlobals
} from "../replaceImportFromStatic";
import fs from "fs";
import { join as pathJoin } from "path";
2021-03-04 21:14:54 +01:00
import { objectKeys } from "evt/tools/typeSafety/objectKeys";
2021-04-11 18:18:52 +02:00
import { ftlValuesGlobalName } from "../ftlValuesGlobalName";
2021-03-04 21:14:54 +01:00
2021-04-08 15:41:40 +02:00
export const pageIds = [
"login.ftl", "register.ftl", "info.ftl",
"error.ftl", "login-reset-password.ftl",
"login-verify-email.ftl", "terms.ftl"
] as const;
2021-03-07 01:47:03 +01:00
2021-03-22 19:40:38 +01:00
export type PageId = typeof pageIds[number];
2021-03-07 01:47:03 +01:00
2021-03-22 19:40:38 +01:00
function loadAdjacentFile(fileBasename: string) {
2021-03-07 01:47:03 +01:00
return fs.readFileSync(pathJoin(__dirname, fileBasename))
.toString("utf8");
};
2021-03-06 22:41:36 +01:00
function loadFtlFile(ftlFileBasename: PageId | "common.ftl") {
2021-03-07 15:37:37 +01:00
try {
return loadAdjacentFile(ftlFileBasename)
.match(/^<script>const _=((?:.|\n)+)<\/script>[\n]?$/)![1];
} catch {
return "{}";
}
2021-03-04 21:14:54 +01:00
}
2021-03-22 20:54:28 +01:00
2021-02-21 17:38:59 +01:00
export function generateFtlFilesCodeFactory(
params: {
cssGlobalsToDefine: Record<string, string>;
indexHtmlCode: string;
2021-03-26 15:29:17 +01:00
urlPathname: string;
2021-04-11 18:18:52 +02:00
urlOrigin: undefined | string;
}
2021-02-21 17:38:59 +01:00
) {
2021-04-11 18:18:52 +02:00
const { cssGlobalsToDefine, indexHtmlCode, urlPathname, urlOrigin } = params;
2021-02-21 17:38:59 +01:00
const $ = cheerio.load(indexHtmlCode);
$("script:not([src])").each((...[, element]) => {
const { fixedJsCode } = replaceImportsFromStaticInJsCode({
2021-04-11 18:18:52 +02:00
"jsCode": $(element).html()!,
urlOrigin
2021-02-21 17:38:59 +01:00
});
2021-02-21 18:05:26 +01:00
$(element).text(fixedJsCode);
2021-02-21 17:38:59 +01:00
});
$("style").each((...[, element]) => {
const { fixedCssCode } = replaceImportsInInlineCssCode({
"cssCode": $(element).html()!,
2021-04-11 18:18:52 +02:00
"urlPathname": params.urlPathname,
urlOrigin
});
$(element).text(fixedCssCode);
});
2021-02-21 17:38:59 +01:00
([
["link", "href"],
["script", "src"],
] as const).forEach(([selector, attrName]) =>
$(selector).each((...[, element]) => {
const href = $(element).attr(attrName);
2021-03-22 19:40:38 +01:00
if (href === undefined) {
2021-02-21 17:38:59 +01:00
return;
}
$(element).attr(
attrName,
2021-04-11 18:18:52 +02:00
urlOrigin !== undefined ?
href.replace(/^\//, `${urlOrigin}/`) :
href.replace(
new RegExp(`^${urlPathname.replace(/\//g, "\\/")}`),
"${url.resourcesPath}/build/"
)
);
2021-02-21 17:38:59 +01:00
})
);
//FTL is no valid html, we can't insert with cheerio, we put placeholder for injecting later.
2021-03-04 21:14:54 +01:00
const ftlCommonPlaceholders = {
'{ "x": "vIdLqMeOed9sdLdIdOxdK0d" }': loadFtlFile("common.ftl"),
'<!-- xIdLqMeOedErIdLsPdNdI9dSlxI -->':
[
'<#if scripts??>',
' <#list scripts as script>',
' <script src="${script}" type="text/javascript"></script>',
' </#list>',
2021-03-07 01:47:03 +01:00
'</#if>'
].join("\n")
};
2021-03-07 01:47:03 +01:00
const pageSpecificCodePlaceholder = "<!-- dIddLqMeOedErIdLsPdNdI9dSl42sw -->";
2021-02-21 17:38:59 +01:00
$("head").prepend(
[
2021-02-23 09:50:24 +01:00
...(Object.keys(cssGlobalsToDefine).length === 0 ? [] : [
'',
'<style>',
2021-03-22 20:54:28 +01:00
generateCssCodeToDefineGlobals({
2021-03-22 19:40:38 +01:00
cssGlobalsToDefine,
2021-03-26 15:29:17 +01:00
urlPathname
2021-03-22 19:40:38 +01:00
}).cssCodeToPrependInHead,
2021-02-23 09:50:24 +01:00
'</style>',
''
]),
2021-03-07 01:47:03 +01:00
...["Object.deepAssign.js", "String.htmlUnescape.js"].map(
fileBasename => [
"<script>",
loadAdjacentFile(fileBasename),
"</script>"
].join("\n")
),
2021-02-21 17:38:59 +01:00
'<script>',
2021-03-07 01:47:03 +01:00
` window.${ftlValuesGlobalName}= Object.assign(`,
` {},`,
2021-03-04 21:14:54 +01:00
` ${objectKeys(ftlCommonPlaceholders)[0]}`,
2021-02-23 09:50:24 +01:00
' );',
2021-02-21 17:38:59 +01:00
'</script>',
'',
2021-03-07 01:47:03 +01:00
pageSpecificCodePlaceholder,
'',
objectKeys(ftlCommonPlaceholders)[1]
2021-02-21 17:38:59 +01:00
].join("\n"),
);
const partiallyFixedIndexHtmlCode = $.html();
function generateFtlFilesCode(
params: {
2021-03-06 22:41:36 +01:00
pageId: PageId;
2021-02-21 17:38:59 +01:00
}
): { ftlCode: string; } {
2021-03-06 22:41:36 +01:00
const { pageId } = params;
2021-02-21 17:38:59 +01:00
const $ = cheerio.load(partiallyFixedIndexHtmlCode);
2021-03-04 21:14:54 +01:00
const ftlPlaceholders = {
2021-03-06 22:41:36 +01:00
'{ "x": "kxOlLqMeOed9sdLdIdOxd444" }': loadFtlFile(pageId),
2021-03-04 21:14:54 +01:00
...ftlCommonPlaceholders
};
2021-03-07 01:47:03 +01:00
let ftlCode = $.html()
.replace(
pageSpecificCodePlaceholder,
[
'<script>',
2021-03-07 02:15:21 +01:00
` Object.deepAssign(`,
2021-03-07 01:47:03 +01:00
` window.${ftlValuesGlobalName},`,
` { "pageId": "${pageId}" }`,
' );',
2021-03-07 02:15:21 +01:00
` Object.deepAssign(`,
2021-03-07 01:47:03 +01:00
` window.${ftlValuesGlobalName},`,
` ${objectKeys(ftlPlaceholders)[0]}`,
' );',
'</script>'
].join("\n")
);
objectKeys(ftlPlaceholders)
.forEach(id => ftlCode = ftlCode.replace(id, ftlPlaceholders[id]));
return { ftlCode };
2021-02-21 17:38:59 +01:00
}
return { generateFtlFilesCode };
}