Skip to content

Commit

Permalink
[gem-book] Restore <details> state
Browse files Browse the repository at this point in the history
Closed #110
  • Loading branch information
mantou132 committed Jan 7, 2024
1 parent ef5d774 commit eff8569
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 42 deletions.
21 changes: 20 additions & 1 deletion packages/gem-book/src/element/elements/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,27 @@ export class Main extends GemElement {
// homepage/footer 等内置元素渲染在 main 前面,不能使用自定义渲染器
static instance?: Main;

static detailsStateCache = new Map<string, boolean>();

static parseMarkdown(mdBody: string) {
return [...parser.parseFromString(parse(mdBody, { renderer: Main.instance?.renderer }), 'text/html').body.children];
const elements = [
...parser.parseFromString(
parse(mdBody, {
renderer: Main.instance?.renderer,
}),
'text/html',
).body.children,
];
elements.forEach((detailsEle) => {
if (detailsEle instanceof HTMLDetailsElement) {
const html = locationStore.path + detailsEle.innerHTML;
detailsEle.open = !!Main.detailsStateCache.get(html);
detailsEle.addEventListener('toggle', () => {
Main.detailsStateCache.set(html, detailsEle.open);
});
}
});
return elements;
}

static unsafeRenderHTML(s: string, style = '') {
Expand Down
9 changes: 5 additions & 4 deletions packages/gem-book/src/element/elements/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,17 @@ export class GemBookPluginElement<T = any> extends GemElement<T> {
return bookStore.getCurrentLink?.();
}

static caches?: Map<string, any>;
static caches = new Map<typeof GemBookPluginElement, Map<string, any>>();

cacheState(getDeps: () => string[]) {
if (!this.state) throw new Error('Only cache state');
const cons = this.constructor as typeof GemBookPluginElement;
const caches = cons.caches || (cons.caches = new Map());
const cache = cons.caches.get(cons) || new Map();
cons.caches.set(cons, cache);
this.memo(
() => {
Object.assign(this.state!, caches.get(getDeps().join()));
return () => caches.set(getDeps().join(), this.state);
Object.assign(this.state!, cache.get(getDeps().join()));
return () => cache.set(getDeps().join(), this.state);
},
() => getDeps(),
);
Expand Down
86 changes: 49 additions & 37 deletions packages/gem-book/src/element/elements/pre.ts
Original file line number Diff line number Diff line change
Expand Up @@ -349,45 +349,57 @@ export class Pre extends GemElement {
}
};

mounted() {
this.effect(async () => {
if (!this.getBoundingClientRect().width) return;
if (this.status === 'hidden') return;
if (!this.codeRef.element) return;
await import(/* @vite-ignore */ /* webpackIgnore: true */ prismjs);
const { Prism } = window as any;
if (this.codelang && !Prism.languages[this.codelang]) {
const lang = langAliases[this.codelang] || this.codelang;
const langDeps = ([] as string[]).concat(langDependencies[lang] || []);
try {
await Promise.all(
langDeps.map((langDep) => {
if (!Prism.languages[langDep]) {
return import(
/* @vite-ignore */ /* webpackIgnore: true */ `${prismjs}/components/prism-${langDep}.min.js`
);
}
}),
);
await import(/* @vite-ignore */ /* webpackIgnore: true */ `${prismjs}/components/prism-${lang}.min.js`);
} catch {
//
}
#updateHtml = async () => {
if (this.status === 'hidden') return;
if (!this.codeRef.element) return;
await import(/* @vite-ignore */ /* webpackIgnore: true */ prismjs);
const { Prism } = window as any;
if (this.codelang && !Prism.languages[this.codelang]) {
const lang = langAliases[this.codelang] || this.codelang;
const langDeps = ([] as string[]).concat(langDependencies[lang] || []);
try {
await Promise.all(
langDeps.map((langDep) => {
if (!Prism.languages[langDep]) {
return import(
/* @vite-ignore */ /* webpackIgnore: true */ `${prismjs}/components/prism-${langDep}.min.js`
);
}
}),
);
await import(/* @vite-ignore */ /* webpackIgnore: true */ `${prismjs}/components/prism-${lang}.min.js`);
} catch {
//
}
const content = Prism.languages[this.codelang]
? Prism.highlight(this.textContent || '', Prism.languages[this.codelang], this.codelang)
: this.innerHTML;
const { parts, lineNumbersParts } = this.#getParts(content);
this.codeRef.element.innerHTML = parts.reduce(
(p, c, i) =>
p +
`<span class="code-ignore token comment"> @@ ${lineNumbersParts[i - 1].at(-1)! + 1}-${
lineNumbersParts[i].at(0)! - 1
} @@</span>` +
c,
);
this.#setOffset();
}
const content = Prism.languages[this.codelang]
? Prism.highlight(this.textContent || '', Prism.languages[this.codelang], this.codelang)
: this.innerHTML;
const { parts, lineNumbersParts } = this.#getParts(content);
this.codeRef.element.innerHTML = parts.reduce(
(p, c, i) =>
p +
`<span class="code-ignore token comment"> @@ ${lineNumbersParts[i - 1].at(-1)! + 1}-${
lineNumbersParts[i].at(0)! - 1
} @@</span>` +
c,
);
this.#setOffset();
};

mounted() {
const io = new IntersectionObserver((entries) => {
entries.forEach(({ intersectionRatio }) => {
if (intersectionRatio === 0) return;
io.disconnect();
this.effect(
() => this.#updateHtml(),
() => [this.textContent, this.codelang],
);
});
});
io.observe(this);
return () => io.disconnect();
}

render() {
Expand Down

0 comments on commit eff8569

Please sign in to comment.