MediaWiki:Gadget-theme.js: различия между версиями
Материал из Space Station 14 Вики
Pok (обсуждение | вклад) мНет описания правки |
Pok (обсуждение | вклад) Нет описания правки |
||
| (не показано 9 промежуточных версий этого же участника) | |||
| Строка 1: | Строка 1: | ||
;(function($, mw){ | ;(function($, mw){ | ||
const COOKIE = 'ss14_wikiTheme'; | const COOKIE = 'ss14_wikiTheme'; | ||
const COOKIE_SPACE = 'ss14_spaceAnimation'; | const COOKIE_SPACE = 'ss14_spaceAnimation'; | ||
const COOKIE_PROJECT = 'ss14_preferredProject'; | |||
function loadTheme() { | function loadTheme() { | ||
| Строка 30: | Строка 31: | ||
$.cookie(COOKIE_SPACE, val, { expires: 365, path: '/' }); | $.cookie(COOKIE_SPACE, val, { expires: 365, path: '/' }); | ||
} | } | ||
function applySpaceAnimation(val) { | function applySpaceAnimation(val) { | ||
const $body = $('body'); | const $body = $('body'); | ||
const themeClasses = ($body.attr('class') || '') | |||
.split(/\s+/) | |||
.filter(cls => cls.indexOf('wgl-space-animation-') === 0); | |||
if (themeClasses.length) { | |||
$body.removeClass(themeClasses.join(' ')); | |||
} | |||
$body.addClass(`wgl-space-animation-${val}`); | $body.addClass(`wgl-space-animation-${val}`); | ||
mw.hook(' | mw.hook('wgl.spaceAnimationChanged').fire(val); | ||
} | |||
function loadPreferredProject() { | |||
return $.cookie(COOKIE_PROJECT) || 'corvax'; | |||
} | |||
function savePreferredProject(val) { | |||
$.cookie(COOKIE_PROJECT, val, { expires: 365, path: '/' }); | |||
} | |||
function applyPreferredProject(val) { | |||
const $body = $('body'); | |||
const classes = ($body.attr('class') || '') | |||
.split(/\s+/) | |||
.filter(cls => cls.indexOf('wgl-preferred-project-') === 0); | |||
if (classes.length) { | |||
$body.removeClass(classes.join(' ')); | |||
} | |||
$body.addClass(`wgl-preferred-project-${val}`); | |||
mw.hook('wgl.preferredProjectChanged').fire(val); | |||
} | } | ||
| Строка 41: | Строка 70: | ||
const $portlet = $('<div>', { | const $portlet = $('<div>', { | ||
class: 'mw-portlet | class: 'mw-portlet mw-portlet-js theme-menu', | ||
id: 'skin-client-prefs-skin-theme' | id: 'skin-client-prefs-skin-theme' | ||
}); | }); | ||
| Строка 58: | Строка 87: | ||
const $wr = $('<div>', { class: 'theme-client-prefs-radio' }); | const $wr = $('<div>', { class: 'theme-client-prefs-radio' }); | ||
const $inp = $('<input>', { | const $inp = $('<input>', { | ||
type: | type: 'radio', | ||
name: | name: 'theme-selection', | ||
id: | id: `theme-value-${opt.key}`, | ||
value: | value: opt.key, | ||
checked: | checked: opt.key === currentTheme | ||
}); | }); | ||
const $lbl = $('<label>', { | const $lbl = $('<label>', { | ||
for: | for: `theme-value-${opt.key}`, | ||
text: | text: opt.label | ||
}); | }); | ||
$wr.append($inp, $lbl); | $wr.append($inp, $lbl); | ||
| Строка 82: | Строка 111: | ||
$container.append($portlet); | $container.append($portlet); | ||
initSpaceMenu($portlet); | initSpaceMenu($portlet); | ||
initPreferredProjectMenu($portlet); | |||
$form.on('change', 'input[name="theme-selection"]', function() { | $form.on('change', 'input[name="theme-selection"]', function() { | ||
| Строка 94: | Строка 124: | ||
const $spacePortlet = $('<div>', { | const $spacePortlet = $('<div>', { | ||
class: 'mw-portlet | class: 'mw-portlet mw-portlet-js theme-menu', | ||
id: 'skin-client-prefs-skin-space' | id: 'skin-client-prefs-skin-space' | ||
}); | }); | ||
| Строка 102: | Строка 132: | ||
); | ); | ||
const $form = $('<form>'); | const $form = $('<form style="grid-template-columns:1fr 1fr;">'); | ||
[ | [ | ||
{ val: 'on', label: 'Включено' }, | { val: 'on', label: 'Включено' }, | ||
{ val: 'off', label: ' | { val: 'off', label: 'Отключено' } | ||
].forEach(opt => { | ].forEach(opt => { | ||
const $wr = $('<div>', { class: ' | const $wr = $('<div>', { class: 'theme-client-prefs-radio' }); | ||
const $inp = $('<input>', { | const $inp = $('<input>', { | ||
type: 'radio', | type: 'radio', | ||
| Строка 138: | Строка 168: | ||
saveSpaceAnimation(newVal); | saveSpaceAnimation(newVal); | ||
applySpaceAnimation(newVal); | applySpaceAnimation(newVal); | ||
}); | |||
} | |||
function initPreferredProjectMenu($afterPortlet, currentVal) { | |||
currentVal = currentVal || loadPreferredProject(); | |||
const $projectPortlet = $('<div>', { | |||
class: 'mw-portlet mw-portlet-js theme-menu', | |||
id: 'skin-client-prefs-skin-project' | |||
}); | |||
$projectPortlet.append( | |||
$('<div>', { class: 'theme-menu__heading', text: 'Предпочитаемый проект' }), | |||
$('<div>', { class: 'theme-menu__content' }) | |||
); | |||
const $form = $('<form style="grid-template-columns:1fr 1fr;">'); | |||
[ | |||
{ val: 'corvax', label: 'Corvax' }, | |||
{ val: 'goob', label: 'Goob' }, | |||
{ val: 'wl', label: 'WL' }, | |||
{ val: 'wega', label: 'Wega' } | |||
].forEach(opt => { | |||
const $wr = $('<div>', { class: 'theme-client-prefs-radio' }); | |||
const $inp = $('<input>', { | |||
type: 'radio', | |||
name: 'preferred-project-selection', | |||
id: `project-value-${opt.val}`, | |||
value: opt.val, | |||
checked: opt.val === currentVal | |||
}); | |||
const $lbl = $('<label>', { | |||
for: `project-value-${opt.val}`, | |||
text: opt.label | |||
}); | |||
$wr.append($inp, $lbl); | |||
$form.append($wr); | |||
}); | |||
$projectPortlet.find('.theme-menu__content').append( | |||
$('<ul>', { class: 'theme-menu__content-list' }) | |||
.append( | |||
$('<li>', { class: 'mw-list-item mw-list-item-js' }) | |||
.append($form) | |||
) | |||
); | |||
$afterPortlet.after($projectPortlet); | |||
applyPreferredProject(currentVal); | |||
$form.on('change', 'input[name="preferred-project-selection"]', function() { | |||
const newVal = $(this).val(); | |||
savePreferredProject(newVal); | |||
applyPreferredProject(newVal); | |||
}); | }); | ||
} | } | ||
| Строка 148: | Строка 231: | ||
saveSpaceAnimation, | saveSpaceAnimation, | ||
applySpaceAnimation, | applySpaceAnimation, | ||
initSpaceMenu | initSpaceMenu, | ||
loadPreferredProject, | |||
savePreferredProject, | |||
applyPreferredProject, | |||
initPreferredProjectMenu | |||
}; | }; | ||
}(jQuery, mediaWiki)); | }(jQuery, mediaWiki)); | ||
Текущая версия от 14:26, 24 июня 2026
;(function($, mw){
const COOKIE = 'ss14_wikiTheme';
const COOKIE_SPACE = 'ss14_spaceAnimation';
const COOKIE_PROJECT = 'ss14_preferredProject';
function loadTheme() {
return $.cookie(COOKIE) || 'dark';
}
function saveTheme(theme) {
$.cookie(COOKIE, theme, { expires: 365, path: '/' });
}
function applyTheme(theme) {
const $body = $('body');
const themeClasses = ($body.attr('class') || '')
.split(/\s+/)
.filter(cls => cls.indexOf('wgl-theme-') === 0);
if (themeClasses.length) {
$body.removeClass(themeClasses.join(' '));
}
$body.addClass(`wgl-theme-${theme}`);
mw.hook('wgl.themeChanged').fire(theme);
}
function loadSpaceAnimation() {
return $.cookie(COOKIE_SPACE) || 'on';
}
function saveSpaceAnimation(val) {
$.cookie(COOKIE_SPACE, val, { expires: 365, path: '/' });
}
function applySpaceAnimation(val) {
const $body = $('body');
const themeClasses = ($body.attr('class') || '')
.split(/\s+/)
.filter(cls => cls.indexOf('wgl-space-animation-') === 0);
if (themeClasses.length) {
$body.removeClass(themeClasses.join(' '));
}
$body.addClass(`wgl-space-animation-${val}`);
mw.hook('wgl.spaceAnimationChanged').fire(val);
}
function loadPreferredProject() {
return $.cookie(COOKIE_PROJECT) || 'corvax';
}
function savePreferredProject(val) {
$.cookie(COOKIE_PROJECT, val, { expires: 365, path: '/' });
}
function applyPreferredProject(val) {
const $body = $('body');
const classes = ($body.attr('class') || '')
.split(/\s+/)
.filter(cls => cls.indexOf('wgl-preferred-project-') === 0);
if (classes.length) {
$body.removeClass(classes.join(' '));
}
$body.addClass(`wgl-preferred-project-${val}`);
mw.hook('wgl.preferredProjectChanged').fire(val);
}
function initThemeMenu($container, currentTheme) {
currentTheme = currentTheme || loadTheme();
const $portlet = $('<div>', {
class: 'mw-portlet mw-portlet-js theme-menu',
id: 'skin-client-prefs-skin-theme'
});
$portlet.append(
$('<div>', { class: 'theme-menu__heading', text: 'Тема' }),
$('<div>', { class: 'theme-menu__content' })
);
const $form = $('<form>');
[
{ key: 'light', label: 'Светлая' },
{ key: 'normal', label: 'Стандартная' },
{ key: 'dark', label: 'Тёмная' },
{ key: 'ss14', label: 'Space Station 14' }
].forEach(opt => {
const $wr = $('<div>', { class: 'theme-client-prefs-radio' });
const $inp = $('<input>', {
type: 'radio',
name: 'theme-selection',
id: `theme-value-${opt.key}`,
value: opt.key,
checked: opt.key === currentTheme
});
const $lbl = $('<label>', {
for: `theme-value-${opt.key}`,
text: opt.label
});
$wr.append($inp, $lbl);
$form.append($wr);
});
$portlet.find('.theme-menu__content').append(
$('<ul>', { class: 'theme-menu__content-list' })
.append(
$('<li>', { class: 'mw-list-item mw-list-item-js' })
.append($form)
)
);
$container.append($portlet);
initSpaceMenu($portlet);
initPreferredProjectMenu($portlet);
$form.on('change', 'input[name="theme-selection"]', function() {
const newTheme = $(this).val();
saveTheme(newTheme);
applyTheme(newTheme);
});
}
function initSpaceMenu($afterPortlet, currentVal) {
currentVal = currentVal || loadSpaceAnimation();
const $spacePortlet = $('<div>', {
class: 'mw-portlet mw-portlet-js theme-menu',
id: 'skin-client-prefs-skin-space'
});
$spacePortlet.append(
$('<div>', { class: 'theme-menu__heading', text: 'Космос' }),
$('<div>', { class: 'theme-menu__content' })
);
const $form = $('<form style="grid-template-columns:1fr 1fr;">');
[
{ val: 'on', label: 'Включено' },
{ val: 'off', label: 'Отключено' }
].forEach(opt => {
const $wr = $('<div>', { class: 'theme-client-prefs-radio' });
const $inp = $('<input>', {
type: 'radio',
name: 'space-animation-selection',
id: `space-value-${opt.val}`,
value: opt.val,
checked: opt.val === currentVal
});
const $lbl = $('<label>', {
for: `space-value-${opt.val}`,
text: opt.label
});
$wr.append($inp, $lbl);
$form.append($wr);
});
$spacePortlet.find('.theme-menu__content').append(
$('<ul>', { class: 'theme-menu__content-list' })
.append(
$('<li>', { class: 'mw-list-item mw-list-item-js' })
.append($form)
)
);
$afterPortlet.after($spacePortlet);
applySpaceAnimation(currentVal);
$form.on('change', 'input[name="space-animation-selection"]', function() {
const newVal = $(this).val();
saveSpaceAnimation(newVal);
applySpaceAnimation(newVal);
});
}
function initPreferredProjectMenu($afterPortlet, currentVal) {
currentVal = currentVal || loadPreferredProject();
const $projectPortlet = $('<div>', {
class: 'mw-portlet mw-portlet-js theme-menu',
id: 'skin-client-prefs-skin-project'
});
$projectPortlet.append(
$('<div>', { class: 'theme-menu__heading', text: 'Предпочитаемый проект' }),
$('<div>', { class: 'theme-menu__content' })
);
const $form = $('<form style="grid-template-columns:1fr 1fr;">');
[
{ val: 'corvax', label: 'Corvax' },
{ val: 'goob', label: 'Goob' },
{ val: 'wl', label: 'WL' },
{ val: 'wega', label: 'Wega' }
].forEach(opt => {
const $wr = $('<div>', { class: 'theme-client-prefs-radio' });
const $inp = $('<input>', {
type: 'radio',
name: 'preferred-project-selection',
id: `project-value-${opt.val}`,
value: opt.val,
checked: opt.val === currentVal
});
const $lbl = $('<label>', {
for: `project-value-${opt.val}`,
text: opt.label
});
$wr.append($inp, $lbl);
$form.append($wr);
});
$projectPortlet.find('.theme-menu__content').append(
$('<ul>', { class: 'theme-menu__content-list' })
.append(
$('<li>', { class: 'mw-list-item mw-list-item-js' })
.append($form)
)
);
$afterPortlet.after($projectPortlet);
applyPreferredProject(currentVal);
$form.on('change', 'input[name="preferred-project-selection"]', function() {
const newVal = $(this).val();
savePreferredProject(newVal);
applyPreferredProject(newVal);
});
}
mw.themeUtils = {
loadTheme,
applyTheme,
initThemeMenu,
loadSpaceAnimation,
saveSpaceAnimation,
applySpaceAnimation,
initSpaceMenu,
loadPreferredProject,
savePreferredProject,
applyPreferredProject,
initPreferredProjectMenu
};
}(jQuery, mediaWiki));