From 421e0a42aac5afac78154222f289a05c9aef4e4d Mon Sep 17 00:00:00 2001 From: Super Manito <68613938+SuperManito@users.noreply.github.com> Date: Fri, 4 Apr 2025 13:15:39 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 60 ++--- docs/assets/js/common.js | 122 +++++++++ docs/assets/js/component.js | 15 ++ .../mirrors-table/data.js} | 24 ++ .../js/components/mirrors-table/index.js | 51 ++++ docs/assets/js/mirrors-table.js | 248 ------------------ docs/assets/js/modules/tdesign-theme.js | 32 +++ docs/assets/js/{ => modules}/tdesign.min.js | 0 .../js/{ => modules}/tdesign.min.js.map | 0 .../js/{ => modules}/vue.global.prod.js | 0 docs/index.md | 8 +- docs/mirrors/index.md | 8 +- docs/other/index.md | 38 +-- docs/sponsor/index.md | 8 +- docs/stylesheets/extra.css | 33 ++- docs/theme/netlify.svg | 1 + docs/theme/partials/comments.html | 16 +- docs/theme/partials/palette.html | 105 ++++++++ docs/theme/partials/toc.html | 44 ++-- docs/use/index.md | 2 +- mkdocs.yml | 16 +- 21 files changed, 489 insertions(+), 342 deletions(-) create mode 100644 docs/assets/js/common.js create mode 100644 docs/assets/js/component.js rename docs/assets/js/{mirrors-table-data.js => components/mirrors-table/data.js} (83%) create mode 100644 docs/assets/js/components/mirrors-table/index.js delete mode 100644 docs/assets/js/mirrors-table.js create mode 100644 docs/assets/js/modules/tdesign-theme.js rename docs/assets/js/{ => modules}/tdesign.min.js (100%) rename docs/assets/js/{ => modules}/tdesign.min.js.map (100%) rename docs/assets/js/{ => modules}/vue.global.prod.js (100%) create mode 100644 docs/theme/netlify.svg create mode 100644 docs/theme/partials/palette.html diff --git a/README.md b/README.md index dc1f529..b0b9bdd 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,11 @@

- + + + 文本 +

-

- - LinuxMirrors - -

GNU/Linux 更换系统软件源脚本及 Docker 安装脚本

@@ -19,95 +17,95 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - +
 Debian Debian 8 ~ 13
 Ubuntu Ubuntu 14 ~ 24
 Kali Linux Kali Linux all
 Linux Mint Linux Mint 19 ~ 22 / LMDE 6
 Deepin(深度) Deepin(深度) all
 Zorin OS Zorin OS all
 Armbian Armbian all
 Proxmox VE Proxmox VE all
 Raspberry Pi OS Raspberry Pi OS all
 Red Hat Enterprise Linux Red Hat Enterprise Linux 7 ~ 9
 Fedora Fedora 30 ~ 41
 CentOS CentOS 7 ~ 8 / Stream 8 ~ 10
 Rocky Linux Rocky Linux 8 ~ 9
 AlmaLinux AlmaLinux 8 ~ 9
 openEuler(开源欧拉) openEuler(开源欧拉) 21 ~ 24
 OpenCloudOS(鸥栖) OpenCloudOS(鸥栖) 8.6 ~ 9 / Stream 23
 openKylin(开放麒麟) openKylin(开放麒麟) all
 Anolis OS(龙蜥) Anolis OS(龙蜥) 8 / 23
 openSUSE openSUSE Leep 15 / Tumbleweed
 Arch Linux Arch Linux all
 Alpine Linux Alpine Linux v3 / edge
 Gentoo Gentoo all
 NixOS NixOS 19 ~ 24
