Skip to content

Commit

Permalink
🗾 Add svg.jsx, generated svgs to kastro
Browse files Browse the repository at this point in the history
  • Loading branch information
KimlikDAO-bot committed Dec 29, 2024
1 parent 906c5dc commit 1bc3dfa
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 23 deletions.
5 changes: 3 additions & 2 deletions kastro/compiler/compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -182,13 +182,14 @@ const buildTarget = (targetName, props) => {
* and returns the bundle name of the asset.
*
* @const {TargetFunction} */
const bundleTarget = (targetName, props) => props.BuildMode == BuildMode.Dev
const bundleTarget = (targetName, props) => (props.BuildMode == BuildMode.Dev && !props.alwaysBuild)
? Promise.resolve(props.childTargets[0].slice(1))
: buildTarget(targetName, props).then(({ contentHash }) => {
/** @const {string} */
const targetFile = targetName.slice(1);
/** @const {string} */
const bundleName = "build/crate/" + (props.bundleName || `${hash.toStr(contentHash)}.${getExt(targetName)}`);
const bundleName = "build/crate/" +
(props.bundleName || `${hash.toStr(contentHash)}.${props.bundleExt || getExt(targetName)}`);
/** @const {!Promise<void>} */
const bundle = mkdir("build/crate", { recursive: true }).then(() =>
CompressedMimes[getExt(targetName)]
Expand Down
14 changes: 14 additions & 0 deletions kastro/compiler/image.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,23 @@ const svgTarget = (_, props) =>
const inlineSvgTarget = (_, props) =>
props.childTargets[0].then(({ content }) => optimize(content, SvgoInlineConfig).data);

/** @const {TargetFunction} */
const svgJsxTarget = (_, props) => props.childTargets[0]
.then(({ targetName: childTargetName }) => import(childTargetName))
.then((mod) => mod.default(props))
.then((content) => content);

/** @const {TargetFunction} */
const inlineSvgJsxTarget = (_, props) => props.childTargets[0]
.then(({ targetName: childTargetName }) => import(childTargetName))
.then((mod) => mod.default(props))
.then((content) => optimize(content, SvgoInlineConfig).data);

export {
inlineSvgTarget,
inlineSvgJsxTarget,
pngTarget,
svgTarget,
svgJsxTarget,
webpTarget
};
Empty file.
13 changes: 10 additions & 3 deletions kastro/compiler/targetRegistry.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,18 @@ const TargetFunction = {};
const TARGET_FUNCTIONS = {};

/**
* @param {string} targetName
* @param {string} targetName
* @return {TargetFunction}
*/
const getTargetFunction = (targetName) => {
const getTargetFunction = (targetName) => TARGET_FUNCTIONS[getLongExt(targetName)];

/**
* @param {string} targetName
* @return {string}
*/
const getLongExt = (targetName) => {
const nameIdx = targetName.lastIndexOf("/");
return TARGET_FUNCTIONS[targetName.slice(targetName.indexOf(".", nameIdx))]
return targetName.slice(targetName.indexOf(".", nameIdx));
}

/**
Expand All @@ -38,6 +44,7 @@ const registerTargetFunction = (extension, func) => {
}

export {
getLongExt,
getTargetFunction,
Props,
registerTargetFunction,
Expand Down
26 changes: 16 additions & 10 deletions kastro/image.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { SAXParser } from "sax";
import { tagYaz } from "../util/html";
import { getExt } from "../util/paths";
import { getDir, getExt } from "../util/paths";
import compiler from "./compiler/compiler";
import { Props } from "./compiler/targetRegistry";
import { Props, getLongExt } from "./compiler/targetRegistry";
import { removeGlobalProps } from "./props";

/**
Expand All @@ -12,8 +12,9 @@ import { removeGlobalProps } from "./props";
* @returns {!Promise<string>}
*/
const InlineSvgImage = ({ src, ...props }) =>
compiler.buildTarget(`/build/${src.slice(0, -4)}.inl.svg`, {
compiler.buildTarget(`/build/${getDir(src)}.inl${getLongExt(src)}`, {
childTargets: [`/${src}`],
alwaysBuild: src.endsWith(".svg.jsx"),
...props
}).then(({ content }) => {
removeGlobalProps(props);
Expand All @@ -35,17 +36,21 @@ const InlineSvgImage = ({ src, ...props }) =>
return result;
});

const makeImageElement = (bundledName, props) => {
const makeImageElement = (bundleName, { inSvg, ...props }) => {
removeGlobalProps(props);
props.src = bundledName;
return tagYaz("img", props, true);
if ("piggyback" in props) delete props.piggyback;
if (inSvg) props.href = bundleName;
else props.src = bundleName;
return tagYaz(inSvg ? "image" : "img", props, true);
}

const SvgImage = ({ src, inline, BuildMode, ...props }) => {
if (inline) return InlineSvgImage({ src, ...props });
const suffix = props.width ? "-w" + props.width : "";
return compiler.bundleTarget(`/build/${src.slice(0, -4)}${suffix}.svg`, {
return compiler.bundleTarget(`/build/${getDir(src)}${suffix}${getLongExt(src)}`, {
BuildMode,
alwaysBuild: src.endsWith(".svg.jsx"),
bundleExt: "svg",
childTargets: [`/${src}`]
}).then((bundledName) => makeImageElement(bundledName, props));
}
Expand Down Expand Up @@ -82,14 +87,15 @@ const Favicon = ({ src, raster, BuildMode, ...props }) => {
*/
const Image = ({ inline, ...props }) => {
if (inline) {
if (!props.src.endsWith(".svg"))
throw new Error("We only inline svgs; for other formats serving directly is more efficient");
return InlineSvgImage(props)
if (props.src.endsWith(".svg") || props.src.endsWith(".svg.jsx"))
return InlineSvgImage(props);
throw new Error("We only inline svgs; for other formats serving directly is more efficient");
}
if (props.rel == "icon")
return Favicon(props);

return {
"jsx": SvgImage,
"svg": SvgImage,
"png": PngImage,
}[getExt(props.src)](props);
Expand Down
27 changes: 19 additions & 8 deletions kastro/kastro.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,14 @@ import { parseArgs } from "../util/cli";
import { combine, getDir } from "../util/paths";
import compiler from "./compiler/compiler";
import { ttfTarget, woff2Target } from "./compiler/font";
import { inlineSvgTarget, pngTarget, svgTarget, webpTarget } from "./compiler/image";
import {
inlineSvgJsxTarget,
inlineSvgTarget,
pngTarget,
svgJsxTarget,
svgTarget,
webpTarget
} from "./compiler/image";
import { pageTarget } from "./compiler/page";
import { getGlobals } from "./compiler/pageGlobals";
import { scriptTarget } from "./compiler/script";
Expand All @@ -15,9 +22,10 @@ import { registerTargetFunction } from "./compiler/targetRegistry";
const setupKastro = () => {
registerTargetFunction(".html", pageTarget);
registerTargetFunction(".inl.svg", inlineSvgTarget);
registerTargetFunction(".inl.svg.jsx", inlineSvgJsxTarget);
registerTargetFunction(".png", pngTarget);
registerTargetFunction(".svg", svgTarget);
registerTargetFunction(".m.svg", svgTarget);
registerTargetFunction(".svg.jsx", svgJsxTarget);
registerTargetFunction(".css", stylesheetTarget);
registerTargetFunction(".webp", webpTarget);
registerTargetFunction(".ttf", ttfTarget);
Expand All @@ -32,14 +40,16 @@ const setupKastro = () => {
const stylesheetLoader = await readFile("/" + combine(moduleDir, "./compiler/loader/stylesheetLoader.js"), "utf8");
const scriptLoader = await readFile("/" + combine(moduleDir, "./compiler/loader/scriptLoader.js"), "utf8");

build.onLoad({ filter: /\.(svg|png|webp)$/ }, (args) => {
const imageComponent = (args) => {
const code = `import { Image } from "@kimlikdao/lib/kastro/image";\n` +
`export default (props) => Image({...props, src: "${args.path.slice(cwdLen)}" });`;
return {
contents: code,
loader: "js"
};
});
}

build.onLoad({ filter: /\.(svg|png|webp)$/ }, imageComponent);
build.onLoad({ filter: /\.css$/ }, (args) => ({
contents: stylesheetLoader.replace("SOURCE", args.path.slice(cwdLen)),
loader: "js"
Expand All @@ -52,14 +62,15 @@ const setupKastro = () => {
loader: "js"
};
});
build.onResolve({ filter: /./, namespace: "script" }, ({ path, importer }) => ({
path: path.startsWith(".") ? "/" + combine(getDir(importer.replace("script:", "")), path) : path,
namespace: "script"
build.onResolve({ filter: /./, namespace: "kastro" }, ({ path, importer }) => ({
path: path.startsWith(".") ? "/" + combine(getDir(importer.replace("kastro:", "")), path) : path,
namespace: "kastro"
}));
build.onLoad({ filter: /.*/, namespace: "script" }, (args) => ({
build.onLoad({ filter: /.js$/, namespace: "kastro" }, (args) => ({
contents: scriptLoader.replace("SOURCE", args.path.slice(cwdLen)),
loader: "js"
}));
build.onLoad({ filter: /.svg.jsx$/, namespace: "kastro" }, imageComponent);
},
});

Expand Down

0 comments on commit 1bc3dfa

Please sign in to comment.