|
|
| Строка 5: |
Строка 5: |
| STICKY_HEADER_COOKIE = 'stickyheader', | | STICKY_HEADER_COOKIE = 'stickyheader', |
| THEME_COOKIE = 'theme', | | THEME_COOKIE = 'theme', |
| FLOORNUMBER_LS = 'floornumber_display',
| |
| theme = ($.cookie('theme') !== null) ? $.cookie('theme') : (($.cookie(DARK_COOKIE) === 'true') ? 'dark' : 'light'),
| |
| currentSticky = $.cookie(STICKY_HEADER_COOKIE) === 'true',
| |
| fixedWidthEnabled = $.cookie('readermode') === 'true', | | fixedWidthEnabled = $.cookie('readermode') === 'true', |
| currentFloornumber = '_auto', | | theme = $.cookie(THEME_COOKIE) || ($.cookie(DARK_COOKIE) === 'true' ? 'dark' : 'light'), |
| themeSwitch,
| |
| stickySwitch, | | stickySwitch, |
| floorSelect,
| |
| floorSelectAuto,
| |
| floorSelectUK,
| |
| floorSelectUS,
| |
| closeButton, | | closeButton, |
| themePortletLink, | | settingsPortletLink, |
| fixedWidthPortletLink,
| |
| $content,
| |
| userLocale = 'UK',
| |
| flsetting,
| |
| browserLocale,
| |
| themePopup; | | themePopup; |
|
| |
|
| var self = { | | var self = { |
| init: function () { | | init: function () { |
| // Add the theme selector
| | self.createThemeButton(); |
| self.createThemePortletLink(); | | self.createSettingsButton(); |
|
| | self.createFixedWidthToggle(); |
| // Add the appearance settings button
| | if ( $.cookie(THEME_COOKIE) == null ) { |
| self.createSettingsPortletLink(); | |
|
| |
| // Add the fixed-width toggle
| |
| self.createFixedWidthPortletLink(); | |
|
| |
| // Perform skin overrides if required
| |
| self.doFloorNumberOverrides();
| |
|
| |
| if (currentSticky) self.doStickyHeaderOverrides();
| |
|
| |
| // Set the theme cookie
| |
| if ( $.cookie('theme') == null ) { | |
| $.cookie(THEME_COOKIE, theme, {expires: 365, path: '/'}); | | $.cookie(THEME_COOKIE, theme, {expires: 365, path: '/'}); |
| } | | } |
|
| |
| }, | | }, |
|
| | |
| /** | | createThemeButton: function() { |
|
| | // Add the theme toggle button inside #user-tools |
| * Perform specific overrides to the skin if the user is currently
| | themePortletLink = mw.util.addPortletLink( |
|
| | 'user-tools', |
| * using the sticky header option.
| | '', |
|
| | 'pt-theme-toggle', |
| */
| | 'Change theme', |
|
| | null, |
| doStickyHeaderOverrides: function() {
| | '#user-tools' |
| $('body').addClass('wgl-stickyheader'); | | ); |
| function onScroll() {
| | $(themePortletLink).find('a') |
| var personal = $('#p-personal'); | | .addClass('oo-ui-icon-advanced') |
| var targetEle = document.getElementById("mw-head"); | | .on('click', function(e) { |
| var head = $('#mw-head'); | | e.preventDefault(); |
|
| | if (!themePopup) { |
| // We're on an edit or preview page, do nothing and reset all the stuff
| | mw.loader.using(['oojs-ui-core','oojs-ui-windows','oojs-ui-widgets']).then(self.buildThemePopup); |
| if (mw.config.get('wgAction') === 'edit' ||
| |
| mw.config.get('wgAction') === 'submit' ||
| |
| window.location.search.includes('veaction')) {
| |
| if (personal.is(":hidden")) { | |
| personal.show(); | |
| head.removeClass('sticky-hidden');
| |
| }
| |
| }
| |
| else {
| |
| // We've scrolled past the header's original position, time to stick it
| |
| if (window.scrollY > (targetEle.offsetTop + targetEle.offsetHeight)) {
| |
| if (personal.is(":visible")) {
| |
| personal.hide();
| |
| head.addClass('sticky-hidden');
| |
| }
| |
| } else { | | } else { |
| if (personal.is(":hidden")) { | | themePopup.toggle(); |
| personal.show();
| |
| head.removeClass('sticky-hidden');
| |
| }
| |
| } | | } |
| } | | }); |
| } | | }, |
| | | |
| onScroll(); | | buildThemePopup: function() { |
|
| | var themeSwitch = new OO.ui.ButtonSelectWidget({ |
| $(window).scroll(onScroll);
| | items: [ |
| | new OO.ui.ButtonOptionWidget({data: 'light', label: 'Light'}), |
| | new OO.ui.ButtonOptionWidget({data: 'dark', label: 'Dark'}) |
| | ] |
| | }); |
| | themeSwitch.selectItemByData(theme); |
| | themeSwitch.on('choose', function() { |
| | theme = themeSwitch.findSelectedItem().getData(); |
| | $.cookie(THEME_COOKIE, theme, {expires: 365, path: '/'}); |
| | self.applyTheme(theme); |
| | }); |
|
| |
|
| // hidden by css when sticky-hidden is not on | | themePopup = new OO.ui.PopupWidget({ |
| if (mw.config.get('wgIsMainPage') !== true) {
| | $content: themeSwitch.$element, |
| mw.util.addPortletLink('p-namespaces', '/', 'Main Page', 'ca-nstab-mainpage', 'Visit the main page');
| | $floatableContainer: $(themePortletLink), |
| } | | autoClose: true |
| | }); |
| | $(document.body).append(themePopup.$element); |
| | themePopup.toggle(true); |
| }, | | }, |
|
| | |
| /**
| | applyTheme: function(name) { |
| * Perform specific overrides to the skin based on the selected
| | $('body').removeClass(function(i, cls) { |
| * floor number preference.
| | return (cls.match(/wgl-theme-\S+/g) || []).join(' '); |
| */
| | }); |
| doFloorNumberOverrides: function() { | | if (name !== 'light') { |
| if (rs.hasLocalStorage()) { | | mw.loader.using(['wgl.theme.' + name]).then(function() { |
| currentFloornumber = window.localStorage.getItem(FLOORNUMBER_LS); | | $('body').addClass('wgl-theme-' + name); |
| 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: function () { |
| | fixedWidthEnabled = !fixedWidthEnabled; |
| if (fixedWidthEnabled) { | | if (fixedWidthEnabled) { |
| // Switch to full width | | $('body').addClass('wgl-fixedWidth'); |
| | mw.loader.load('wg.fixedwidth'); |
| | } else { |
| $('body').removeClass('wgl-fixedWidth'); | | $('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: '/'}); | | $.cookie('readermode', fixedWidthEnabled, {expires: 365, path: '/'}); |
| }, | | }, |
|
| | |
| /**
| | createFixedWidthToggle: function() { |
| * Adds fixed width portlet link to the page
| | var link = mw.util.addPortletLink('p-personal', '', '', 'pt-fixed-width', 'Toggle fixed-width mode'); |
| */
| | $(link).find('a').on('click', function(e) { |
| 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(); | | e.preventDefault(); |
| self.toggleFixedWidth(); | | self.toggleFixedWidth(); |
| Строка 164: |
Строка 97: |
| }, | | }, |
|
| |
|
| /** | | createSettingsButton: function() { |
| * Adds the theme select portlet link to the page
| | settingsPortletLink = mw.util.addPortletLink('p-personal', '', '', 'pt-settings', 'Appearance settings'); |
| */
| | $(settingsPortletLink).find('a').on('click', function(e) { |
| 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(); | | e.preventDefault(); |
| if (!themePopup) { | | mw.loader.using(['oojs-ui-core','oojs-ui-windows','oojs-ui-widgets']).then(self.openSettingsModal); |
| mw.loader.using(['oojs-ui-core','oojs-ui-windows','oojs-ui-widgets']).then(self.createThemePopup);
| |
| } else {
| |
| themePopup.toggle();
| |
| }
| |
| }); | | }); |
| }, | | }, |
|
| | |
| /**
| | openSettingsModal: function() { |
| * Adds the appearance settings portlet link to the page
| | var stickySwitch = new OO.ui.ToggleSwitchWidget({value: $.cookie(STICKY_HEADER_COOKIE)==='true'}); |
| */
| | stickySwitch.on('change', function() { |
| createSettingsPortletLink: function() { | | $.cookie(STICKY_HEADER_COOKIE, stickySwitch.getValue(), {expires:365, path:'/'}); |
| settingsPortletLink = mw.util.addPortletLink('p-personal', '', '', 'pt-skin-toggles', 'Appearance settings', null, $('#pt-userpage, #pt-anonuserpage')); | |
| $(settingsPortletLink).find('a').addClass('oo-ui-icon-advanced').add('.floor-convention').click(function(e) {
| |
| e.preventDefault();
| |
| if (!window.OOUIWindowManager || !window.OOUIWindowManager.hasWindow('skin')) {
| |
| mw.loader.using(['oojs-ui-core','oojs-ui-windows','oojs-ui-widgets']).then(self.createAppearanceModal);
| |
| } else {
| |
| window.OOUIWindowManager.openWindow('skin');
| |
| }
| |
| });
| |
| },
| |
|
| |
| /**
| |
| * 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>'),
| |
| }),
| |
| ]
| |
| }); | | }); |
|
| |
|
| // Set the toggle to whatever theme is currently active | | var closeBtn = new OO.ui.ButtonInputWidget({label: 'Close', flags: 'destructive'}); |
| themeSwitch.selectItemByData(theme);
| |
| | | |
| themeSwitch.on('choose', function() { | | var $content = $('<div>').append( |
| // Change the theme instantly without needing a refresh
| | $('<h3>').text('Sticky header'), |
| theme = themeSwitch.findSelectedItem().getData();
| | stickySwitch.$element, |
| $.cookie(THEME_COOKIE, theme, {expires: 365, path: '/'});
| | closeBtn.$element |
| 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.
| |
| */
| |
|
| |
| createAppearanceModal: function() {
| |
| stickySwitch = new OO.ui.ToggleSwitchWidget({
| |
|
| |
| value: currentSticky, | |
|
| |
| classes: ['reader-toggle'],
| |
|
| |
| align: 'right'
| |
|
| |
| });
| |
| 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 = 'Changes 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());
| |
| }
| |
| });
| |
|
| |
|
| |
| stickySwitch.on('change', function() {
| |
|
| |
| $.cookie(STICKY_HEADER_COOKIE, stickySwitch.getValue(), {expires: 365, path: '/'});
| |
| })
| |
|
| |
| closeButton = new OO.ui.ButtonInputWidget({ label: 'Close', flags: 'destructive'});
| |
|
| |
|
| $content = $('<div>'); | | rs.createOOUIWindow('settings', 'Appearance settings', {size:'medium'}, function(modal){ |
| $content
| | modal.$body.append($content); |
| .addClass('appearance-modal')
| | closeBtn.on('click', function(){ window.OOUIWindowManager.closeWindow(modal); }); |
| .append(
| | }, true); |
| $('<div>')
| |
| .addClass('reader-mode')
| |
| .append(
| |
| stickySwitch.$element,
| |
| $('<div>').addClass('setting-header sticky-header-header').text('Sticky header'),
| |
| $('<p>').addClass('sticky-header-desc').text('Pin the navigation bar and search to the top when scrolling.'),
| |
| 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('We use <a href="https://weirdgloop.org/privacy">cookies</a> 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('skin', 'Appearance settings', {size: 'large', classes: ['rsw-skin-toggle-popup']}, initModal, true, true).then(function () {
| |
|
| |
| window.OOUIWindowManager.on('closing', function (win, closed, data) {
| |
|
| |
| if (win.$element.hasClass('rsw-skin-toggle-popup')) {
| |
|
| |
| // If the window that closed is this one, finalise some stuff (mostly reader mode etc).
| |
|
| |
| var requireReload = false;
| |
|
| |
|
| |
|
| |
| if ((stickySwitch.getValue() !== currentSticky)) {
| |
|
| |
| requireReload = true;
| |
|
| |
| }
| |
|
| |
|
| |
|
| |
| if (requireReload === true) {
| |
|
| |
| window.location.reload(true);
| |
|
| |
| return;
| |
|
| |
| }
| |
|
| |
| }
| |
|
| |
| })
| |
|
| |
| })
| |
| } | | } |
| } | | }; |
|
| |
|
| mw.loader.using(['ext.gadget.rsw-util'], function () { | | mw.loader.using(['ext.gadget.rsw-util'], function(){ |
| $(self.init); | | $(self.init); |
| }) | | }); |
|
| |
|
| }(jQuery, mediaWiki, rswiki)); | | }(jQuery, mediaWiki, rswiki)); |