From c7dbc75e51bd038adeaf9524637084ef5905a4b6 Mon Sep 17 00:00:00 2001 From: Spectrollay <2819288472@qq.com> Date: Mon, 9 Sep 2024 22:02:07 +0800 Subject: [PATCH] 2024090901 --- Feed/update.xml | 8 + Verification/file-hashes.json | 26 +-- Verification/project-hash.json | 2 +- advanced/settings.html | 53 ++++- experiments/exp.css | 21 -- experiments/{exp.js => index.css} | 9 +- experiments/{flags.html => index.html} | 19 +- experiments/index.js | 71 +++++++ flags/index.html | 23 ++- index.html | 8 +- javascript/accessibility.js | 255 +++++++++++++------------ javascript/advanced.js | 22 +-- javascript/custom_elements.js | 153 +++++++-------- javascript/public_define.js | 4 +- javascript/public_script.js | 23 ++- updatelog/index.html | 37 ++++ 16 files changed, 444 insertions(+), 290 deletions(-) delete mode 100644 experiments/exp.css rename experiments/{exp.js => index.css} (92%) rename experiments/{flags.html => index.html} (90%) create mode 100644 experiments/index.js diff --git a/Feed/update.xml b/Feed/update.xml index be9e6b8..78ac9e3 100644 --- a/Feed/update.xml +++ b/Feed/update.xml @@ -6,6 +6,14 @@ https://spectrollay.github.io/minecraft_repository_test/updatelog/ 星月Minecraft版本库是一个开放共享的资源站,专注于收录Minecraft发布过的所有版本. zh-cn + + 版本库已更新 4.6.5.51.Canary + https://spectrollay.github.io/minecraft_repository_test/ + 更新内容详见: + 开发日志 + + Mon, 09 Sep 2024 22:00:00 GMT + 版本库已更新 4.6.5.50.Canary https://spectrollay.github.io/minecraft_repository_test/ diff --git a/Verification/file-hashes.json b/Verification/file-hashes.json index cd6e98a..ed5d83c 100644 --- a/Verification/file-hashes.json +++ b/Verification/file-hashes.json @@ -1,21 +1,21 @@ { "404.html": "b724c56bbefba662700eadea51a4b5b9", "advanced\\debug.html": "f3f599c403fbe59bb6cf99fc2ac1dd21", - "advanced\\settings.html": "74024a6deb37c32f09e15ee77621b996", + "advanced\\settings.html": "54b3711fe9143fd8d7186255b4b73309", "advanced\\status.html": "ac6adf46440b16e99c3151b8c8c9ba94", "default\\coming_soon.html": "541c00b3ff6cdea5f7bf7129b131c5dd", "default\\error_default.html": "13ebe0116389f9e10d0ec6dc2a8af39a", "default\\error_no-access.html": "b2d0b116e80f954ffd8416d3cef8627e", "default\\error_not-found.html": "9125c5cbfa529d708e78254b8333152f", "donate.html": "26df29641e07c5a582eca1068971fb48", - "experiments\\exp.css": "f227348871eca5403b0aca19d0edd65e", - "experiments\\exp.js": "91ebfaa6d90350f16bfabb60ab0df26c", - "experiments\\flags.html": "fe30ad879a59198ce60634f7385abcd6", + "experiments\\index.css": "0ef80c42887552a3734a200d13a3e8cd", + "experiments\\index.html": "ec259e3546b3f1fddc9aa8c0e923d920", + "experiments\\index.js": "fd29a9466e3324e94dbf8f7235acc6c1", "Feed\\database.xml": "c3b1879c690866f41a3479f7ed28edb6", "Feed\\main.xml": "f5be196f7e0f95f94eee17f5c73efcd5", "Feed\\messages.xml": "1c24a98ff83bdc56d026043d412bd778", - "Feed\\update.xml": "19ddc1049f06c89cc2c6b1eb65838c3d", - "flags\\index.html": "d645714594ec9c14b02ddfe5cacf271d", + "Feed\\update.xml": "7fee6d4fc5a33c073a7736029fb154a5", + "flags\\index.html": "a58d058834f9236883db1104c2d2d074", "fonts\\Minecraft-Five-Bold.otf": "17ba4c2007cf79329c4b84e8dbc6fd34", "fonts\\Minecraft-Five.otf": "070d5f6822481c45102b7c8e71619fe1", "fonts\\Minecraft-Seven.otf": "29cc62e5424a2e7fd7a546e491837e17", @@ -128,14 +128,14 @@ "images\\update\\logo\\Update_Aquatic.png": "cc3e6f78620f02b96f3dd1ee6bc788ae", "images\\update\\logo\\Village&Pillage.png": "afa9288d18710378aa0b997c4559aa5b", "images\\Write.png": "9eb90637a35e8f1fd31aea178b024d3c", - "index.html": "e8a12dc58d958131c2acad66c1b333d7", + "index.html": "5a31632d5cdcc72dfbfd69743ac4bb89", "issue_tracker\\index.html": "edc1f27b2d6381751ed4d60d7aa53ccc", - "javascript\\accessibility.js": "722948e45907330bc74f30ecb8e6beb4", - "javascript\\advanced.js": "0d38129123a736a59d09970b876f11ec", - "javascript\\custom_elements.js": "f9c1f72cad6afebd7983f4ffc93ae185", + "javascript\\accessibility.js": "4c3d2f7fe221a2bc26da35c85eb344f4", + "javascript\\advanced.js": "288d119cbdc37f0fddc5dc651bab47d8", + "javascript\\custom_elements.js": "04446e8fe8e97792ae231631e133b3fe", "javascript\\editions.js": "795a056b1011d662f3cbd38c41962bee", - "javascript\\public_define.js": "2c411443fb954f9aa5418a41f1ec69fb", - "javascript\\public_script.js": "954a52994db77927dac0db9116e5f90f", + "javascript\\public_define.js": "41a9db737fdd735ce80f2a707a02e80d", + "javascript\\public_script.js": "92f0dffd50c059db5fb0378f60cd9168", "notifications\\index.html": "aa15a9909792415b682b4fd6d9866f49", "README-en_US.md": "8c9ce26d032adfdc4e620dc53d683e74", "README.md": "f6ad7532a8a75f70ec4240a668ee3bb4", @@ -151,5 +151,5 @@ "stylesheet\\loading_mask.css": "2701a0ba77a2b46b52280505bb0194af", "stylesheet\\public_style.css": "a221d9cf3686e0757b093661e857312f", "Template\\index.html": "d90907446df4ac3d061035c95d0d22b7", - "updatelog\\index.html": "814895e28fa1b5767fd244ffad80567e" + "updatelog\\index.html": "4592cd6e5617f7801dbd4486c6c7bcac" } \ No newline at end of file diff --git a/Verification/project-hash.json b/Verification/project-hash.json index b4c8a37..3b29e04 100644 --- a/Verification/project-hash.json +++ b/Verification/project-hash.json @@ -1,3 +1,3 @@ { - "projectHash": "ed885f553ceb2afe9f5bdbc457de3324" + "projectHash": "61fe1cec5075f981f21d7a63c2a4538f" } \ No newline at end of file diff --git a/advanced/settings.html b/advanced/settings.html index 274c486..053bee8 100644 --- a/advanced/settings.html +++ b/advanced/settings.html @@ -87,6 +87,19 @@ +
无障碍
+
+ 使用文本转语音 +
+
+ 文本转语音音量 +
+
+ 高对比度UI +
+
+ 通知持续时间 +
外观
主题 @@ -139,7 +152,11 @@
-
+
+
新的实验性内容页面
+ +
+
环境指南
@@ -157,7 +174,7 @@
-
+
加载调试程序
@@ -270,7 +287,7 @@ - + @@ -378,6 +395,26 @@ window.addEventListener('load', function () { hide_mask(); }); + + // 新的实验性内容页面 TODO: 在旧的实验性内容页面被移除时时删除 + const newFlagsPageElement = document.getElementsByClassName('new_flags_page'); + if (!rootPath.includes('_test')) { + newFlagsPageElement[0].style.display = 'none'; + } + + // 实验性无障碍 TODO: 在移除实验性无障碍时移除相关代码 + expAccessibilityState = localStorage.getItem('(/minecraft_repository_test/)experimental_accessibility'); + accessibility_elements = document.querySelectorAll('.exp_accessibility'); + + if (expAccessibilityState === 'on') { + accessibility_elements.forEach(accessibility_element => { + accessibility_element.style.display = 'flex'; + }) + } else { + accessibility_elements.forEach(accessibility_element => { + accessibility_element.style.display = 'none'; + }) + } @@ -411,6 +448,16 @@ #setting_version_detail { display: flex; align-items: center; + justify-items: center; + } + + /* 使开关区域与按钮区域等宽 */ + custom-switch { + width: 132px; + } + + .switch_content { + display: flex; justify-content: center; } diff --git a/experiments/exp.css b/experiments/exp.css deleted file mode 100644 index 17ce04f..0000000 --- a/experiments/exp.css +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright © 2020. Spectrollay - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ diff --git a/experiments/exp.js b/experiments/index.css similarity index 92% rename from experiments/exp.js rename to experiments/index.css index 9e058e0..270820f 100644 --- a/experiments/exp.js +++ b/experiments/index.css @@ -20,5 +20,10 @@ * SOFTWARE. */ -// 实验性 -console.log("实验性内容"); \ No newline at end of file +.exp_envi_guide { + display: none !important; +} + +.debug_mode { + display: none !important; +} \ No newline at end of file diff --git a/experiments/flags.html b/experiments/index.html similarity index 90% rename from experiments/flags.html rename to experiments/index.html index f7fdf35..25fdc82 100644 --- a/experiments/flags.html +++ b/experiments/index.html @@ -90,37 +90,42 @@
设置页面
- +
环境指南页面
- +
自定义元素
- +
惰性加载机制
- +
响应式设计
- +
无障碍体验优化
- +
服务响应优化
- + +
+ +
+
返回重载优化
+

