MediaWiki:Gadget-site-js.js:修订间差异
MediaWiki界面页面
更多操作
第1行: | 第1行: | ||
/********************** | /********************** | ||
* 模块 | * 模块 0:vConsole 加载 | ||
**********************/ | **********************/ | ||
const vConsoleScript = document.createElement('script'); | |||
vConsoleScript.src = 'https://cdn.bootcdn.net/ajax/libs/vConsole/3.15.1/vconsole.min.js'; | |||
document.head.appendChild(vConsoleScript); | |||
vConsoleScript.onload = () => new VConsole(); | |||
/********************** | /********************** | ||
* 模块 1:CSS 变量 RGB | * 模块 1:CSS 变量 RGB 转换 | ||
**********************/ | **********************/ | ||
const ColorUtil = (function () { | |||
const OBS_VAR = '--background-color-base'; | |||
let cachedRgb = ''; | |||
function parseHex(hex) { | |||
hex = hex.replace(/^#/, ''); | |||
if (hex.length === 3) hex = hex.split('').map(c => c + c).join(''); | |||
if (hex.length !== 6) return '0, 0, 0'; | |||
const [r, g, b] = [0, 2, 4].map(i => parseInt(hex.substring(i, i + 2), 16)); | |||
return `${r}, ${g}, ${b}`; | |||
} | |||
function update() { | |||
const root = document.documentElement; | |||
const hex = getComputedStyle(root).getPropertyValue(OBS_VAR).trim(); | |||
const rgb = parseHex(hex || '#000'); | |||
if (rgb !== cachedRgb) { | |||
root.style.setProperty('--background-color-rgb', rgb); | |||
cachedRgb = rgb; | |||
} | |||
} | |||
update(); | |||
const mo = new MutationObserver(update); | |||
mo.observe(document.documentElement, { attributes: true, attributeFilter: ['style'] }); | |||
return { | |||
destroy() { mo.disconnect(); } | |||
}; | |||
} | |||
})(); | })(); | ||
/********************** | /********************** | ||
* 模块 | * 模块 2:上传页引导弹窗 | ||
**********************/ | **********************/ | ||
if (mw?.config?.get('wgCanonicalSpecialPageName') === 'Upload') { | |||
const KEY = 'uploadPreference'; | |||
const pref = mw.storage.get(KEY); | |||
if (pref === 'wizard') window.location = mw.util.getUrl('Special:UploadWizard'); | |||
if (pref === 'classic') ; | |||
document.addEventListener('click', function initDialog() { | |||
document.removeEventListener('click', initDialog); | |||
mw.loader.using(['oojs-ui-core', 'oojs-ui-widgets']).then(() => { | |||
class UploadDialog extends OO.ui.ProcessDialog { | |||
static name = 'UploadDialog'; | |||
static title = '请选择上传方式'; | |||
static actions = [{ action: 'classic', label: '❌ 传统方式', flags: ['safe'] }]; | |||
initialize() { | |||
super.initialize(); | |||
this._remember = new OO.ui.CheckboxInputWidget(); | |||
const wizardBtn = new OO.ui.ButtonWidget({ | |||
label: '✅ 上传向导', | |||
flags: ['primary'], | |||
href: mw.util.getUrl('Special:UploadWizard'), | |||
target: '_self' | |||
}); | |||
wizardBtn.on('click', () => { | |||
if (this._remember.isSelected()) mw.storage.set(KEY, 'wizard'); | |||
}); | |||
this.$body.append( | |||
$('<p>').text('请选择上传方式:'), | |||
wizardBtn.$element, | |||
new OO.ui.FieldLayout(this._remember, { label: '记住选择', align: 'inline' }).$element | |||
); | |||
} | |||
getActionProcess(action) { | |||
if (action === 'classic') { | |||
if (this._remember.isSelected()) mw.storage.set(KEY, 'classic'); | |||
return new OO.ui.Process(() => this.close()); | |||
} | } | ||
return super.getActionProcess(action); | |||
} | |||
} | |||
} | |||
const wm = new OO.ui.WindowManager(); | |||
document.body.appendChild(wm.$element); | |||
document. | wm.addWindows([new UploadDialog()]); | ||
wm.openWindow('UploadDialog'); | |||
}); | |||
}); | |||
} | |||
} | |||
/********************** | /********************** | ||
* 模块 | * 模块 3:加载指示器(带配置) | ||
**********************/ | **********************/ | ||
const LoadingIndicator = (function () { | |||
const defaultConfig = { | |||
imageUrl: 'https://wiki.ottohub.cn/images/0/02/Loading.png', | |||
position: { bottom: '20px', right: '20px' }, | |||
size: '256px', | |||
timeout: 15000, | |||
zIndex: '99999', | |||
fadeDuration: 300 | |||
}; | |||
let indicator = null; | |||
let timerId = null; | |||
let currentConfig = { ...defaultConfig }; | |||
function createIndicator() { | |||
const div = document.createElement('div'); | |||
div.style.cssText = ` | |||
position: fixed; | |||
width: ${currentConfig.size}; | |||
height: ${currentConfig.size}; | |||
bottom: ${currentConfig.position.bottom}; | |||
right: ${currentConfig.position.right}; | |||
z-index: ${currentConfig.zIndex}; | |||
background: url('${currentConfig.imageUrl}') center/contain no-repeat; | |||
opacity: 0; | |||
transition: opacity ${currentConfig.fadeDuration}ms; | |||
`; | |||
return div; | |||
} | |||
function show() { | |||
if (indicator) return; | |||
indicator = createIndicator(); | |||
document.body.appendChild(indicator); | |||
setTimeout(() => { | |||
indicator.style.opacity = '1'; | |||
}, 10); | |||
timerId = setTimeout(hide, currentConfig.timeout); | |||
} | |||
function hide() { | |||
} | if (!indicator) return; | ||
indicator.style.opacity = '0'; | |||
setTimeout(() => { | |||
indicator.remove(); | |||
indicator = null; | |||
}, currentConfig.fadeDuration); | |||
clearTimeout(timerId); | |||
} | |||
function updateConfig(newConfig) { | |||
currentConfig = { ...defaultConfig, ...newConfig }; | |||
} | |||
document.addEventListener('DOMContentLoaded', show); | |||
window.addEventListener('load', hide); | |||
return { | |||
show, | |||
hide, | |||
updateConfig | |||
}; | |||
} | |||
})(); | })(); |
2025年6月21日 (六) 08:10的版本
/**********************
* 模块 0:vConsole 加载
**********************/
const vConsoleScript = document.createElement('script');
vConsoleScript.src = 'https://cdn.bootcdn.net/ajax/libs/vConsole/3.15.1/vconsole.min.js';
document.head.appendChild(vConsoleScript);
vConsoleScript.onload = () => new VConsole();
/**********************
* 模块 1:CSS 变量 RGB 转换
**********************/
const ColorUtil = (function () {
const OBS_VAR = '--background-color-base';
let cachedRgb = '';
function parseHex(hex) {
hex = hex.replace(/^#/, '');
if (hex.length === 3) hex = hex.split('').map(c => c + c).join('');
if (hex.length !== 6) return '0, 0, 0';
const [r, g, b] = [0, 2, 4].map(i => parseInt(hex.substring(i, i + 2), 16));
return `${r}, ${g}, ${b}`;
}
function update() {
const root = document.documentElement;
const hex = getComputedStyle(root).getPropertyValue(OBS_VAR).trim();
const rgb = parseHex(hex || '#000');
if (rgb !== cachedRgb) {
root.style.setProperty('--background-color-rgb', rgb);
cachedRgb = rgb;
}
}
update();
const mo = new MutationObserver(update);
mo.observe(document.documentElement, { attributes: true, attributeFilter: ['style'] });
return {
destroy() { mo.disconnect(); }
};
})();
/**********************
* 模块 2:上传页引导弹窗
**********************/
if (mw?.config?.get('wgCanonicalSpecialPageName') === 'Upload') {
const KEY = 'uploadPreference';
const pref = mw.storage.get(KEY);
if (pref === 'wizard') window.location = mw.util.getUrl('Special:UploadWizard');
if (pref === 'classic') ;
document.addEventListener('click', function initDialog() {
document.removeEventListener('click', initDialog);
mw.loader.using(['oojs-ui-core', 'oojs-ui-widgets']).then(() => {
class UploadDialog extends OO.ui.ProcessDialog {
static name = 'UploadDialog';
static title = '请选择上传方式';
static actions = [{ action: 'classic', label: '❌ 传统方式', flags: ['safe'] }];
initialize() {
super.initialize();
this._remember = new OO.ui.CheckboxInputWidget();
const wizardBtn = new OO.ui.ButtonWidget({
label: '✅ 上传向导',
flags: ['primary'],
href: mw.util.getUrl('Special:UploadWizard'),
target: '_self'
});
wizardBtn.on('click', () => {
if (this._remember.isSelected()) mw.storage.set(KEY, 'wizard');
});
this.$body.append(
$('<p>').text('请选择上传方式:'),
wizardBtn.$element,
new OO.ui.FieldLayout(this._remember, { label: '记住选择', align: 'inline' }).$element
);
}
getActionProcess(action) {
if (action === 'classic') {
if (this._remember.isSelected()) mw.storage.set(KEY, 'classic');
return new OO.ui.Process(() => this.close());
}
return super.getActionProcess(action);
}
}
const wm = new OO.ui.WindowManager();
document.body.appendChild(wm.$element);
wm.addWindows([new UploadDialog()]);
wm.openWindow('UploadDialog');
});
});
}
/**********************
* 模块 3:加载指示器(带配置)
**********************/
const LoadingIndicator = (function () {
const defaultConfig = {
imageUrl: 'https://wiki.ottohub.cn/images/0/02/Loading.png',
position: { bottom: '20px', right: '20px' },
size: '256px',
timeout: 15000,
zIndex: '99999',
fadeDuration: 300
};
let indicator = null;
let timerId = null;
let currentConfig = { ...defaultConfig };
function createIndicator() {
const div = document.createElement('div');
div.style.cssText = `
position: fixed;
width: ${currentConfig.size};
height: ${currentConfig.size};
bottom: ${currentConfig.position.bottom};
right: ${currentConfig.position.right};
z-index: ${currentConfig.zIndex};
background: url('${currentConfig.imageUrl}') center/contain no-repeat;
opacity: 0;
transition: opacity ${currentConfig.fadeDuration}ms;
`;
return div;
}
function show() {
if (indicator) return;
indicator = createIndicator();
document.body.appendChild(indicator);
setTimeout(() => {
indicator.style.opacity = '1';
}, 10);
timerId = setTimeout(hide, currentConfig.timeout);
}
function hide() {
if (!indicator) return;
indicator.style.opacity = '0';
setTimeout(() => {
indicator.remove();
indicator = null;
}, currentConfig.fadeDuration);
clearTimeout(timerId);
}
function updateConfig(newConfig) {
currentConfig = { ...defaultConfig, ...newConfig };
}
document.addEventListener('DOMContentLoaded', show);
window.addEventListener('load', hide);
return {
show,
hide,
updateConfig
};
})();