diff --git a/public/i18n/en_US.yaml b/public/i18n/en_US.yaml index 92d1f3f..6aa906b 100644 --- a/public/i18n/en_US.yaml +++ b/public/i18n/en_US.yaml @@ -27,6 +27,9 @@ setting: autoRefreshOnExpand: title: Auto Refresh on Expand description: Automatically refreshes the items within a dynamic group when it is expanded from a collapsed state. + ariaLabel: + title: Display Hover Box + description: Display full title of the bookmark item in a hover box when the mouse hovers viewMode: bookmark: Bookmark Style card: Card Style diff --git a/public/i18n/zh_CN.yaml b/public/i18n/zh_CN.yaml index 6598579..5fc870c 100644 --- a/public/i18n/zh_CN.yaml +++ b/public/i18n/zh_CN.yaml @@ -27,6 +27,9 @@ setting: autoRefreshOnExpand: title: 展开后刷新 description: 展开一个被折叠的动态组时,自动刷新其中的内容 + ariaLabel: + title: 显示悬浮框 + description: 鼠标悬停在书签项目上时,在悬浮框中显示书签项目的完整标题 viewMode: bookmark: 书签样式 card: 卡片样式 diff --git a/src/components/group.tsx b/src/components/group.tsx index 9261fa6..5a7c04d 100644 --- a/src/components/group.tsx +++ b/src/components/group.tsx @@ -12,6 +12,7 @@ import { i18n, renderI18n } from "@/utils/i18n"; import Item from "./item"; import { groups, setGroups, configs, itemInfo } from "../model"; import { BookmarkContext, itemMoving, setItemMoving, groupDrop, setGroupDrop } from "./context"; +import { getActiveDoc } from "@/utils"; interface Props { @@ -281,18 +282,7 @@ const Group: Component = (props) => { label: i18n_.currentdoc, icon: "iconAdd", click: () => { - let wnd = document.querySelector('div.layout__wnd--active[data-type="wnd"]'); - let container = wnd ?? document; - const li = container.querySelector( - "ul.layout-tab-bar>li.item--focus" - ); - if (!li) return; - const dataId = li.getAttribute("data-id"); - const protyle = document.querySelector( - `div.protyle[data-id="${dataId}"] .protyle-title` - ); - if (!protyle) return; - const id = protyle.getAttribute("data-node-id"); + let id = getActiveDoc(); addItemByBlockId(id); }, }); diff --git a/src/components/item.tsx b/src/components/item.tsx index e473699..06b3e87 100644 --- a/src/components/item.tsx +++ b/src/components/item.tsx @@ -3,7 +3,7 @@ import { render } from "solid-js/web"; import { Menu, openTab, showMessage } from "siyuan"; import { buildItemDetail } from "../libs/dom"; -import { itemInfo, setGroups, groupMap } from "../model"; +import { itemInfo, setGroups, groupMap, configs } from "../model"; import { BookmarkContext, itemMoving, setItemMoving } from "./context"; @@ -61,6 +61,8 @@ const showErrItem = (item: IBookmarkItemInfo) => { }); } +// const ariaLabel = () => `Callout 插件 10.07 kB
更新于 2024-07-18 15:36:20, 3 天前
创建于 2024-06-29 19:09:50, 3 个星期前`; + const Item: Component = (props) => { const item = () => itemInfo[props.itemCore.id]; @@ -85,6 +87,14 @@ const Item: Component = (props) => { } }); + const notebook = createMemo(() => { + return getNotebook(item().box).name; + }) + + const hoverContext = createMemo(() => { + return `${notebook()}
${item().title}`; + }); + createEffect(() => { let value = item(); if (value) { @@ -316,7 +326,13 @@ const Item: Component = (props) => {
- + {item().title} { }} /> + + { + setConfigs('ariaLabel', v); + }} + /> + { model.save(); diff --git a/src/libs/components/item-input.tsx b/src/libs/components/item-input.tsx index 6c65561..c19c52f 100644 --- a/src/libs/components/item-input.tsx +++ b/src/libs/components/item-input.tsx @@ -1,4 +1,4 @@ -import { createMemo } from "solid-js"; +import { createMemo, For } from "solid-js"; interface IProps extends ISettingItemCore { changed: (v?: any) => void; @@ -23,7 +23,7 @@ export default function InputItem(props: IProps) { styles = { resize: "vertical", height: '10rem', "white-space": "nowrap" }; } let propstyle = props.style ?? {}; - styles = {...styles, ...propstyle}; + styles = { ...styles, ...propstyle }; return { style: styles }; @@ -102,14 +102,15 @@ export default function InputItem(props: IProps) { classList={{ fn__size200: fn_size }} {...attrStyle()} id={props.key} - value={props.value} onChange={(e) => { changed(e.currentTarget.value); }} > - {Object.entries(props.options).map(([optionValue, text]) => ( - - ))} + + {([optionValue, text]) => ( + + )} + ); } else if (props.type === "slider") { diff --git a/src/libs/template.ts b/src/libs/template.ts new file mode 100644 index 0000000..19aca5c --- /dev/null +++ b/src/libs/template.ts @@ -0,0 +1,41 @@ +import { getActiveDoc } from "@/utils"; + +type TVarName = string; +type TVars = Record string | null>; + + +const DefaultVars: TVars = { + 'yyyy': () => new Date().getFullYear().toString(), + 'mm': () => (new Date().getMonth() + 1).toString().padStart(2, '0'), + 'dd': () => new Date().getDate().toString().padStart(2, '0'), + 'docid': () => getActiveDoc(), +} + +/** + * 将所有模板变量替换为实际的值 + * 模板变量使用 {{\s*(...)\s*}} 包裹 + * 默认模板变量: + * - yyyy: 当前年份 + * - mm: 当前月份 + * - dd: 当前日期 + * - docid: 当前激活中的文档的 id + * @param template 模板字符串 + * @param vars 自定义模板变量 + * @returns (string | null) 替换后的字符串; 如果有模板变量没有被正确替换, 则返回 null + */ +const renderTemplate = (template: string, vars?: TVars): string => { + vars = vars ?? {}; + vars = { ...DefaultVars, ...vars }; + let result = template; + for (const [varName, evaluate] of Object.entries(vars)) { + const varReg = new RegExp(`{{\\s*${varName}\\s*}}`, 'g'); + let value = evaluate(); + if (value === null || value === undefined) return null; + result = result.replace(varReg, value); + } + return result; +} + +export { + renderTemplate +}; diff --git a/src/model/stores.ts b/src/model/stores.ts index 2701122..29967ea 100644 --- a/src/model/stores.ts +++ b/src/model/stores.ts @@ -23,6 +23,7 @@ interface IConfig { viewMode: 'bookmark' | 'card'; replaceDefault: boolean; autoRefreshOnExpand: boolean; + ariaLabel: boolean; } export const [configs, setConfigs] = createStore({ @@ -30,5 +31,6 @@ export const [configs, setConfigs] = createStore({ hideDeleted: true, viewMode: 'bookmark', replaceDefault: true, - autoRefreshOnExpand: false + autoRefreshOnExpand: false, + ariaLabel: false, }); diff --git a/src/utils/index.ts b/src/utils/index.ts index 08aeec2..54bcb4c 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -3,7 +3,7 @@ * @Author : frostime * @Date : 2024-04-18 21:05:32 * @FilePath : /src/utils/index.ts - * @LastEditTime : 2024-06-14 13:37:22 + * @LastEditTime : 2024-07-20 18:17:00 * @Description : */ import * as api from '../api'; @@ -27,21 +27,20 @@ export const getNotebook = (boxId: string): Notebook => { } } -export function getActiveDoc() { - let tab = document.querySelector("div.layout__wnd--active ul.layout-tab-bar>li.item--focus"); - let dataId: string = tab?.getAttribute("data-id"); - if (!dataId) { - return null; - } - const activeTab: HTMLDivElement = document.querySelector( - `.layout-tab-container.fn__flex-1>div.protyle[data-id="${dataId}"]` - ) as HTMLDivElement; - if (!activeTab) { - return; - } - const eleTitle = activeTab.querySelector(".protyle-title"); - let docId = eleTitle?.getAttribute("data-node-id"); - return docId; +export function getActiveDoc(): DocumentId { + let wnd = document.querySelector('div.layout__wnd--active[data-type="wnd"]'); + let container = wnd ?? document; + const li = container.querySelector( + "ul.layout-tab-bar>li.item--focus" + ); + if (!li) return; + const dataId = li.getAttribute("data-id"); + const protyle = document.querySelector( + `div.protyle[data-id="${dataId}"] .protyle-title` + ); + if (!protyle) return; + const id = protyle.getAttribute("data-node-id"); + return id; } export function isnot(value: any) {