diff --git a/experiments/index.js b/experiments/index.js new file mode 100644 index 0000000..06656fc --- /dev/null +++ b/experiments/index.js @@ -0,0 +1,71 @@ +/* + * Copyright © 2020. Spectrollay + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +// 实验性 +console.log("实验性内容"); + +const exp_css = document.createElement('link'); +exp_css.rel = 'stylesheet'; +exp_css.href = '/minecraft_repository_test/experiments/index.css'; + +document.head.appendChild(exp_css); + + +// 新的实验性页面 +let newFlagsPageSwitch = document.getElementById('new_flags_page'); +let newFlagsPageState; + +if (newFlagsPageSwitch) { + newFlagsPageState = localStorage.getItem('(/minecraft_repository_test/)new_flags_page'); + if (newFlagsPageState === 'on') { + newFlagsPageSwitch.setAttribute('active', 'on'); + } else { + newFlagsPageSwitch.setAttribute('active', 'off'); + } +} + +function flagsPage() { + rootPath = '/' + (window.location.pathname.split('/').filter(Boolean).length > 0 ? window.location.pathname.split('/').filter(Boolean)[0] + '/' : ''); + newFlagsPageState = localStorage.getItem('(/minecraft_repository_test/)new_flags_page'); + if (newFlagsPageState === 'on') { + setTimeout(function () { + window.location.href = "/minecraft_repository_test/flags/"; + }, 600); + } else { + setTimeout(function () { + window.location.href = "/minecraft_repository_test/experiments/"; + }, 600); + } +} + + +// 实验性无障碍 +let expAccessibilitySwitch = document.getElementById('experimental_accessibility'); +let expAccessibilityState = localStorage.getItem('(/minecraft_repository_test/)experimental_accessibility'); + +if (expAccessibilitySwitch) { + if (expAccessibilityState === 'on') { + expAccessibilitySwitch.setAttribute('active', 'on'); + } else { + expAccessibilitySwitch.setAttribute('active', 'off'); + } +} diff --git a/flags/index.html b/flags/index.html index b7ba457..959081c 100644 --- a/flags/index.html +++ b/flags/index.html @@ -83,7 +83,7 @@
设置页面
- +
启用版本库的设置页面
@@ -92,7 +92,7 @@
环境指南页面
- +
启用环境指南页面
@@ -101,7 +101,7 @@
自定义元素
- +
抢先体验自定义元素及功能封装,开启后无法关闭
@@ -110,7 +110,7 @@
惰性加载机制
- +
通过推迟加载部分大型资源提升网页加载速度
@@ -119,7 +119,7 @@
响应式布局
- +
使用更加灵活的页面布局以适应不同的设备
@@ -128,7 +128,7 @@
无障碍体验优化
- +
适配无障碍设计,优化在各种环境下的使用体验
@@ -137,11 +137,20 @@
服务响应优化
- +
通过优化网站缓存与加载机制提升响应速度
+
+
+
+
返回重载优化
+ +
+
优化在执行返回操作时的页面重加载流程
+
+
diff --git a/index.html b/index.html index a801275..b9ee769 100644 --- a/index.html +++ b/index.html @@ -558,7 +558,7 @@ document.head.appendChild(public_define); rootPath = '/' + (window.location.pathname.split('/').filter(Boolean).length > 0 ? window.location.pathname.split('/').filter(Boolean)[0] + '/' : ''); - const repositoryAttribute = localStorage.getItem('repository_attribute'); + const repositoryAttribute = localStorage.getItem('minecraft_repository_attribute'); if (repositoryAttribute) { if (repositoryAttribute.includes('test=true')) { @@ -567,7 +567,7 @@ } } else if (repositoryAttribute.includes('test=false')) { if (rootPath.includes('_test')) { - localStorage.setItem('repository_attribute', 'test=true'); + localStorage.setItem('minecraft_repository_attribute', 'test=true'); } } } else { @@ -613,14 +613,14 @@ const day = date.getDate(); if (rootPath.includes('_test')) { - const neverShowIn15Days = localStorage.getItem(`(${rootPath})neverShowIn15Days`); + const neverShowIn15Days = localStorage.getItem('(/minecraft_repository_test/)neverShowIn15Days'); if (neverShowIn15Days) { const lastHideTime = new Date(parseInt(neverShowIn15Days, 10)); const now = new Date(); const diff = now - lastHideTime; const fifteenDays = 15 * 24 * 60 * 60 * 1000; if (diff > fifteenDays) { - localStorage.removeItem(`(${rootPath})neverShowIn15Days`); + localStorage.removeItem('(/minecraft_repository_test/)neverShowIn15Days'); } else { console.log("时间未到,不显示测试仓库提示"); } diff --git a/javascript/accessibility.js b/javascript/accessibility.js index c461199..f9b423f 100644 --- a/javascript/accessibility.js +++ b/javascript/accessibility.js @@ -20,150 +20,161 @@ * SOFTWARE. */ -// 焦点事件 - -// 选择多个类名、ID 和自定义元素 - -// 移除焦点列表 -const exclusionSelectors = [ - 'button', - '.overlay', - 'modal_area', - 'modal_checkbox_area .custom-checkbox' -]; -// 新增焦点列表 -const inclusionSelectors = [ - '.header_item:not(.header_right_blank)', - '#banner_tip', - 'modal_close_btn', - '.edition_block', - '.btn:not(.disabled_btn)', - '.tab_bar_btn', - '.expandable_card', - '.plan_block', - '.custom-checkbox:not(.disabled)', - '.switch:not(.disabled_switch) .switch_slider', - '.slider_slider:not(.disabled_slider)' -]; - -// 生成选择器字符串 -const exclusionSelectorString = exclusionSelectors.join(', '); -const inclusionSelectorString = inclusionSelectors.join(', '); - -// 选择所有匹配的元素 -const exclusionElements = document.querySelectorAll(exclusionSelectorString); -const inclusionElements = document.querySelectorAll(inclusionSelectorString); - -// 为每个选中的元素设置 tabindex 属性 -exclusionElements.forEach(exclusionElement => { - exclusionElement.setAttribute('tabindex', '-1'); -}); - -inclusionElements.forEach(inclusionElement => { - inclusionElement.setAttribute('tabindex', '0'); - inclusionElement.addEventListener('keyup', function (event) { - if (event.key === 'Enter') { - inclusionElement.click(); - } +if (localStorage.getItem('(/minecraft_repository_test/)experimental_accessibility') === 'on') { + // 焦点事件 + // 选择多个类名、ID 和自定义元素 + // 移除焦点列表 + const exclusionSelectors = [ + 'button', + '.overlay', + 'modal_area', + 'modal_checkbox_area .custom-checkbox' + ]; + // 新增焦点列表 + const inclusionSelectors = [ + '.header_item:not(.header_right_blank)', + '#banner_tip', + 'modal_close_btn', + '.edition_block', + '.btn:not(.disabled_btn)', + '.tab_bar_btn', + '.expandable_card', + '.plan_block', + '.custom-checkbox:not(.disabled)', + '.switch:not(.disabled_switch) .switch_slider', + '.slider_slider:not(.disabled_slider)' + ]; + + // 生成选择器字符串 + const exclusionSelectorString = exclusionSelectors.join(', '); + const inclusionSelectorString = inclusionSelectors.join(', '); + + // 选择所有匹配的元素 + const exclusionElements = document.querySelectorAll(exclusionSelectorString); + const inclusionElements = document.querySelectorAll(inclusionSelectorString); + + // 为每个选中的元素设置 tabindex 属性 + exclusionElements.forEach(exclusionElement => { + exclusionElement.setAttribute('tabindex', '-1'); }); -}); - -// 弹窗焦点陷阱 -function updateFocusableElements() { - const modals = document.querySelectorAll('modal'); - modals.forEach((modal) => { - // 移除旧的事件监听器 - const oldHandler = (e) => { - if (e.key === 'Tab') { - handleTabNavigation(e, modal); + inclusionElements.forEach(inclusionElement => { + inclusionElement.setAttribute('tabindex', '0'); + inclusionElement.addEventListener('keyup', function (event) { + if (event.key === 'Enter') { + inclusionElement.click(); } - }; - modal.removeEventListener('keydown', oldHandler); + }); + }); + - // 更新焦点元素 - const focusableElementsString = 'a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]):not(.disabled_btn), iframe, object, embed, [tabindex="0"], [contenteditable]'; + // 弹窗焦点陷阱 + function updateFocusableElements() { + const modals = document.querySelectorAll('modal'); + modals.forEach((modal) => { + // 移除旧的事件监听器 + const oldHandler = (e) => { + if (e.key === 'Tab') { + handleTabNavigation(e, modal); + } + }; + modal.removeEventListener('keydown', oldHandler); + + // 更新焦点元素 + const focusableElementsString = 'a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]):not(.disabled_btn), iframe, object, embed, [tabindex="0"], [contenteditable]'; + let focusableElements = modal.querySelectorAll(focusableElementsString); + focusableElements = Array.from(focusableElements); + + const firstTabStop = focusableElements[0]; + const lastTabStop = focusableElements[focusableElements.length - 1]; + + modal.addEventListener('keydown', (e) => handleTabNavigation(e, modal)); + + // 聚焦模态框内的第一个可聚焦元素 + modal.addEventListener('shown.modal', () => { + if (firstTabStop) { + firstTabStop.focus(); + } + }); + }); + } + + function handleTabNavigation(e, modal) { + const focusableElementsString = 'a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]):not(.disabled_btn), custom-checkbox:not(.disabled), iframe, object, embed, [tabindex="0"], [contenteditable]'; let focusableElements = modal.querySelectorAll(focusableElementsString); focusableElements = Array.from(focusableElements); const firstTabStop = focusableElements[0]; const lastTabStop = focusableElements[focusableElements.length - 1]; - modal.addEventListener('keydown', (e) => handleTabNavigation(e, modal)); - - // 聚焦模态框内的第一个可聚焦元素 - modal.addEventListener('shown.modal', () => { - if (firstTabStop) { - firstTabStop.focus(); - } - }); - }); -} - -function handleTabNavigation(e, modal) { - const focusableElementsString = 'a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]):not(.disabled_btn), custom-checkbox:not(.disabled), iframe, object, embed, [tabindex="0"], [contenteditable]'; - let focusableElements = modal.querySelectorAll(focusableElementsString); - focusableElements = Array.from(focusableElements); - - const firstTabStop = focusableElements[0]; - const lastTabStop = focusableElements[focusableElements.length - 1]; - - if (e.key === 'Tab') { - if (e.shiftKey) { - // Shift + Tab - if (document.activeElement === firstTabStop) { - e.preventDefault(); - lastTabStop.focus(); - } - } else { - // Tab - if (document.activeElement === lastTabStop) { - e.preventDefault(); - firstTabStop.focus(); + if (e.key === 'Tab') { + if (e.shiftKey) { + // Shift + Tab + if (document.activeElement === firstTabStop) { + e.preventDefault(); + lastTabStop.focus(); + } + } else { + // Tab + if (document.activeElement === lastTabStop) { + e.preventDefault(); + firstTabStop.focus(); + } } } } -} -updateFocusableElements(); + updateFocusableElements(); + + // TTS文本转语音 + let enable_tts; + enable_tts = false; + if (enable_tts) { + useTTS(); + } + + function useTTS() { + if ('speechSynthesis' in window) { + // 支持TTS + let currentUtterance = null; + let lastText = ''; -// TTS文本转语音 -let enable_tts; -enable_tts = false; -if (enable_tts) { - if ('speechSynthesis' in window) { - // 支持TTS - let currentUtterance = null; - let lastText = ''; + function speakText(text) { + if (text === lastText) return; // 如果目标文本没有改变 + lastText = text; - function speakText(text) { - if (text === lastText) return; // If the text hasn't changed, do nothing - lastText = text; + if (currentUtterance) { + window.speechSynthesis.cancel(); + } - if (currentUtterance) { - window.speechSynthesis.cancel(); + currentUtterance = new SpeechSynthesisUtterance(text); + window.speechSynthesis.speak(currentUtterance); } - currentUtterance = new SpeechSynthesisUtterance(text); - window.speechSynthesis.speak(currentUtterance); - } + function handleEvent(event) { + const text = event.target.innerText.trim(); + if (text) { + speakText(text); + } + } + + document.addEventListener('mouseover', handleEvent); + document.addEventListener('touchstart', handleEvent, {passive: true}); - function handleEvent(event) { - const text = event.target.innerText.trim(); - if (!text) return; - speakText(text); + window.addEventListener('unload', () => { + window.speechSynthesis.cancel(); // 页面卸载时取消未完成的语音任务 + }); + } else { + // 不支持TTS + console.log("当前浏览器不支持TTS文本转语音"); } + } - document.addEventListener('mouseover', handleEvent); - document.addEventListener('touchstart', handleEvent, {passive: true}); - } else { - // 不支持TTS + // Screen Reader屏幕阅读器 + let element; + if (element) { + element.setAttribute('role', 'main'); + element.setAttribute('aria-hidden', true); } -} -// Screen Reader屏幕阅读器 -let element; -if (element) { - element.setAttribute('role', 'main'); - element.setAttribute('aria-hidden', true); } \ No newline at end of file diff --git a/javascript/advanced.js b/javascript/advanced.js index a4ea953..734f194 100644 --- a/javascript/advanced.js +++ b/javascript/advanced.js @@ -20,18 +20,6 @@ * SOFTWARE. */ -// 跳转实验性页面 -function flagsPage() { - rootPath = '/' + (window.location.pathname.split('/').filter(Boolean).length > 0 ? window.location.pathname.split('/').filter(Boolean)[0] + '/' : ''); - setTimeout(function () { - if (rootPath.includes('_test')) { - window.location.href = "/minecraft_repository_test/experiments/flags.html"; - } else { - window.location.href = "/minecraft_repository_test/flags/"; - } - }, 600); -} - // 点击Debug图标事件 function debugPage() { setTimeout(function () { @@ -41,9 +29,17 @@ function debugPage() { // 清除存储 function clearStorage() { - localStorage.clear(); + const keyPatterns = ["(/minecraft_repository_test/)", "minecraft_repository_attribute"]; + for (let i = 0; i < localStorage.length; i++) { + const key = localStorage.key(i); + if (keyPatterns.some(pattern => key.includes(pattern))) { + localStorage.removeItem(key); + i--; + } + } sessionStorage.clear(); console.log('清除存储数据成功'); + mainPage(); } // 重载页面 diff --git a/javascript/custom_elements.js b/javascript/custom_elements.js index b47503d..b639ea3 100644 --- a/javascript/custom_elements.js +++ b/javascript/custom_elements.js @@ -383,6 +383,11 @@ customElements.define('custom-slider', CustomSlider); class CustomSwitch extends HTMLElement { constructor() { super(); + this.isSwitchOn = false; // 用于存储当前开关的状态 + this.isSwitchDisabled = false; // 用于存储当前开关的禁用状态 + this.eventsBound = false; // 标志位,避免重复绑定事件 + this.startX = 0; // 用于拖动时记录起始位置 + this.isDragging = false; // 用于标识是否正在拖动 this.render(); } @@ -391,19 +396,19 @@ class CustomSwitch extends HTMLElement { } attributeChangedCallback(name, oldValue, newValue) { - this.render(); + this.updateRender(); } render() { const active = this.getAttribute('active') || 'off'; const status = this.getAttribute('status') || 'disabled_switch'; - const isDisabled = status !== 'enabled'; - const isOn = active === 'on'; + this.isSwitchDisabled = status !== 'enabled'; + this.isSwitchOn = localStorage.getItem('(/minecraft_repository_test/)' + this.id) === 'on' || active === 'on'; this.innerHTML = `
-
+
@@ -411,98 +416,74 @@ class CustomSwitch extends HTMLElement {
`; - // 添加点击事件监听器 - const switchElement = this.querySelector(".switch"); - const switchSlider = this.querySelector(".switch_slider"); - let isSwitchOn = switchElement.classList.contains("on"); - let isSwitchDisabled = switchElement.classList.contains("disabled_switch"); - let startX = 0; - let isDragging = false; - - if (!isSwitchDisabled) { - - // 点击父元素执行点击事件 - const parentElement = this.parentElement; - if (parentElement) { - parentElement.addEventListener("click", () => { - if (!isDragging) { - isSwitchOn = !isSwitchOn; - this.updateSwitchState(isSwitchOn); - } - }); - } - - // 点击元素本身执行点击事件 - switchElement.addEventListener("click", () => { - isSwitchOn = !isSwitchOn; - this.updateSwitchState(isSwitchOn); - }); + if (!this.eventsBound) { + this.bindEvents(); + this.eventsBound = true; + } + } - // 键盘事件监听器 - switchElement.addEventListener("keydown", (e) => { - if (e.key === "Enter") { - isSwitchOn = !isSwitchOn; - this.updateSwitchState(isSwitchOn); - } - }); + updateRender() { + const active = this.getAttribute('active') || 'off'; + this.isSwitchOn = localStorage.getItem('(/minecraft_repository_test/)' + this.id) === 'on' || active === 'on'; + const switchElement = this.querySelector(".switch"); + if (switchElement) { + switchElement.classList.toggle("on", this.isSwitchOn); + switchElement.classList.toggle("off", !this.isSwitchOn); + } + } - // 拖动事件 - switchElement.addEventListener("mousedown", (e) => { - isDragging = true; - switchSlider.classList.add('active'); - startX = e.clientX; - }); + bindEvents() { + const switchElement = this.querySelector(".switch"); + const switchSlider = this.querySelector(".switch_slider"); - switchElement.addEventListener("touchstart", (e) => { - isDragging = true; + if (!this.isSwitchDisabled) { + // 点击和拖动事件 + const handlePointerDown = (e) => { + this.isDragging = true; switchSlider.classList.add('active'); - startX = e.touches[0].clientX; - }); - - document.addEventListener("mouseup", (e) => { - if (isDragging) { - let elementAtPoint = document.elementFromPoint(e.clientX, e.clientY); - if (!switchElement.contains(elementAtPoint)) { - let currentX = e.clientX; - if (currentX - startX > 10) { - if (!isSwitchOn) { - isSwitchOn = true; - this.updateSwitchState(isSwitchOn); - } - } else if (currentX - startX < -10) { - if (isSwitchOn) { - isSwitchOn = false; - this.updateSwitchState(isSwitchOn); - } - } + this.startX = e.type === 'mousedown' ? e.clientX : e.touches[0].clientX; + }; + + const handlePointerUp = (e) => { + if (this.isDragging) { + const currentX = e.type === 'mouseup' ? e.clientX : e.changedTouches[0].clientX; + const distanceMoved = currentX - this.startX; + if (distanceMoved > 10 && !this.isSwitchOn) { + this.isSwitchOn = true; + this.updateSwitchState(this.isSwitchOn); + } else if (distanceMoved < -10 && this.isSwitchOn) { + this.isSwitchOn = false; + this.updateSwitchState(this.isSwitchOn); } } setTimeout(() => { - isDragging = false; + this.isDragging = false; switchSlider.classList.remove('active'); }, 0); - }); + }; + + const handleClick = () => { + this.isSwitchOn = !this.isSwitchOn; + this.updateSwitchState(this.isSwitchOn); + }; - document.addEventListener("touchend", (e) => { - if (isDragging) { - let currentX = e.changedTouches[0].clientX; - if (currentX - startX > 10) { - if (!isSwitchOn) { - isSwitchOn = true; - this.updateSwitchState(isSwitchOn); - } - } else if (currentX - startX < -10) { - if (isSwitchOn) { - isSwitchOn = false; - this.updateSwitchState(isSwitchOn); - } + // 点击父元素执行点击事件 + const parentElement = this.parentElement; + if (parentElement) { + parentElement.addEventListener("click", (e) => { + if (!this.isDragging && e.target !== switchElement) { + this.isSwitchOn = !this.isSwitchOn; + this.updateSwitchState(this.isSwitchOn); } - } - setTimeout(() => { - isDragging = false; - switchSlider.classList.remove('active'); - }, 0); - }); + }, true); // 使用事件捕获阶段 + } + + // 绑定点击和拖动事件 + switchElement.addEventListener("click", handleClick); + switchElement.addEventListener("mousedown", handlePointerDown); + switchElement.addEventListener("touchstart", handlePointerDown); + document.addEventListener("mouseup", handlePointerUp); + document.addEventListener("touchend", handlePointerUp); } } @@ -516,9 +497,11 @@ class CustomSwitch extends HTMLElement { if (isOn) { switchSlider.classList.add('switch_bounce_left'); switchSlider.classList.remove('switch_bounce_right'); + localStorage.setItem('(/minecraft_repository_test/)' + this.id, 'on'); } else { switchSlider.classList.add('switch_bounce_right'); switchSlider.classList.remove('switch_bounce_left'); + localStorage.setItem('(/minecraft_repository_test/)' + this.id, 'off'); } const switchStatus = this.querySelector(".switch_status"); if (switchStatus) { diff --git a/javascript/public_define.js b/javascript/public_define.js index 047e384..650ccc6 100644 --- a/javascript/public_define.js +++ b/javascript/public_define.js @@ -25,12 +25,12 @@ const main_version_name = "4"; const primary_version_name = main_version_name + ".6"; // 例 4.0 const secondary_version_name = primary_version_name + ".5"; // 例 4.0.0 -const version_name_short = secondary_version_name + ".50"; // 例 4.0.0.1 NOTE 小版本 +const version_name_short = secondary_version_name + ".51"; // 例 4.0.0.1 NOTE 小版本 const version_type = "Canary"; // Preview/Insider_(Preview/Alpha/Beta)/Canary/Alpha/Beta/Pre/RC/Stable/Release/SP const version_type_count = version_type + ""; // 例 Build1 NOTE 小版本,可为空 const version_name = version_name_short + "." + version_type; // 例 4.0.0.1.Build const version_nickname = secondary_version_name + "-" + version_type_count; // 例 4.0.0-Build1 -const update_count = "20240830" + ".01"; // NOTE 小版本,有提交就变 +const update_count = "20240909" + ".01"; // NOTE 小版本,有提交就变 const publish_version_name = primary_version_name + "." + update_count; // 例 4.20240101.01 const server_version = "4.0"; let commit = "#"; // 例 #2024010101 , 仅留 # 则从 update_count 提取 NOTE 有不更改版本的提交就变 diff --git a/javascript/public_script.js b/javascript/public_script.js index a85b738..34577ad 100644 --- a/javascript/public_script.js +++ b/javascript/public_script.js @@ -210,6 +210,8 @@ const slashCount = (currentPagePath.match(/\//g) || []).length; // 创建内联元素 const accessibility_js = document.createElement('script'); accessibility_js.src = '/minecraft_repository_test/javascript/accessibility.js'; +const exp_js = document.createElement('script'); +exp_js.src = '/minecraft_repository_test/experiments/index.js'; const custom_elements_css = document.createElement('link'); custom_elements_css.rel = 'stylesheet'; custom_elements_css.href = '/minecraft_repository_test/stylesheet/custom_elements.css'; @@ -219,6 +221,7 @@ public_style.href = '/minecraft_repository_test/stylesheet/public_style.css'; // 将内联元素添加到头部 document.head.appendChild(accessibility_js); +document.head.appendChild(exp_js); document.head.appendChild(custom_elements_css); document.head.appendChild(public_style); @@ -259,21 +262,21 @@ if (rootPath.includes('_test')) { console.log("当前位于" + pageLevel); -if (rootPath.includes('_test') && !localStorage.getItem('repository_attribute')) { - localStorage.setItem('repository_attribute', 'test=true'); -} else if (!rootPath.includes('_test') && !localStorage.getItem('repository_attribute')) { - localStorage.setItem('repository_attribute', 'test=false'); +if (rootPath.includes('_test') && !localStorage.getItem('minecraft_repository_attribute')) { + localStorage.setItem('minecraft_repository_attribute', 'test=true'); +} else if (!rootPath.includes('_test') && !localStorage.getItem('minecraft_repository_attribute')) { + localStorage.setItem('minecraft_repository_attribute', 'test=false'); } function joinTest() { - localStorage.setItem('repository_attribute', 'test=true'); + localStorage.setItem('minecraft_repository_attribute', 'test=true'); setTimeout(function () { window.location.href = hostPath + "/minecraft_repository_test"; }, 600); } function leaveTest() { - localStorage.setItem('repository_attribute', 'test=false'); + localStorage.setItem('minecraft_repository_attribute', 'test=false'); localStorage.removeItem('(/minecraft_repository_test/)neverShowIn15Days'); setTimeout(function () { window.location.href = hostPath + "/minecraft_repository"; @@ -318,7 +321,7 @@ const compatibilityModal = ` document.body.insertAdjacentHTML('afterbegin', compatibilityModal); setTimeout(function () { - if (localStorage.getItem(`(${rootPath})neverShowCompatibilityModalAgain`) !== '1') { + if (localStorage.getItem('(/minecraft_repository_test/)neverShowCompatibilityModalAgain') !== '1') { const overlay = document.getElementById("overlay_compatibility_modal"); const modal = document.getElementById("compatibility_modal"); overlay.style.display = "block"; @@ -339,7 +342,7 @@ function hideCompatibilityModal(button) { function neverShowCompatibilityModalAgain(button) { hideCompatibilityModal(button); - localStorage.setItem(`(${rootPath})neverShowCompatibilityModalAgain`, '1'); + localStorage.setItem('(/minecraft_repository_test/)neverShowCompatibilityModalAgain', '1'); console.log("关闭兼容性提示弹窗且不再提示"); } @@ -369,7 +372,7 @@ const firstVisitTodayModal = ` document.body.insertAdjacentHTML('afterbegin', firstVisitTodayModal); function checkFirstVisit() { - const firstVisit = localStorage.getItem(`(${rootPath})firstVisit`); + const firstVisit = localStorage.getItem('(/minecraft_repository_test/)firstVisit'); const is404Page = document.title.includes("404 NOT FOUND"); const firstVisitAllowedPaths = [ `${rootPath}`, @@ -390,7 +393,7 @@ function checkFirstVisit() { } if (window.location.pathname === `${rootPath}` || window.location.pathname === `${rootPath}index.html`) { - localStorage.setItem(`(${rootPath})firstVisit`, today); + localStorage.setItem('(/minecraft_repository_test/)firstVisit', today); } function hideFirstVisitTodayModal(button) { diff --git a/updatelog/index.html b/updatelog/index.html index a34865f..8b9608b 100644 --- a/updatelog/index.html +++ b/updatelog/index.html @@ -223,6 +223,43 @@
+
+ + 4.6.20240909.01 + (V) 4.6.5.51 + + + 本次更新主要对无障碍和自定义元素进行了改进, 优化了实验性内容的实现并进行了一些改进. 欢迎向我们汇报你发现的问题. + + + 实验性 + 加入了返回重载优化开关 + 目前没有任何内容,也无法通过常规手段访问 + 无障碍更改现在可以在实验性内容页面自由的启用或禁用了 + 未完成的文本转语音任务现在会在页面卸载时清除了 + 优化了Switch开关的实现方式 + 现在Switch开关可以记住上次页面卸载时的状态了 + 修复了可能会重复出现多次点击事件的问题 + 修复了在某些时候无法触发点击事件的问题 + 现在未被启用的实验性功能将不再可见了 + + + 新内容 + 新增了一些显示判定 + + + 更改 + 你现在可以选择是否启用新版实验性内容页面了 + 更改了部分存储数据的格式 + + + 修复 + 修复了清除存储数据功能会清除部分不该清除的数据的问题 + + + +
+
4.6.20240830.01