@tnotesjs/core 0.1.23 → 0.1.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-BSTQOJVE.js → chunk-4KG6RXFS.js} +113 -130
- package/dist/{chunk-O4DCXHOV.js → chunk-AGSL3VZE.js} +1 -4
- package/dist/cli/index.js +162 -173
- package/dist/index.js +1 -1
- package/dist/vitepress/config/index.js +6 -8
- package/package.json +4 -1
- package/types/config.ts +1 -1
- package/types/index.ts +1 -1
- package/types/note.ts +1 -1
- package/vitepress/assets/icons/index.ts +1 -1
- package/vitepress/components/BilibiliOutsidePlayer/BilibiliOutsidePlayer.vue +4 -0
- package/vitepress/components/CodeBlockFullscreen/CodeBlockFullscreen.vue +4 -0
- package/vitepress/components/CodeBlockFullscreen/index.ts +8 -0
- package/vitepress/components/CodeBlockFullscreen/styles.css +4 -0
- package/vitepress/components/Discussions/Discussions.vue +4 -0
- package/vitepress/components/EnWordList/EnWordList.vue +4 -0
- package/vitepress/components/EnWordList/RightClickMenu.vue +4 -0
- package/vitepress/components/Footprints/Footprints.vue +4 -0
- package/vitepress/components/Layout/AboutModal.vue +4 -0
- package/vitepress/components/Layout/AboutPanel.vue +4 -0
- package/vitepress/components/Layout/ContentCollapse.vue +4 -0
- package/vitepress/components/Layout/CustomSidebar.vue +4 -0
- package/vitepress/components/Layout/DocBeforeControls.vue +4 -0
- package/vitepress/components/Layout/DocFooter.vue +4 -0
- package/vitepress/components/Layout/ImagePreview.vue +4 -0
- package/vitepress/components/Layout/Layout.vue +4 -0
- package/vitepress/components/Layout/NavBarSettingsTrigger.vue +4 -0
- package/vitepress/components/Layout/NoteStatus.vue +4 -0
- package/vitepress/components/Layout/SidebarItems.vue +4 -0
- package/vitepress/components/Layout/SidebarNavBefore.vue +4 -0
- package/vitepress/components/Layout/SidebarResizeHandle.vue +65 -4
- package/vitepress/components/Layout/Swiper.vue +4 -0
- package/vitepress/components/Layout/ToggleFullContent.vue +4 -0
- package/vitepress/components/Layout/ToggleSidebar.vue +4 -1
- package/vitepress/components/Layout/composables/useCollapseControl.ts +6 -0
- package/vitepress/components/Layout/composables/useNoteConfig.ts +7 -0
- package/vitepress/components/Layout/composables/useNoteSave.ts +4 -0
- package/vitepress/components/Layout/composables/useNoteValidation.ts +8 -0
- package/vitepress/components/Layout/composables/useRedirect.ts +7 -0
- package/vitepress/components/Layout/composables/useRenameOverlay.ts +3 -0
- package/vitepress/components/Layout/composables/useRenameRedirect.ts +3 -0
- package/vitepress/components/Layout/composables/useSidebarLayout.ts +6 -0
- package/vitepress/components/Layout/composables/useVSCodeIntegration.ts +6 -0
- package/vitepress/components/Layout/homeReadme.data.ts +3 -1
- package/vitepress/components/LoadingPage/LoadingPage.vue +4 -0
- package/vitepress/components/MarkMap/MarkMap.vue +4 -0
- package/vitepress/components/Mermaid/Mermaid.vue +6 -0
- package/vitepress/components/NotesTable/NotesTable.vue +4 -0
- package/vitepress/components/Settings/Settings.vue +6 -0
- package/vitepress/components/Settings/SettingsDialog.vue +6 -0
- package/vitepress/components/Settings/composables/useSettingsDialog.ts +3 -0
- package/vitepress/components/SidebarCard/MindMapView.vue +4 -0
- package/vitepress/components/SidebarCard/NotesTrendChart.vue +4 -0
- package/vitepress/components/SidebarCard/SidebarCard.vue +4 -0
- package/vitepress/components/Tooltip/Tooltip.vue +6 -0
- package/vitepress/components/constants.ts +3 -0
- package/vitepress/components/notesConfig.data.ts +7 -1
- package/vitepress/components/sidebar.data.ts +1 -1
- package/vitepress/components/tnotes-config.data.ts +13 -8
- package/vitepress/components/utils.ts +6 -0
- package/vitepress/config/index.ts +5 -13
- package/vitepress/configs/constants.ts +1 -0
- package/vitepress/configs/head.config.ts +1 -0
- package/vitepress/configs/index.ts +1 -0
- package/vitepress/configs/markdown.config.ts +1 -0
- package/vitepress/configs/theme.config.ts +1 -0
- package/vitepress/plugins/buildProgressPlugin.ts +1 -1
- package/vitepress/plugins/fileWatcherBridgePlugin.ts +2 -1
- package/vitepress/plugins/getNoteByConfigIdPlugin.ts +2 -1
- package/vitepress/plugins/renameNotePlugin.ts +2 -1
- package/vitepress/plugins/sidebarStructurePlugin.ts +3 -2
- package/vitepress/plugins/updateConfigPlugin.ts +2 -1
- package/vitepress/theme/index.ts +1 -4
- package/vitepress/theme/styles/layout.scss +8 -7
|
@@ -1,5 +1,10 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
vitepress/components/Layout/SidebarResizeHandle.vue
|
|
3
|
+
-->
|
|
4
|
+
|
|
1
5
|
<template>
|
|
2
6
|
<div
|
|
7
|
+
v-if="isSidebarAvailable"
|
|
3
8
|
class="sidebar-resize-handle"
|
|
4
9
|
:class="{
|
|
5
10
|
'is-hidden': hidden,
|
|
@@ -30,7 +35,8 @@
|
|
|
30
35
|
</template>
|
|
31
36
|
|
|
32
37
|
<script setup lang="ts">
|
|
33
|
-
import {
|
|
38
|
+
import { useRoute } from 'vitepress'
|
|
39
|
+
import { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
|
34
40
|
|
|
35
41
|
import { useSidebarLayout } from './composables/useSidebarLayout'
|
|
36
42
|
import { icon__next, icon__prev } from '../../assets/icons'
|
|
@@ -46,9 +52,12 @@ const {
|
|
|
46
52
|
saveSidebarWidth,
|
|
47
53
|
} = useSidebarLayout()
|
|
48
54
|
|
|
55
|
+
const route = useRoute()
|
|
49
56
|
const isDragging = ref(false)
|
|
50
57
|
const isContentFullscreen = ref(false)
|
|
58
|
+
const isSidebarAvailable = ref(false)
|
|
51
59
|
const shortcutText = ref('Ctrl + Alt + ,')
|
|
60
|
+
const WIDE_LAYOUT_MIN_WIDTH = 1440
|
|
52
61
|
let fullscreenObserver: MutationObserver | null = null
|
|
53
62
|
|
|
54
63
|
const toggleIcon = computed(() => (hidden.value ? icon__next : icon__prev))
|
|
@@ -62,6 +71,7 @@ const toggleTitle = computed(
|
|
|
62
71
|
onMounted(() => {
|
|
63
72
|
initSidebarLayout()
|
|
64
73
|
shortcutText.value = getShortcutText()
|
|
74
|
+
updateSidebarAvailability()
|
|
65
75
|
updateContentFullscreen()
|
|
66
76
|
fullscreenObserver = new MutationObserver(updateContentFullscreen)
|
|
67
77
|
fullscreenObserver.observe(document.documentElement, {
|
|
@@ -85,13 +95,13 @@ function startResize(event: MouseEvent) {
|
|
|
85
95
|
document.body.classList.add('is-sidebar-resizing')
|
|
86
96
|
window.addEventListener('mousemove', resize)
|
|
87
97
|
window.addEventListener('mouseup', stopResize)
|
|
88
|
-
setSidebarWidth(event.clientX)
|
|
98
|
+
setSidebarWidth(getSidebarWidthFromClientX(event.clientX))
|
|
89
99
|
}
|
|
90
100
|
|
|
91
101
|
function resize(event: MouseEvent) {
|
|
92
102
|
if (!isDragging.value) return
|
|
93
103
|
|
|
94
|
-
setSidebarWidth(event.clientX)
|
|
104
|
+
setSidebarWidth(getSidebarWidthFromClientX(event.clientX))
|
|
95
105
|
}
|
|
96
106
|
|
|
97
107
|
function stopResize() {
|
|
@@ -105,17 +115,60 @@ function stopResize() {
|
|
|
105
115
|
}
|
|
106
116
|
|
|
107
117
|
function handleShortcut(event: KeyboardEvent) {
|
|
108
|
-
if (
|
|
118
|
+
if (
|
|
119
|
+
!isSidebarAvailable.value ||
|
|
120
|
+
!isToggleShortcut(event) ||
|
|
121
|
+
isEditableTarget(event.target)
|
|
122
|
+
) {
|
|
123
|
+
return
|
|
124
|
+
}
|
|
109
125
|
|
|
110
126
|
event.preventDefault()
|
|
111
127
|
toggleSidebar()
|
|
112
128
|
}
|
|
113
129
|
|
|
130
|
+
watch(
|
|
131
|
+
() => route.path,
|
|
132
|
+
async () => {
|
|
133
|
+
await nextTick()
|
|
134
|
+
updateSidebarAvailability()
|
|
135
|
+
updateContentFullscreen()
|
|
136
|
+
},
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
function updateSidebarAvailability() {
|
|
140
|
+
if (typeof document === 'undefined') return
|
|
141
|
+
|
|
142
|
+
isSidebarAvailable.value = Boolean(
|
|
143
|
+
document.querySelector('.VPContent.has-sidebar') &&
|
|
144
|
+
document.querySelector('.VPSidebar'),
|
|
145
|
+
)
|
|
146
|
+
}
|
|
147
|
+
|
|
114
148
|
function updateContentFullscreen() {
|
|
115
149
|
isContentFullscreen.value =
|
|
116
150
|
document.documentElement.classList.contains('content-fullscreen')
|
|
117
151
|
}
|
|
118
152
|
|
|
153
|
+
function getSidebarWidthFromClientX(clientX: number): number {
|
|
154
|
+
return clientX - getSidebarLayoutOffset()
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function getSidebarLayoutOffset(): number {
|
|
158
|
+
if (typeof window === 'undefined' || typeof document === 'undefined') return 0
|
|
159
|
+
if (window.innerWidth < WIDE_LAYOUT_MIN_WIDTH) return 0
|
|
160
|
+
|
|
161
|
+
const layoutMaxWidth = Number.parseFloat(
|
|
162
|
+
window
|
|
163
|
+
.getComputedStyle(document.documentElement)
|
|
164
|
+
.getPropertyValue('--vp-layout-max-width'),
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
if (!Number.isFinite(layoutMaxWidth)) return 0
|
|
168
|
+
|
|
169
|
+
return Math.max(0, (window.innerWidth - layoutMaxWidth) / 2)
|
|
170
|
+
}
|
|
171
|
+
|
|
119
172
|
function isToggleShortcut(event: KeyboardEvent): boolean {
|
|
120
173
|
return (
|
|
121
174
|
(event.ctrlKey || event.metaKey) && event.altKey && event.code === 'Comma'
|
|
@@ -308,4 +361,12 @@ function isEditableTarget(target: EventTarget | null): boolean {
|
|
|
308
361
|
display: none;
|
|
309
362
|
}
|
|
310
363
|
}
|
|
364
|
+
|
|
365
|
+
@media (min-width: 1440px) {
|
|
366
|
+
.sidebar-resize-handle {
|
|
367
|
+
left: calc(
|
|
368
|
+
(100vw - var(--vp-layout-max-width)) / 2 + var(--tn-sidebar-width, 260px) - 5px
|
|
369
|
+
);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
311
372
|
</style>
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* vitepress/components/Layout/composables/useRenameOverlay.ts
|
|
3
|
+
*
|
|
2
4
|
* 全局「重命名遮罩」状态。
|
|
3
5
|
*
|
|
4
6
|
* Layout 顶层渲染 `<LoadingPage />`,由本 store 控制 visible/message/tip,
|
|
5
7
|
* `useRenameRedirect` 调用 show/hide 即可。
|
|
6
8
|
*/
|
|
9
|
+
|
|
7
10
|
import { reactive } from 'vue'
|
|
8
11
|
|
|
9
12
|
export interface RenameOverlayState {
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* vitepress/components/Layout/composables/useRenameRedirect.ts
|
|
3
|
+
*
|
|
2
4
|
* 重命名后跳转工具:显示遮罩 → 等 Vite HMR 重建路由 → 整页跳到新 URL。
|
|
3
5
|
*
|
|
4
6
|
* 关于面板保存与文件系统直接重命名两条入口共用此函数,确保行为一致。
|
|
5
7
|
*/
|
|
8
|
+
|
|
6
9
|
import { useRenameOverlay } from './useRenameOverlay'
|
|
7
10
|
|
|
8
11
|
export interface RedirectAfterRenameOptions {
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* vitepress/components/Settings/composables/useSettingsDialog.ts
|
|
3
|
+
*
|
|
2
4
|
* 全局「设置 Dialog」状态。
|
|
3
5
|
*
|
|
4
6
|
* Layout 顶层渲染 `<SettingsDialog />`,本 store 控制 visible/fullscreen,
|
|
5
7
|
* 任何位置(导航入口、SidebarCard 提示等)调 `open()` 即可弹出,
|
|
6
8
|
* 关闭后停留在当前路由与滚动位置。
|
|
7
9
|
*/
|
|
10
|
+
|
|
8
11
|
import { reactive } from 'vue'
|
|
9
12
|
|
|
10
13
|
export interface SettingsDialogState {
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* vitepress/components/constants.ts
|
|
3
|
+
*
|
|
2
4
|
* 以下常量由 defineNotesConfig() 通过 vite.define 注入
|
|
3
5
|
* 见 vitepress/config/index.ts 中的 define 配置
|
|
4
6
|
*/
|
|
7
|
+
|
|
5
8
|
declare const __TNOTES_REPO_NAME__: string
|
|
6
9
|
declare const __TNOTES_AUTHOR__: string
|
|
7
10
|
declare const __TNOTES_IGNORE_DIRS__: string[]
|
|
@@ -1,21 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* vitepress/components/tnotes-config.data.ts
|
|
3
|
+
*
|
|
4
|
+
* 负责加载和监视 .tnotes.json 配置文件的变化
|
|
5
|
+
* 供 VitePress 组件使用,确保组件能够实时响应配置变更
|
|
6
|
+
*/
|
|
7
|
+
|
|
1
8
|
import fs from 'node:fs'
|
|
2
9
|
import path from 'node:path'
|
|
3
10
|
|
|
4
|
-
|
|
11
|
+
import { validateAndCompleteConfig } from '../../config/defaultConfig'
|
|
5
12
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
repoName?: string
|
|
10
|
-
[key: string]: any
|
|
11
|
-
}
|
|
13
|
+
import type { TNotesConfig } from '../../types'
|
|
14
|
+
|
|
15
|
+
const rootPath = process.cwd()
|
|
12
16
|
|
|
13
17
|
export default {
|
|
14
18
|
watch: [path.resolve(rootPath, '.tnotes.json')],
|
|
15
19
|
load(watchedFiles: string[]): TNotesConfig {
|
|
16
20
|
console.log('[tnotes-config.data.ts] Config loaded')
|
|
17
21
|
const fileContent = fs.readFileSync(watchedFiles[0], 'utf-8')
|
|
18
|
-
const
|
|
22
|
+
const rawConfig = JSON.parse(fileContent)
|
|
23
|
+
const { config } = validateAndCompleteConfig(rawConfig)
|
|
19
24
|
return config
|
|
20
25
|
},
|
|
21
26
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* vitepress/config/index.ts
|
|
3
3
|
*
|
|
4
4
|
* VitePress 站点配置工厂函数
|
|
5
5
|
*
|
|
@@ -7,10 +7,12 @@
|
|
|
7
7
|
* import { defineNotesConfig } from './tnotes/vitepress/config'
|
|
8
8
|
* export default defineNotesConfig()
|
|
9
9
|
*/
|
|
10
|
+
|
|
10
11
|
import fs from 'fs'
|
|
11
12
|
import path from 'path'
|
|
12
13
|
import { defineConfig, type UserConfig } from 'vitepress'
|
|
13
14
|
|
|
15
|
+
import { ConfigManager } from '../../config/ConfigManager'
|
|
14
16
|
import {
|
|
15
17
|
getIgnoreList,
|
|
16
18
|
getGithubPageUrl,
|
|
@@ -25,17 +27,6 @@ import { renameNotePlugin } from '../plugins/renameNotePlugin'
|
|
|
25
27
|
import { sidebarStructurePlugin } from '../plugins/sidebarStructurePlugin'
|
|
26
28
|
import { updateConfigPlugin } from '../plugins/updateConfigPlugin'
|
|
27
29
|
|
|
28
|
-
import type { TNotesConfig } from '../../types'
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* 读取 .tnotes.json 配置文件
|
|
32
|
-
*/
|
|
33
|
-
function loadTNotesConfig(rootPath: string): TNotesConfig {
|
|
34
|
-
const configPath = path.resolve(rootPath, '.tnotes.json')
|
|
35
|
-
const configContent = fs.readFileSync(configPath, 'utf-8')
|
|
36
|
-
return JSON.parse(configContent) as TNotesConfig
|
|
37
|
-
}
|
|
38
|
-
|
|
39
30
|
/**
|
|
40
31
|
* 创建 VitePress 站点配置
|
|
41
32
|
*
|
|
@@ -44,7 +35,8 @@ function loadTNotesConfig(rootPath: string): TNotesConfig {
|
|
|
44
35
|
*/
|
|
45
36
|
export function defineNotesConfig(overrides: UserConfig = {}) {
|
|
46
37
|
const rootPath = process.cwd()
|
|
47
|
-
|
|
38
|
+
ConfigManager.init({ rootPath })
|
|
39
|
+
const config = ConfigManager.getInstance().getAll()
|
|
48
40
|
const { repoName } = config
|
|
49
41
|
|
|
50
42
|
const IGNORE_LIST = getIgnoreList(config)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* vitepress/plugins/fileWatcherBridgePlugin.ts
|
|
3
3
|
*
|
|
4
4
|
* file-watcher 与浏览器之间的 IPC 桥。
|
|
5
5
|
*
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* 两者无法共享单例。文件夹直接重命名后,file-watcher 会 fetch 本接口,
|
|
8
8
|
* 本接口调 `server.ws.send` 向浏览器广播 `tnotes:note-renamed`。
|
|
9
9
|
*/
|
|
10
|
+
|
|
10
11
|
import type { PluginOption } from 'vite'
|
|
11
12
|
|
|
12
13
|
const RENAME_EVENT = 'tnotes:note-renamed'
|