diff --git a/plugins/GmeekTOC.js b/plugins/GmeekTOC.js
index 4ba9551..eb8a9d2 100644
--- a/plugins/GmeekTOC.js
+++ b/plugins/GmeekTOC.js
@@ -1,59 +1,92 @@
-function loadResource(type, attributes, callback) {
- var element;
- if (type === 'script') {
- element = document.createElement('script');
- element.src = attributes.src;
- element.onload = callback;
- } else if (type === 'link') {
- element = document.createElement('link');
- element.rel = attributes.rel;
- element.href = attributes.href;
- } else if (type === 'style') {
- element = document.createElement('style');
- element.rel = 'stylesheet';
- element.appendChild(document.createTextNode(attributes.css));
- }
- document.head.appendChild(element);
-}
-
function createTOC() {
var tocElement = document.createElement('div');
tocElement.className = 'toc';
var contentContainer = document.getElementById('content');
- if (contentContainer.firstChild) {
- contentContainer.insertBefore(tocElement, contentContainer.firstChild);
- } else {
- contentContainer.appendChild(tocElement);
- }
+ contentContainer.prepend(tocElement);
+ const headings = contentContainer.querySelectorAll('h1, h2, h3, h4, h5, h6');
+ tocElement.insertAdjacentHTML('afterbegin', '
文章目录
');
+ headings.forEach(heading => {
+ if (!heading.id) {
+ heading.id = heading.textContent.trim().replace(/\s+/g, '-').toLowerCase();
+ }
+ const link = document.createElement('a');
+ link.href = '#' + heading.id;
+ link.textContent = heading.textContent;
+ link.className = 'toc-link';
+ link.style.paddingLeft = `${(parseInt(heading.tagName.charAt(1)) - 1) * 10}px`;
+ tocElement.appendChild(link);
+ });
+ tocElement.insertAdjacentHTML('beforeend', 'Top');
}
+
document.addEventListener("DOMContentLoaded", function() {
createTOC();
- var css = '.toc {position:fixed;top:130px;left:50%;transform: translateX(50%) translateX(300px);width:200px;padding-left:30px;}@media (max-width: 1249px) {.toc{position:static;top:auto;left:auto;transform:none;padding:10px;margin-bottom:20px;background-color:#eee;}}';
- loadResource('style', {css: css});
+ var css = `
+ .toc {
+ position:fixed;
+ top:130px;
+ left:50%;
+ transform: translateX(50%) translateX(320px);
+ width:200px;
+ border: 1px solid #e1e4e8;
+ border-radius: 6px;
+ padding: 10px;
+ overflow-y: auto;
+ box-shadow: 0 2px 10px rgba(0,0,0,0.1);
+ max-height: 70vh;
+ }
+ .toc-title{
+ font-weight: bold;
+ text-align: center;
+ border-bottom: 1px solid #ddd;
+ padding-bottom: 8px;
+ }
+ .toc-end{
+ font-weight: bold;
+ text-align: center;
+ visibility: hidden;
+ }
+ .toc a {
+ display: block;
+ color: var(--color-diff-blob-addition-num-text);
+ text-decoration: none;
+ padding: 5px 0;
+ font-size: 14px;
+ line-height: 1.5;
+ border-bottom: 1px solid #e1e4e8;
+ }
+ .toc a:last-child {
+ border-bottom: none;
+ }
+ .toc a:hover {
+ background-color:var(--color-select-menu-tap-focus-bg);
+ }
- loadResource('script', { src: 'https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.27.4/tocbot.min.js' }, function() {
- tocbot.init({
- tocSelector: '.toc',
- contentSelector: '.markdown-body',
- headingSelector: 'h1, h2, h3, h4, h5, h6',
- scrollSmooth: true,
- scrollSmoothOffset: -10,
- headingsOffset: 10,
- });
- });
-
- loadResource('link', { rel: 'stylesheet', href: 'https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.27.4/tocbot.css' });
-
- const headings = document.querySelectorAll('.markdown-body h1, .markdown-body h2, .markdown-body h3, .markdown-body h4, .markdown-body h5, .markdown-body h6');
- headings.forEach((heading) => {
- if (!heading.id) {
- heading.id = heading.textContent.trim().replace(/\s+/g, '-');
+ @media (max-width: 1249px)
+ {
+ .toc{
+ position:static;
+ top:auto;
+ left:auto;
+ transform:none;
+ padding:10px;
+ margin-bottom:20px;
}
- });
+ }`;
+
+ const style = document.createElement('style');
+ style.textContent = css;
+ document.head.appendChild(style);
+
+ window.onscroll = function() {
+ const backToTopButton = document.querySelector('.toc-end');
+ if (document.body.scrollTop > 20 || document.documentElement.scrollTop > 20) {
+ backToTopButton.style="visibility: visible;"
+ } else {
+ backToTopButton.style="visibility: hidden;"
+ }
+ };
- var footerPlaceholder = document.createElement('div');
- footerPlaceholder.style.height = window.innerHeight + 'px';
- document.body.appendChild(footerPlaceholder);
console.log("\n %c GmeekTOC Plugins https://github.com/Meekdai/Gmeek \n","padding:5px 0;background:#C333D0;color:#fff");
-});
+});
\ No newline at end of file
diff --git a/plugins/GmeekTocBot.js b/plugins/GmeekTocBot.js
new file mode 100644
index 0000000..fc216dd
--- /dev/null
+++ b/plugins/GmeekTocBot.js
@@ -0,0 +1,59 @@
+function loadResource(type, attributes, callback) {
+ var element;
+ if (type === 'script') {
+ element = document.createElement('script');
+ element.src = attributes.src;
+ element.onload = callback;
+ } else if (type === 'link') {
+ element = document.createElement('link');
+ element.rel = attributes.rel;
+ element.href = attributes.href;
+ } else if (type === 'style') {
+ element = document.createElement('style');
+ element.rel = 'stylesheet';
+ element.appendChild(document.createTextNode(attributes.css));
+ }
+ document.head.appendChild(element);
+}
+
+function createTOC() {
+ var tocElement = document.createElement('div');
+ tocElement.className = 'toc';
+ var contentContainer = document.getElementById('content');
+ if (contentContainer.firstChild) {
+ contentContainer.insertBefore(tocElement, contentContainer.firstChild);
+ } else {
+ contentContainer.appendChild(tocElement);
+ }
+}
+
+document.addEventListener("DOMContentLoaded", function() {
+ createTOC();
+ var css = '.toc {position:fixed;top:130px;left:50%;transform: translateX(50%) translateX(300px);width:200px;padding-left:30px;}@media (max-width: 1249px) {.toc{position:static;top:auto;left:auto;transform:none;padding:10px;margin-bottom:20px;background-color:var(--color-open-muted);}}';
+ loadResource('style', {css: css});
+
+ loadResource('script', { src: 'https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.27.4/tocbot.min.js' }, function() {
+ tocbot.init({
+ tocSelector: '.toc',
+ contentSelector: '.markdown-body',
+ headingSelector: 'h1, h2, h3, h4, h5, h6',
+ scrollSmooth: true,
+ scrollSmoothOffset: -10,
+ headingsOffset: 10,
+ });
+ });
+
+ loadResource('link', { rel: 'stylesheet', href: 'https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.27.4/tocbot.css' });
+
+ const headings = document.querySelectorAll('.markdown-body h1, .markdown-body h2, .markdown-body h3, .markdown-body h4, .markdown-body h5, .markdown-body h6');
+ headings.forEach((heading) => {
+ if (!heading.id) {
+ heading.id = heading.textContent.trim().replace(/\s+/g, '-');
+ }
+ });
+
+ var footerPlaceholder = document.createElement('div');
+ footerPlaceholder.style.height = window.innerHeight + 'px';
+ document.body.appendChild(footerPlaceholder);
+ console.log("\n %c GmeekTocBot Plugins https://github.com/Meekdai/Gmeek \n","padding:5px 0;background:#C333D0;color:#fff");
+});
diff --git a/plugins/articletoc.js b/plugins/articletoc.js
new file mode 100644
index 0000000..67b9af0
--- /dev/null
+++ b/plugins/articletoc.js
@@ -0,0 +1,158 @@
+function loadResource(type, attributes) {
+ if (type === 'style') {
+ const style = document.createElement('style');
+ style.textContent = attributes.css;
+ document.head.appendChild(style);
+ }
+}
+
+function createTOC() {
+ const tocElement = document.createElement('div');
+ tocElement.className = 'toc';
+ const contentContainer = document.querySelector('.markdown-body');
+ contentContainer.appendChild(tocElement);
+
+ const headings = contentContainer.querySelectorAll('h1, h2, h3, h4, h5, h6');
+ headings.forEach(heading => {
+ if (!heading.id) {
+ heading.id = heading.textContent.trim().replace(/\s+/g, '-').toLowerCase();
+ }
+ const link = document.createElement('a');
+ link.href = '#' + heading.id;
+ link.textContent = heading.textContent;
+ link.className = 'toc-link';
+ link.style.paddingLeft = `${(parseInt(heading.tagName.charAt(1)) - 1) * 10}px`;
+ tocElement.appendChild(link);
+ });
+}
+
+function toggleTOC() {
+ const tocElement = document.querySelector('.toc');
+ const tocIcon = document.querySelector('.toc-icon');
+ if (tocElement) {
+ tocElement.classList.toggle('show');
+ tocIcon.classList.toggle('active');
+ tocIcon.textContent = tocElement.classList.contains('show') ? '✖' : '☰';
+ }
+}
+
+document.addEventListener("DOMContentLoaded", function() {
+ createTOC();
+ const css = `
+ :root {
+ --toc-bg: #fff;
+ --toc-border: #e1e4e8;
+ --toc-text: #24292e;
+ --toc-hover: #f6f8fa;
+ --toc-icon-bg: #fff;
+ --toc-icon-color: #ad6598;
+ --toc-icon-active-bg: #813c85;
+ --toc-icon-active-color: #fff;
+ }
+
+ @media (prefers-color-scheme: dark) {
+ :root {
+ --toc-bg: #2d333b;
+ --toc-border: #444c56;
+ --toc-text: #adbac7;
+ --toc-hover: #373e47;
+ --toc-icon-bg: #22272e;
+ --toc-icon-color: #ad6598;
+ --toc-icon-active-bg: #813c85;
+ --toc-icon-active-color: #adbac7;
+ }
+ }
+
+ .toc {
+ position: fixed;
+ bottom: 60px;
+ right: 20px;
+ width: 250px;
+ max-height: 70vh;
+ background-color: var(--toc-bg);
+ border: 1px solid var(--toc-border);
+ border-radius: 6px;
+ padding: 10px;
+ box-shadow: 0 2px 10px rgba(0,0,0,0.1);
+ overflow-y: auto;
+ z-index: 1000;
+ opacity: 0;
+ visibility: hidden;
+ transform: translateY(20px) scale(0.9);
+ transition: opacity 0.3s ease, transform 0.3s ease, visibility 0.3s;
+ }
+ .toc.show {
+ opacity: 1;
+ visibility: visible;
+ transform: translateY(0) scale(1);
+ }
+ .toc a {
+ display: block;
+ color: var(--toc-text);
+ text-decoration: none;
+ padding: 5px 0;
+ font-size: 14px;
+ line-height: 1.5;
+ border-bottom: 1px solid var(--toc-border);
+ transition: background-color 0.2s ease, padding-left 0.2s ease;
+ }
+ .toc a:last-child {
+ border-bottom: none;
+ }
+ .toc a:hover {
+ background-color: var(--toc-hover);
+ padding-left: 5px;
+ }
+ .toc-icon {
+ position: fixed;
+ bottom: 20px;
+ right: 20px;
+ cursor: pointer;
+ font-size: 24px;
+ background-color: var(--toc-icon-bg);
+ color: var(--toc-icon-color);
+ border: 2px solid var(--toc-icon-color);
+ border-radius: 50%;
+ width: 40px;
+ height: 40px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ box-shadow: 0 1px 3px rgba(0,0,0,0.12);
+ z-index: 1001;
+ transition: all 0.3s ease;
+ user-select: none;
+ -webkit-tap-highlight-color: transparent;
+ outline: none;
+ }
+ .toc-icon:hover {
+ transform: scale(1.1);
+ }
+ .toc-icon:active {
+ transform: scale(0.9);
+ }
+ .toc-icon.active {
+ background-color: var(--toc-icon-active-bg);
+ color: var(--toc-icon-active-color);
+ border-color: var(--toc-icon-active-bg);
+ transform: rotate(90deg);
+ }
+ `;
+ loadResource('style', {css: css});
+
+ const tocIcon = document.createElement('div');
+ tocIcon.className = 'toc-icon';
+ tocIcon.textContent = '☰';
+ tocIcon.onclick = (e) => {
+ e.stopPropagation();
+ toggleTOC();
+ };
+ document.body.appendChild(tocIcon);
+
+ document.addEventListener('click', (e) => {
+ const tocElement = document.querySelector('.toc');
+ if (tocElement && tocElement.classList.contains('show') && !tocElement.contains(e.target) && !e.target.classList.contains('toc-icon')) {
+ toggleTOC();
+ }
+ });
+});