mirror of
https://github.com/jackyzha0/quartz.git
synced 2026-03-21 21:45:42 -05:00
fix: only call scripts one per page
This commit is contained in:
parent
912642590c
commit
34480c686d
@ -18,6 +18,7 @@ export interface RegisteredComponent {
|
||||
|
||||
class ComponentRegistry {
|
||||
private components = new Map<string, RegisteredComponent>()
|
||||
private instanceCache = new Map<string, QuartzComponent>()
|
||||
|
||||
register(
|
||||
name: string,
|
||||
@ -40,6 +41,30 @@ class ComponentRegistry {
|
||||
return new Map(this.components)
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate a component constructor with options, returning a cached instance
|
||||
* if the same constructor was already called with equivalent options.
|
||||
* This prevents duplicate afterDOMLoaded scripts when the same component
|
||||
* appears in multiple page-type layouts.
|
||||
*/
|
||||
instantiate(constructor: QuartzComponentConstructor, options?: unknown): QuartzComponent {
|
||||
const optsKey = options !== undefined ? JSON.stringify(options) : ""
|
||||
// Use constructor identity + serialized options as cache key
|
||||
// We store constructor name as a hint but rely on a unique id for identity
|
||||
const ctorId =
|
||||
(constructor as unknown as { __cacheId?: string }).__cacheId ??
|
||||
((constructor as unknown as { __cacheId: string }).__cacheId =
|
||||
`ctor_${this.instanceCache.size}`)
|
||||
const cacheKey = `${ctorId}:${optsKey}`
|
||||
|
||||
const cached = this.instanceCache.get(cacheKey)
|
||||
if (cached) return cached
|
||||
|
||||
const instance = constructor(options)
|
||||
this.instanceCache.set(cacheKey, instance)
|
||||
return instance
|
||||
}
|
||||
|
||||
getAllComponents(): QuartzComponent[] {
|
||||
// Deduplicate by component reference (same constructor may be registered under multiple keys)
|
||||
const seen = new Set<QuartzComponent | QuartzComponentConstructor>()
|
||||
@ -50,7 +75,7 @@ class ComponentRegistry {
|
||||
try {
|
||||
let instance: QuartzComponent
|
||||
if (typeof r.component === "function") {
|
||||
instance = (r.component as QuartzComponentConstructor)(undefined)
|
||||
instance = this.instantiate(r.component as QuartzComponentConstructor, undefined)
|
||||
} else {
|
||||
instance = r.component as QuartzComponent
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@ import path from "path"
|
||||
import YAML from "yaml"
|
||||
import { styleText } from "util"
|
||||
import { QuartzConfig, GlobalConfiguration, FullPageLayout } from "../../cfg"
|
||||
import { QuartzComponent } from "../../components/types"
|
||||
import { QuartzComponent, QuartzComponentConstructor } from "../../components/types"
|
||||
import { PluginTypes } from "../types"
|
||||
import {
|
||||
PluginManifest,
|
||||
@ -561,11 +561,12 @@ export async function loadQuartzLayout(layoutOverrides?: {
|
||||
const footerReg = componentRegistry.get("footer") ?? componentRegistry.get("Footer")
|
||||
if (footerReg) {
|
||||
if (typeof footerReg.component === "function" && !("displayName" in footerReg.component)) {
|
||||
// It's a constructor, instantiate with options
|
||||
// It's a constructor — use registry cache for consistent instances
|
||||
const opts = { ...footerEntry.options }
|
||||
footer = (footerReg.component as Function)(
|
||||
footer = componentRegistry.instantiate(
|
||||
footerReg.component as QuartzComponentConstructor,
|
||||
Object.keys(opts).length > 0 ? opts : undefined,
|
||||
) as QuartzComponent
|
||||
)
|
||||
} else {
|
||||
footer = footerReg.component as QuartzComponent
|
||||
}
|
||||
@ -648,11 +649,14 @@ function buildLayoutForEntries(
|
||||
|
||||
let component: QuartzComponent
|
||||
if (typeof reg.component === "function" && !("displayName" in reg.component)) {
|
||||
// It's a constructor, instantiate with options
|
||||
// It's a constructor — use registry cache to avoid duplicate instances
|
||||
// (and duplicate afterDOMLoaded scripts) across page-type layouts
|
||||
const opts = { ...entry.options }
|
||||
component = (reg.component as Function)(
|
||||
Object.keys(opts).length > 0 ? opts : undefined,
|
||||
) as QuartzComponent
|
||||
const optsArg = Object.keys(opts).length > 0 ? opts : undefined
|
||||
component = componentRegistry.instantiate(
|
||||
reg.component as QuartzComponentConstructor,
|
||||
optsArg,
|
||||
)
|
||||
} else {
|
||||
component = reg.component as QuartzComponent
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user