77 * of this license document, but changing it is not allowed.
88 */
99
10+ import { JsonUtil , StrUtil } from "zhi-common"
11+
12+ const getFoldInner = ( foldBlocksDatas : any , foldEl : any ) => {
13+ const foldBlockId = foldEl . getAttribute ( "data-node-id" )
14+
15+ if ( ! foldBlockId || ! foldBlocksDatas ) {
16+ return null
17+ }
18+
19+ const foldBlock = foldBlocksDatas . foldBlockMap [ foldBlockId ]
20+
21+ if ( ! foldBlock ) {
22+ return null
23+ }
24+
25+ return foldBlock
26+ }
27+
1028const addToggleFoldButton = ( el : HTMLElement ) => {
11- // 获取所有具有 fold="1" 属性的 div 元素
12- const divs = el . querySelectorAll ( "div[fold='1']" )
29+ // 从data-foldblocks取数据
30+ const foldBlocksStr = el . getAttribute ( "data-foldblocks" )
31+ const foldBlocksDatas = JsonUtil . safeParse < any > ( foldBlocksStr , { } as any )
1332
33+ // 获取所有具有 fold="1" 属性的 div 元素
34+ const foldBlocks = el . querySelectorAll ( "div[fold='1']" )
1435 // 遍历每个 div 元素,添加按钮并设置事件监听器
15- divs . forEach ( ( div ) => {
16- // 创建 div 元素作为按钮
36+ foldBlocks . forEach ( ( foldEl ) => {
37+ const foldBlockId = foldEl . getAttribute ( "data-node-id" )
38+
39+ // 创建切换按钮
1740 const toggleButton = document . createElement ( "div" )
1841 toggleButton . textContent = "+展开" // 默认文本为 +展开
1942 toggleButton . classList . add ( "fold-block-toggle-button" ) // 使用 fold-block- 前缀
2043
2144 // 获取 div 的父元素
22- const parent = div . parentNode
23- if ( ! parent ) { return }
45+ const parent = foldEl . parentNode
46+ if ( ! parent ) {
47+ return
48+ }
2449
2550 // 创建一个容器包裹按钮和原始元素,避免破坏 DOM 结构
2651 const wrapper = document . createElement ( "div" )
27- wrapper . style . display = "flex" // 横向排列
28- wrapper . style . alignItems = "baseline"
29- parent . insertBefore ( wrapper , div )
52+ wrapper . classList . add ( "fold-block-wrapper" )
53+ // 标题不能 flex
54+ if ( foldEl . getAttribute ( "data-type" ) === "NodeHeading" ) {
55+ wrapper . style . display = "block"
56+ }
57+
58+ // 插入按钮和原始元素
59+ parent . insertBefore ( wrapper , foldEl )
3060 wrapper . appendChild ( toggleButton )
31- wrapper . appendChild ( div )
61+ wrapper . appendChild ( foldEl )
3262
3363 // 为按钮添加点击事件
3464 toggleButton . addEventListener ( "click" , ( ) => {
35- // 如果 fold 属性是 "1",则更改为 "0"
36- if ( div . getAttribute ( "fold" ) === "1" ) {
37- div . setAttribute ( "fold" , "0" )
65+ const isFolded = foldEl . getAttribute ( "fold" ) === "1"
66+
67+ // 如果当前是折叠状态
68+ if ( isFolded ) {
69+ foldEl . setAttribute ( "fold" , "0" )
3870 toggleButton . textContent = "-收起" // 切换按钮为 -收起
71+
72+ // 获取需要追加的 HTML 内容,可能为空
73+ const newContent = getFoldInner ( foldBlocksDatas , foldEl )
74+ // 如果 newContent 有值,动态创建并插入内容
75+ if ( ! StrUtil . isEmptyString ( newContent ) ) {
76+ // 用于存储动态追加的内容
77+ const foldInner : HTMLElement | null = document . createElement ( "div" )
78+ foldInner . id = "fold-inner-" + foldBlockId
79+ foldInner . innerHTML = newContent || "" // 即使是空内容,也插入空元素
80+ foldInner . classList . add ( "fold-inner" ) // 为追加的内容添加特定的类名
81+
82+ // 获取 foldEl 的父元素
83+ const parent = foldEl . parentNode
84+ if ( parent ) {
85+ // 将 foldInner 插入到 foldEl 的下一个兄弟元素位置
86+ parent . insertBefore ( foldInner , foldEl . nextSibling )
87+ }
88+ }
3989 } else {
40- div . setAttribute ( "fold" , "1" )
90+ // 当前是展开状态
91+ foldEl . setAttribute ( "fold" , "1" )
4192 toggleButton . textContent = "+展开" // 切换按钮为 +展开
93+
94+ // 展开状态时,删除动态追加的内容
95+ const foldInner = foldEl . parentNode ?. querySelector ( `#fold-inner-${ foldBlockId } ` )
96+ if ( foldInner ) {
97+ foldEl . parentNode ?. removeChild ( foldInner )
98+ }
4299 }
43100 } )
44101 } )
@@ -59,7 +116,6 @@ export default defineNuxtPlugin(({ vueApp }) => {
59116 vueApp . directive ( "fold" , {
60117 mounted ( el , binding ) {
61118 addToggleFoldButton ( el )
62- logger . info ( "fold directive mounted" )
63119 }
64120 } )
65121} )
0 commit comments