@@ -120,12 +118,12 @@ *** -这是一个完全开源的项目,旨在为从事计算机相关行业的朋友们提供便利,使换源更简单 - ### LICENSE Copyright © 2025, [SuperManito](https://github.com/SuperManito). Released under the [MIT](https://github.com/SuperManito/LinuxMirrors/blob/main/LICENSE). +这是一个完全开源的项目,旨在为从事计算机相关行业的朋友们提供便利,使换源更简单 + diff --git a/docs/assets/js/common.js b/docs/assets/js/common.js new file mode 100644 index 0000000..ebbfa46 --- /dev/null +++ b/docs/assets/js/common.js @@ -0,0 +1,122 @@ +// 防抖 +function debounce(func, wait) { + let timeout + return function () { + const context = this + const args = arguments + clearTimeout(timeout) + timeout = setTimeout(() => func.apply(context, args), wait) + } +} + +// 组件管理系统(每个组件都是一个 Vue 实例) +const ComponentSystem = { + // 组件状态数据 + components: {}, + + // 注册组件 + register: function (componentId, componentDef) { + // 为每个组件创建自己的状态 + this.components[componentId] = { + id: componentId, + instance: null, + isInitializing: false, + lastInitTime: 0, + def: componentDef, + debouncedInit: null, + } + // 创建组件初始化函数 + const initFunc = function () { + const component = ComponentSystem.components[componentId] + // 如果正在初始化或者距离上次初始化时间太短,则跳过 + const now = Date.now() + if (component.isInitializing || now - component.lastInitTime < 1000) { + return + } + // 使用缓存,如果没有则查询 + if (!component.instance) { + component.instance = document.getElementById(componentId) + } + // 如果找不到容器,不执行后续操作 + if (!component.instance) { + return + } + // 如果组件已经初始化过,且DOM没有变化,则跳过 + if (component.instance.hasAttribute('data-initialized')) { + return + } + // console.log(`找到组件 ${componentId} 容器,开始初始化`) + component.isInitializing = true + component.lastInitTime = now + try { + // 清空容器内容,防止重复初始化 + while (component.instance.firstChild) { + component.instance.removeChild(component.instance.firstChild) + } + // 确保容器有适当的尺寸 + if (!component.instance.style.width) { + component.instance.style.width = '100%' + } + // 确保 Vue 和 TDesign 已加载 + if (typeof Vue !== 'undefined' && typeof TDesign !== 'undefined') { + // 创建 Vue 应用 + const App = Vue.createApp(component.def) + // 注册 TDesign 组件 + App.use(TDesign.default) + // 挂载应用 + App.mount(component.instance) + // console.log(`组件 ${componentId} 初始化成功`) + // 标记组件已初始化 + component.instance.setAttribute('data-initialized', 'true') + // 立即更新主题 + updateTDesignGlobalTheme() + } else if (typeof Vue !== 'undefined') { + console.error('Vue 未找到') + const errorDiv = document.createElement('div') + errorDiv.innerHTML = `

组件 ${componentId} 加载失败,请检查 Vue 是否存在!

` + component.instance.appendChild(errorDiv) + } else if (typeof TDesign !== 'undefined') { + console.error('TDesign UI 未找到') + const errorDiv = document.createElement('div') + errorDiv.innerHTML = `

组件 ${componentId} 加载失败,请检查 TDesign UI 是否存在!

