MediaWiki:Gadget-skinTogglesNew.js: Difference between revisions
Jump to navigation
Jump to search
Content added Content deleted
No edit summary Tag: Reverted |
No edit summary |
||
(One intermediate revision by the same user not shown) | |||
Line 1: | Line 1: | ||
"use strict"; |
|||
/** |
/** |
||
* Handles the full-width toggle, dark mode toggle, and other appearance-related |
* Handles the full-width toggle, dark mode toggle, and other appearance-related |
||
Line 7: | Line 9: | ||
* |
* |
||
*/ |
*/ |
||
; |
|||
;(function($, mw, rs){ |
|||
(function ($, mw, rs) { |
|||
var DARK_COOKIE = 'darkmode', |
|||
var DARK_COOKIE = 'darkmode', |
|||
THEME_COOKIE = 'theme', |
|||
THEME_COOKIE = 'theme', |
|||
FLOORNUMBER_LS = 'floornumber_display', |
|||
FLOORNUMBER_LS = 'floornumber_display', |
|||
theme = ($.cookie('theme') !== null) ? $.cookie('theme') : (($.cookie(DARK_COOKIE) === 'true') ? 'dark' : 'light'), |
|||
theme = $.cookie('theme') !== null ? $.cookie('theme') : $.cookie(DARK_COOKIE) === 'true' ? 'dark' : 'light', |
|||
fixedWidthEnabled = $.cookie('readermode') === 'true', |
|||
currentFloornumber = '_auto', |
|||
currentFloornumber = '_auto', |
|||
themeSwitch, |
|||
themeSwitch, |
|||
floorSelect, |
|||
floorSelect, |
|||
floorSelectAuto, |
|||
floorSelectAuto, |
|||
floorSelectUK, |
|||
floorSelectUK, |
|||
floorSelectUS, |
|||
floorSelectUS, |
|||
closeButton, |
|||
closeButton, |
|||
themePortletLink, |
|||
themePortletLink, |
|||
fixedWidthPortletLink, |
|||
fixedWidthPortletLink, |
|||
$content, |
|||
$content, |
|||
userLocale = 'UK', |
|||
userLocale = 'UK', |
|||
flsetting, |
|||
flsetting, |
|||
browserLocale, |
|||
browserLocale, |
|||
themePopup; |
|||
themePopup; |
|||
var self = { |
|||
init: function init() { |
|||
// Add the theme selector |
|||
self.createThemePortletLink(); |
|||
// Add the fixed-width toggle |
|||
var self = { |
|||
self.createFixedWidthPortletLink(); |
|||
init: function () { |
|||
// Add the theme selector |
|||
self.createThemePortletLink(); |
|||
// Add the fixed-width toggle |
|||
self.createFixedWidthPortletLink(); |
|||
// Handle the floor numbering modal |
|||
$('.floor-convention').click(function(e) { |
|||
e.preventDefault(); |
|||
if (!window.OOUIWindowManager || !window.OOUIWindowManager.hasWindow('floorNumber')) { |
|||
mw.loader.using(['oojs-ui-core','oojs-ui-windows','oojs-ui-widgets']).then(self.createFloorNumberModal); |
|||
} else { |
|||
window.OOUIWindowManager.openWindow('floorNumber'); |
|||
} |
|||
}); |
|||
// Perform skin overrides if required |
|||
self.doFloorNumberOverrides(); |
|||
// Handle the floor numbering modal |
|||
$('.floor-convention').click(function (e) { |
|||
if ( $.cookie('theme') == null ) { |
|||
e.preventDefault(); |
|||
$.cookie(THEME_COOKIE, theme, {expires: 365, path: '/'}); |
|||
if (!window.OOUIWindowManager || !window.OOUIWindowManager.hasWindow('floorNumber')) { |
|||
} |
|||
mw.loader.using(['oojs-ui-core', 'oojs-ui-windows', 'oojs-ui-widgets']).then(self.createFloorNumberModal); |
|||
}, |
|||
} else { |
|||
window.OOUIWindowManager.openWindow('floorNumber'); |
|||
/** |
|||
} |
|||
* Perform specific overrides to the skin based on the selected |
|||
}); |
|||
* floor number preference. |
|||
*/ |
|||
doFloorNumberOverrides: function() { |
|||
if (rs.hasLocalStorage()) { |
|||
currentFloornumber = window.localStorage.getItem(FLOORNUMBER_LS); |
|||
if (currentFloornumber == null) { |
|||
currentFloornumber = '_auto'; |
|||
} |
|||
} |
|||
flsetting = currentFloornumber; |
|||
if (window.navigator.languages && window.navigator.languages.length) { |
|||
browserLocale = window.navigator.languages[0]; |
|||
} else { |
|||
browserLocale = navigator.userLanguage || navigator.language || navigator.browserLanguage || 'en'; |
|||
} |
|||
switch (browserLocale) { |
|||
// all langs in -US or -CA |
|||
case 'en-US': |
|||
case 'es-US': |
|||
case 'en-CA': |
|||
case 'fr-CA': |
|||
userLocale = 'US'; |
|||
break; |
|||
} |
|||
if (currentFloornumber == '_auto') { |
|||
flsetting = userLocale; |
|||
} |
|||
switch (flsetting) { |
|||
case 'US': |
|||
flsetting = 'floornumber-setting-us'; |
|||
break; |
|||
case 'UK': |
|||
default: |
|||
flsetting = 'floornumber-setting-gb'; |
|||
break; |
|||
} |
|||
$('body').addClass(flsetting); |
|||
}, |
|||
toggleFixedWidth: function () { |
|||
if (fixedWidthEnabled) { |
|||
// Switch to full width |
|||
$('body').removeClass('wgl-fixedWidth'); |
|||
} else { |
|||
// Switch to fixed width |
|||
mw.loader.load('wg.fixedwidth'); |
|||
$('body').addClass('wgl-fixedWidth'); |
|||
} |
|||
fixedWidthEnabled = !fixedWidthEnabled; |
|||
$.cookie('readermode', fixedWidthEnabled, {expires: 365, path: '/'}); |
|||
}, |
|||
/** |
|||
* Adds fixed width portlet link to the page |
|||
*/ |
|||
createFixedWidthPortletLink: function() { |
|||
fixedWidthPortletLink = mw.mw.util.addPortletLink('p-personal', '', '', 'pt-fixed-width', 'Toggle fixed-width mode', null, $('#pt-userpage, #pt-anonuserpage')); |
|||
$(fixedWidthPortletLink).find('a').addClass('oo-ui-icon-advanced').click(function(e) { |
|||
e.preventDefault(); |
|||
self.toggleFixedWidth(); |
|||
}); |
|||
}, |
|||
/** |
|||
* Adds the theme select portlet link to the page |
|||
*/ |
|||
createThemePortletLink: function() { |
|||
themePortletLink = mw.mw.util.addPortletLink('p-personal', '', '', 'pt-theme-toggles', 'Change theme', null, $('#pt-userpage, #pt-anonuserpage')); |
|||
$(themePortletLink).find('a').addClass('oo-ui-icon-advanced').click(function(e) { |
|||
e.preventDefault(); |
|||
if (!themePopup) { |
|||
mw.loader.using(['oojs-ui-core','oojs-ui-windows','oojs-ui-widgets']).then(self.createThemePopup); |
|||
} else { |
|||
themePopup.toggle(); |
|||
} |
|||
}); |
|||
}, |
|||
/** |
|||
* Loads a theme by its name |
|||
*/ |
|||
loadTheme: function(themeName) { |
|||
var removeExistingTheme = function () { |
|||
// Remove any existing theme class |
|||
$('body').removeClass(function (i, className) { |
|||
return (className.match (/(^|\s)wgl-theme-\S+/g) || []).join(' ') |
|||
}) |
|||
} |
|||
// Add new theme class |
|||
if (themeName === 'light') { |
|||
removeExistingTheme(); |
|||
$('body').addClass('wgl-theme-light'); |
|||
} else { |
|||
mw.loader.using(['wgl.theme.' + themeName]).then(function () { |
|||
removeExistingTheme(); |
|||
$('body').addClass('wgl-theme-' + themeName); |
|||
}); |
|||
} |
|||
}, |
|||
/** |
|||
* Initialises the creation of the theme toggle widget |
|||
*/ |
|||
createThemeToggle: function() { |
|||
// Create the theme toggle |
|||
themeSwitch = new OO.ui.ButtonSelectWidget({ |
|||
classes: ['appearance-buttons'], |
|||
items: [ |
|||
new OO.ui.ButtonOptionWidget({ |
|||
classes: ['light-mode-button'], |
|||
data: 'light', |
|||
title: 'Light', |
|||
framed: false, |
|||
label: new OO.ui.HtmlSnippet('<div class="button-img"></div>'), |
|||
}), |
|||
new OO.ui.ButtonOptionWidget({ |
|||
classes: ['dark-mode-button'], |
|||
data: 'dark', |
|||
title: 'Dark', |
|||
framed: false, |
|||
label: new OO.ui.HtmlSnippet('<div class="button-img"></div>'), |
|||
}), |
|||
new OO.ui.ButtonOptionWidget({ |
|||
classes: ['brown-mode-button'], |
|||
data: 'browntown', |
|||
title: 'Browntown', |
|||
framed: false, |
|||
label: new OO.ui.HtmlSnippet('<div class="button-img"></div>'), |
|||
}), |
|||
] |
|||
}); |
|||
// Perform skin overrides if required |
|||
// Set the toggle to whatever theme is currently active |
|||
self.doFloorNumberOverrides(); |
|||
themeSwitch.selectItemByData(theme); |
|||
themeSwitch.on('choose', function() { |
|||
// Change the theme instantly without needing a refresh |
|||
theme = themeSwitch.findSelectedItem().getData(); |
|||
$.cookie(THEME_COOKIE, theme, {expires: 365, path: '/'}); |
|||
self.loadTheme(theme); |
|||
}) |
|||
}, |
|||
/** |
|||
* Initialises the creation of the theme popup window, which appears |
|||
* when the moon icon is clicked at the top right of the page. |
|||
*/ |
|||
createThemePopup: function() { |
|||
self.createThemeToggle(); |
|||
// Create the popup |
|||
themePopup = new OO.ui.PopupWidget( { |
|||
classes: ['wgl-theme-popup'], |
|||
$content: themeSwitch.$element, |
|||
$floatableContainer: $(themePortletLink), |
|||
width: null, |
|||
autoClose: true, |
|||
} ); |
|||
themePopup.on('toggle', function (visible) { |
|||
// When the popup is opened, change the moon icon to an X |
|||
if (visible) { |
|||
$(themePortletLink).find('a').addClass('wgl-theme-popup-opened'); |
|||
} else { |
|||
$(themePortletLink).find('a').removeClass('wgl-theme-popup-opened'); |
|||
} |
|||
}) |
|||
$(document.body).append(themePopup.$element); |
|||
// Open the popup, since we'll have only created the popup if the |
|||
// user tried to interact with it in the first place. |
|||
themePopup.toggle(true); |
|||
}, |
|||
/** |
|||
* Initialises the creation of the gear modal, for other non-theme |
|||
* related appearance settings. |
|||
*/ |
|||
createFloorNumberModal: function() { |
|||
floorSelectAuto = new OO.ui.RadioOptionWidget({ |
|||
data: '_auto', |
|||
label: 'Auto-detect: '+userLocale |
|||
}); |
|||
floorSelectUK = new OO.ui.RadioOptionWidget({ |
|||
data: 'UK', |
|||
label: 'UK' |
|||
}); |
|||
floorSelectUS = new OO.ui.RadioOptionWidget({ |
|||
data: 'US', |
|||
label: 'US' |
|||
}); |
|||
floorSelect = new OO.ui.RadioSelectWidget({ |
|||
classes: ['floornumber-select'], |
|||
items: [ |
|||
floorSelectAuto, |
|||
floorSelectUK, |
|||
floorSelectUS |
|||
] |
|||
}); |
|||
floorSelect.selectItemByData(currentFloornumber); |
|||
floorSelectHelp = 'Adjust how floor numbers are displayed on the wiki - whether the numbering begins at 0 (ground) or 1.'; |
|||
if (!rs.hasLocalStorage()) { |
|||
floorSelect.setDisabled(true); |
|||
floorSelectHelp = 'This option requires local storage to be supported and enabled in your browser.'; |
|||
} |
|||
floorSelectAuto.$element.attr('title', 'Automatically detect the type to use from your browser.'); |
|||
floorSelectUK.$element.attr('title', 'The numbering used in the UK, Europe, and many Commonwealth countries: entrance on the ground floor, then above that is 1st floor, 2nd floor, etc.'); |
|||
floorSelectUS.$element.attr('title', 'The numbering used in the US and Canada: entrance on the 1st floor, then above that is 2nd floor, 3rd floor, etc.'); |
|||
floorSelect.on('choose', function () { |
|||
if (rs.hasLocalStorage()) { |
|||
window.localStorage.setItem(FLOORNUMBER_LS, floorSelect.findSelectedItem().getData()); |
|||
} |
|||
}); |
|||
// Set the theme cookie |
|||
closeButton = new OO.ui.ButtonInputWidget({ label: 'Close', flags: 'destructive'}); |
|||
if ($.cookie('theme') == null) { |
|||
$.cookie(THEME_COOKIE, theme, { |
|||
expires: 365, |
|||
path: '/' |
|||
}); |
|||
} |
|||
}, |
|||
/** |
|||
* Perform specific overrides to the skin based on the selected |
|||
* floor number preference. |
|||
*/ |
|||
doFloorNumberOverrides: function doFloorNumberOverrides() { |
|||
if (rs.hasLocalStorage()) { |
|||
currentFloornumber = window.localStorage.getItem(FLOORNUMBER_LS); |
|||
if (currentFloornumber == null) { |
|||
currentFloornumber = '_auto'; |
|||
} |
|||
} |
|||
flsetting = currentFloornumber; |
|||
if (window.navigator.languages && window.navigator.languages.length) { |
|||
browserLocale = window.navigator.languages[0]; |
|||
} else { |
|||
browserLocale = navigator.userLanguage || navigator.language || navigator.browserLanguage || 'en'; |
|||
} |
|||
switch (browserLocale) { |
|||
// all langs in -US or -CA |
|||
case 'en-US': |
|||
case 'es-US': |
|||
case 'en-CA': |
|||
case 'fr-CA': |
|||
userLocale = 'US'; |
|||
break; |
|||
} |
|||
if (currentFloornumber == '_auto') { |
|||
flsetting = userLocale; |
|||
} |
|||
switch (flsetting) { |
|||
case 'US': |
|||
flsetting = 'floornumber-setting-us'; |
|||
break; |
|||
case 'UK': |
|||
default: |
|||
flsetting = 'floornumber-setting-gb'; |
|||
break; |
|||
} |
|||
$('body').addClass(flsetting); |
|||
}, |
|||
toggleFixedWidth: function toggleFixedWidth() { |
|||
if (fixedWidthEnabled) { |
|||
// Switch to full width |
|||
$('body').removeClass('wgl-fixedWidth'); |
|||
} else { |
|||
// Switch to fixed width |
|||
mw.loader.load('wg.fixedwidth'); |
|||
$('body').addClass('wgl-fixedWidth'); |
|||
} |
|||
fixedWidthEnabled = !fixedWidthEnabled; |
|||
$.cookie('readermode', fixedWidthEnabled, { |
|||
expires: 365, |
|||
path: '/' |
|||
}); |
|||
}, |
|||
/** |
|||
* Adds fixed width portlet link to the page |
|||
*/ |
|||
createFixedWidthPortletLink: function createFixedWidthPortletLink() { |
|||
fixedWidthPortletLink = mw.util.addPortletLink('p-personal', '', '', 'pt-fixed-width', 'Toggle fixed-width mode', null, $('#pt-userpage, #pt-anonuserpage')); |
|||
$(fixedWidthPortletLink).find('a').addClass('oo-ui-icon-advanced').click(function (e) { |
|||
e.preventDefault(); |
|||
self.toggleFixedWidth(); |
|||
}); |
|||
}, |
|||
/** |
|||
* Adds the theme select portlet link to the page |
|||
*/ |
|||
createThemePortletLink: function createThemePortletLink() { |
|||
themePortletLink = mw.util.addPortletLink('p-personal', '', '', 'pt-theme-toggles', 'Change theme', null, $('#pt-userpage, #pt-anonuserpage')); |
|||
$(themePortletLink).find('a').addClass('oo-ui-icon-advanced').click(function (e) { |
|||
e.preventDefault(); |
|||
if (!themePopup) { |
|||
mw.loader.using(['oojs-ui-core', 'oojs-ui-windows', 'oojs-ui-widgets']).then(self.createThemePopup); |
|||
} else { |
|||
themePopup.toggle(); |
|||
} |
|||
}); |
|||
}, |
|||
/** |
|||
* Loads a theme by its name |
|||
*/ |
|||
loadTheme: function loadTheme(themeName) { |
|||
var removeExistingTheme = function removeExistingTheme() { |
|||
// Remove any existing theme class |
|||
$('body').removeClass(function (i, className) { |
|||
return (className.match(/(^|\s)wgl-theme-\S+/g) || []).join(' '); |
|||
}); |
|||
}; |
|||
// Add new theme class |
|||
$content = $('<div>'); |
|||
if (themeName === 'light') { |
|||
$content |
|||
removeExistingTheme(); |
|||
.addClass('appearance-modal') |
|||
$('body').addClass('wgl-theme-light'); |
|||
.append( |
|||
} else { |
|||
$('<div>') |
|||
mw.loader.using(['wgl.theme.' + themeName]).then(function () { |
|||
.addClass('reader-mode') |
|||
removeExistingTheme(); |
|||
.append( |
|||
$('body').addClass('wgl-theme-' + themeName); |
|||
floorSelect.$element, |
|||
}); |
|||
$('<div>').addClass('setting-header floornumber-header').text('Floor numbering'), |
|||
} |
|||
$('<p>').addClass('floornumber-desc').text(floorSelectHelp) |
|||
}, |
|||
), |
|||
/** |
|||
$('<div>') |
|||
* Initialises the creation of the theme toggle widget |
|||
.addClass('appearance-save') |
|||
*/ |
|||
.append( |
|||
createThemeToggle: function createThemeToggle() { |
|||
$('<p>').addClass('save-button-desc').html('<a href="https://weirdgloop.org/privacy">Cookies</a> are used to personalise the wiki.'), |
|||
// Create the theme toggle |
|||
$('<div>').addClass('save-button-container') |
|||
themeSwitch = new OO.ui.ButtonSelectWidget({ |
|||
.append(closeButton.$element) |
|||
classes: ['appearance-buttons'], |
|||
) |
|||
items: [new OO.ui.ButtonOptionWidget({ |
|||
); |
|||
classes: ['light-mode-button'], |
|||
data: 'light', |
|||
title: 'Light', |
|||
framed: false, |
|||
label: new OO.ui.HtmlSnippet('<div class="button-img"></div>') |
|||
}), new OO.ui.ButtonOptionWidget({ |
|||
classes: ['dark-mode-button'], |
|||
data: 'dark', |
|||
title: 'Dark', |
|||
framed: false, |
|||
label: new OO.ui.HtmlSnippet('<div class="button-img"></div>') |
|||
}), new OO.ui.ButtonOptionWidget({ |
|||
classes: ['brown-mode-button'], |
|||
data: 'browntown', |
|||
title: 'Browntown', |
|||
framed: false, |
|||
label: new OO.ui.HtmlSnippet('<div class="button-img"></div>') |
|||
})] |
|||
}); |
|||
// Set the toggle to whatever theme is currently active |
|||
var initModal = function (modal) { |
|||
themeSwitch.selectItemByData(theme); |
|||
modal.$body.append( $content ); |
|||
themeSwitch.on('choose', function () { |
|||
closeButton.on('click', function(modal){window.OOUIWindowManager.closeWindow(modal);}, [modal]); |
|||
// Change the theme instantly without needing a refresh |
|||
}; |
|||
theme = themeSwitch.findSelectedItem().getData(); |
|||
$.cookie(THEME_COOKIE, theme, { |
|||
expires: 365, |
|||
path: '/' |
|||
}); |
|||
self.loadTheme(theme); |
|||
}); |
|||
}, |
|||
/** |
|||
* Initialises the creation of the theme popup window, which appears |
|||
* when the moon icon is clicked at the top right of the page. |
|||
*/ |
|||
createThemePopup: function createThemePopup() { |
|||
self.createThemeToggle(); |
|||
// Create the popup |
|||
rs.createOOUIWindow('floorNumber', 'Floor numbering', {size: 'large', classes: ['rsw-skin-toggle-popup']}, initModal, true, true); |
|||
themePopup = new OO.ui.PopupWidget({ |
|||
} |
|||
classes: ['wgl-theme-popup'], |
|||
} |
|||
$content: themeSwitch.$element, |
|||
$floatableContainer: $(themePortletLink), |
|||
width: null, |
|||
autoClose: true |
|||
}); |
|||
themePopup.on('toggle', function (visible) { |
|||
// When the popup is opened, change the moon icon to an X |
|||
if (visible) { |
|||
$(themePortletLink).find('a').addClass('wgl-theme-popup-opened'); |
|||
} else { |
|||
$(themePortletLink).find('a').removeClass('wgl-theme-popup-opened'); |
|||
} |
|||
}); |
|||
$(document.body).append(themePopup.$element); |
|||
// Open the popup, since we'll have only created the popup if the |
|||
mw.loader.using(['ext.gadget.rsw-mw.util'], function () { |
|||
// user tried to interact with it in the first place. |
|||
$(self.init); |
|||
themePopup.toggle(true); |
|||
}) |
|||
}, |
|||
/** |
|||
* Initialises the creation of the gear modal, for other non-theme |
|||
* related appearance settings. |
|||
*/ |
|||
createFloorNumberModal: function createFloorNumberModal() { |
|||
}(jQuery, mediaWiki, rswiki)); |
|||
floorSelectAuto = new OO.ui.RadioOptionWidget({ |
|||
data: '_auto', |
|||
label: 'Auto-detect: ' + userLocale |
|||
}); |
|||
floorSelectUK = new OO.ui.RadioOptionWidget({ |
|||
data: 'UK', |
|||
label: 'UK' |
|||
}); |
|||
floorSelectUS = new OO.ui.RadioOptionWidget({ |
|||
data: 'US', |
|||
label: 'US' |
|||
}); |
|||
floorSelect = new OO.ui.RadioSelectWidget({ |
|||
classes: ['floornumber-select'], |
|||
items: [floorSelectAuto, floorSelectUK, floorSelectUS] |
|||
}); |
|||
floorSelect.selectItemByData(currentFloornumber); |
|||
floorSelectHelp = 'Adjust how floor numbers are displayed on the wiki - whether the numbering begins at 0 (ground) or 1.'; |
|||
if (!rs.hasLocalStorage()) { |
|||
floorSelect.setDisabled(true); |
|||
floorSelectHelp = 'This option requires local storage to be supported and enabled in your browser.'; |
|||
} |
|||
floorSelectAuto.$element.attr('title', 'Automatically detect the type to use from your browser.'); |
|||
floorSelectUK.$element.attr('title', 'The numbering used in the UK, Europe, and many Commonwealth countries: entrance on the ground floor, then above that is 1st floor, 2nd floor, etc.'); |
|||
floorSelectUS.$element.attr('title', 'The numbering used in the US and Canada: entrance on the 1st floor, then above that is 2nd floor, 3rd floor, etc.'); |
|||
floorSelect.on('choose', function () { |
|||
if (rs.hasLocalStorage()) { |
|||
window.localStorage.setItem(FLOORNUMBER_LS, floorSelect.findSelectedItem().getData()); |
|||
} |
|||
}); |
|||
closeButton = new OO.ui.ButtonInputWidget({ |
|||
label: 'Close', |
|||
flags: 'destructive' |
|||
}); |
|||
$content = $('<div>'); |
|||
$content.addClass('appearance-modal').append($('<div>').addClass('reader-mode').append(floorSelect.$element, $('<div>').addClass('setting-header floornumber-header').text('Floor numbering'), $('<p>').addClass('floornumber-desc').text(floorSelectHelp)), $('<div>').addClass('appearance-save').append($('<p>').addClass('save-button-desc').html('<a href="https://weirdgloop.org/privacy">Cookies</a> are used to personalise the wiki.'), $('<div>').addClass('save-button-container').append(closeButton.$element))); |
|||
var initModal = function initModal(modal) { |
|||
modal.$body.append($content); |
|||
closeButton.on('click', function (modal) { |
|||
window.OOUIWindowManager.closeWindow(modal); |
|||
}, [modal]); |
|||
}; |
|||
rs.createOOUIWindow('floorNumber', 'Floor numbering', { |
|||
size: 'large', |
|||
classes: ['rsw-skin-toggle-popup'] |
|||
}, initModal, true, true); |
|||
} |
|||
}; |
|||
mw.loader.using(['ext.gadget.rsw-util'], function () { |
|||
$(self.init); |
|||
}); |
|||
})(jQuery, mediaWiki, rswiki); |
Latest revision as of 12:06, 20 October 2024
"use strict";
/**
* Handles the full-width toggle, dark mode toggle, and other appearance-related
* toggles on the page.
*
* @author Gaz Lloyd
* @author Jayden
*
*/
;
(function ($, mw, rs) {
var DARK_COOKIE = 'darkmode',
THEME_COOKIE = 'theme',
FLOORNUMBER_LS = 'floornumber_display',
theme = $.cookie('theme') !== null ? $.cookie('theme') : $.cookie(DARK_COOKIE) === 'true' ? 'dark' : 'light',
fixedWidthEnabled = $.cookie('readermode') === 'true',
currentFloornumber = '_auto',
themeSwitch,
floorSelect,
floorSelectAuto,
floorSelectUK,
floorSelectUS,
closeButton,
themePortletLink,
fixedWidthPortletLink,
$content,
userLocale = 'UK',
flsetting,
browserLocale,
themePopup;
var self = {
init: function init() {
// Add the theme selector
self.createThemePortletLink();
// Add the fixed-width toggle
self.createFixedWidthPortletLink();
// Handle the floor numbering modal
$('.floor-convention').click(function (e) {
e.preventDefault();
if (!window.OOUIWindowManager || !window.OOUIWindowManager.hasWindow('floorNumber')) {
mw.loader.using(['oojs-ui-core', 'oojs-ui-windows', 'oojs-ui-widgets']).then(self.createFloorNumberModal);
} else {
window.OOUIWindowManager.openWindow('floorNumber');
}
});
// Perform skin overrides if required
self.doFloorNumberOverrides();
// Set the theme cookie
if ($.cookie('theme') == null) {
$.cookie(THEME_COOKIE, theme, {
expires: 365,
path: '/'
});
}
},
/**
* Perform specific overrides to the skin based on the selected
* floor number preference.
*/
doFloorNumberOverrides: function doFloorNumberOverrides() {
if (rs.hasLocalStorage()) {
currentFloornumber = window.localStorage.getItem(FLOORNUMBER_LS);
if (currentFloornumber == null) {
currentFloornumber = '_auto';
}
}
flsetting = currentFloornumber;
if (window.navigator.languages && window.navigator.languages.length) {
browserLocale = window.navigator.languages[0];
} else {
browserLocale = navigator.userLanguage || navigator.language || navigator.browserLanguage || 'en';
}
switch (browserLocale) {
// all langs in -US or -CA
case 'en-US':
case 'es-US':
case 'en-CA':
case 'fr-CA':
userLocale = 'US';
break;
}
if (currentFloornumber == '_auto') {
flsetting = userLocale;
}
switch (flsetting) {
case 'US':
flsetting = 'floornumber-setting-us';
break;
case 'UK':
default:
flsetting = 'floornumber-setting-gb';
break;
}
$('body').addClass(flsetting);
},
toggleFixedWidth: function toggleFixedWidth() {
if (fixedWidthEnabled) {
// Switch to full width
$('body').removeClass('wgl-fixedWidth');
} else {
// Switch to fixed width
mw.loader.load('wg.fixedwidth');
$('body').addClass('wgl-fixedWidth');
}
fixedWidthEnabled = !fixedWidthEnabled;
$.cookie('readermode', fixedWidthEnabled, {
expires: 365,
path: '/'
});
},
/**
* Adds fixed width portlet link to the page
*/
createFixedWidthPortletLink: function createFixedWidthPortletLink() {
fixedWidthPortletLink = mw.util.addPortletLink('p-personal', '', '', 'pt-fixed-width', 'Toggle fixed-width mode', null, $('#pt-userpage, #pt-anonuserpage'));
$(fixedWidthPortletLink).find('a').addClass('oo-ui-icon-advanced').click(function (e) {
e.preventDefault();
self.toggleFixedWidth();
});
},
/**
* Adds the theme select portlet link to the page
*/
createThemePortletLink: function createThemePortletLink() {
themePortletLink = mw.util.addPortletLink('p-personal', '', '', 'pt-theme-toggles', 'Change theme', null, $('#pt-userpage, #pt-anonuserpage'));
$(themePortletLink).find('a').addClass('oo-ui-icon-advanced').click(function (e) {
e.preventDefault();
if (!themePopup) {
mw.loader.using(['oojs-ui-core', 'oojs-ui-windows', 'oojs-ui-widgets']).then(self.createThemePopup);
} else {
themePopup.toggle();
}
});
},
/**
* Loads a theme by its name
*/
loadTheme: function loadTheme(themeName) {
var removeExistingTheme = function removeExistingTheme() {
// Remove any existing theme class
$('body').removeClass(function (i, className) {
return (className.match(/(^|\s)wgl-theme-\S+/g) || []).join(' ');
});
};
// Add new theme class
if (themeName === 'light') {
removeExistingTheme();
$('body').addClass('wgl-theme-light');
} else {
mw.loader.using(['wgl.theme.' + themeName]).then(function () {
removeExistingTheme();
$('body').addClass('wgl-theme-' + themeName);
});
}
},
/**
* Initialises the creation of the theme toggle widget
*/
createThemeToggle: function createThemeToggle() {
// Create the theme toggle
themeSwitch = new OO.ui.ButtonSelectWidget({
classes: ['appearance-buttons'],
items: [new OO.ui.ButtonOptionWidget({
classes: ['light-mode-button'],
data: 'light',
title: 'Light',
framed: false,
label: new OO.ui.HtmlSnippet('<div class="button-img"></div>')
}), new OO.ui.ButtonOptionWidget({
classes: ['dark-mode-button'],
data: 'dark',
title: 'Dark',
framed: false,
label: new OO.ui.HtmlSnippet('<div class="button-img"></div>')
}), new OO.ui.ButtonOptionWidget({
classes: ['brown-mode-button'],
data: 'browntown',
title: 'Browntown',
framed: false,
label: new OO.ui.HtmlSnippet('<div class="button-img"></div>')
})]
});
// Set the toggle to whatever theme is currently active
themeSwitch.selectItemByData(theme);
themeSwitch.on('choose', function () {
// Change the theme instantly without needing a refresh
theme = themeSwitch.findSelectedItem().getData();
$.cookie(THEME_COOKIE, theme, {
expires: 365,
path: '/'
});
self.loadTheme(theme);
});
},
/**
* Initialises the creation of the theme popup window, which appears
* when the moon icon is clicked at the top right of the page.
*/
createThemePopup: function createThemePopup() {
self.createThemeToggle();
// Create the popup
themePopup = new OO.ui.PopupWidget({
classes: ['wgl-theme-popup'],
$content: themeSwitch.$element,
$floatableContainer: $(themePortletLink),
width: null,
autoClose: true
});
themePopup.on('toggle', function (visible) {
// When the popup is opened, change the moon icon to an X
if (visible) {
$(themePortletLink).find('a').addClass('wgl-theme-popup-opened');
} else {
$(themePortletLink).find('a').removeClass('wgl-theme-popup-opened');
}
});
$(document.body).append(themePopup.$element);
// Open the popup, since we'll have only created the popup if the
// user tried to interact with it in the first place.
themePopup.toggle(true);
},
/**
* Initialises the creation of the gear modal, for other non-theme
* related appearance settings.
*/
createFloorNumberModal: function createFloorNumberModal() {
floorSelectAuto = new OO.ui.RadioOptionWidget({
data: '_auto',
label: 'Auto-detect: ' + userLocale
});
floorSelectUK = new OO.ui.RadioOptionWidget({
data: 'UK',
label: 'UK'
});
floorSelectUS = new OO.ui.RadioOptionWidget({
data: 'US',
label: 'US'
});
floorSelect = new OO.ui.RadioSelectWidget({
classes: ['floornumber-select'],
items: [floorSelectAuto, floorSelectUK, floorSelectUS]
});
floorSelect.selectItemByData(currentFloornumber);
floorSelectHelp = 'Adjust how floor numbers are displayed on the wiki - whether the numbering begins at 0 (ground) or 1.';
if (!rs.hasLocalStorage()) {
floorSelect.setDisabled(true);
floorSelectHelp = 'This option requires local storage to be supported and enabled in your browser.';
}
floorSelectAuto.$element.attr('title', 'Automatically detect the type to use from your browser.');
floorSelectUK.$element.attr('title', 'The numbering used in the UK, Europe, and many Commonwealth countries: entrance on the ground floor, then above that is 1st floor, 2nd floor, etc.');
floorSelectUS.$element.attr('title', 'The numbering used in the US and Canada: entrance on the 1st floor, then above that is 2nd floor, 3rd floor, etc.');
floorSelect.on('choose', function () {
if (rs.hasLocalStorage()) {
window.localStorage.setItem(FLOORNUMBER_LS, floorSelect.findSelectedItem().getData());
}
});
closeButton = new OO.ui.ButtonInputWidget({
label: 'Close',
flags: 'destructive'
});
$content = $('<div>');
$content.addClass('appearance-modal').append($('<div>').addClass('reader-mode').append(floorSelect.$element, $('<div>').addClass('setting-header floornumber-header').text('Floor numbering'), $('<p>').addClass('floornumber-desc').text(floorSelectHelp)), $('<div>').addClass('appearance-save').append($('<p>').addClass('save-button-desc').html('<a href="https://weirdgloop.org/privacy">Cookies</a> are used to personalise the wiki.'), $('<div>').addClass('save-button-container').append(closeButton.$element)));
var initModal = function initModal(modal) {
modal.$body.append($content);
closeButton.on('click', function (modal) {
window.OOUIWindowManager.closeWindow(modal);
}, [modal]);
};
rs.createOOUIWindow('floorNumber', 'Floor numbering', {
size: 'large',
classes: ['rsw-skin-toggle-popup']
}, initModal, true, true);
}
};
mw.loader.using(['ext.gadget.rsw-util'], function () {
$(self.init);
});
})(jQuery, mediaWiki, rswiki);