diff --git a/src/bin/keycloakify/generateFtl/generateFtl.ts b/src/bin/keycloakify/generateFtl/generateFtl.ts index 2a81687e..cac21a6f 100644 --- a/src/bin/keycloakify/generateFtl/generateFtl.ts +++ b/src/bin/keycloakify/generateFtl/generateFtl.ts @@ -64,7 +64,7 @@ export function generateFtlFilesCodeFactory(params: { const { fixedCssCode } = replaceImportsInCssCode({ cssCode, - fileRelativeDirPath: ".", + cssFileRelativeDirPath: undefined, buildContext }); diff --git a/src/bin/keycloakify/generateResources/generateResourcesForMainTheme.ts b/src/bin/keycloakify/generateResources/generateResourcesForMainTheme.ts index 1911310c..4e0ba155 100644 --- a/src/bin/keycloakify/generateResources/generateResourcesForMainTheme.ts +++ b/src/bin/keycloakify/generateResources/generateResourcesForMainTheme.ts @@ -134,7 +134,7 @@ export async function generateResourcesForMainTheme(params: { if (filePath.endsWith(".css")) { const { fixedCssCode } = replaceImportsInCssCode({ cssCode: sourceCode.toString("utf8"), - fileRelativeDirPath: pathDirname(fileRelativePath), + cssFileRelativeDirPath: pathDirname(fileRelativePath), buildContext }); diff --git a/src/bin/keycloakify/replacers/replaceImportsInCssCode.ts b/src/bin/keycloakify/replacers/replaceImportsInCssCode.ts index 445fff1c..c48dc348 100644 --- a/src/bin/keycloakify/replacers/replaceImportsInCssCode.ts +++ b/src/bin/keycloakify/replacers/replaceImportsInCssCode.ts @@ -1,4 +1,5 @@ import type { BuildContext } from "../../shared/buildContext"; +import { basenameOfTheKeycloakifyResourcesDir } from "../../shared/constants"; import { assert } from "tsafe/assert"; import { posix } from "path"; @@ -10,12 +11,12 @@ assert(); export function replaceImportsInCssCode(params: { cssCode: string; - fileRelativeDirPath: string; + cssFileRelativeDirPath: string | undefined; buildContext: BuildContextLike; }): { fixedCssCode: string; } { - const { cssCode, fileRelativeDirPath, buildContext } = params; + const { cssCode, cssFileRelativeDirPath, buildContext } = params; const fixedCssCode = cssCode.replace( /url\(["']?(\/[^/][^)"']+)["']?\)/g, @@ -31,8 +32,16 @@ export function replaceImportsInCssCode(params: { ); } + inline_style_in_html: { + if (cssFileRelativeDirPath !== undefined) { + break inline_style_in_html; + } + + return `url(\${url.resourcesPath}/${basenameOfTheKeycloakifyResourcesDir}${assetFileAbsoluteUrlPathname})`; + } + const assetFileRelativeUrlPathname = posix.relative( - fileRelativeDirPath.replace(/\\/g, "/"), + cssFileRelativeDirPath.replace(/\\/g, "/"), assetFileAbsoluteUrlPathname.replace(/^\//, "") ); diff --git a/test/bin/replacers.spec.ts b/test/bin/replacers.spec.ts index 39ac725b..313ba397 100644 --- a/test/bin/replacers.spec.ts +++ b/test/bin/replacers.spec.ts @@ -395,7 +395,7 @@ describe("css replacer", () => { background-image: url(/assets/media/something.svg); } `, - fileRelativeDirPath: "assets/", + cssFileRelativeDirPath: "assets/", buildContext: { urlPathname: undefined } @@ -433,7 +433,7 @@ describe("css replacer", () => { background-image: url(/a/b/assets/media/something.svg); } `, - fileRelativeDirPath: "assets/", + cssFileRelativeDirPath: "assets/", buildContext: { urlPathname: "/a/b/" } @@ -455,6 +455,82 @@ describe("css replacer", () => { expect(isSameCode(fixedCssCode, fixedCssCodeExpected)).toBe(true); }); + + it("replaceImportsInCssCode - 3", () => { + const { fixedCssCode } = replaceImportsInCssCode({ + cssCode: ` + .my-div { + background: url(/a/b/background.png) no-repeat center center; + } + + .my-div2 { + background: url(/a/b/assets/background.png) repeat center center; + } + + .my-div3 { + background-image: url(/a/b/assets/media/something.svg); + } + `, + cssFileRelativeDirPath: undefined, + buildContext: { + urlPathname: "/a/b/" + } + }); + + const fixedCssCodeExpected = ` + .my-div { + background: url(\${url.resourcesPath}/${basenameOfTheKeycloakifyResourcesDir}/background.png) no-repeat center center; + } + + .my-div2 { + background: url(\${url.resourcesPath}/${basenameOfTheKeycloakifyResourcesDir}/assets/background.png) repeat center center; + } + + .my-div3 { + background-image: url(\${url.resourcesPath}/${basenameOfTheKeycloakifyResourcesDir}/assets/media/something.svg); + } + `; + + expect(isSameCode(fixedCssCode, fixedCssCodeExpected)).toBe(true); + }); + + it("replaceImportsInCssCode - 4", () => { + const { fixedCssCode } = replaceImportsInCssCode({ + cssCode: ` + .my-div { + background: url(/background.png) no-repeat center center; + } + + .my-div2 { + background: url(/assets/background.png) repeat center center; + } + + .my-div3 { + background-image: url(/assets/media/something.svg); + } + `, + cssFileRelativeDirPath: undefined, + buildContext: { + urlPathname: undefined + } + }); + + const fixedCssCodeExpected = ` + .my-div { + background: url(\${url.resourcesPath}/${basenameOfTheKeycloakifyResourcesDir}/background.png) no-repeat center center; + } + + .my-div2 { + background: url(\${url.resourcesPath}/${basenameOfTheKeycloakifyResourcesDir}/assets/background.png) repeat center center; + } + + .my-div3 { + background-image: url(\${url.resourcesPath}/${basenameOfTheKeycloakifyResourcesDir}/assets/media/something.svg); + } + `; + + expect(isSameCode(fixedCssCode, fixedCssCodeExpected)).toBe(true); + }); }); export function isSameCode(code1: string, code2: string): boolean {