MediaWiki:Gadget-skinTogglesNew.js

From RuneRealm Wiki

This is an old revision of this page, as edited by Alex (talk | contribs) at 17:15, 17 October 2024. The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

Jump to navigation Jump to search

After saving, you may need to bypass your browser's cache to see the changes. For further information, see Wikipedia:Bypass your cache.

  • In most Windows and Linux browsers: Hold down Ctrl and press F5.
  • In Safari: Hold down ⇧ Shift and click the Reload button.
  • In Chrome and Firefox for Mac: Hold down both ⌘ Cmd+⇧ Shift and press R.
/**
 * 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 () {
			// 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() {
			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.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.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>'),
					}),
				]
			});

			// 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() {
			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());
				}
			});

			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 (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));