mediawiki-skins-Vector/resources/skins.vector.js/popupNotification.js
Steph Toyofuku 4a0c2cb684 Disable night mode if gadget detected
While our implementation of night mode is in beta, we want to respect
the existing night mode gadget and disable night mode in favor of the
gadget, providing a notice with an option to disable the gadget and
reload the page

Additionally, raise the max bundle size to account for the additional
code added

Note: the tests still aren't exactly where I'd like them to be, but
hopefully they raise confidence a little bit with reviewing this patch

Additional changes:
* Upgrade to latest version of TypeScript types and remove several
@ts-ignore statements

Bug: T365083
Change-Id: I9583ee7ebf8c810ddd504193d568034c954d28f2
2024-05-30 20:23:38 +00:00

98 lines
2.5 KiB
JavaScript

/** @module PopupNotification */
// Store active notifications to only show one at a time, for use inside clearHints and showHint
const /** @type {Record<string,OoUiPopupWidget>} */ activeNotification = {};
/**
* Adds and show a popup to the user to point them to the new location of the element
*
* @param {HTMLElement} container
* @param {string} message
* @param {string} id
* @param {string[]} [classes]
* @param {number|false} [timeout]
* @param {Function} [onDismiss]
* @return {JQuery.Promise<OoUiPopupWidget|undefined>}
*/
function add( container, message, id, classes = [], timeout = 4000, onDismiss = () => {} ) {
/**
* @type {OoUiPopupWidget}
*/
let popupWidget;
// load oojs-ui if it's not already loaded
// FIXME: This should be replaced with Codex.
return mw.loader.using( 'oojs-ui-core' ).then( () => {
// use existing hint.
if ( id && activeNotification[ id ] ) {
return activeNotification[ id ];
}
const content = document.createElement( 'p' );
content.textContent = message;
popupWidget = new OO.ui.PopupWidget( {
// eslint-disable-next-line no-jquery/no-jquery-constructor
$content: $( content ),
padded: true,
autoClose: timeout !== false,
head: timeout === false,
anchor: true,
align: 'center',
position: 'below',
classes: [ 'vector-popup-notification' ].concat( classes ),
container
} );
// eslint-disable-next-line no-jquery/no-other-methods
popupWidget.$element.appendTo( container );
popupWidget.on( 'closing', () => {
onDismiss();
} );
if ( popupWidget && id ) {
activeNotification[ id ] = popupWidget;
}
return popupWidget;
} );
}
/**
* Hides the popup widget
*
* @param {OoUiPopupWidget} popupWidget popupWidget from oojs-ui
* cannot use type because it's not loaded yet
*/
function hide( popupWidget ) {
popupWidget.toggle( false );
}
/**
* Shows the popup widget
*
* @param {OoUiPopupWidget} popupWidget popupWidget from oojs-ui
* cannot use type because it's not loaded yet
* @param {number|false} [timeout] use false if user must dismiss it themselves.
*/
function show( popupWidget, timeout = 4000 ) {
popupWidget.toggle( true );
popupWidget.toggleClipping( true );
// hide the popup after timeout ms
if ( timeout === false ) {
return;
}
setTimeout( () => {
hide( popupWidget );
}, timeout );
}
/**
* Hides all popups
*
*/
function hideAll() {
for ( const key in activeNotification ) {
const popupWidget = activeNotification[ key ];
hide( popupWidget );
}
}
module.exports = {
add,
hide,
hideAll,
show
};