` + component.instance.appendChild(errorDiv) + } + } catch (error) { + console.error(`组件 ${componentId} 初始化时发生错误:${error}`) + } finally { + component.isInitializing = false + } + } + // 为每个组件创建防抖初始化函数 + this.components[componentId].debouncedInit = debounce(initFunc, 300) + return this.components[componentId].debouncedInit + }, + + // 初始化所有组件 + initAll: function () { + Object.values(this.components).forEach((component) => { + if (component.debouncedInit) { + component.debouncedInit() + } + }) + }, + + // 重新初始化组件 + reinitialize: function (componentId) { + const component = this.components[componentId] + if (component) { + component.instance = document.getElementById(componentId) + if (component.instance) { + component.instance.removeAttribute('data-initialized') + setTimeout(component.debouncedInit, 300) + } + } + }, + + // 重新初始化所有组件 + reinitializeAll: function () { + Object.keys(this.components).forEach((id) => { + this.reinitialize(id) + }) + }, +} diff --git a/docs/assets/js/component.js b/docs/assets/js/component.js new file mode 100644 index 0000000..0ca4a57 --- /dev/null +++ b/docs/assets/js/component.js @@ -0,0 +1,15 @@ +// 使用 mkdocs-material 与第三方 JavaScript 库集成的方法 +document$.subscribe(function () { + // 重新初始化组件 + ComponentSystem.reinitializeAll() + // 延迟初始化以确保DOM完全渲染 + setTimeout(() => { + ComponentSystem.initAll() + }, 300) +}) + +// 首次加载事件 +window.addEventListener('load', function () { + // 初始化所有组件 + ComponentSystem.initAll() +}) diff --git a/docs/assets/js/mirrors-table-data.js b/docs/assets/js/components/mirrors-table/data.js similarity index 83% rename from docs/assets/js/mirrors-table-data.js rename to docs/assets/js/components/mirrors-table/data.js index 579d9d4..990acd4 100644 --- a/docs/assets/js/mirrors-table-data.js +++ b/docs/assets/js/components/mirrors-table/data.js @@ -1,3 +1,4 @@ +// 表格数据 const mirrorsTableData = [ { name: '阿里云', @@ -322,3 +323,26 @@ const mirrorsTableData = [ raspberry: true, }, ] + +// 表格列配置 +const mirrorsTableColumns = [ + { colKey: 'name', title: '镜像站', align: 'center', width: '160', fixed: 'left' }, + { colKey: 'ipv6', title: 'IPv6', align: 'center' }, + { colKey: 'epel', title: 'EPEL', align: 'center', tooltip: 'Extra Packages for Enterprise Linux (EPEL) 是由 Fedora 组织维护的一个附加软件包仓库,它主要适用于除 Fedora 操作系统以外的红帽系 Linux 发行版。' }, + { colKey: 'archlinux', title: 'Arch Linux', align: 'center' }, + { colKey: 'kalilinux', title: 'Kali Linux', align: 'center' }, + { colKey: 'armbian', title: 'Armbian', align: 'center' }, + { colKey: 'deepin', title: 'Deepin', align: 'center' }, + { colKey: 'raspberry', title: 'Raspberry Pi OS', align: 'center', width: '130' }, + { colKey: 'linuxmint', title: 'Linux Mint', align: 'center' }, + { colKey: 'proxmox', title: 'Proxmox VE', align: 'center' }, + { colKey: 'fedora', title: 'Fedora', align: 'center' }, + { colKey: 'rockylinux', title: 'Rocky Linux', align: 'center' }, + { colKey: 'almalinux', title: 'AlmaLinux', align: 'center' }, + { colKey: 'opencloudos', title: 'OpenCloudOS', align: 'center', width: '120' }, + { colKey: 'anolis', title: 'Anolis OS', align: 'center' }, + { colKey: 'openkylin', title: 'openKylin', align: 'center' }, + { colKey: 'alpinelinux', title: 'Alpine Linux', align: 'center' }, + { colKey: 'gentoo', title: 'Gentoo', align: 'center' }, + { colKey: 'nix', title: 'NixOS', align: 'center' }, +] diff --git a/docs/assets/js/components/mirrors-table/index.js b/docs/assets/js/components/mirrors-table/index.js new file mode 100644 index 0000000..e6f9d91 --- /dev/null +++ b/docs/assets/js/components/mirrors-table/index.js @@ -0,0 +1,51 @@ +ComponentSystem.register('mirrors-table', { + template: ` +
+ + + + +
+ `, + data() { + return { + columns: mirrorsTableColumns, + data: mirrorsTableData, + } + }, +}) diff --git a/docs/assets/js/mirrors-table.js b/docs/assets/js/mirrors-table.js deleted file mode 100644 index f82ecde..0000000 --- a/docs/assets/js/mirrors-table.js +++ /dev/null @@ -1,248 +0,0 @@ -const appId = 'mirrors-table' // 表格容器ID -let appInstance = null // 缓存表格容器引用 -let vueApp = null // Vue 应用实例 -let isInitializing = false // 是否正在初始化 -let lastInitTime = 0 // 上次初始化时间 -const INIT_COOLDOWN = 1000 // 初始化冷却时间(毫秒) - -// 更新表格主题 -function updateTableTheme() { - const scheme = document.querySelector('[data-md-color-scheme]')?.getAttribute('data-md-color-scheme') - const isDarkMode = scheme === 'slate' || scheme === 'dark' - // 设置 TDesign 的主题模式 - if (isDarkMode) { - document.documentElement.setAttribute('theme-mode', 'dark') - } else { - document.documentElement.removeAttribute('theme-mode') - } -} - -// 初始化表格的函数 -function initTables() { - // 如果正在初始化或者距离上次初始化时间太短,则跳过 - const now = Date.now() - if (isInitializing || now - lastInitTime < INIT_COOLDOWN) { - return - } - // 使用缓存的引用,如果没有则查询 - if (!appInstance) { - appInstance = document.getElementById(appId) - } - // 如果找不到容器,不执行后续操作 - if (!appInstance) { - return - } - // 如果表格已经初始化过,且DOM没有变化,则跳过 - if (appInstance.hasAttribute('data-initialized')) { - return - } - // console.log('找到表格容器,初始化表格') - isInitializing = true - lastInitTime = now - try { - // 清空容器内容,防止重复初始化 - while (appInstance.firstChild) { - appInstance.removeChild(appInstance.firstChild) - } - // 确保容器有适当的尺寸 - if (!appInstance.style.width) { - appInstance.style.width = '100%' - } - // 确保 Vue 和 TDesign 已加载 - if (typeof Vue !== 'undefined' && typeof TDesign !== 'undefined') { - // 创建 Vue 应用 - const App = Vue.createApp(app) - // 注册 TDesign 组件 - App.use(TDesign.default) - // 挂载应用 - vueApp = App.mount(appInstance) - // console.log('表格初始化成功') - // 标记表格已初始化 - appInstance.setAttribute('data-initialized', 'true') - // 立即更新主题 - updateTableTheme() - } else { - console.error('Vue 或 TDesign 未加载') - // 显示错误消息 - const errorDiv = document.createElement('div') - errorDiv.style.padding = '20px' - errorDiv.style.color = 'red' - errorDiv.textContent = 'Vue 或 TDesign 未加载,请在 mkdocs.yml 中添加相应 CDN 链接' - appInstance.appendChild(errorDiv) - } - } catch (error) { - console.error('初始化表格时发生错误:', error) - } finally { - isInitializing = false - } -} - -// 初始化 -function reinitializeTable() { - appInstance = document.getElementById(appId) - if (appInstance) { - appInstance.removeAttribute('data-initialized') - setTimeout(debouncedInit, 300) // 使用更短的延迟 - } -} - -// 设置主题监听器 -function setupThemeObserver() { - // 监听主题变化 - const observer = new MutationObserver(() => { - updateTableTheme() - }) - const element = document.querySelector('[data-md-color-scheme]') - if (element) { - observer.observe(element, { - attributes: true, - attributeFilter: ['data-md-color-scheme'], - }) - } else { - // 如果元素不存在,等待页面加载完成后重试 - setTimeout(setupThemeObserver, 1000) - } -} - -// 使用防抖函数包装初始化逻辑 -function debounce(func, wait) { - let timeout - return function () { - const context = this - const args = arguments - clearTimeout(timeout) - timeout = setTimeout(() => func.apply(context, args), wait) - } -} - -// 列定义 -const columns = [ - { colKey: 'name', title: '镜像站', align: 'center', width: '160', fixed: 'left' }, - { colKey: 'ipv6', title: 'IPv6', align: 'center' }, - { colKey: 'epel', title: 'EPEL', align: 'center', tooltip: 'Extra Packages for Enterprise Linux (EPEL) 是由 Fedora 组织维护的一个附加软件包仓库,它主要适用于除 Fedora 操作系统以外的红帽系 Linux 发行版。' }, - { colKey: 'archlinux', title: 'Arch Linux', align: 'center' }, - { colKey: 'kalilinux', title: 'Kali Linux', align: 'center' }, - { colKey: 'armbian', title: 'Armbian', align: 'center' }, - { colKey: 'deepin', title: 'Deepin', align: 'center' }, - { colKey: 'raspberry', title: 'Raspberry Pi OS', align: 'center', width: '130' }, - { colKey: 'linuxmint', title: 'Linux Mint', align: 'center' }, - { colKey: 'proxmox', title: 'Proxmox VE', align: 'center' }, - { colKey: 'fedora', title: 'Fedora', align: 'center' }, - { colKey: 'rockylinux', title: 'Rocky Linux', align: 'center' }, - { colKey: 'almalinux', title: 'AlmaLinux', align: 'center' }, - { colKey: 'opencloudos', title: 'OpenCloudOS', align: 'center', width: '120' }, - { colKey: 'anolis', title: 'Anolis OS', align: 'center' }, - { colKey: 'openkylin', title: 'openKylin', align: 'center' }, - { colKey: 'alpinelinux', title: 'Alpine Linux', align: 'center' }, - { colKey: 'gentoo', title: 'Gentoo', align: 'center' }, - { colKey: 'nix', title: 'NixOS', align: 'center' }, -] - -// 修改 app 对象的模板部分,添加自定义表头渲染 -const app = { - template: ` -
- - - - -
- `, - data() { - return { - columns, - data: mirrorsTableData, - } - }, -} - -// 防抖处理的初始化函数 -const debouncedInit = debounce(initTables, 300) - -// 仅在导航完成后监听URL变化 -let lastUrl = location.href -const urlObserver = new MutationObserver(() => { - const url = location.href - if (url !== lastUrl) { - lastUrl = url - // 重置初始化状态 - appInstance = document.getElementById(appId) - if (appInstance) { - appInstance.removeAttribute('data-initialized') - } - // 延迟初始化 - setTimeout(debouncedInit, 400) - } -}) -urlObserver.observe(document, { subtree: true, childList: true }) - -// 页面加载事件 -window.addEventListener('load', function () { - debouncedInit() - // 尝试找到 MkDocs 内容容器来精确监听 - const contentContainer = document.querySelector('.md-content') || document.querySelector('.md-main__inner') || document.querySelector('article') || document.body - // 只监听这个元素的子元素变化 - urlObserver.observe(contentContainer, { - childList: true, // 监听子节点添加或删除 - subtree: false, // 不监听所有后代变化,降低开销 - attributes: false, // 不监听属性变化 - }) - // 监听 iframe 情况下的 hashchange 和 popstate 事件 - window.addEventListener('hashchange', function () { - if (location.href !== lastUrl) { - lastUrl = location.href - appInstance = null - reinitializeTable() - } - }) - window.addEventListener('popstate', function () { - if (location.href !== lastUrl) { - lastUrl = location.href - appInstance = null - reinitializeTable() - } - }) -}) -document.addEventListener('DOMContentLoaded', function () { - // 设置主题观察器 - setupThemeObserver() -}) -// MkDocs 页面切换事件 -document.addEventListener('DOMContentSwitch', function () { - reinitializeTable() -}) diff --git a/docs/assets/js/modules/tdesign-theme.js b/docs/assets/js/modules/tdesign-theme.js new file mode 100644 index 0000000..7bbe4df --- /dev/null +++ b/docs/assets/js/modules/tdesign-theme.js @@ -0,0 +1,32 @@ +// 更新 TDesign 主题 +function updateTDesignGlobalTheme() { + const scheme = document.querySelector('[data-md-color-scheme]')?.getAttribute('data-md-color-scheme') + const isDarkMode = scheme === 'slate' || scheme === 'dark' + if (isDarkMode) { + document.documentElement.setAttribute('theme-mode', 'dark') + } else { + document.documentElement.removeAttribute('theme-mode') + } +} + +// 主题监听器 +function setupThemeObserver() { + // 监听主题变化 + const observer = new MutationObserver(() => { + updateTDesignGlobalTheme() + }) + const element = document.querySelector('[data-md-color-scheme]') + if (element) { + observer.observe(element, { + attributes: true, + attributeFilter: ['data-md-color-scheme'], + }) + } else { + // 如果元素不存在,等待页面加载完成后重试 + setTimeout(setupThemeObserver, 1000) + } +} + +document.addEventListener('DOMContentLoaded', function () { + setupThemeObserver() +}) diff --git a/docs/assets/js/tdesign.min.js b/docs/assets/js/modules/tdesign.min.js similarity index 100% rename from docs/assets/js/tdesign.min.js rename to docs/assets/js/modules/tdesign.min.js diff --git a/docs/assets/js/tdesign.min.js.map b/docs/assets/js/modules/tdesign.min.js.map similarity index 100% rename from docs/assets/js/tdesign.min.js.map rename to docs/assets/js/modules/tdesign.min.js.map diff --git a/docs/assets/js/vue.global.prod.js b/docs/assets/js/modules/vue.global.prod.js similarity index 100% rename from docs/assets/js/vue.global.prod.js rename to docs/assets/js/modules/vue.global.prod.js diff --git a/docs/index.md b/docs/index.md index 2c5aeb0..dbb007e 100644 --- a/docs/index.md +++ b/docs/index.md @@ -131,15 +131,15 @@ hide:
diff --git a/docs/mirrors/index.md b/docs/mirrors/index.md index b64e8ef..9acf1cc 100644 --- a/docs/mirrors/index.md +++ b/docs/mirrors/index.md @@ -10,7 +10,7 @@ hide: > 下方列表中的镜像站均支持 `Debian` `Ubuntu` `CentOS` `openSUSE` `openEuler` 软件源,列表根据单位性质、地理位置、名称长度进行排序,与实际速度无关 -

正在加载表格

+

正在加载表格

+ {% endif %} diff --git a/docs/use/index.md b/docs/use/index.md index 1ae19df..2dc5d0d 100644 --- a/docs/use/index.md +++ b/docs/use/index.md @@ -341,7 +341,7 @@ hide: - ### 关于调用脚本的互联网位置 - 项目利用 [GitHub Action](https://github.com/SuperManito/LinuxMirrors/blob/main/.github/workflows/build-docs.yml#L29) 在每次提交后自动拷贝源码到文档目录作为网站资源发布,网站托管于知名 CDN 云服务商几乎没有被劫持的风险请放心使用。 + 项目利用 [GitHub Action](https://github.com/SuperManito/LinuxMirrors/blob/main/.github/workflows/build-docs.yml#L29) 在每次提交后自动拷贝源码到文档目录作为网站资源发布,网站托管于 :netlify: Netlify,几乎没有被劫持的风险请放心使用。 当然你也可以使用代码托管仓库的原始地址来调用,这里只是想告诉你为什么会有几个不同的地址,默认的官网地址更易于记忆和访问。 diff --git a/mkdocs.yml b/mkdocs.yml index 9e38771..e92bb3b 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -2,13 +2,16 @@ site_name: LinuxMirrors repo_name: LinuxMirrors repo_url: https://github.com/SuperManito/LinuxMirrors edit_uri: edit/main/docs/ -copyright: 'Copyright © 2025 SuperManito ' +copyright: 'Copyright © 2025 SuperManito
本网站由 Netlify 部署并提供全球 CDN 边缘加速服务 ' extra_javascript: - - assets/js/vue.global.prod.js - - assets/js/tdesign.min.js - - assets/js/mirrors-table-data.js - - assets/js/mirrors-table.js + - assets/js/modules/vue.global.prod.js + - assets/js/modules/tdesign.min.js + - assets/js/modules/tdesign-theme.js + - assets/js/common.js + - assets/js/component.js + - assets/js/components/mirrors-table/data.js + - assets/js/components/mirrors-table/index.js extra_css: - assets/css/tdesign.min.css - stylesheets/extra.css @@ -32,13 +35,13 @@ theme: success: octicons/check-16 question: octicons/question-16 warning: octicons/alert-16 - failure: octicons/x-circle-16 danger: octicons/zap-16 bug: octicons/bug-16 example: octicons/beaker-16 quote: octicons/quote-16 palette: - media: "(prefers-color-scheme)" + scheme: system toggle: icon: material/brightness-auto name: 跟随系统 @@ -60,6 +63,7 @@ theme: - navigation.tabs - navigation.path - navigation.instant + - navigation.instant.progress - navigation.indexes - navigation.footer - navigation.tracking