mirror of
https://gerrit.wikimedia.org/r/mediawiki/skins/Vector.git
synced 2024-11-24 15:53:46 +00:00
Merge "Moves feature classes from BODY element to HTML element"
This commit is contained in:
commit
ebe6154e6c
|
@ -5,7 +5,7 @@
|
|||
},
|
||||
{
|
||||
"resourceModule": "skins.vector.styles",
|
||||
"maxSize": "11.1 kB"
|
||||
"maxSize": "11.2 kB"
|
||||
},
|
||||
{
|
||||
"resourceModule": "skins.vector.legacy.js",
|
||||
|
|
|
@ -6,7 +6,6 @@ use Config;
|
|||
use IContextSource;
|
||||
use MediaWiki\Auth\Hook\LocalUserCreatedHook;
|
||||
use MediaWiki\Hook\MakeGlobalVariablesScriptHook;
|
||||
use MediaWiki\Hook\OutputPageBodyAttributesHook;
|
||||
use MediaWiki\Hook\RequestContextCreateSkinHook;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use MediaWiki\Preferences\Hook\GetPreferencesHook;
|
||||
|
@ -32,7 +31,6 @@ class Hooks implements
|
|||
GetPreferencesHook,
|
||||
LocalUserCreatedHook,
|
||||
MakeGlobalVariablesScriptHook,
|
||||
OutputPageBodyAttributesHook,
|
||||
ResourceLoaderSiteModulePagesHook,
|
||||
ResourceLoaderSiteStylesModulePagesHook,
|
||||
RequestContextCreateSkinHook,
|
||||
|
@ -650,26 +648,6 @@ class Hooks implements
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when OutputPage::headElement is creating the body tag to allow skins
|
||||
* and extensions to add attributes they might need to the body of the page.
|
||||
*
|
||||
* @param OutputPage $out
|
||||
* @param Skin $sk
|
||||
* @param string[] &$bodyAttrs
|
||||
*/
|
||||
public function onOutputPageBodyAttributes( $out, $sk, &$bodyAttrs ): void {
|
||||
$skinName = $out->getSkin()->getSkinName();
|
||||
if ( !self::isVectorSkin( $skinName ) ) {
|
||||
return;
|
||||
}
|
||||
$config = $sk->getConfig();
|
||||
|
||||
$featureManager = VectorServices::getFeatureManager();
|
||||
$bodyAttrs['class'] .= ' ' . implode( ' ', $featureManager->getFeatureBodyClass() );
|
||||
$bodyAttrs['class'] = trim( $bodyAttrs['class'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Temporary RequestContextCreateSkin hook handler.
|
||||
* Switches to new Vector on certain pages.
|
||||
|
|
|
@ -185,6 +185,8 @@ class SkinVector22 extends SkinMustache {
|
|||
*/
|
||||
public function getHtmlElementAttributes() {
|
||||
$original = parent::getHtmlElementAttributes();
|
||||
$featureManager = VectorServices::getFeatureManager();
|
||||
$original['class'] .= ' ' . implode( ' ', $featureManager->getFeatureBodyClass() );
|
||||
|
||||
if ( VectorServices::getFeatureManager()->isFeatureEnabled( Constants::FEATURE_STICKY_HEADER ) ) {
|
||||
// T290518: Add scroll padding to root element when the sticky header is
|
||||
|
@ -200,6 +202,7 @@ class SkinVector22 extends SkinMustache {
|
|||
// possibly others). It must instead be applied to the html tag.
|
||||
$original['class'] = implode( ' ', [ $original['class'] ?? '', self::STICKY_HEADER_ENABLED_CLASS ] );
|
||||
}
|
||||
$original['class'] = trim( $original['class'] );
|
||||
|
||||
return $original;
|
||||
}
|
||||
|
|
|
@ -4,25 +4,12 @@ let /** @type {MwApi} */ api;
|
|||
const debounce = require( /** @type {string} */ ( 'mediawiki.util' ) ).debounce;
|
||||
|
||||
/**
|
||||
* Saves preference to user preferences and/or localStorage.
|
||||
* Saves preference to user preferences if user is logged in
|
||||
*
|
||||
* @param {string} feature
|
||||
* @param {boolean} enabled
|
||||
*/
|
||||
function save( feature, enabled ) {
|
||||
let featuresJSON;
|
||||
// @ts-ignore
|
||||
const features = mw.storage.get( 'VectorFeatures' ) || '{}';
|
||||
|
||||
try {
|
||||
featuresJSON = JSON.parse( features );
|
||||
} catch ( e ) {
|
||||
featuresJSON = {};
|
||||
}
|
||||
featuresJSON[ feature ] = enabled;
|
||||
// @ts-ignore
|
||||
mw.storage.set( 'VectorFeatures', JSON.stringify( featuresJSON ) );
|
||||
|
||||
if ( !mw.user.isAnon() ) {
|
||||
debounce( function () {
|
||||
api = api || new mw.Api();
|
||||
|
@ -57,12 +44,40 @@ function toggleBodyClasses( name, override ) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} name feature name
|
||||
* @param {boolean} [override] option to force enabled or disabled state.
|
||||
*
|
||||
* @return {boolean} The new feature state (false=disabled, true=enabled).
|
||||
* @throws {Error} if unknown feature toggled.
|
||||
*/
|
||||
function toggleDocClasses( name, override ) {
|
||||
const featureClassEnabled = `vector-feature-${name}-enabled`,
|
||||
classList = document.documentElement.classList,
|
||||
featureClassDisabled = `vector-feature-${name}-disabled`;
|
||||
|
||||
if ( classList.contains( featureClassDisabled ) || override === true ) {
|
||||
classList.remove( featureClassDisabled );
|
||||
classList.add( featureClassEnabled );
|
||||
return true;
|
||||
} else if ( classList.contains( featureClassEnabled ) || override === false ) {
|
||||
classList.add( featureClassDisabled );
|
||||
classList.remove( featureClassEnabled );
|
||||
return false;
|
||||
} else {
|
||||
// Perhaps we are dealing with cached HTML ?
|
||||
// FIXME: Can be removed and replaced with throw new Error when cache is clear.
|
||||
return toggleBodyClasses( name, override );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} name
|
||||
* @throws {Error} if unknown feature toggled.
|
||||
*/
|
||||
function toggle( name ) {
|
||||
const featureState = toggleBodyClasses( name );
|
||||
const featureState = toggleDocClasses( name );
|
||||
save( name, featureState );
|
||||
}
|
||||
|
||||
|
@ -73,9 +88,10 @@ function toggle( name ) {
|
|||
* @return {boolean}
|
||||
*/
|
||||
function isEnabled( name ) {
|
||||
return document.body.classList.contains(
|
||||
'vector-feature-' + name + '-enabled'
|
||||
);
|
||||
const className = `vector-feature-${name}-enabled`;
|
||||
return document.documentElement.classList.contains( className ) ||
|
||||
// FIXME: For cached HTML. Remove after one train cycle.
|
||||
document.body.classList.contains( className );
|
||||
}
|
||||
|
||||
module.exports = { isEnabled, toggle, toggleBodyClasses };
|
||||
module.exports = { isEnabled, toggle, toggleDocClasses };
|
||||
|
|
|
@ -21,11 +21,11 @@
|
|||
}
|
||||
|
||||
//NOTE: enabled/disabled class on body.
|
||||
&.vector-feature-limited-width-disabled .vector-limited-width-toggle:before {
|
||||
.vector-feature-limited-width-disabled .vector-limited-width-toggle:before {
|
||||
background-image: url( images/fullscreen-close.svg );
|
||||
}
|
||||
|
||||
&.vector-feature-limited-width-enabled .vector-limited-width-toggle:before {
|
||||
.vector-feature-limited-width-enabled .vector-limited-width-toggle:before {
|
||||
background-image: url( images/fullscreen.svg );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,14 +31,14 @@ function disablePinningAtBreakpoint( header, e ) {
|
|||
// FIXME: Class toggling should be centralized instead of being
|
||||
// handled here, in features.js and togglePinnableClasses().
|
||||
if ( e.matches && savedPinnedState === true ) {
|
||||
features.toggleBodyClasses( featureName, false );
|
||||
features.toggleDocClasses( featureName, false );
|
||||
header.classList.remove( PINNED_HEADER_CLASS );
|
||||
header.classList.add( UNPINNED_HEADER_CLASS );
|
||||
movePinnableElement( pinnableElementId, unpinnedContainerId );
|
||||
}
|
||||
|
||||
if ( !e.matches && savedPinnedState === true ) {
|
||||
features.toggleBodyClasses( featureName, true );
|
||||
features.toggleDocClasses( featureName, true );
|
||||
header.classList.add( PINNED_HEADER_CLASS );
|
||||
header.classList.remove( UNPINNED_HEADER_CLASS );
|
||||
movePinnableElement( pinnableElementId, pinnedContainerId );
|
||||
|
|
|
@ -32,11 +32,15 @@
|
|||
|
||||
@media ( min-width: @min-width-desktop-wide ) {
|
||||
// Ensure search box is aligned with content when search thumbnails or JS is off
|
||||
// FIXME: Remove html:not( .client-js ) when cache has cleared.
|
||||
.vector-feature-page-tools-disabled & .vector-search-box:not( .vector-search-box-auto-expand-width ),
|
||||
.vector-feature-page-tools-disabled:not( .client-js ) & .vector-search-box,
|
||||
html:not( .client-js ) .vector-feature-page-tools-disabled & .vector-search-box {
|
||||
padding-left: @size-search-expand;
|
||||
}
|
||||
|
||||
// FIXME: Remove .client-js .vector-feature-page-tools-enabled when cache has cleared.
|
||||
.client-js.vector-feature-page-tools-enabled & .vector-search-box.vector-search-box-auto-expand-width,
|
||||
.client-js .vector-feature-page-tools-enabled & .vector-search-box.vector-search-box-auto-expand-width {
|
||||
// Ensure search box is aligned with content when it autoexpands (i.e. search thumbnails)
|
||||
margin-left: -@size-search-expand;
|
||||
|
|
|
@ -18,11 +18,15 @@
|
|||
contain: paint;
|
||||
}
|
||||
|
||||
// FIXME: `.vector-feature-page-tools-disabled.vector-toc-pinned` can be removed when cached HTML no longer an issue.
|
||||
.vector-feature-page-tools-disabled .vector-toc-pinned &,
|
||||
.vector-feature-page-tools-disabled.vector-toc-pinned & {
|
||||
// Align the left edge of the TOC text with the main menu button icon.
|
||||
margin-left: -27px;
|
||||
}
|
||||
|
||||
// FIXME: `.vector-feature-page-tools-enabled.vector-toc-pinned` can be removed when cached HTML no longer an issue.
|
||||
.vector-feature-page-tools-enabled .vector-toc-pinned &,
|
||||
.vector-feature-page-tools-enabled.vector-toc-pinned & {
|
||||
// Align the left edge of the TOC text with the page container
|
||||
margin-left: -@spacing-subsection-toggle;
|
||||
|
@ -40,11 +44,15 @@
|
|||
padding-top: 1.5em;
|
||||
}
|
||||
|
||||
// FIXME: .vector-feature-page-tools-disabled.vector-toc-pinned can be removed when cached HTML no longer an issue.
|
||||
.vector-feature-page-tools-disabled .vector-toc-pinned @{selector-main-menu-closed} ~ .mw-table-of-contents-container &,
|
||||
.vector-feature-page-tools-disabled.vector-toc-pinned @{selector-main-menu-closed} ~ .mw-table-of-contents-container & {
|
||||
// Needed to align TOC with bottom of title, 1.5em padding + 1.5em margin = 3em
|
||||
margin-top: 1.5em;
|
||||
}
|
||||
|
||||
// FIXME: .vector-feature-page-tools-enabled.vector-toc-pinned can be removed when cached HTML no longer an issue.
|
||||
.vector-feature-page-tools-enabled.vector-feature-main-menu-pinned-disabled .vector-toc-pinned &,
|
||||
.vector-feature-page-tools-enabled.vector-toc-pinned.vector-feature-main-menu-pinned-disabled & {
|
||||
// Align TOC with bottom of title when main menu is not pinned but the TOC is
|
||||
margin-top: @margin-top-pinned-toc;
|
||||
|
|
|
@ -108,7 +108,10 @@
|
|||
|
||||
// Horizontally center content when column start is empty (i.e. no pinned ToC or pinned main menu)
|
||||
.vector-feature-page-tools-disabled {
|
||||
|
||||
// FIXME: &.vector-toc-unpinned can be removed when cache is clear.
|
||||
@{selector-sidebar-no-toc-sidebar-closed},
|
||||
.vector-toc-unpinned @{selector-main-menu-closed},
|
||||
&.vector-toc-unpinned @{selector-main-menu-closed} {
|
||||
& ~ .mw-content-container {
|
||||
grid-column: mainMenu / pageContent;
|
||||
|
@ -121,7 +124,9 @@
|
|||
|
||||
// Horizontally center content when column start is empty (i.e. no pinned ToC or pinned main menu)
|
||||
.vector-feature-page-tools-enabled {
|
||||
// FIXME: &.vector-toc-unpinned can be removed when cache is clear.
|
||||
&.vector-feature-main-menu-pinned-disabled .vector-sidebar-container-no-toc ~ .mw-content-container,
|
||||
&.vector-feature-main-menu-pinned-disabled .vector-toc-unpinned .mw-content-container,
|
||||
&.vector-toc-unpinned.vector-feature-main-menu-pinned-disabled .mw-content-container {
|
||||
grid-column: mainMenu / pageContent;
|
||||
margin-left: auto;
|
||||
|
|
|
@ -175,7 +175,6 @@
|
|||
"GetPreferences": "VectorHooks",
|
||||
"LocalUserCreated": "VectorHooks",
|
||||
"MakeGlobalVariablesScript": "VectorHooks",
|
||||
"OutputPageBodyAttributes": "VectorHooks",
|
||||
"ResourceLoaderSiteModulePages": "VectorHooks",
|
||||
"ResourceLoaderSiteStylesModulePages": "VectorHooks",
|
||||
"SkinPageReadyConfig": "VectorHooks"
|
||||
|
|
Loading…
Reference in a new issue