chore: update Angular TypeScript build info cache
This commit is contained in:
@@ -6,8 +6,27 @@ import mermaid, { MermaidConfig, RenderResult } from 'mermaid';
|
||||
|
||||
type MermaidLib = typeof mermaid;
|
||||
|
||||
type MathJaxInstance = {
|
||||
tex2chtml(math: string, options: { display: boolean }): HTMLElement;
|
||||
startup: {
|
||||
promise: Promise<void>;
|
||||
document: {
|
||||
clear(): void;
|
||||
updateDocument(): void;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
type MetadataEntryType = 'text' | 'date' | 'email' | 'url' | 'number' | 'boolean' | 'image' | 'list' | 'object';
|
||||
|
||||
export interface WikiLinkActivation {
|
||||
target: string;
|
||||
heading?: string;
|
||||
headingText?: string;
|
||||
block?: string;
|
||||
alias: string;
|
||||
}
|
||||
|
||||
interface MetadataEntry {
|
||||
key: string;
|
||||
label: string;
|
||||
@@ -129,6 +148,7 @@ export class NoteViewerComponent implements OnDestroy {
|
||||
note = input.required<Note>();
|
||||
noteHtmlContent = input.required<string>();
|
||||
noteLinkClicked = output<string>();
|
||||
wikiLinkActivated = output<WikiLinkActivation>();
|
||||
tagClicked = output<string>();
|
||||
|
||||
private readonly elementRef = inject(ElementRef<HTMLElement>);
|
||||
@@ -140,6 +160,8 @@ export class NoteViewerComponent implements OnDestroy {
|
||||
private mermaidRenderScheduled = false;
|
||||
private mermaidLoader: Promise<MermaidLib> | null = null;
|
||||
private mermaidLib: MermaidLib | null = null;
|
||||
private mathRenderScheduled = false;
|
||||
private mathJaxLoader: Promise<MathJaxInstance> | null = null;
|
||||
private readonly dateFormatter = new Intl.DateTimeFormat(undefined, { dateStyle: 'medium' });
|
||||
private readonly metadataKeysToExclude = new Set(['tags', 'tag', 'keywords']);
|
||||
private attachmentErrorCleanup: (() => void) | null = null;
|
||||
@@ -208,6 +230,7 @@ export class NoteViewerComponent implements OnDestroy {
|
||||
this.noteHtmlContent();
|
||||
this.scheduleMermaidRender();
|
||||
this.scheduleAttachmentHandlers();
|
||||
this.scheduleMathRender();
|
||||
});
|
||||
|
||||
afterNextRender(() => {
|
||||
@@ -245,12 +268,31 @@ export class NoteViewerComponent implements OnDestroy {
|
||||
} else if (noteTitle) {
|
||||
this.noteLinkClicked.emit(noteTitle.toLowerCase().replace(/\s+/g, '-'));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const wikiAnchor = target.closest('a.md-wiki-link') as HTMLAnchorElement | null;
|
||||
if (wikiAnchor) {
|
||||
event.preventDefault();
|
||||
const targetValue = wikiAnchor.getAttribute('data-target') ?? '';
|
||||
const headingSlug = wikiAnchor.getAttribute('data-heading') ?? undefined;
|
||||
const headingText = wikiAnchor.getAttribute('data-heading-text') ?? undefined;
|
||||
const blockRef = wikiAnchor.getAttribute('data-block') ?? undefined;
|
||||
this.wikiLinkActivated.emit({
|
||||
target: targetValue,
|
||||
heading: headingSlug || undefined,
|
||||
headingText: headingText || undefined,
|
||||
block: blockRef || undefined,
|
||||
alias: wikiAnchor.textContent?.trim() ?? targetValue
|
||||
});
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
this.setupMermaidObservation();
|
||||
this.scheduleMermaidRender();
|
||||
this.scheduleAttachmentHandlers();
|
||||
this.scheduleMathRender();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -259,10 +301,22 @@ export class NoteViewerComponent implements OnDestroy {
|
||||
this.mermaidObserver = null;
|
||||
this.mermaidLib = null;
|
||||
this.mermaidLoader = null;
|
||||
this.mathJaxLoader = null;
|
||||
this.attachmentErrorCleanup?.();
|
||||
this.attachmentErrorCleanup = null;
|
||||
}
|
||||
|
||||
private scheduleMathRender(): void {
|
||||
if (this.mathRenderScheduled) {
|
||||
return;
|
||||
}
|
||||
this.mathRenderScheduled = true;
|
||||
queueMicrotask(() => {
|
||||
this.mathRenderScheduled = false;
|
||||
this.renderMathExpressions();
|
||||
});
|
||||
}
|
||||
|
||||
getFrontmatterKeys(frontmatter: { [key: string]: any }): string[] {
|
||||
return Object.keys(frontmatter).filter(key => key !== 'tags' && key !== 'aliases' && key !== 'mtime');
|
||||
}
|
||||
@@ -449,6 +503,43 @@ export class NoteViewerComponent implements OnDestroy {
|
||||
});
|
||||
}
|
||||
|
||||
private async renderMathExpressions(): Promise<void> {
|
||||
if (typeof window === 'undefined') {
|
||||
return;
|
||||
}
|
||||
|
||||
const hostElement = this.elementRef.nativeElement as HTMLElement;
|
||||
const mathElements = Array.from(hostElement.querySelectorAll<HTMLElement>('.md-math-inline, .md-math-block'));
|
||||
const pending = mathElements.filter(element => element.dataset.math && element.dataset.mathProcessed !== 'true');
|
||||
if (!pending.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const mathJax = await this.ensureMathJax();
|
||||
for (const element of pending) {
|
||||
const expression = element.dataset.math ?? '';
|
||||
if (!expression.trim()) {
|
||||
continue;
|
||||
}
|
||||
const display = element.classList.contains('md-math-block');
|
||||
try {
|
||||
const rendered = mathJax.tex2chtml(expression, { display });
|
||||
element.innerHTML = '';
|
||||
element.appendChild(rendered);
|
||||
element.setAttribute('data-math-processed', 'true');
|
||||
} catch (error) {
|
||||
console.error('MathJax render error:', error);
|
||||
element.textContent = expression;
|
||||
}
|
||||
}
|
||||
mathJax.startup.document.clear();
|
||||
mathJax.startup.document.updateDocument();
|
||||
} catch (error) {
|
||||
console.error('Unable to initialise MathJax:', error);
|
||||
}
|
||||
}
|
||||
|
||||
private decodeMermaidSource(encoded: string): string {
|
||||
try {
|
||||
return decodeURIComponent(encoded);
|
||||
@@ -464,6 +555,80 @@ export class NoteViewerComponent implements OnDestroy {
|
||||
.replace(/>/g, '>');
|
||||
}
|
||||
|
||||
private ensureMathJax(): Promise<MathJaxInstance> {
|
||||
if (typeof window === 'undefined') {
|
||||
return Promise.reject(new Error('MathJax requires a browser environment.'));
|
||||
}
|
||||
|
||||
const globalWithMathJax = window as unknown as {
|
||||
MathJax?: MathJaxInstance & { startup: { promise: Promise<void> } };
|
||||
_mathJaxLoading?: boolean;
|
||||
};
|
||||
|
||||
if (globalWithMathJax.MathJax) {
|
||||
return globalWithMathJax.MathJax.startup.promise.then(() => globalWithMathJax.MathJax as MathJaxInstance);
|
||||
}
|
||||
|
||||
if (this.mathJaxLoader) {
|
||||
return this.mathJaxLoader;
|
||||
}
|
||||
|
||||
this.mathJaxLoader = new Promise<MathJaxInstance>((resolve, reject) => {
|
||||
if (globalWithMathJax._mathJaxLoading) {
|
||||
const interval = window.setInterval(() => {
|
||||
if (globalWithMathJax.MathJax) {
|
||||
window.clearInterval(interval);
|
||||
globalWithMathJax.MathJax.startup.promise.then(() => resolve(globalWithMathJax.MathJax as MathJaxInstance));
|
||||
}
|
||||
}, 30);
|
||||
return;
|
||||
}
|
||||
|
||||
globalWithMathJax._mathJaxLoading = true;
|
||||
(window as any).MathJax = {
|
||||
startup: {
|
||||
typeset: false
|
||||
},
|
||||
tex: {
|
||||
inlineMath: [['$', '$'], ['\\(', '\\)']],
|
||||
displayMath: [['$$', '$$'], ['\\[', '\\]']],
|
||||
processEscapes: true
|
||||
},
|
||||
options: {
|
||||
skipHtmlTags: ['script', 'noscript', 'style', 'textarea', 'pre']
|
||||
}
|
||||
};
|
||||
|
||||
const existing = document.getElementById('mathjax-loader') as HTMLScriptElement | null;
|
||||
if (existing) {
|
||||
existing.addEventListener('load', () => {
|
||||
if (globalWithMathJax.MathJax) {
|
||||
globalWithMathJax.MathJax.startup.promise.then(() => resolve(globalWithMathJax.MathJax as MathJaxInstance));
|
||||
}
|
||||
}, { once: true });
|
||||
existing.addEventListener('error', () => reject(new Error('Failed to load MathJax script.')), { once: true });
|
||||
return;
|
||||
}
|
||||
|
||||
const script = document.createElement('script');
|
||||
script.id = 'mathjax-loader';
|
||||
script.async = true;
|
||||
script.src = 'https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js';
|
||||
script.addEventListener('load', () => {
|
||||
const mathJax = globalWithMathJax.MathJax;
|
||||
if (!mathJax) {
|
||||
reject(new Error('MathJax failed to initialise.'));
|
||||
return;
|
||||
}
|
||||
mathJax.startup.promise.then(() => resolve(mathJax as MathJaxInstance));
|
||||
}, { once: true });
|
||||
script.addEventListener('error', () => reject(new Error('Failed to load MathJax script.')), { once: true });
|
||||
document.head.appendChild(script);
|
||||
});
|
||||
|
||||
return this.mathJaxLoader;
|
||||
}
|
||||
|
||||
private toggleMetadataPanel(): void {
|
||||
if (typeof window !== 'undefined') {
|
||||
const currentScroll = window.scrollY;
|
||||
|
||||
Reference in New Issue
Block a user