2023-04-11 17:22:58 +00:00
|
|
|
const languageButton = require( './languageButton.js' ),
|
2023-04-11 22:54:40 +00:00
|
|
|
pinnableElement = require( './pinnableElement.js' ),
|
|
|
|
searchToggle = require( './searchToggle.js' ),
|
2022-09-15 00:31:29 +00:00
|
|
|
echo = require( './echo.js' ),
|
2023-05-11 19:03:15 +00:00
|
|
|
initExperiment = require( './AB.js' ),
|
|
|
|
ABTestConfig = require( /** @type {string} */ ( './activeABTest.json' ) ),
|
2020-08-04 12:02:50 +00:00
|
|
|
initSearchLoader = require( './searchLoader.js' ).initSearchLoader,
|
2023-07-20 10:56:06 +00:00
|
|
|
portletsManager = require( './portlets.js' ),
|
2022-08-16 19:50:34 +00:00
|
|
|
dropdownMenus = require( './dropdownMenus.js' ).dropdownMenus,
|
2024-05-24 16:15:14 +00:00
|
|
|
tables = require( './tables.js' ).init,
|
2023-05-15 19:05:38 +00:00
|
|
|
watchstar = require( './watchstar.js' ).init,
|
2023-04-10 19:31:50 +00:00
|
|
|
setupIntersectionObservers = require( './setupIntersectionObservers.js' ),
|
2023-09-22 17:00:27 +00:00
|
|
|
menuTabs = require( './menuTabs.js' ),
|
2024-06-18 20:24:39 +00:00
|
|
|
userPreferences = require( './userPreferences.js' ),
|
2024-07-03 20:52:26 +00:00
|
|
|
{ isNightModeGadgetEnabled, disableNightModeForGadget, alterExclusionMessage, removeBetaNotice } = require( './disableNightModeIfGadget.js' ),
|
2023-09-22 17:00:27 +00:00
|
|
|
teleportTarget = /** @type {HTMLElement} */require( /** @type {string} */ ( 'mediawiki.page.ready' ) ).teleportTarget;
|
2020-04-10 15:24:13 +00:00
|
|
|
|
2020-05-28 20:19:06 +00:00
|
|
|
/**
|
|
|
|
* Wait for first paint before calling this function. That's its whole purpose.
|
|
|
|
*
|
|
|
|
* Some CSS animations and transitions are "disabled" by default as a workaround to this old Chrome
|
|
|
|
* bug, https://bugs.chromium.org/p/chromium/issues/detail?id=332189, which otherwise causes them to
|
|
|
|
* render in their terminal state on page load. By adding the `vector-animations-ready` class to the
|
|
|
|
* `html` root element **after** first paint, the animation selectors suddenly match causing the
|
|
|
|
* animations to become "enabled" when they will work properly. A similar pattern is used in Minerva
|
|
|
|
* (see T234570#5779890, T246419).
|
|
|
|
*
|
|
|
|
* Example usage in Less:
|
|
|
|
*
|
|
|
|
* ```less
|
|
|
|
* .foo {
|
|
|
|
* color: #f00;
|
2022-05-13 20:34:51 +00:00
|
|
|
* transform: translateX( -100% );
|
2020-05-28 20:19:06 +00:00
|
|
|
* }
|
|
|
|
*
|
|
|
|
* // This transition will be disabled initially for JavaScript users. It will never be enabled for
|
2022-05-13 19:41:15 +00:00
|
|
|
* // non-JavaScript users.
|
2020-05-28 20:19:06 +00:00
|
|
|
* .vector-animations-ready .foo {
|
2022-05-13 19:41:15 +00:00
|
|
|
* transition: transform 100ms ease-out;
|
2020-05-28 20:19:06 +00:00
|
|
|
* }
|
|
|
|
* ```
|
|
|
|
*
|
|
|
|
* @param {Document} document
|
|
|
|
* @return {void}
|
|
|
|
*/
|
|
|
|
function enableCssAnimations( document ) {
|
|
|
|
document.documentElement.classList.add( 'vector-animations-ready' );
|
|
|
|
}
|
|
|
|
|
2020-03-30 20:07:35 +00:00
|
|
|
/**
|
|
|
|
* @param {Window} window
|
|
|
|
* @return {void}
|
|
|
|
*/
|
|
|
|
function main( window ) {
|
2021-09-03 15:55:50 +00:00
|
|
|
enableCssAnimations( window.document );
|
|
|
|
initSearchLoader( document );
|
|
|
|
languageButton();
|
2022-09-15 00:31:29 +00:00
|
|
|
echo();
|
2023-07-20 10:56:06 +00:00
|
|
|
portletsManager.main();
|
2022-11-07 22:57:31 +00:00
|
|
|
watchstar();
|
2023-04-11 22:54:40 +00:00
|
|
|
// Initialize the search toggle for the main header only. The sticky header
|
|
|
|
// toggle is initialized after Codex search loads.
|
|
|
|
const searchToggleElement = document.querySelector( '.mw-header .search-toggle' );
|
|
|
|
if ( searchToggleElement ) {
|
|
|
|
searchToggle( searchToggleElement );
|
|
|
|
}
|
|
|
|
pinnableElement.initPinnableElement();
|
|
|
|
// Initializes the TOC and sticky header, behaviour of which depend on scroll behaviour.
|
2023-04-10 19:31:50 +00:00
|
|
|
setupIntersectionObservers.main();
|
2023-09-22 17:00:27 +00:00
|
|
|
// Apply body styles to teleported elements
|
|
|
|
teleportTarget.classList.add( 'vector-body' );
|
2023-11-07 23:35:26 +00:00
|
|
|
|
|
|
|
// Load client preferences
|
2024-04-12 03:27:34 +00:00
|
|
|
const appearanceMenuSelector = '#vector-appearance';
|
|
|
|
const appearanceMenuExists = document.querySelectorAll( appearanceMenuSelector ).length > 0;
|
|
|
|
if ( appearanceMenuExists ) {
|
2024-03-12 13:36:15 +00:00
|
|
|
mw.loader.using( [
|
|
|
|
'skins.vector.clientPreferences',
|
|
|
|
'skins.vector.search.codex.styles',
|
|
|
|
'skins.vector.search.codex.scripts'
|
|
|
|
] ).then( () => {
|
2023-11-07 23:35:26 +00:00
|
|
|
const clientPreferences = require( /** @type {string} */ ( 'skins.vector.clientPreferences' ) );
|
2024-01-12 00:07:33 +00:00
|
|
|
const clientPreferenceConfig = ( require( './clientPreferences.json' ) );
|
2024-01-31 21:11:51 +00:00
|
|
|
// Can be removed once wgVectorNightMode is removed.
|
|
|
|
if ( document.documentElement.classList.contains( 'vector-feature-night-mode-disabled' ) ) {
|
|
|
|
// @ts-ignore issues relating to delete operator are not relevant here.
|
2024-03-20 18:13:14 +00:00
|
|
|
delete clientPreferenceConfig[ 'skin-theme' ];
|
2024-01-31 21:11:51 +00:00
|
|
|
}
|
2024-05-28 23:30:23 +00:00
|
|
|
|
|
|
|
// while we're in beta, temporarily check if the night mode gadget is installed and
|
|
|
|
// disable our night mode if so
|
|
|
|
if ( isNightModeGadgetEnabled() ) {
|
|
|
|
disableNightModeForGadget();
|
2024-09-26 19:24:25 +00:00
|
|
|
clientPreferences.render(
|
|
|
|
appearanceMenuSelector, clientPreferenceConfig, userPreferences
|
|
|
|
);
|
2024-05-28 23:30:23 +00:00
|
|
|
alterExclusionMessage();
|
2024-07-03 20:52:26 +00:00
|
|
|
removeBetaNotice();
|
2024-05-28 23:30:23 +00:00
|
|
|
} else {
|
2024-09-26 19:24:25 +00:00
|
|
|
clientPreferences.render(
|
|
|
|
appearanceMenuSelector, clientPreferenceConfig, userPreferences
|
|
|
|
);
|
2024-05-28 23:30:23 +00:00
|
|
|
}
|
2023-11-07 23:35:26 +00:00
|
|
|
} );
|
|
|
|
}
|
2024-01-30 18:12:38 +00:00
|
|
|
|
|
|
|
dropdownMenus();
|
|
|
|
// menuTabs should follow `dropdownMenus` as that can move menu items from a
|
|
|
|
// tab menu to a dropdown.
|
|
|
|
menuTabs();
|
2024-05-24 16:15:14 +00:00
|
|
|
tables();
|
2021-09-03 15:55:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param {Window} window
|
|
|
|
* @return {void}
|
|
|
|
*/
|
|
|
|
function init( window ) {
|
2023-04-11 17:22:58 +00:00
|
|
|
const now = mw.now();
|
2021-03-17 23:04:42 +00:00
|
|
|
// This is the earliest time we can run JS for users (and bucket anonymous
|
|
|
|
// users for A/B tests).
|
|
|
|
// Where the browser supports it, for a 10% sample of users
|
|
|
|
// we record a value to give us a sense of the expected delay in running A/B tests or
|
|
|
|
// disabling JS features. This will inform us on various things including what to expect
|
|
|
|
// with regards to delay while running A/B tests to anonymous users.
|
|
|
|
// When EventLogging is not available this will reject.
|
|
|
|
// This code can be removed by the end of the Desktop improvements project.
|
|
|
|
// https://www.mediawiki.org/wiki/Desktop_improvements
|
2024-06-06 15:22:05 +00:00
|
|
|
mw.loader.using( 'ext.eventLogging' ).then( () => {
|
2021-03-17 23:04:42 +00:00
|
|
|
if (
|
|
|
|
mw.eventLog &&
|
|
|
|
mw.eventLog.eventInSample( 100 /* 1 in 100 */ ) &&
|
|
|
|
window.performance &&
|
|
|
|
window.performance.timing &&
|
|
|
|
window.performance.timing.navigationStart
|
|
|
|
) {
|
|
|
|
mw.track( 'timing.Vector.ready', now - window.performance.timing.navigationStart ); // milliseconds
|
|
|
|
}
|
|
|
|
} );
|
2020-04-10 15:24:13 +00:00
|
|
|
}
|
|
|
|
|
2021-09-03 15:55:50 +00:00
|
|
|
init( window );
|
2023-05-11 19:03:15 +00:00
|
|
|
if ( ABTestConfig.enabled && !mw.user.isAnon() ) {
|
|
|
|
initExperiment( ABTestConfig, String( mw.user.getId() ) );
|
|
|
|
}
|
2021-09-03 15:55:50 +00:00
|
|
|
if ( document.readyState === 'interactive' || document.readyState === 'complete' ) {
|
2023-04-10 19:31:50 +00:00
|
|
|
main( window );
|
2021-09-03 15:55:50 +00:00
|
|
|
} else {
|
|
|
|
// This is needed when document.readyState === 'loading'.
|
2024-06-06 15:22:05 +00:00
|
|
|
document.addEventListener( 'DOMContentLoaded', () => {
|
2023-04-10 19:31:50 +00:00
|
|
|
main( window );
|
2021-09-03 15:55:50 +00:00
|
|
|
} );
|
|
|
|
}
|
2023-09-22 21:05:20 +00:00
|
|
|
|
|
|
|
// Provider of skins.vector.js module:
|
|
|
|
/**
|
2024-01-11 19:08:25 +00:00
|
|
|
* skins.vector.js
|
2024-04-21 21:48:09 +00:00
|
|
|
*
|
2024-01-11 19:08:25 +00:00
|
|
|
* @stable for use inside WikimediaEvents ONLY.
|
|
|
|
*/
|
2023-09-22 21:05:20 +00:00
|
|
|
module.exports = { pinnableElement };
|