+
加载调试程序
@@ -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开关可以记住上次页面卸载时的状态了
+ 修复了可能会重复出现多次点击事件的问题
+ 修复了在某些时候无法触发点击事件的问题
+ 现在未被启用的实验性功能将不再可见了
+
+
+ 新内容
+ 新增了一些显示判定
+
+
+ 更改
+ 你现在可以选择是否启用新版实验性内容页面了
+ 更改了部分存储数据的格式
+
+
+ 修复
+ 修复了清除存储数据功能会清除部分不该清除的数据的问题
+
+
+
+
+