文件
halo-theme/src/alpine/theme-comment.ts
T
admin 261c0116ba
Theme CD / Package Theme (release) Failing after 13m8s
Theme CD / Release (release) Failing after 14m59s
refactor(alpine): restructure components and remove unused utilities for better modularity and maintainability
2026-06-14 08:31:42 +08:00

89 行
2.5 KiB
TypeScript

import commentWidgetThemeStyle from "../styles/devcm-comment-widget.css?raw";
const injectShadowStyle = (root: ShadowRoot | null | undefined, id: string, css: string) => {
if (!root || root.querySelector(`#${id}`)) {
return;
}
const style = document.createElement("style");
style.id = id;
style.textContent = css;
root.appendChild(style);
};
const themeCommentRoot = (root: ParentNode | null | undefined) => {
if (!root) {
return;
}
root.querySelectorAll<HTMLElement>("*").forEach((element) => {
if (element.shadowRoot) {
injectShadowStyle(element.shadowRoot, "devcm-comment-widget-theme", commentWidgetThemeStyle);
themeCommentRoot(element.shadowRoot);
}
});
};
const commentScopeSelector = ".devcm-comments, .devcm-moment-comments";
const getCommentScopes = (root: ParentNode) => {
const scopes = Array.from(root.querySelectorAll<HTMLElement>(commentScopeSelector));
if (root instanceof HTMLElement && root.matches(commentScopeSelector)) {
scopes.unshift(root);
}
return scopes;
};
const themeCommentWidget = (root: ParentNode) => {
const commentScopes = getCommentScopes(root);
if (!commentScopes.length) {
return;
}
commentScopes.forEach((comments) => {
themeCommentRoot(comments);
comments.querySelectorAll<HTMLElement>("comment-widget").forEach((widget) => {
injectShadowStyle(widget.shadowRoot, "devcm-comment-widget-theme", commentWidgetThemeStyle);
const form = widget.shadowRoot?.querySelector<HTMLElement>("comment-form");
injectShadowStyle(form?.shadowRoot, "devcm-comment-form-theme", commentWidgetThemeStyle);
const baseForm = form?.shadowRoot?.querySelector<HTMLElement>("base-form");
injectShadowStyle(baseForm?.shadowRoot, "devcm-comment-base-form-theme", commentWidgetThemeStyle);
});
});
};
type ThemeCommentState = {
$el: HTMLElement;
observer: MutationObserver | null;
timers: number[];
init: () => void;
destroy: () => void;
refresh: () => void;
};
export const themeComment = (): ThemeCommentState => ({
$el: null as unknown as HTMLElement,
observer: null,
timers: [],
init() {
this.refresh();
this.timers = [120, 500, 1200, 2400].map((delay) => window.setTimeout(() => this.refresh(), delay));
this.observer = new MutationObserver(() => this.refresh());
this.observer.observe(this.$el, {
childList: true,
subtree: true,
});
},
destroy() {
this.observer?.disconnect();
this.timers.forEach((timer) => window.clearTimeout(timer));
},
refresh() {
themeCommentWidget(this.$el);
},
});