192 lines
6.3 KiB
TypeScript
192 lines
6.3 KiB
TypeScript
import { shallowRef, type ComponentPublicInstance, type Ref } from 'vue';
|
|
|
|
export const BLOG_DOM_IDS = {
|
|
banner: 'banner',
|
|
bannerContainer: 'banner_container',
|
|
blogSettingsPopup: 'blog_settings_popup',
|
|
commentEmotionButton: 'comment_emotion_btn',
|
|
commentPostUseMarkdown: 'comment_post_use_markdown',
|
|
comments: 'comments',
|
|
content: 'content',
|
|
floatBackToTop: 'fabtn_back_to_top',
|
|
floatReadingProgress: 'fabtn_reading_progress',
|
|
floatSettingsToggle: 'fabtn_toggle_blog_settings_popup',
|
|
floatToggleSides: 'fabtn_toggle_sides',
|
|
footer: 'footer',
|
|
headerNavbar: 'navbar-main',
|
|
leftbar: 'leftbar',
|
|
leftbarCatalog: 'leftbar_catalog',
|
|
leftbarCatalogTab: 'leftbar_tab_catalog',
|
|
leftbarCatalogTabButton: 'leftbar_tab_catalog_btn',
|
|
leftbarOverviewAuthorImage: 'leftbar_overview_author_image',
|
|
leftbarOverviewAuthorName: 'leftbar_overview_author_name',
|
|
leftbarOverviewTab: 'leftbar_tab_overview',
|
|
leftbarOverviewTabButton: 'leftbar_tab_overview_btn',
|
|
leftbarPart1: 'leftbar_part1',
|
|
leftbarPart1Menu: 'leftbar_part1_menu',
|
|
leftbarPart2: 'leftbar_part2',
|
|
leftbarPart2Inner: 'leftbar_part2_inner',
|
|
leftbarSearchContainer: 'leftbar_search_container',
|
|
leftbarSearchInput: 'leftbar_search_input',
|
|
live2dCanvas: 'live2d',
|
|
live2dChatText: 'live2dChatText',
|
|
live2dSend: 'live2dSend',
|
|
live2dSendClose: 'live2dSendClose',
|
|
live2dTextureButton: 'live2d-texture-button',
|
|
main: 'main',
|
|
openSidebar: 'open_sidebar',
|
|
postArticleTitle: 'post_article_title',
|
|
postComment: 'post_comment',
|
|
postCommentCaptcha: 'post_comment_captcha',
|
|
postCommentContent: 'post_comment_content',
|
|
postCommentEmail: 'post_comment_email',
|
|
postCommentName: 'post_comment_name',
|
|
postCommentSend: 'post_comment_send',
|
|
postContent: 'post_content',
|
|
primary: 'primary',
|
|
rightbar: 'rightbar',
|
|
shareContainer: 'share_container',
|
|
shareCopyLink: 'share_copy_link',
|
|
sharePanel: 'share',
|
|
shareShow: 'share_show',
|
|
sidebarMask: 'sidebar_mask',
|
|
settingsFontSansSerif: 'blog_setting_font_sans_serif',
|
|
settingsFontSerif: 'blog_setting_font_serif',
|
|
settingsShadowBig: 'blog_setting_shadow_big',
|
|
settingsShadowSmall: 'blog_setting_shadow_small',
|
|
themeStyle: 'kt-blog-theme-style',
|
|
} as const;
|
|
|
|
export const BLOG_META_NAMES = {
|
|
themeColor: 'theme-color',
|
|
themeColorRgb: 'theme-color-rgb',
|
|
} as const;
|
|
|
|
export type BlogDomIdKey = keyof typeof BLOG_DOM_IDS;
|
|
|
|
/**
|
|
* @param key Semantic key for a stable Argon-compatible DOM id.
|
|
* @returns Concrete DOM id string used by markup, source tests, and Argon compatibility hooks.
|
|
*/
|
|
export function blogDomId(key: BlogDomIdKey) {
|
|
return BLOG_DOM_IDS[key];
|
|
}
|
|
|
|
/**
|
|
* @param key Semantic key for a stable Argon-compatible DOM id.
|
|
* @returns CSS id selector for document queries that cannot yet be replaced by a Vue ref.
|
|
*/
|
|
export function blogDomSelector(key: BlogDomIdKey) {
|
|
return blogDomSelectorFromId(blogDomId(key));
|
|
}
|
|
|
|
/**
|
|
* @param id Existing DOM id from WordPress, upstream plugins, or generated Argon content.
|
|
* @returns CSS id selector for legacy ids that are externally defined but still queried by app code.
|
|
*/
|
|
export function blogDomSelectorFromId(id: string) {
|
|
return `#${id}`;
|
|
}
|
|
|
|
/**
|
|
* @param key Semantic key for a stable Argon-compatible DOM id.
|
|
* @returns Hash href pointing at the matching local DOM id.
|
|
*/
|
|
export function blogDomAnchor(key: BlogDomIdKey) {
|
|
return blogDomAnchorFromId(blogDomId(key));
|
|
}
|
|
|
|
/**
|
|
* @param id Existing DOM id from WordPress or generated Argon catalog content.
|
|
* @returns Hash href without resolving it through the browser URL.
|
|
*/
|
|
export function blogDomAnchorFromId(id: string) {
|
|
return `#${id}`;
|
|
}
|
|
|
|
/**
|
|
* @param articleId Local article id mirrored as Argon's `post-{id}` card anchor.
|
|
* @returns Stable article card DOM id.
|
|
*/
|
|
export function blogPostCardId(articleId: number | string) {
|
|
return `post-${articleId}`;
|
|
}
|
|
|
|
/**
|
|
* @param index One-based paragraph index in fallback article content.
|
|
* @returns Stable fallback paragraph DOM id.
|
|
*/
|
|
export function blogPostParagraphId(index: number) {
|
|
return `post_paragraph_${index}`;
|
|
}
|
|
|
|
/**
|
|
* @param index One-based heading index produced for WordPress content without preserved heading ids.
|
|
* @returns Stable heading id matching Argon's captured `header-id-N` convention.
|
|
*/
|
|
export function blogGeneratedHeadingId(index: number) {
|
|
return `header-id-${index}`;
|
|
}
|
|
|
|
/**
|
|
* @param filterMode Blog filter preference value rendered in the settings panel.
|
|
* @returns Stable settings filter button id.
|
|
*/
|
|
export function blogSettingsFilterId(filterMode: string) {
|
|
return `blog_setting_filter_${filterMode}`;
|
|
}
|
|
|
|
/**
|
|
* @param postType WordPress search result type rendered in the filter checkbox row.
|
|
* @returns Stable search filter checkbox id.
|
|
*/
|
|
export function blogSearchFilterId(postType: string) {
|
|
return `search_filter_${postType}`;
|
|
}
|
|
|
|
/**
|
|
* @param name Meta tag name controlled by the Blog theme runtime.
|
|
* @returns CSS selector for the matching meta tag.
|
|
*/
|
|
export function blogMetaSelector(name: string) {
|
|
return `meta[name="${name}"]`;
|
|
}
|
|
|
|
/**
|
|
* @param id Concrete DOM id, often from generated WordPress heading anchors.
|
|
* @returns Matching HTMLElement when it exists in the current document.
|
|
*/
|
|
export function getBlogElementById<T extends HTMLElement = HTMLElement>(id: string) {
|
|
return document.getElementById(id) as T | null;
|
|
}
|
|
|
|
/**
|
|
* @returns Shallow Vue ref for DOM nodes whose identity, not deep fields, drives layout side effects.
|
|
*/
|
|
export function createBlogElementRef<T extends HTMLElement = HTMLElement>() {
|
|
return shallowRef<T | null>(null);
|
|
}
|
|
|
|
/**
|
|
* @returns Shallow Vue ref for focusable component instances such as antdv-next inputs.
|
|
*/
|
|
export function createBlogFocusableRef<T = unknown>() {
|
|
return shallowRef<T | null>(null);
|
|
}
|
|
|
|
/**
|
|
* @param target Vue ref callback payload from native elements or component instances.
|
|
* @returns Native HTMLElement only when the callback payload is a real DOM element.
|
|
*/
|
|
export function toBlogHTMLElement(target: Element | ComponentPublicInstance | null) {
|
|
return target instanceof HTMLElement ? target : null;
|
|
}
|
|
|
|
/**
|
|
* @param targetRef Layout-owned HTMLElement ref that cross-component effects read from.
|
|
* @param target Vue ref callback payload emitted by TSX render functions.
|
|
*/
|
|
export function assignBlogElementRef(targetRef: Ref<HTMLElement | null>, target: Element | ComponentPublicInstance | null) {
|
|
targetRef.value = toBlogHTMLElement(target);
|
|
}
|