@remloyal/docsify-plugins 1.0.0
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/LICENSE +21 -0
- package/README.md +72 -0
- package/dist/flexsearch/docsify-flexsearch.css +248 -0
- package/dist/flexsearch/docsify-flexsearch.js +4614 -0
- package/dist/flexsearch/docsify-flexsearch.min.css +2 -0
- package/dist/flexsearch/docsify-flexsearch.min.css.map +1 -0
- package/dist/flexsearch/docsify-flexsearch.min.js +8 -0
- package/dist/flexsearch/docsify-flexsearch.min.js.map +1 -0
- package/dist/sidebar-collapse/docsify-sidebar-collapse.css +25 -0
- package/dist/sidebar-collapse/docsify-sidebar-collapse.js +193 -0
- package/dist/sidebar-collapse/docsify-sidebar-collapse.min.css +2 -0
- package/dist/sidebar-collapse/docsify-sidebar-collapse.min.css.map +1 -0
- package/dist/sidebar-collapse/docsify-sidebar-collapse.min.js +8 -0
- package/dist/sidebar-collapse/docsify-sidebar-collapse.min.js.map +1 -0
- package/package.json +60 -0
- package/src/flexsearch/index.js +822 -0
- package/src/flexsearch/markdown-to-txt.js +206 -0
- package/src/flexsearch/style.css +247 -0
- package/src/sidebar-collapse/index.js +11 -0
- package/src/sidebar-collapse/sidebar-collapse-plugin.js +251 -0
- package/src/sidebar-collapse/sidebar.css +27 -0
- package/src/sidebar-collapse/style.css +25 -0
- package/src/utils/utils.js +96 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
.sidebar-nav > ul > li ul {
|
|
2
|
+
display: none;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.app-sub-sidebar {
|
|
6
|
+
display: none;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.app-sub-sidebar.open {
|
|
10
|
+
display: block;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.sidebar-nav .open > ul:not(.app-sub-sidebar),
|
|
14
|
+
.sidebar-nav .active:not(.collapse) > ul {
|
|
15
|
+
display: block;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/* 抖动 */
|
|
19
|
+
.sidebar-nav li.open:not(.collapse) > ul {
|
|
20
|
+
display: block;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.active + ul.app-sub-sidebar {
|
|
24
|
+
display: block;
|
|
25
|
+
}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Docsify Plugin: sidebar-collapse v1.0.0
|
|
3
|
+
* https://github.com/remloyal/docsify-plugins#readme
|
|
4
|
+
* (c) 2017-2026
|
|
5
|
+
* MIT license
|
|
6
|
+
*/
|
|
7
|
+
(function() {
|
|
8
|
+
"use strict";
|
|
9
|
+
let isFirstLoad = true;
|
|
10
|
+
const sidebarCollapseState = {};
|
|
11
|
+
function sidebarCollapsePlugin(hook, vm) {
|
|
12
|
+
hook.doneEach(function(html, next) {
|
|
13
|
+
const activeNode = getActiveNode();
|
|
14
|
+
openActiveToRoot(activeNode);
|
|
15
|
+
addFolderFileClass();
|
|
16
|
+
isFirstLoad && addLevelClass();
|
|
17
|
+
syncScrollTop(activeNode);
|
|
18
|
+
restoreCollapseState(activeNode);
|
|
19
|
+
next(html);
|
|
20
|
+
});
|
|
21
|
+
hook.ready(function() {
|
|
22
|
+
collectInitialCollapseState();
|
|
23
|
+
document.querySelector(".sidebar-nav").addEventListener("click", handleMenuClick);
|
|
24
|
+
setTimeout(() => {
|
|
25
|
+
const activeNode = getActiveNode();
|
|
26
|
+
restoreCollapseState(activeNode);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
function init() {
|
|
31
|
+
document.addEventListener("scroll", scrollSyncMenuStatus);
|
|
32
|
+
}
|
|
33
|
+
let lastTop;
|
|
34
|
+
function syncScrollTop(activeNode) {
|
|
35
|
+
if (activeNode && lastTop != undefined) {
|
|
36
|
+
const curTop = activeNode.getBoundingClientRect().top;
|
|
37
|
+
document.querySelector(".sidebar").scrollBy(0, curTop - lastTop);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function scrollSyncMenuStatus() {
|
|
41
|
+
requestAnimationFrame(() => {
|
|
42
|
+
let el = document.querySelector(".app-sub-sidebar > .active");
|
|
43
|
+
if (el) {
|
|
44
|
+
el.parentNode.parentNode.querySelectorAll(".app-sub-sidebar").forEach(dom => dom.classList.remove("open"));
|
|
45
|
+
while (el.parentNode.classList.contains("app-sub-sidebar")) {
|
|
46
|
+
if (el.parentNode.classList.contains("open")) {
|
|
47
|
+
break;
|
|
48
|
+
} else {
|
|
49
|
+
el.parentNode.classList.add("open");
|
|
50
|
+
el = el.parentNode;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
function handleMenuClick(e) {
|
|
57
|
+
lastTop = e.target.getBoundingClientRect().top;
|
|
58
|
+
const targetNode = e.target.tagName === "A" ? e.target.parentNode : e.target;
|
|
59
|
+
const newActiveNode = findTagParent(targetNode, "LI", 2);
|
|
60
|
+
if (!newActiveNode) return;
|
|
61
|
+
const nodeHref = newActiveNode.querySelector("a")?.getAttribute("href");
|
|
62
|
+
if (!nodeHref) return;
|
|
63
|
+
if (newActiveNode.classList.contains("open")) {
|
|
64
|
+
newActiveNode.classList.remove("open");
|
|
65
|
+
setTimeout(() => {
|
|
66
|
+
newActiveNode.classList.add("collapse");
|
|
67
|
+
}, 0);
|
|
68
|
+
sidebarCollapseState[nodeHref] = "collapse";
|
|
69
|
+
} else {
|
|
70
|
+
removeOpenToRoot(getActiveNode());
|
|
71
|
+
openActiveToRoot(newActiveNode);
|
|
72
|
+
setTimeout(() => {
|
|
73
|
+
newActiveNode.classList.remove("collapse");
|
|
74
|
+
}, 0);
|
|
75
|
+
sidebarCollapseState[nodeHref] = "open";
|
|
76
|
+
}
|
|
77
|
+
syncScrollTop(newActiveNode);
|
|
78
|
+
}
|
|
79
|
+
function getActiveNode() {
|
|
80
|
+
let node = document.querySelector(".sidebar-nav .active");
|
|
81
|
+
if (!node) {
|
|
82
|
+
const curHref = decodeURIComponent(location.hash).replace(/ /gi, "%20");
|
|
83
|
+
const curLink = document.querySelector(`.sidebar-nav a[href="${curHref}"]`);
|
|
84
|
+
node = findTagParent(curLink, "LI", 2);
|
|
85
|
+
if (node) {
|
|
86
|
+
node.classList.add("active");
|
|
87
|
+
const nodeHref = node.querySelector("a")?.getAttribute("href");
|
|
88
|
+
nodeHref && (sidebarCollapseState[nodeHref] = "open");
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return node;
|
|
92
|
+
}
|
|
93
|
+
function openActiveToRoot(node) {
|
|
94
|
+
if (node) {
|
|
95
|
+
node.classList.add("open", "active");
|
|
96
|
+
while (node && node.className !== "sidebar-nav" && node.parentNode) {
|
|
97
|
+
if (node.parentNode.tagName === "LI" || node.parentNode.className === "app-sub-sidebar") {
|
|
98
|
+
node.parentNode.classList.add("open");
|
|
99
|
+
}
|
|
100
|
+
node = node.parentNode;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
function removeOpenToRoot(node) {
|
|
105
|
+
if (node) {
|
|
106
|
+
node.classList.remove("open", "active");
|
|
107
|
+
while (node && node.className !== "sidebar-nav" && node.parentNode) {
|
|
108
|
+
if (node.parentNode.tagName === "LI" || node.parentNode.className === "app-sub-sidebar") {
|
|
109
|
+
node.parentNode.classList.remove("open");
|
|
110
|
+
}
|
|
111
|
+
node = node.parentNode;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
function findTagParent(curNode, tagName, level) {
|
|
116
|
+
if (curNode && curNode.tagName === tagName) return curNode;
|
|
117
|
+
let l = 0;
|
|
118
|
+
while (curNode) {
|
|
119
|
+
l++;
|
|
120
|
+
if (l > level) return;
|
|
121
|
+
if (curNode.parentNode.tagName === tagName) {
|
|
122
|
+
return curNode.parentNode;
|
|
123
|
+
}
|
|
124
|
+
curNode = curNode.parentNode;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
function addFolderFileClass() {
|
|
128
|
+
document.querySelectorAll(".sidebar-nav li").forEach(li => {
|
|
129
|
+
if (li.querySelector("ul:not(.app-sub-sidebar)")) {
|
|
130
|
+
li.classList.add("folder");
|
|
131
|
+
} else {
|
|
132
|
+
li.classList.add("file");
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
function addLevelClass() {
|
|
137
|
+
function find(root, level) {
|
|
138
|
+
root && root.childNodes && root.childNodes.forEach(child => {
|
|
139
|
+
if (child.classList && child.classList.contains("folder")) {
|
|
140
|
+
child.classList.add(`level-${level}`);
|
|
141
|
+
const firstOpenLevel = window.$docsify?.sidebarFirstOpenLevel || window.$docsify?.sidebarDisplayLevel;
|
|
142
|
+
if (firstOpenLevel && typeof firstOpenLevel === "number" && level <= firstOpenLevel) {
|
|
143
|
+
child.classList.add("open");
|
|
144
|
+
const nodeHref = child.querySelector("a")?.getAttribute("href");
|
|
145
|
+
nodeHref && (sidebarCollapseState[nodeHref] = "open");
|
|
146
|
+
}
|
|
147
|
+
if (child && child.childNodes.length > 1) {
|
|
148
|
+
find(child.childNodes[1], level + 1);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
find(document.querySelector(".sidebar-nav > ul"), 1);
|
|
154
|
+
isFirstLoad = false;
|
|
155
|
+
}
|
|
156
|
+
function restoreCollapseState(activeNode) {
|
|
157
|
+
const activeHref = activeNode?.querySelector("a")?.getAttribute("href");
|
|
158
|
+
document.querySelectorAll(".sidebar-nav li.folder, .sidebar-nav li.file").forEach(li => {
|
|
159
|
+
const nodeHref = li.querySelector("a")?.getAttribute("href");
|
|
160
|
+
if (!nodeHref || nodeHref === activeHref) return;
|
|
161
|
+
const saveState = sidebarCollapseState[nodeHref];
|
|
162
|
+
if (saveState) {
|
|
163
|
+
li.classList.remove(saveState === "open" ? "collapse" : "open");
|
|
164
|
+
li.classList.add(saveState);
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
function collectInitialCollapseState() {
|
|
169
|
+
const allSidebarNodes = document.querySelectorAll(".sidebar-nav li.folder, .sidebar-nav li.file");
|
|
170
|
+
allSidebarNodes.forEach(li => {
|
|
171
|
+
const aTag = li.querySelector("a");
|
|
172
|
+
const nodeHref = aTag?.getAttribute("href");
|
|
173
|
+
if (!nodeHref) return;
|
|
174
|
+
let initialState = "collapse";
|
|
175
|
+
if (li.classList.contains("open")) {
|
|
176
|
+
initialState = "open";
|
|
177
|
+
} else if (li.classList.contains("collapse")) {
|
|
178
|
+
initialState = "collapse";
|
|
179
|
+
}
|
|
180
|
+
sidebarCollapseState[nodeHref] = initialState;
|
|
181
|
+
});
|
|
182
|
+
console.log("侧边栏初始状态收集完成:", sidebarCollapseState);
|
|
183
|
+
}
|
|
184
|
+
init();
|
|
185
|
+
function install(...plugins) {
|
|
186
|
+
if (!window.$docsify) {
|
|
187
|
+
console.error("这是一个docsify插件,请先引用docsify库!");
|
|
188
|
+
} else {
|
|
189
|
+
$docsify.plugins = plugins.concat($docsify.plugins || []);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
install(sidebarCollapsePlugin);
|
|
193
|
+
})();
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
.app-sub-sidebar,.sidebar-nav>ul>li ul{display:none}.active+ul.app-sub-sidebar,.app-sub-sidebar.open,.sidebar-nav .active:not(.collapse)>ul,.sidebar-nav .open>ul:not(.app-sub-sidebar),.sidebar-nav li.open:not(.collapse)>ul{display:block}
|
|
2
|
+
/*# sourceMappingURL=docsify-sidebar-collapse.min.css.map */
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["style.css"],"names":[],"mappings":"AAIA,uCACE,YACF,CAgBA,2KACE,aACF","file":"docsify-sidebar-collapse.min.css","sourcesContent":[".sidebar-nav > ul > li ul {\n display: none;\n}\n\n.app-sub-sidebar {\n display: none;\n}\n\n.app-sub-sidebar.open {\n display: block;\n}\n\n.sidebar-nav .open > ul:not(.app-sub-sidebar),\n.sidebar-nav .active:not(.collapse) > ul {\n display: block;\n}\n\n/* 抖动 */\n.sidebar-nav li.open:not(.collapse) > ul {\n display: block;\n}\n\n.active + ul.app-sub-sidebar {\n display: block;\n}"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Docsify Plugin: sidebar-collapse v1.0.0
|
|
3
|
+
* https://github.com/remloyal/docsify-plugins#readme
|
|
4
|
+
* (c) 2017-2026
|
|
5
|
+
* MIT license
|
|
6
|
+
*/
|
|
7
|
+
!function(){"use strict";let e=!0;const t={};let o;function s(e){if(e&&null!=o){const t=e.getBoundingClientRect().top;document.querySelector(".sidebar").scrollBy(0,t-o)}}function a(){requestAnimationFrame(()=>{let e=document.querySelector(".app-sub-sidebar > .active");if(e)for(e.parentNode.parentNode.querySelectorAll(".app-sub-sidebar").forEach(e=>e.classList.remove("open"));e.parentNode.classList.contains("app-sub-sidebar")&&!e.parentNode.classList.contains("open");)e.parentNode.classList.add("open"),e=e.parentNode})}function n(e){o=e.target.getBoundingClientRect().top;const a=i("A"===e.target.tagName?e.target.parentNode:e.target,"LI",2);if(!a)return;const n=a.querySelector("a")?.getAttribute("href");n&&(a.classList.contains("open")?(a.classList.remove("open"),setTimeout(()=>{a.classList.add("collapse")},0),t[n]="collapse"):(!function(e){if(e)for(e.classList.remove("open","active");e&&"sidebar-nav"!==e.className&&e.parentNode;)"LI"!==e.parentNode.tagName&&"app-sub-sidebar"!==e.parentNode.className||e.parentNode.classList.remove("open"),e=e.parentNode}(r()),c(a),setTimeout(()=>{a.classList.remove("collapse")},0),t[n]="open"),s(a))}function r(){let e=document.querySelector(".sidebar-nav .active");if(!e){const o=decodeURIComponent(location.hash).replace(/ /gi,"%20");if(e=i(document.querySelector(`.sidebar-nav a[href="${o}"]`),"LI",2),e){e.classList.add("active");const o=e.querySelector("a")?.getAttribute("href");o&&(t[o]="open")}}return e}function c(e){if(e)for(e.classList.add("open","active");e&&"sidebar-nav"!==e.className&&e.parentNode;)"LI"!==e.parentNode.tagName&&"app-sub-sidebar"!==e.parentNode.className||e.parentNode.classList.add("open"),e=e.parentNode}function i(e,t,o){if(e&&e.tagName===t)return e;let s=0;for(;e;){if(s++,s>o)return;if(e.parentNode.tagName===t)return e.parentNode;e=e.parentNode}}function l(e){const o=e?.querySelector("a")?.getAttribute("href");document.querySelectorAll(".sidebar-nav li.folder, .sidebar-nav li.file").forEach(e=>{const s=e.querySelector("a")?.getAttribute("href");if(!s||s===o)return;const a=t[s];a&&(e.classList.remove("open"===a?"collapse":"open"),e.classList.add(a))})}document.addEventListener("scroll",a),function(...e){window.$docsify?$docsify.plugins=e.concat($docsify.plugins||[]):console.error("这是一个docsify插件,请先引用docsify库!")}(function(o,a){o.doneEach(function(o,a){const n=r();c(n),document.querySelectorAll(".sidebar-nav li").forEach(e=>{e.querySelector("ul:not(.app-sub-sidebar)")?e.classList.add("folder"):e.classList.add("file")}),e&&function(){function o(e,s){e&&e.childNodes&&e.childNodes.forEach(e=>{if(e.classList&&e.classList.contains("folder")){e.classList.add(`level-${s}`);const a=window.$docsify?.sidebarFirstOpenLevel||window.$docsify?.sidebarDisplayLevel;if(a&&"number"==typeof a&&s<=a){e.classList.add("open");const o=e.querySelector("a")?.getAttribute("href");o&&(t[o]="open")}e&&e.childNodes.length>1&&o(e.childNodes[1],s+1)}})}o(document.querySelector(".sidebar-nav > ul"),1),e=!1}(),s(n),l(n),a(o)}),o.ready(function(){document.querySelectorAll(".sidebar-nav li.folder, .sidebar-nav li.file").forEach(e=>{const o=e.querySelector("a"),s=o?.getAttribute("href");if(!s)return;let a="collapse";e.classList.contains("open")?a="open":e.classList.contains("collapse")&&(a="collapse"),t[s]=a}),console.log("侧边栏初始状态收集完成:",t),document.querySelector(".sidebar-nav").addEventListener("click",n),setTimeout(()=>{l(r())})})})}();
|
|
8
|
+
//# sourceMappingURL=docsify-sidebar-collapse.min.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docsify-sidebar-collapse.min.js","sources":["../../src/sidebar-collapse/sidebar-collapse-plugin.js","../../src/sidebar-collapse/index.js"],"sourcesContent":["import \"./style.css\";\n\n// 首次加载标记 - 控制层级仅首次展开\nlet isFirstLoad = true;\n// 全局侧边栏折叠状态对象,持久化每个节点状态(键:href,值:open/collapse)\nconst sidebarCollapseState = {};\n\nfunction sidebarCollapsePlugin(hook, vm) {\n hook.doneEach(function (html, next) {\n const activeNode = getActiveNode();\n // 自动展开当前激活项的根层级(核心体验保留)\n openActiveToRoot(activeNode);\n\n addFolderFileClass();\n // 仅首次加载执行层级类添加+初始展开\n isFirstLoad && addLevelClass();\n syncScrollTop(activeNode);\n\n // doneEach最后恢复折叠状态,避免自动逻辑覆盖\n restoreCollapseState(activeNode);\n\n next(html);\n });\n hook.ready(function () {\n // 1. 关键:hook.ready中先收集全量初始状态(DOM已完整,仅执行一次)\n collectInitialCollapseState();\n // 2. 再绑定点击事件,确保初始状态收集完成后再处理用户操作\n document\n .querySelector(\".sidebar-nav\")\n .addEventListener(\"click\", handleMenuClick);\n setTimeout(() => {\n const activeNode = getActiveNode();\n restoreCollapseState(activeNode);\n });\n });\n}\n\nfunction init() {\n document.addEventListener(\"scroll\", scrollSyncMenuStatus);\n}\n\nlet lastTop; // 侧边栏滚动状态\nfunction syncScrollTop(activeNode) {\n if (activeNode && lastTop != undefined) {\n const curTop = activeNode.getBoundingClientRect().top;\n document.querySelector(\".sidebar\").scrollBy(0, curTop - lastTop);\n }\n}\n\nfunction scrollSyncMenuStatus() {\n requestAnimationFrame(() => {\n let el = document.querySelector(\".app-sub-sidebar > .active\");\n if (el) {\n el.parentNode.parentNode\n .querySelectorAll(\".app-sub-sidebar\")\n .forEach((dom) => dom.classList.remove(\"open\"));\n while (el.parentNode.classList.contains(\"app-sub-sidebar\")) {\n if (el.parentNode.classList.contains(\"open\")) {\n break;\n } else {\n el.parentNode.classList.add(\"open\");\n el = el.parentNode;\n }\n }\n }\n });\n}\n\nfunction handleMenuClick(e) {\n lastTop = e.target.getBoundingClientRect().top;\n // 兼容点击<a>标签或父级LI的情况,找到实际的LI节点\n const targetNode = e.target.tagName === \"A\" ? e.target.parentNode : e.target;\n const newActiveNode = findTagParent(targetNode, \"LI\", 2);\n if (!newActiveNode) return;\n // 找到节点内的<a>标签,获取唯一标识href\n const nodeHref = newActiveNode.querySelector(\"a\")?.getAttribute(\"href\");\n if (!nodeHref) return;\n\n if (newActiveNode.classList.contains(\"open\")) {\n // 手动折叠:移除open,添加collapse\n newActiveNode.classList.remove(\"open\");\n setTimeout(() => {\n newActiveNode.classList.add(\"collapse\");\n }, 0);\n // 收集状态:折叠状态存入对象\n sidebarCollapseState[nodeHref] = \"collapse\";\n } else {\n // 手动展开:先关闭其他激活项,再展开当前\n removeOpenToRoot(getActiveNode());\n openActiveToRoot(newActiveNode);\n setTimeout(() => {\n newActiveNode.classList.remove(\"collapse\");\n }, 0);\n // 收集状态:展开状态存入对象\n sidebarCollapseState[nodeHref] = \"open\";\n }\n syncScrollTop(newActiveNode);\n}\n\nfunction getActiveNode() {\n let node = document.querySelector(\".sidebar-nav .active\");\n\n if (!node) {\n const curHref = decodeURIComponent(location.hash).replace(/ /gi, \"%20\");\n const curLink = document.querySelector(`.sidebar-nav a[href=\"${curHref}\"]`);\n node = findTagParent(curLink, \"LI\", 2);\n if (node) {\n node.classList.add(\"active\");\n // 初始化激活项状态:默认展开\n const nodeHref = node.querySelector(\"a\")?.getAttribute(\"href\");\n nodeHref && (sidebarCollapseState[nodeHref] = \"open\");\n }\n }\n return node;\n}\n\nfunction openActiveToRoot(node) {\n if (node) {\n node.classList.add(\"open\", \"active\");\n while (node && node.className !== \"sidebar-nav\" && node.parentNode) {\n if (\n node.parentNode.tagName === \"LI\" ||\n node.parentNode.className === \"app-sub-sidebar\"\n ) {\n node.parentNode.classList.add(\"open\");\n }\n node = node.parentNode;\n }\n }\n}\n\nfunction removeOpenToRoot(node) {\n if (node) {\n node.classList.remove(\"open\", \"active\");\n while (node && node.className !== \"sidebar-nav\" && node.parentNode) {\n if (\n node.parentNode.tagName === \"LI\" ||\n node.parentNode.className === \"app-sub-sidebar\"\n ) {\n node.parentNode.classList.remove(\"open\");\n }\n node = node.parentNode;\n }\n }\n}\n\nfunction findTagParent(curNode, tagName, level) {\n if (curNode && curNode.tagName === tagName) return curNode;\n let l = 0;\n while (curNode) {\n l++;\n if (l > level) return;\n if (curNode.parentNode.tagName === tagName) {\n return curNode.parentNode;\n }\n curNode = curNode.parentNode;\n }\n}\n\nfunction addFolderFileClass() {\n document.querySelectorAll(\".sidebar-nav li\").forEach((li) => {\n if (li.querySelector(\"ul:not(.app-sub-sidebar)\")) {\n li.classList.add(\"folder\");\n } else {\n li.classList.add(\"file\");\n }\n });\n}\n\nfunction addLevelClass() {\n function find(root, level) {\n root &&\n root.childNodes &&\n root.childNodes.forEach((child) => {\n if (child.classList && child.classList.contains(\"folder\")) {\n child.classList.add(`level-${level}`);\n // 优先读取专属配置,兼容原配置\n const firstOpenLevel =\n window.$docsify?.sidebarFirstOpenLevel ||\n window.$docsify?.sidebarDisplayLevel;\n if (\n firstOpenLevel &&\n typeof firstOpenLevel === \"number\" &&\n level <= firstOpenLevel\n ) {\n child.classList.add(\"open\");\n // 初始化首次展开的节点状态:存入open\n const nodeHref = child.querySelector(\"a\")?.getAttribute(\"href\");\n nodeHref && (sidebarCollapseState[nodeHref] = \"open\");\n }\n if (child && child.childNodes.length > 1) {\n find(child.childNodes[1], level + 1);\n }\n }\n });\n }\n find(document.querySelector(\".sidebar-nav > ul\"), 1);\n // 首次执行后关闭标记\n isFirstLoad = false;\n}\n\nfunction restoreCollapseState(activeNode) {\n // 获取激活节点的href(用于排除,不覆盖其状态)\n const activeHref = activeNode?.querySelector(\"a\")?.getAttribute(\"href\");\n // 遍历所有菜单节点,根据状态对象恢复\n document\n .querySelectorAll(\".sidebar-nav li.folder, .sidebar-nav li.file\")\n .forEach((li) => {\n const nodeHref = li.querySelector(\"a\")?.getAttribute(\"href\");\n // 容错:无href的节点不处理,排除激活项\n if (!nodeHref || nodeHref === activeHref) return;\n // 从状态对象获取保存的状态\n const saveState = sidebarCollapseState[nodeHref];\n if (saveState) {\n // 恢复状态:移除相反类名,添加保存的类名\n li.classList.remove(saveState === \"open\" ? \"collapse\" : \"open\");\n li.classList.add(saveState);\n }\n });\n}\n\n// 2. 新增:hook.ready专用 - 收集侧边栏全量初始状态函数(仅执行一次)\nfunction collectInitialCollapseState() {\n // 遍历所有侧边栏可交互节点(folder/file,此时addFolderFileClass已执行,类名存在)\n const allSidebarNodes = document.querySelectorAll(\n \".sidebar-nav li.folder, .sidebar-nav li.file\",\n );\n allSidebarNodes.forEach((li) => {\n // 获取节点唯一标识:a标签的href(容错,无a/href则跳过)\n const aTag = li.querySelector(\"a\");\n const nodeHref = aTag?.getAttribute(\"href\");\n if (!nodeHref) return;\n\n // 核心:根据DOM真实类名判断初始状态,与实际展示严格一致\n let initialState = \"collapse\"; // 默认折叠(Docsify原生默认行为)\n if (li.classList.contains(\"open\")) {\n initialState = \"open\"; // 有open类=展开状态\n } else if (li.classList.contains(\"collapse\")) {\n initialState = \"collapse\"; // 有collapse类=折叠状态\n }\n\n // 将真实初始状态存入全局状态对象,完成初始化\n sidebarCollapseState[nodeHref] = initialState;\n });\n // 可选:调试用,查看收集的初始状态(开发完成后可删除)\n console.log(\"侧边栏初始状态收集完成:\", sidebarCollapseState);\n}\n\ninit();\n\nexport default sidebarCollapsePlugin;\n","import sidebarCollapsePlugin from './sidebar-collapse-plugin'\n\nfunction install(...plugins) {\n if (!window.$docsify) {\n console.error('这是一个docsify插件,请先引用docsify库!')\n } else {\n $docsify.plugins = plugins.concat($docsify.plugins || [])\n }\n}\n\ninstall(sidebarCollapsePlugin)"],"names":["isFirstLoad","sidebarCollapseState","lastTop","syncScrollTop","activeNode","undefined","curTop","getBoundingClientRect","top","document","querySelector","scrollBy","scrollSyncMenuStatus","requestAnimationFrame","el","parentNode","querySelectorAll","forEach","dom","classList","remove","contains","add","handleMenuClick","e","target","newActiveNode","findTagParent","tagName","nodeHref","getAttribute","setTimeout","node","className","removeOpenToRoot","getActiveNode","openActiveToRoot","curHref","decodeURIComponent","location","hash","replace","curNode","level","l","restoreCollapseState","activeHref","li","saveState","addEventListener","plugins","window","$docsify","concat","console","error","install","hook","vm","doneEach","html","next","find","root","childNodes","child","firstOpenLevel","sidebarFirstOpenLevel","sidebarDisplayLevel","length","addLevelClass","ready","aTag","initialState","log"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@remloyal/docsify-plugins",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "plugins for docsify",
|
|
5
|
+
"main": "src",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"start": "rollup -c -w",
|
|
8
|
+
"clean": "rimraf ./dist",
|
|
9
|
+
"build": "npm run clean && rollup -c",
|
|
10
|
+
"pb": "npm run build && npm publish",
|
|
11
|
+
"prepare": "npm run build"
|
|
12
|
+
},
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "git+https://github.com/remloyal/docsify-plugins.git"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"docsify",
|
|
19
|
+
"plugins",
|
|
20
|
+
"sidebar",
|
|
21
|
+
"collapse",
|
|
22
|
+
"flexsearch",
|
|
23
|
+
"search"
|
|
24
|
+
],
|
|
25
|
+
"files": [
|
|
26
|
+
"src",
|
|
27
|
+
"dist"
|
|
28
|
+
],
|
|
29
|
+
"author": "remloyal",
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"bugs": {
|
|
32
|
+
"url": "https://github.com/remloyal/docsify-plugins/issues"
|
|
33
|
+
},
|
|
34
|
+
"homepage": "https://github.com/remloyal/docsify-plugins#readme",
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"common-tags": "^1.8.0",
|
|
37
|
+
"flexsearch": "^0.8.212",
|
|
38
|
+
"marked": "^17.0.1"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@rollup/plugin-babel": "^6.0.4",
|
|
42
|
+
"@rollup/plugin-commonjs": "^29.0.0",
|
|
43
|
+
"@rollup/plugin-node-resolve": "^16.0.0",
|
|
44
|
+
"@rollup/plugin-replace": "^6.0.1",
|
|
45
|
+
"@rollup/plugin-terser": "^0.4.3",
|
|
46
|
+
"autoprefixer": "^10.4.23",
|
|
47
|
+
"clean-css-cli": "^4.3.0",
|
|
48
|
+
"cssnano": "^7.1.2",
|
|
49
|
+
"glob": "^13.0.0",
|
|
50
|
+
"npm-run-all": "^4.1.5",
|
|
51
|
+
"rimraf": "^6.1.2",
|
|
52
|
+
"rollup": "^4.56.0",
|
|
53
|
+
"rollup-plugin-import-css": "^4.0.1",
|
|
54
|
+
"rollup-plugin-postcss": "^4.0.2",
|
|
55
|
+
"uglify-js": "^3.4.9"
|
|
56
|
+
},
|
|
57
|
+
"engines": {
|
|
58
|
+
"node": ">=20.11.0"
|
|
59
|
+
}
|
|
60
|
+
}
|