Skip to content

Commit

Permalink
🏙️ Improve kastro image support
Browse files Browse the repository at this point in the history
  • Loading branch information
KimlikDAO-bot committed Sep 14, 2024
1 parent 663ed7f commit 5f92f48
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 462 deletions.
4 changes: 0 additions & 4 deletions kastro/compiler/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,6 @@ const compileComponent = (name, props, globals) => {
if (globals.BuildMode > 0 && tagName.toLowerCase() == "script")
return htmlParts.push(generateScript(tagProps, globals));

if (tagName.toLowerCase() == "link" && tagProps.rel == "stylesheet")
return (("data-shared" in tagProps) ? globals.SharedCss : globals.PageCss)
.add(normalizePath(tagProps.href));

if ("data-dev-remove" in tagProps) {
delete tagProps["data-dev-remove"];
if (globals.BuildMode == 0) return;
Expand Down
65 changes: 51 additions & 14 deletions kastro/compiler/image.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,39 @@
import { readFile } from "node:fs/promises";
import { mkdir, readFile } from "node:fs/promises";
import { SAXParser } from "sax";
import { optimize } from "svgo";
import { tagYaz } from "../../util/html";
import { getExt } from "../../util/paths";
import { getByKey } from "./hashcache/buildCache";
import { hashAndCompressContent, hashFile } from "./hashcache/compression";
import SvgoConfig from "./svgoConfig";
import SvgoInlineConfig from "./svgoInlineConfig";


const removeGlobalProps = (props) => {
for (const prop in props)
if (prop.charCodeAt(0) < 91)
delete props[prop];
}

const webp = (inputName, outputName, passes = 10, quality = 70) =>
mkdir(getDir(outputName), { recursive: true }).then(() =>
spawn([
"cwebp",
"-m", 6,
"-pass", passes,
"-q", quality,
inputName,
"-o", outputName
]).exited);

/**
* We optimize the inline svgs regardless of the build mode.
*
* @param {!Object<string, *>} props
* @returns {!Promise<string>}
*/
const compileInlineSvg = ({ src, ...props }) =>
getByKey("build/" + src, () =>
const InlineSvgImage = ({ src, ...props }) =>
getByKey("InlineSvgImage:" + src, () =>
getByKey(src, () => readFile(src, "utf-8"))
.then((svg) => optimize(svg, SvgoInlineConfig).data))
.then((svg) => {
Expand All @@ -41,24 +56,46 @@ const compileInlineSvg = ({ src, ...props }) =>
return result;
});

const SvgImage = ({ src, inline, BuildMode, ...props }) => inline
? InlineSvgImage({ src, ...props })
: (BuildMode == 0
? Promise.resolve(src)
: getByKey(src, () => readFile(src, "utf-8")
.then((svg) => hashAndCompressContent(optimize(svg, SvgoConfig).data, "svg"))
))
.then((hashedName) => {
removeGlobalProps(props);
props.src = hashedName;
return tagYaz("img", props, true);
});

const PngImage = ({ src, passes, quality, BuildMode, ...props }) => (BuildMode == 0
? Promise.resolve(src)
: getByKey(src, () => {
const webpName = `build/${src.slice(0, -4)}.webp`;
return webp(src, webpName, passes, quality)
.then(() => hashFile(webpName))
}))
.then((hashedName) => {
removeGlobalProps(props)
props.src = hashedName;
return tagYaz("img", props, true);
});

/**
* @param {!Object<string, *>} props
* @return {!Promise<string>}
*/
const Image = (props) => {
const { inline, src, ...restProps } = props;
const Image = ({ inline, ...props }) => {
if (inline) {
if (!src.endsWith(".svg"))
if (!props.src.endsWith(".svg"))
throw new Error("We only inline svgs; for other formats serving directly is more efficient");
return compileInlineSvg(props)
return InlineSvgImage(props)
}

for (const prop in props)
if (prop[0] === prop[0].toUpperCase())
delete props[prop];

return tagYaz("img", props, true);
return {
"svg": SvgImage,
"png": PngImage,
}[getExt(props.src)](props);
};

export { Image };
export { Image, InlineSvgImage, PngImage, SvgImage };
44 changes: 23 additions & 21 deletions kastro/compiler/jsx-runtime.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import { KapalıTag, tagYaz } from "../../util/html";
import { getGlobals } from "./pageGlobals";
import { LangCode } from "../crate";
import { getGlobals } from "./pageGlobals";
/**
* @param {!Array<*>} children
* @param {LangCode} lang
* @return {string}
* @return {!Promise<string>}
*/
const mergeChildren = (children, lang) => children
const mergeChildren = (children, lang) => Promise.all(children
.flat()
.filter((c) => typeof c != "boolean")
.map((c) => typeof c == "object" && c[lang] ? c[lang] : c)
.join("");
.filter((c) => typeof c != "boolean"))
.then((children) => children
.map((c) => typeof c == "object" && c[lang] ? c[lang] : c)
.join("")
);

/**
* @param {!Object} props
Expand All @@ -31,17 +33,17 @@ const jsx = (name, props = {}) => {
const nameType = typeof name;
if (nameType != "function") {
const { children, ...prop } = props;
const childStr = mergeChildren([].concat(children || []), globals.Lang);
if (nameType == "object") {
if (nameType == "object") { // `{@link name}` is a placeholder dom element
prop.id = name.id;
name = name.name;
}
const closed = KapalıTag[name];
return name == Fragment
? childStr
: childStr || !closed
? tagYaz(name, prop, false) + childStr + `</${name}>`
: tagYaz(name, prop, true);
return mergeChildren([].concat(children || []), globals.Lang)
.then((childStr) => name == Fragment
? childStr
: (childStr || !KapalıTag[name])
? tagYaz(name, prop, false) + childStr + `</${name}>`
: tagYaz(name, prop, true)
)
}
return name({ ...props, ...globals });
}
Expand All @@ -59,13 +61,13 @@ const jsxs = (name, props) => {
prop.id = name.id;
name = name.name;
}
const childStr = children ? mergeChildren(children, globals.Lang) : "";
const closed = KapalıTag[name];
return name == Fragment
? childStr
: childStr || !closed
? tagYaz(name, prop, false) + childStr + `</${name}>`
: tagYaz(name, prop, true);
return mergeChildren(children || [], globals.Lang)
.then((childStr) => name == Fragment
? childStr
: childStr || !KapalıTag[name]
? tagYaz(name, prop, false) + childStr + `</${name}>`
: tagYaz(name, prop, true)
);
}
return name({ ...props, ...globals });
};
Expand Down
Loading

0 comments on commit 5f92f48

Please sign in to comment.