mediawiki-skins-Vector/resources/skins.vector.js/disableNightModeIfGadget.js
Steph Toyofuku b8e9eaf6ed Show night mode gadget disable message on the correct section
Currently, this selector is not specific enough, and so if there is an
additional client pref that is disabled on the page, we'll put the night
mode gadget message in the wrong spot.  Target the skin-theme section
correctly this time, and add a test to ensure this is fixed properly

Bug: T369846
Change-Id: I3495aa9ebf3be510f62a8f19440968fe444be892
2024-07-11 11:44:56 -07:00

109 lines
3.4 KiB
JavaScript

const userPreferences = require( './userPreferences.js' );
/**
* T365083 - Disable night mode if night mode gadget is enabled
*
* While our implementation of night mode is still in beta, we want to respect the existing gadget
* and disable our version to avoid a double invert - that said, we will still provide a prompt for
* the user to disable the gadget so they can try our night mode
*/
/**
* Are any of the gadgets associated with the broader night mode gadget enabled?
* Note: This is localized to the names of the gadget in our particular language
*
* @return {boolean}
*/
function isNightModeGadgetEnabled() {
return mw.msg( 'vector-night-mode-gadget-names' ).split( '|' ).some( ( gadget ) => {
const state = mw.loader.getState( `ext.gadget.${ gadget }` );
// the state is null if it's not installed or we're on the preference page, otherwise it's
// registered if the user doesn't have it turned on - all other states we consider enabled
return state !== null && state !== 'registered';
} );
}
/**
* Manually mark the page we're on as excluded
*/
function disableNightModeForGadget() {
document.documentElement.classList.remove( 'skin-theme-clientpref-night', 'skin-theme-clientpref-os' );
document.documentElement.classList.add( 'skin-theme-clientpref--excluded' );
}
/**
* Modify the link to disable the gadget so that, when clicked, it will disable the night mode
* gadget rather than simply take you to the page
* Note: The gadget names are similarly localized to the current language
*
* @param {Element} container an html element containing a link
*/
function alterDisableLink( container ) {
const gadgetNames = mw.msg( 'vector-night-mode-gadget-names' );
const link = container.querySelector( 'a' );
// if we can't disable the gadget, keep the link functional
// (if we can't find a link, not much we can do)
if ( !gadgetNames || !link ) {
return;
}
link.removeAttribute( 'title' );
link.removeAttribute( 'href' );
link.style.display = 'inline';
link.addEventListener( 'click', () => {
/** @type {Object.<string, number>} */
const disableOptions = {};
gadgetNames.split( '|' ).forEach( ( gadgetName ) => {
disableOptions[ `gadget-${ gadgetName }` ] = 0;
} );
userPreferences.saveOptions( disableOptions ).then( () => {
window.location.reload();
} );
} );
}
/**
* Removes the link that solicits user feedback for dark mode.
*/
function removeBetaNotice() {
const feedbackNoticeContainer = document.getElementById( 'skin-theme-beta-notice' );
if ( feedbackNoticeContainer ) {
feedbackNoticeContainer.remove();
}
}
/**
* Modify the default exclusion message to indicate that we've disabled night mode on the page due
* to a conflicting gadget, providing a link to disable the gadget in favor of our night mode
*/
function alterExclusionMessage() {
const noticeContainer = document.querySelector( '#skin-client-prefs-skin-theme .exclusion-notice' );
// if there's no exclusion notice, nothing we can do
if ( !noticeContainer ) {
return;
}
mw.loader.using( 'mediawiki.jqueryMsg' ).then( () => {
// remove existing message
noticeContainer.textContent = '';
mw.message( 'vector-night-mode-gadget-warning' ).parseDom().appendTo( noticeContainer );
alterDisableLink( noticeContainer );
} );
}
module.exports = {
isNightModeGadgetEnabled,
disableNightModeForGadget,
alterDisableLink,
alterExclusionMessage,
removeBetaNotice
};