From de0729e6048088d71c2315a0efa7fdc369a30e35 Mon Sep 17 00:00:00 2001 From: Jon Robson Date: Fri, 10 Jun 2022 13:45:18 -0700 Subject: [PATCH] [Refactor] Separate sidebar persistence code from checkbox hack code Change-Id: I5d7d8897f656419a71b1327c37e88c9dd7f0767c --- .../{sidebar.js => checkbox.js} | 54 +--------------- .../skins.vector.js/sidebarPersistence.js | 64 +++++++++++++++++++ resources/skins.vector.js/skin.js | 6 +- skin.json | 3 +- 4 files changed, 73 insertions(+), 54 deletions(-) rename resources/skins.vector.js/{sidebar.js => checkbox.js} (69%) create mode 100644 resources/skins.vector.js/sidebarPersistence.js diff --git a/resources/skins.vector.js/sidebar.js b/resources/skins.vector.js/checkbox.js similarity index 69% rename from resources/skins.vector.js/sidebar.js rename to resources/skins.vector.js/checkbox.js index e86a1f25e..529f3a78b 100644 --- a/resources/skins.vector.js/sidebar.js +++ b/resources/skins.vector.js/checkbox.js @@ -1,27 +1,21 @@ /** - * JavaScript enhancement to the collapsible sidebar. + * JavaScript enhancement for appropriately marked checkbox hacks * - * The sidebar provides basic show/hide functionality with CSS + * The checkbox hack in Vector provides basic show/hide functionality with CSS * but JavaScript is used for progressive enhancements. * * Enhancements include: * - Update `aria-role`s based on expanded/collapsed state. * - Update button icon based on expanded/collapsed state. - * - Persist the sidebar state for logged-in users. * */ /** @interface MwApiConstructor */ /** @interface CheckboxHack */ -/** @interface MwApi */ var checkboxHack = /** @type {CheckboxHack} */ require( /** @type {string} */( 'mediawiki.page.ready' ) ).checkboxHack, SIDEBAR_BUTTON_ID = 'mw-sidebar-button', - SIDEBAR_CHECKBOX_ID = 'mw-sidebar-checkbox', - SIDEBAR_PREFERENCE_NAME = 'VectorSidebarVisible'; - -var debounce = require( /** @type {string} */ ( 'mediawiki.util' ) ).debounce; -/** @type {MwApi} */ var api; + SIDEBAR_CHECKBOX_ID = 'mw-sidebar-checkbox'; /** * Revise the button's `aria-expanded` state to match the checked state. @@ -117,45 +111,6 @@ function initCheckboxHack( checkbox, button ) { } } -/** - * Execute a debounced API request to save the sidebar user preference. - * The request is meant to fire 1000 milliseconds after the last click on - * the sidebar button. - * - * @param {HTMLInputElement} checkbox - * @return {any} - */ -function saveSidebarState( checkbox ) { - return debounce( function () { - api = api || new mw.Api(); - api.saveOption( SIDEBAR_PREFERENCE_NAME, checkbox.checked ? 1 : 0 ); - - // Trigger a resize event so other parts of the page can adapt: - var event; - if ( typeof Event === 'function' ) { - event = new Event( 'resize' ); - } else { - // IE11 - event = window.document.createEvent( 'UIEvents' ); - event.initUIEvent( 'resize', true, false, window, 0 ); - } - window.dispatchEvent( event ); - }, 1000 ); -} - -/** - * Bind the event handler that saves the sidebar state to the click event - * on the sidebar button. - * - * @param {HTMLElement|null} checkbox - * @param {HTMLElement|null} button - */ -function bindSidebarClickEvent( checkbox, button ) { - if ( checkbox instanceof HTMLInputElement && button ) { - checkbox.addEventListener( 'input', saveSidebarState( checkbox ) ); - } -} - /** * Initialize all JavaScript sidebar enhancements. * @@ -166,9 +121,6 @@ function init( window ) { button = window.document.getElementById( SIDEBAR_BUTTON_ID ); initCheckboxHack( checkbox, button ); - if ( mw.config.get( 'wgUserName' ) && !mw.config.get( 'wgVectorDisableSidebarPersistence' ) ) { - bindSidebarClickEvent( checkbox, button ); - } } module.exports = { diff --git a/resources/skins.vector.js/sidebarPersistence.js b/resources/skins.vector.js/sidebarPersistence.js new file mode 100644 index 000000000..8014d017f --- /dev/null +++ b/resources/skins.vector.js/sidebarPersistence.js @@ -0,0 +1,64 @@ +/** + * JavaScript enhancement to persist the sidebar state for logged-in users. + * + */ + +/** @interface MwApi */ + +var /** @type {MwApi} */api, + SIDEBAR_BUTTON_ID = 'mw-sidebar-button', + debounce = require( /** @type {string} */ ( 'mediawiki.util' ) ).debounce, + SIDEBAR_CHECKBOX_ID = 'mw-sidebar-checkbox', + SIDEBAR_PREFERENCE_NAME = 'VectorSidebarVisible'; + +/** + * Execute a debounced API request to save the sidebar user preference. + * The request is meant to fire 1000 milliseconds after the last click on + * the sidebar button. + * + * @param {HTMLInputElement} checkbox + * @return {any} + */ +function saveSidebarState( checkbox ) { + return debounce( function () { + api = api || new mw.Api(); + api.saveOption( SIDEBAR_PREFERENCE_NAME, checkbox.checked ? 1 : 0 ); + + // Trigger a resize event so other parts of the page can adapt: + var event; + if ( typeof Event === 'function' ) { + event = new Event( 'resize' ); + } else { + // IE11 + event = window.document.createEvent( 'UIEvents' ); + event.initUIEvent( 'resize', true, false, window, 0 ); + } + window.dispatchEvent( event ); + }, 1000 ); +} + +/** + * Bind the event handler that saves the sidebar state to the click event + * on the sidebar button. + * + * @param {HTMLElement|null} checkbox + * @param {HTMLElement|null} button + */ +function bindSidebarClickEvent( checkbox, button ) { + if ( checkbox instanceof HTMLInputElement && button ) { + checkbox.addEventListener( 'input', saveSidebarState( checkbox ) ); + } +} + +function init() { + var checkbox = window.document.getElementById( SIDEBAR_CHECKBOX_ID ), + button = window.document.getElementById( SIDEBAR_BUTTON_ID ); + + if ( mw.config.get( 'wgUserName' ) && !mw.config.get( 'wgVectorDisableSidebarPersistence' ) ) { + bindSidebarClickEvent( checkbox, button ); + } +} + +module.exports = { + init: init +}; diff --git a/resources/skins.vector.js/skin.js b/resources/skins.vector.js/skin.js index ef53be882..a2c9111ee 100644 --- a/resources/skins.vector.js/skin.js +++ b/resources/skins.vector.js/skin.js @@ -1,7 +1,8 @@ var languageButton = require( './languageButton.js' ), initSearchLoader = require( './searchLoader.js' ).initSearchLoader, dropdownMenus = require( './dropdownMenus.js' ), - sidebar = require( './sidebar.js' ); + sidebarPersistence = require( './sidebarPersistence.js' ), + checkbox = require( './checkbox.js' ); /** * Wait for first paint before calling this function. That's its whole purpose. @@ -41,7 +42,8 @@ function enableCssAnimations( document ) { */ function main( window ) { enableCssAnimations( window.document ); - sidebar.init( window ); + sidebarPersistence.init(); + checkbox.init( window ); initSearchLoader( document ); languageButton(); dropdownMenus(); diff --git a/skin.json b/skin.json index 5dd3ff1af..a5e11f048 100644 --- a/skin.json +++ b/skin.json @@ -322,7 +322,8 @@ "callback": "MediaWiki\\Skins\\Vector\\Hooks::getVectorResourceLoaderConfig" }, "resources/skins.vector.js/dropdownMenus.js", - "resources/skins.vector.js/sidebar.js", + "resources/skins.vector.js/checkbox.js", + "resources/skins.vector.js/sidebarPersistence.js", "resources/skins.vector.js/languageButton.js", "resources/skins.vector.js/searchLoader.js" ],