2023-06-04 02:07:19 +07:00
|
|
|
import { GlobalConfiguration } from '../cfg'
|
|
|
|
import { QuartzComponent } from '../components/types'
|
2023-05-30 22:02:20 +07:00
|
|
|
import { StaticResources } from '../resources'
|
2023-06-04 02:07:19 +07:00
|
|
|
import { googleFontHref, joinStyles } from '../theme'
|
|
|
|
import { EmitCallback, PluginTypes } from './types'
|
|
|
|
import styles from '../styles/base.scss'
|
2023-07-01 14:03:01 +07:00
|
|
|
|
2023-06-10 09:58:58 +07:00
|
|
|
// @ts-ignore
|
2023-06-08 12:38:45 +07:00
|
|
|
import spaRouterScript from '../components/scripts/spa.inline'
|
2023-07-01 14:03:01 +07:00
|
|
|
// @ts-ignore
|
|
|
|
import popoverScript from '../components/scripts/popover.inline'
|
|
|
|
import popoverStyle from '../components/styles/popover.scss'
|
2023-06-04 02:07:19 +07:00
|
|
|
|
|
|
|
export type ComponentResources = {
|
|
|
|
css: string[],
|
|
|
|
beforeDOMLoaded: string[],
|
|
|
|
afterDOMLoaded: string[]
|
|
|
|
}
|
|
|
|
|
|
|
|
function joinScripts(scripts: string[]): string {
|
2023-06-18 06:05:46 +07:00
|
|
|
// wrap with iife to prevent scope collision
|
|
|
|
return scripts.map(script => `(function () {${script}})();`).join("\n")
|
2023-06-04 02:07:19 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
export function emitComponentResources(cfg: GlobalConfiguration, resources: StaticResources, plugins: PluginTypes, emit: EmitCallback) {
|
|
|
|
const fps: string[] = []
|
2023-06-08 12:27:32 +07:00
|
|
|
const allComponents: Set<QuartzComponent> = new Set()
|
2023-06-04 02:07:19 +07:00
|
|
|
for (const emitter of plugins.emitters) {
|
|
|
|
const components = emitter.getQuartzComponents()
|
|
|
|
for (const component of components) {
|
|
|
|
allComponents.add(component)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const componentResources: ComponentResources = {
|
|
|
|
css: [],
|
|
|
|
beforeDOMLoaded: [],
|
|
|
|
afterDOMLoaded: []
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const component of allComponents) {
|
|
|
|
const { css, beforeDOMLoaded, afterDOMLoaded } = component
|
|
|
|
if (css) {
|
|
|
|
componentResources.css.push(css)
|
|
|
|
}
|
|
|
|
if (beforeDOMLoaded) {
|
|
|
|
componentResources.beforeDOMLoaded.push(beforeDOMLoaded)
|
|
|
|
}
|
|
|
|
if (afterDOMLoaded) {
|
2023-06-07 11:19:00 +07:00
|
|
|
componentResources.afterDOMLoaded.push(afterDOMLoaded)
|
2023-06-04 02:07:19 +07:00
|
|
|
}
|
|
|
|
}
|
2023-07-02 03:35:27 +07:00
|
|
|
|
|
|
|
if (cfg.enablePopovers) {
|
|
|
|
componentResources.afterDOMLoaded.push(popoverScript)
|
|
|
|
componentResources.css.push(popoverStyle)
|
|
|
|
}
|
2023-06-04 02:07:19 +07:00
|
|
|
|
2023-06-18 02:07:40 +07:00
|
|
|
if (cfg.enableSPA) {
|
|
|
|
componentResources.afterDOMLoaded.push(spaRouterScript)
|
|
|
|
} else {
|
|
|
|
componentResources.afterDOMLoaded.push(`
|
2023-06-20 10:37:45 +07:00
|
|
|
window.spaNavigate = (url, _) => window.location.assign(url)
|
2023-06-18 02:07:40 +07:00
|
|
|
const event = new CustomEvent("nav", { detail: { slug: document.body.dataset.slug } })
|
|
|
|
document.dispatchEvent(event)`
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2023-06-04 02:07:19 +07:00
|
|
|
emit({
|
|
|
|
slug: "index",
|
|
|
|
ext: ".css",
|
|
|
|
content: joinStyles(cfg.theme, styles, ...componentResources.css)
|
|
|
|
})
|
|
|
|
emit({
|
|
|
|
slug: "prescript",
|
|
|
|
ext: ".js",
|
|
|
|
content: joinScripts(componentResources.beforeDOMLoaded)
|
|
|
|
})
|
|
|
|
emit({
|
|
|
|
slug: "postscript",
|
|
|
|
ext: ".js",
|
|
|
|
content: joinScripts(componentResources.afterDOMLoaded)
|
|
|
|
})
|
|
|
|
|
|
|
|
fps.push("index.css", "prescript.js", "postscript.js")
|
|
|
|
resources.css.push(googleFontHref(cfg.theme))
|
|
|
|
return fps
|
|
|
|
}
|
2023-05-30 22:02:20 +07:00
|
|
|
|
|
|
|
export function getStaticResourcesFromPlugins(plugins: PluginTypes) {
|
|
|
|
const staticResources: StaticResources = {
|
|
|
|
css: [],
|
|
|
|
js: [],
|
|
|
|
}
|
|
|
|
|
2023-06-04 02:07:19 +07:00
|
|
|
for (const transformer of plugins.transformers) {
|
2023-06-18 03:08:06 +07:00
|
|
|
const res = transformer.externalResources ? transformer.externalResources() : {}
|
2023-05-30 22:02:20 +07:00
|
|
|
if (res?.js) {
|
|
|
|
staticResources.js = staticResources.js.concat(res.js)
|
|
|
|
}
|
|
|
|
if (res?.css) {
|
|
|
|
staticResources.css = staticResources.css.concat(res.css)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return staticResources
|
|
|
|
}
|
|
|
|
|
|
|
|
export * from './transformers'
|
|
|
|
export * from './filters'
|
|
|
|
export * from './emitters'
|
|
|
|
|
|
|
|
declare module 'vfile' {
|
|
|
|
// inserted in processors.ts
|
|
|
|
interface DataMap {
|
|
|
|
slug: string
|
|
|
|
filePath: string
|
|
|
|
}
|
|
|
|
}
|