mirror of
https://gerrit.wikimedia.org/r/mediawiki/skins/Vector.git
synced 2024-09-23 10:21:40 +00:00
Merge "Removes old style rule"
This commit is contained in:
commit
7932f6894d
|
@ -12,8 +12,8 @@ class VectorComponentPinnableHeader implements VectorComponent {
|
|||
/** @var bool */
|
||||
private $pinned;
|
||||
/** @var string */
|
||||
private $name;
|
||||
/** @var string|null */
|
||||
private $id;
|
||||
/** @var string */
|
||||
private $featureName;
|
||||
/**
|
||||
* @var bool
|
||||
|
@ -28,9 +28,9 @@ class VectorComponentPinnableHeader implements VectorComponent {
|
|||
/**
|
||||
* @param MessageLocalizer $localizer
|
||||
* @param bool $pinned
|
||||
* @param string $name By convention, this should include the `vector-`
|
||||
* @param string $id Pinnable element id, by convention this should include the `vector-`
|
||||
* prefix e.g. `vector-page-tools` or `vector-toc`.
|
||||
* @param string|null $featureName If set, pinned and unpinned states will
|
||||
* @param string $featureName Pinned and unpinned states will
|
||||
* persist for logged-in users by leveraging features.js to manage the user
|
||||
* preference storage and the toggling of the body class. This name should NOT
|
||||
* contain the "vector-" prefix.
|
||||
|
@ -41,14 +41,14 @@ class VectorComponentPinnableHeader implements VectorComponent {
|
|||
public function __construct(
|
||||
MessageLocalizer $localizer,
|
||||
bool $pinned,
|
||||
string $name,
|
||||
?string $featureName,
|
||||
string $id,
|
||||
string $featureName,
|
||||
?bool $moveElement = true,
|
||||
?string $labelTagName = 'div'
|
||||
) {
|
||||
$this->localizer = $localizer;
|
||||
$this->pinned = $pinned;
|
||||
$this->name = $name;
|
||||
$this->id = $id;
|
||||
$this->featureName = $featureName;
|
||||
$this->moveElement = $moveElement;
|
||||
$this->labelTagName = $labelTagName;
|
||||
|
@ -61,19 +61,18 @@ class VectorComponentPinnableHeader implements VectorComponent {
|
|||
$messageLocalizer = $this->localizer;
|
||||
$data = [
|
||||
'is-pinned' => $this->pinned,
|
||||
'label' => $messageLocalizer->msg( $this->name . '-label' ),
|
||||
'label' => $messageLocalizer->msg( $this->id . '-label' ),
|
||||
'label-tag-name' => $this->labelTagName,
|
||||
'pin-label' => $messageLocalizer->msg( 'vector-pin-element-label' ),
|
||||
'unpin-label' => $messageLocalizer->msg( 'vector-unpin-element-label' ),
|
||||
'data-name' => $this->name,
|
||||
'data-pinnable-element-id' => $this->id,
|
||||
'data-feature-name' => $this->featureName
|
||||
];
|
||||
if ( $this->moveElement ) {
|
||||
// Assumes consistent naming standard for pinnable elements and their containers
|
||||
$data = array_merge( $data, [
|
||||
'data-pinnable-element-id' => $this->name,
|
||||
'data-unpinned-container-id' => $this->name . '-unpinned-container',
|
||||
'data-pinned-container-id' => $this->name . '-pinned-container',
|
||||
'data-unpinned-container-id' => $this->id . '-unpinned-container',
|
||||
'data-pinned-container-id' => $this->id . '-pinned-container',
|
||||
] );
|
||||
}
|
||||
return $data;
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
<div
|
||||
class="vector-pinnable-header {{data-name}}-pinnable-header vector-pinnable-header-{{#is-pinned}}pinned{{/is-pinned}}{{^is-pinned}}unpinned{{/is-pinned}}"
|
||||
data-name="{{data-name}}"
|
||||
class="vector-pinnable-header {{data-pinnable-element-id}}-pinnable-header vector-pinnable-header-{{#is-pinned}}pinned{{/is-pinned}}{{^is-pinned}}unpinned{{/is-pinned}}"
|
||||
{{#data-feature-name}}data-feature-name="{{.}}"{{/data-feature-name}}
|
||||
{{#data-pinnable-element-id}}data-pinnable-element-id="{{.}}"{{/data-pinnable-element-id}}
|
||||
{{#data-pinned-container-id}}data-pinned-container-id="{{.}}"{{/data-pinned-container-id}}
|
||||
{{#data-unpinned-container-id}}data-unpinned-container-id="{{.}}"{{/data-unpinned-container-id}}
|
||||
>
|
||||
<{{label-tag-name}} class="vector-pinnable-header-label">{{label}}</{{label-tag-name}}>
|
||||
<button class="vector-pinnable-header-toggle-button vector-pinnable-header-pin-button" data-event-name="pinnable-header.{{data-name}}.pin">{{pin-label}}</button>
|
||||
<button class="vector-pinnable-header-toggle-button vector-pinnable-header-unpin-button" data-event-name="pinnable-header.{{data-name}}.unpin">{{unpin-label}}</button>
|
||||
<button class="vector-pinnable-header-toggle-button vector-pinnable-header-pin-button" data-event-name="pinnable-header.{{data-pinnable-element-id}}.pin">{{pin-label}}</button>
|
||||
<button class="vector-pinnable-header-toggle-button vector-pinnable-header-unpin-button" data-event-name="pinnable-header.{{data-pinnable-element-id}}.unpin">{{unpin-label}}</button>
|
||||
</div>
|
||||
|
|
|
@ -75,7 +75,22 @@ function toggle( name ) {
|
|||
* @return {boolean}
|
||||
*/
|
||||
function isEnabled( name ) {
|
||||
return document.documentElement.classList.contains( `vector-feature-${name}-enabled` );
|
||||
return document.documentElement.classList.contains( getClass( name, true ) );
|
||||
}
|
||||
|
||||
module.exports = { isEnabled, toggle, toggleDocClasses };
|
||||
/**
|
||||
* Get name of feature class.
|
||||
*
|
||||
* @param {string} name
|
||||
* @param {boolean} featureEnabled
|
||||
* @return {string}
|
||||
*/
|
||||
function getClass( name, featureEnabled ) {
|
||||
if ( featureEnabled ) {
|
||||
return `vector-feature-${name}-enabled`;
|
||||
} else {
|
||||
return `vector-feature-${name}-disabled`;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { getClass, isEnabled, toggle, toggleDocClasses };
|
||||
|
|
|
@ -28,19 +28,13 @@ function disablePinningAtBreakpoint( header, e ) {
|
|||
// Hide the button at lower resolutions.
|
||||
header.hidden = e.matches;
|
||||
|
||||
// FIXME: Class toggling should be centralized instead of being
|
||||
// handled here, in features.js and togglePinnableClasses().
|
||||
if ( e.matches && savedPinnedState === true ) {
|
||||
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.toggleDocClasses( featureName, true );
|
||||
header.classList.add( PINNED_HEADER_CLASS );
|
||||
header.classList.remove( UNPINNED_HEADER_CLASS );
|
||||
movePinnableElement( pinnableElementId, pinnedContainerId );
|
||||
}
|
||||
}
|
||||
|
@ -65,16 +59,12 @@ function setSavedPinnableState( header ) {
|
|||
* @param {HTMLElement} header pinnable element
|
||||
*/
|
||||
function togglePinnableClasses( header ) {
|
||||
const { featureName, name } = header.dataset;
|
||||
const { featureName } = header.dataset;
|
||||
|
||||
if ( featureName ) {
|
||||
// Leverage features.js to toggle the body classes and persist the state
|
||||
// for logged-in users.
|
||||
features.toggle( featureName );
|
||||
} else {
|
||||
// Toggle body classes, assumes default pinned classes are initialized serverside
|
||||
document.body.classList.toggle( `${name}-pinned` );
|
||||
document.body.classList.toggle( `${name}-unpinned` );
|
||||
}
|
||||
|
||||
// Toggle pinned class
|
||||
|
@ -139,10 +129,6 @@ function setFocusAfterToggle( pinnableElementId ) {
|
|||
* @param {HTMLElement} header
|
||||
*/
|
||||
function bindPinnableToggleButtons( header ) {
|
||||
if ( !header.dataset.name ) {
|
||||
return;
|
||||
}
|
||||
|
||||
const pinnableBreakpoint = window.matchMedia( '(max-width: 1000px)' );
|
||||
const toggleButtons = header.querySelectorAll( '.vector-pinnable-header-toggle-button' );
|
||||
|
||||
|
@ -168,11 +154,11 @@ function bindPinnableToggleButtons( header ) {
|
|||
* @return {boolean} Returns true if the element is pinned and false otherwise.
|
||||
*/
|
||||
function isPinned( header ) {
|
||||
// In the future, consider delegating to `features.isEnabled()` if and when
|
||||
// TOC (T316060, T325032) and all pinnable elements use the
|
||||
// `vector-feature-{name}-pinned-enabled` naming convention for the body
|
||||
// class.
|
||||
return header.classList.contains( PINNED_HEADER_CLASS );
|
||||
if ( !header.dataset.featureName ) {
|
||||
return false;
|
||||
} else {
|
||||
return features.isEnabled( header.dataset.featureName );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -157,15 +157,13 @@
|
|||
}
|
||||
}
|
||||
|
||||
// - T314330 `.vector-toc-pinned #vector-toc-pinned-container`
|
||||
// - T314330 `.vector-feature-toc-pinned-enabled #vector-toc-pinned-container`
|
||||
// Prevent ToC from jumping when sticky header is enabled.
|
||||
// - T289817 `.mw-sticky-header-element` provides an API for template developers
|
||||
// to make their templates compatible with the Vector 2022 sticky header.
|
||||
// @stable See the Integration notes for developers section at
|
||||
// https://www.mediawiki.org/wiki/Reading/Web/Desktop_Improvements/Features/Sticky_Header
|
||||
// - `.charts-stickyhead th` makes chart and table headers appear below the sticky header.
|
||||
// FIXME: Remove the following line containing '.vector-toc-pinned #vector-toc-pinned-container' after line 169 has been in prod for a week.
|
||||
.vector-toc-pinned #vector-toc-pinned-container,
|
||||
&.vector-feature-toc-pinned-enabled #vector-toc-pinned-container,
|
||||
&.vector-feature-page-tools-pinned-enabled .vector-page-tools-landmark,
|
||||
.mw-sticky-header-element,
|
||||
|
|
|
@ -150,20 +150,8 @@
|
|||
|
||||
.client-js {
|
||||
@media ( min-width: @min-width-desktop ) {
|
||||
/**
|
||||
* FIXME: Remove the following line containing '.vector-toc-unpinned' after line 157 has been in prod for a week.
|
||||
*/
|
||||
.vector-toc-unpinned.vector-sticky-header-visible .vector-sticky-header .vector-toc-landmark,
|
||||
&.vector-feature-toc-pinned-disabled .vector-sticky-header-visible .vector-sticky-header .vector-toc-landmark,
|
||||
/**
|
||||
* FIXME: Remove the following line containing '.vector-toc-unpinned' after line 162 has been in prod for a week.
|
||||
*/
|
||||
.vector-toc-unpinned:not( .vector-sticky-header-visible ) .vector-page-titlebar .vector-toc-landmark,
|
||||
&.vector-feature-toc-pinned-disabled body:not( .vector-sticky-header-visible ) .vector-page-titlebar .vector-toc-landmark,
|
||||
/**
|
||||
* FIXME: Remove the following line containing '.vector-toc-pinned' after line 167 has been in prod for a week.
|
||||
*/
|
||||
.vector-toc-pinned .mw-table-of-contents-container.vector-toc-landmark,
|
||||
&.vector-feature-toc-pinned-enabled .mw-table-of-contents-container.vector-toc-landmark {
|
||||
display: block;
|
||||
}
|
||||
|
|
|
@ -112,10 +112,6 @@
|
|||
.vector-feature-page-tools-disabled {
|
||||
|
||||
@{selector-sidebar-no-toc-sidebar-closed},
|
||||
/**
|
||||
* FIXME: Remove the following line containing '.vector-toc-unpinned' after line 117 has been in prod for a week.
|
||||
*/
|
||||
.vector-toc-unpinned @{selector-main-menu-closed},
|
||||
&.vector-feature-toc-pinned-disabled @{selector-main-menu-closed} {
|
||||
& ~ .mw-content-container {
|
||||
grid-column: mainMenu / pageContent;
|
||||
|
@ -129,10 +125,6 @@
|
|||
// Horizontally center content when column start is empty (i.e. no pinned ToC or pinned main menu)
|
||||
.vector-feature-page-tools-enabled {
|
||||
&.vector-feature-main-menu-pinned-disabled .vector-sidebar-container-no-toc ~ .mw-content-container,
|
||||
/**
|
||||
* FIXME: Remove the following line containing '.vector-toc-unpinned' after line 134 has been in prod for a week.
|
||||
*/
|
||||
&.vector-feature-main-menu-pinned-disabled .vector-toc-unpinned .mw-content-container,
|
||||
&.vector-feature-main-menu-pinned-disabled.vector-feature-toc-pinned-disabled .mw-content-container {
|
||||
grid-column: mainMenu / pageContent;
|
||||
margin-left: auto;
|
||||
|
|
|
@ -9,8 +9,6 @@
|
|||
|
||||
@media ( min-width: @min-width-desktop ) {
|
||||
#mw-panel-toc {
|
||||
// FIXME: Remove the following line containing '.vector-toc-pinned' after line 14 has been in prod for a week.
|
||||
.vector-toc-pinned &,
|
||||
.vector-feature-toc-pinned-enabled & {
|
||||
// Support: Chrome
|
||||
// Work around sticky-positioned layers disabling subpixel text rendering (T327460).
|
||||
|
@ -21,15 +19,11 @@
|
|||
contain: paint;
|
||||
}
|
||||
|
||||
// FIXME: Remove the following line containing '.vector-toc-pinned' after line 26 has been in prod for a week.
|
||||
.vector-feature-page-tools-disabled .vector-toc-pinned &,
|
||||
.vector-feature-page-tools-disabled.vector-feature-toc-pinned-enabled & {
|
||||
// Align the left edge of the TOC text with the main menu button icon.
|
||||
margin-left: -27px;
|
||||
}
|
||||
|
||||
// FIXME: Remove the following line containing '.vector-toc-pinned' after line 33 has been in prod for a week.
|
||||
.vector-feature-page-tools-enabled .vector-toc-pinned &,
|
||||
.vector-feature-page-tools-enabled.vector-feature-toc-pinned-enabled & {
|
||||
// Align the left edge of the TOC text with the page container
|
||||
margin-left: -@spacing-subsection-toggle;
|
||||
|
@ -41,22 +35,16 @@
|
|||
position: sticky;
|
||||
top: 0;
|
||||
|
||||
// FIXME: Remove the following line containing '.vector-toc-pinned &' after line 46 has been in prod for a week.
|
||||
.vector-toc-pinned &,
|
||||
.vector-feature-toc-pinned-enabled & {
|
||||
// Default spacing separating the sidebar TOC from the main menu.
|
||||
margin-top: 1.5em;
|
||||
}
|
||||
|
||||
// FIXME: Remove the following line containing '.vector-toc-pinned' after line 53 has been in prod for a week.
|
||||
.vector-feature-page-tools-disabled .vector-toc-pinned @{selector-main-menu-closed} ~ .mw-table-of-contents-container &,
|
||||
.vector-feature-page-tools-disabled.vector-feature-toc-pinned-enabled @{selector-main-menu-closed} ~ .mw-table-of-contents-container & {
|
||||
// Needed to align TOC with bottom of title.
|
||||
margin-top: @margin-top-pinned-toc;
|
||||
}
|
||||
|
||||
// FIXME: Remove the following line containing '.vector-toc-pinned' after line 60 has been in prod for a week.
|
||||
.vector-feature-page-tools-enabled.vector-feature-main-menu-pinned-disabled .vector-toc-pinned &,
|
||||
.vector-feature-page-tools-enabled.vector-feature-main-menu-pinned-disabled.vector-feature-toc-pinned-enabled & {
|
||||
// Align TOC with bottom of title when main menu is not pinned but the TOC is
|
||||
margin-top: @margin-top-pinned-toc;
|
||||
|
|
|
@ -97,8 +97,6 @@ body:not( .vector-below-page-title ) #vector-page-titlebar-toc-label {
|
|||
//
|
||||
// TOC in page titlebar
|
||||
//
|
||||
// FIXME: Remove the following line containing '.vector-toc-unpinned' after line 102 has been in prod for a week.
|
||||
.vector-toc-unpinned:not( .vector-sticky-header-visible ),
|
||||
&.vector-feature-toc-pinned-disabled body:not( .vector-sticky-header-visible ) {
|
||||
.vector-page-titlebar-toc {
|
||||
.mixin-toc-unpinned();
|
||||
|
@ -108,8 +106,6 @@ body:not( .vector-below-page-title ) #vector-page-titlebar-toc-label {
|
|||
//
|
||||
// TOC in page titlebar below page title
|
||||
//
|
||||
// FIXME: Remove the following line containing '.vector-toc-unpinned' after line 113 has been in prod for a week.
|
||||
.vector-toc-unpinned:not( .vector-sticky-header-visible ).vector-below-page-title,
|
||||
&.vector-feature-toc-pinned-disabled body:not( .vector-sticky-header-visible ).vector-below-page-title {
|
||||
.vector-page-titlebar-toc {
|
||||
.mixin-toc-below-page-title();
|
||||
|
@ -119,8 +115,6 @@ body:not( .vector-below-page-title ) #vector-page-titlebar-toc-label {
|
|||
//
|
||||
// TOC in sticky header
|
||||
//
|
||||
// FIXME: Remove the following line containing '.vector-toc-unpinned' after line 124 has been in prod for a week.
|
||||
.vector-toc-unpinned.vector-sticky-header-visible,
|
||||
&.vector-feature-toc-pinned-disabled .vector-sticky-header-visible {
|
||||
.vector-sticky-header-toc {
|
||||
.mixin-toc-unpinned();
|
||||
|
|
|
@ -12,10 +12,10 @@ exports[`Pinnable header renders 1`] = `
|
|||
</label>
|
||||
<div class=\\"vector-menu-content\\">
|
||||
<div id=\\"unpinned-container\\">
|
||||
<div id=\\"pinnable-element\\"> <div class=\\"vector-pinnable-header simple-pinnable-header vector-pinnable-header-unpinned\\" data-name=\\"simple\\" data-pinnable-element-id=\\"pinnable-element\\">
|
||||
<div id=\\"pinnable-element\\"> <div class=\\"vector-pinnable-header pinnable-element-pinnable-header vector-pinnable-header-unpinned\\" data-feature-name=\\"pinned\\" data-pinnable-element-id=\\"pinnable-element\\">
|
||||
<div class=\\"vector-pinnable-header-label\\">simple pinnable element</div>
|
||||
<button class=\\"vector-pinnable-header-toggle-button vector-pinnable-header-pin-button\\" data-event-name=\\"pinnable-header.simple.pin\\">pin</button>
|
||||
<button class=\\"vector-pinnable-header-toggle-button vector-pinnable-header-unpin-button\\" data-event-name=\\"pinnable-header.simple.unpin\\">unpin</button>
|
||||
<button class=\\"vector-pinnable-header-toggle-button vector-pinnable-header-pin-button\\" data-event-name=\\"pinnable-header.pinnable-element.pin\\">pin</button>
|
||||
<button class=\\"vector-pinnable-header-toggle-button vector-pinnable-header-unpin-button\\" data-event-name=\\"pinnable-header.pinnable-element.unpin\\">unpin</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
exports[`Table of contents reloadTableOfContents re-renders toc when wikipage.tableOfContents hook is fired with empty sections 1`] = `
|
||||
"<div id=\\"vector-toc\\" class=\\"vector-toc vector-pinnable-element\\">
|
||||
<div class=\\"vector-pinnable-header vector-toc-pinnable-header vector-pinnable-header-pinned\\" data-name=\\"vector-toc\\">
|
||||
<div class=\\"vector-pinnable-header vector-toc-pinnable-header vector-pinnable-header-pinned\\" data-feature-name=\\"pinned\\" data-pinnable-element-id=\\"vector-toc\\">
|
||||
<h2 class=\\"vector-pinnable-header-label\\">Contents</h2>
|
||||
<button class=\\"vector-pinnable-header-toggle-button vector-pinnable-header-pin-button\\" data-event-name=\\"pinnable-header.vector-toc.pin\\">move to sidebar</button>
|
||||
<button class=\\"vector-pinnable-header-toggle-button vector-pinnable-header-unpin-button\\" data-event-name=\\"pinnable-header.vector-toc.unpin\\">hide</button>
|
||||
|
@ -63,13 +63,13 @@ exports[`Table of contents reloadTableOfContents re-renders toc when wikipage.ta
|
|||
|
||||
exports[`Table of contents reloadTableOfContents re-renders toc when wikipage.tableOfContents hook is fired with sections 1`] = `
|
||||
"<div id=\\"vector-toc\\" class=\\"vector-toc vector-pinnable-element\\">
|
||||
<div class=\\"vector-pinnable-header vector-toc-pinnable-header vector-pinnable-header-pinned\\" data-name=\\"vector-toc\\">
|
||||
<div class=\\"vector-pinnable-header vector-toc-pinnable-header vector-pinnable-header-pinned\\" data-feature-name=\\"pinned\\" data-pinnable-element-id=\\"vector-toc\\">
|
||||
<h2 class=\\"vector-pinnable-header-label\\">Contents</h2>
|
||||
<button class=\\"vector-pinnable-header-toggle-button vector-pinnable-header-pin-button\\" data-event-name=\\"pinnable-header.vector-toc.pin\\">move to sidebar</button>
|
||||
<button class=\\"vector-pinnable-header-toggle-button vector-pinnable-header-unpin-button\\" data-event-name=\\"pinnable-header.vector-toc.unpin\\">hide</button>
|
||||
</div>
|
||||
<ul class=\\"vector-toc-contents\\" id=\\"mw-panel-toc-list\\"><div id=\\"vector-toc\\" class=\\"vector-toc vector-pinnable-element\\">
|
||||
<div class=\\"vector-pinnable-header vector-toc-pinnable-header vector-pinnable-header-pinned\\" data-name=\\"vector-toc\\">
|
||||
<div class=\\"vector-pinnable-header vector-toc-pinnable-header vector-pinnable-header-pinned\\" data-feature-name=\\"pinned\\" data-pinnable-element-id=\\"vector-toc\\">
|
||||
<h2 class=\\"vector-pinnable-header-label\\">Contents</h2>
|
||||
<button class=\\"vector-pinnable-header-toggle-button vector-pinnable-header-pin-button\\" data-event-name=\\"pinnable-header.vector-toc.pin\\">move to sidebar</button>
|
||||
<button class=\\"vector-pinnable-header-toggle-button vector-pinnable-header-unpin-button\\" data-event-name=\\"pinnable-header.vector-toc.unpin\\">hide</button>
|
||||
|
@ -140,7 +140,7 @@ exports[`Table of contents reloadTableOfContents re-renders toc when wikipage.ta
|
|||
|
||||
exports[`Table of contents renders when \`vector-is-collapse-sections-enabled\` is false 1`] = `
|
||||
"<div id=\\"vector-toc\\" class=\\"vector-toc vector-pinnable-element\\">
|
||||
<div class=\\"vector-pinnable-header vector-toc-pinnable-header vector-pinnable-header-pinned\\" data-name=\\"vector-toc\\">
|
||||
<div class=\\"vector-pinnable-header vector-toc-pinnable-header vector-pinnable-header-pinned\\" data-feature-name=\\"pinned\\" data-pinnable-element-id=\\"vector-toc\\">
|
||||
<h2 class=\\"vector-pinnable-header-label\\">Contents</h2>
|
||||
<button class=\\"vector-pinnable-header-toggle-button vector-pinnable-header-pin-button\\" data-event-name=\\"pinnable-header.vector-toc.pin\\">move to sidebar</button>
|
||||
<button class=\\"vector-pinnable-header-toggle-button vector-pinnable-header-unpin-button\\" data-event-name=\\"pinnable-header.vector-toc.unpin\\">hide</button>
|
||||
|
@ -201,7 +201,7 @@ exports[`Table of contents renders when \`vector-is-collapse-sections-enabled\`
|
|||
|
||||
exports[`Table of contents renders when \`vector-is-collapse-sections-enabled\` is true 1`] = `
|
||||
"<div id=\\"vector-toc\\" class=\\"vector-toc vector-pinnable-element\\">
|
||||
<div class=\\"vector-pinnable-header vector-toc-pinnable-header vector-pinnable-header-pinned\\" data-name=\\"vector-toc\\">
|
||||
<div class=\\"vector-pinnable-header vector-toc-pinnable-header vector-pinnable-header-pinned\\" data-feature-name=\\"pinned\\" data-pinnable-element-id=\\"vector-toc\\">
|
||||
<h2 class=\\"vector-pinnable-header-label\\">Contents</h2>
|
||||
<button class=\\"vector-pinnable-header-toggle-button vector-pinnable-header-pin-button\\" data-event-name=\\"pinnable-header.vector-toc.pin\\">move to sidebar</button>
|
||||
<button class=\\"vector-pinnable-header-toggle-button vector-pinnable-header-unpin-button\\" data-event-name=\\"pinnable-header.vector-toc.unpin\\">hide</button>
|
||||
|
|
|
@ -24,9 +24,18 @@ Object.defineProperty( window, 'matchMedia', {
|
|||
} ) )
|
||||
} );
|
||||
|
||||
// Mock functionality of features.js
|
||||
let pinnedStatus = false;
|
||||
features.toggle = jest.fn( () => {
|
||||
pinnedStatus = !pinnedStatus;
|
||||
} );
|
||||
features.isEnabled = jest.fn( () => {
|
||||
return pinnedStatus;
|
||||
} );
|
||||
|
||||
const simpleData = {
|
||||
'is-pinned': false,
|
||||
'data-name': 'simple',
|
||||
'data-feature-name': 'pinned',
|
||||
'data-pinnable-element-id': 'pinnable-element',
|
||||
label: 'simple pinnable element',
|
||||
'label-tag-name': 'div',
|
||||
|
@ -34,20 +43,14 @@ const simpleData = {
|
|||
'unpin-label': 'unpin'
|
||||
};
|
||||
|
||||
const movableData = {
|
||||
'is-pinned': false,
|
||||
'data-name': 'movable',
|
||||
'data-pinnable-element-id': 'pinnable-element',
|
||||
const movableData = { ...simpleData, ...{
|
||||
'data-pinned-container-id': 'pinned-container',
|
||||
'data-unpinned-container-id': 'unpinned-container',
|
||||
label: 'moveable pinnable element',
|
||||
'label-tag-name': 'div',
|
||||
'pin-label': 'pin',
|
||||
'unpin-label': 'unpin'
|
||||
};
|
||||
'data-unpinned-container-id': 'unpinned-container'
|
||||
} };
|
||||
|
||||
// @ts-ignore
|
||||
const initializeHTML = ( headerData ) => {
|
||||
pinnedStatus = headerData[ 'is-pinned' ];
|
||||
const pinnableHeaderHTML = mustache.render( pinnableHeaderTemplate, headerData );
|
||||
const pinnableElementHTML = `<div id="pinnable-element"> ${ pinnableHeaderHTML } </div>`;
|
||||
document.body.innerHTML = `
|
||||
|
@ -66,20 +69,6 @@ const initializeHTML = ( headerData ) => {
|
|||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
if ( headerData[ 'data-feature-name' ] ) {
|
||||
// Return early if the persistent option is enabled as features.js will
|
||||
// manage the body classes instead of pinnableElement.
|
||||
return;
|
||||
}
|
||||
|
||||
if ( headerData[ 'is-pinned' ] ) {
|
||||
document.body.classList.add( `${headerData[ 'data-name' ]}-pinned` );
|
||||
document.body.classList.remove( `${headerData[ 'data-name' ]}-unpinned` );
|
||||
} else {
|
||||
document.body.classList.remove( `${headerData[ 'data-name' ]}-pinned` );
|
||||
document.body.classList.add( `${headerData[ 'data-name' ]}-unpinned` );
|
||||
}
|
||||
};
|
||||
|
||||
describe( 'Pinnable header', () => {
|
||||
|
@ -88,27 +77,21 @@ describe( 'Pinnable header', () => {
|
|||
expect( document.body.innerHTML ).toMatchSnapshot();
|
||||
} );
|
||||
|
||||
test( 'updates pinnable classes when toggle is pressed', () => {
|
||||
test( 'updates pinnable header classes when toggle is pressed', () => {
|
||||
initializeHTML( simpleData );
|
||||
pinnableElement.initPinnableElement();
|
||||
const pinButton = /** @type {HTMLElement} */ ( document.querySelector( '.vector-pinnable-header-pin-button' ) );
|
||||
const unpinButton = /** @type {HTMLElement} */ ( document.querySelector( '.vector-pinnable-header-unpin-button' ) );
|
||||
const header = /** @type {HTMLElement} */ ( document.querySelector( `.${simpleData[ 'data-name' ]}-pinnable-header` ) );
|
||||
const header = /** @type {HTMLElement} */ ( document.querySelector( `.${simpleData[ 'data-pinnable-element-id' ]}-pinnable-header` ) );
|
||||
|
||||
expect( header.classList.contains( pinnableElement.PINNED_HEADER_CLASS ) ).toBe( false );
|
||||
expect( document.body.classList.contains( `${simpleData[ 'data-name' ]}-pinned` ) ).toBe( false );
|
||||
expect( header.classList.contains( pinnableElement.UNPINNED_HEADER_CLASS ) ).toBe( true );
|
||||
expect( document.body.classList.contains( `${simpleData[ 'data-name' ]}-unpinned` ) ).toBe( true );
|
||||
pinButton.click();
|
||||
expect( header.classList.contains( pinnableElement.PINNED_HEADER_CLASS ) ).toBe( true );
|
||||
expect( document.body.classList.contains( `${simpleData[ 'data-name' ]}-pinned` ) ).toBe( true );
|
||||
expect( header.classList.contains( pinnableElement.UNPINNED_HEADER_CLASS ) ).toBe( false );
|
||||
expect( document.body.classList.contains( `${simpleData[ 'data-name' ]}-unpinned` ) ).toBe( false );
|
||||
unpinButton.click();
|
||||
expect( header.classList.contains( pinnableElement.PINNED_HEADER_CLASS ) ).toBe( false );
|
||||
expect( document.body.classList.contains( `${simpleData[ 'data-name' ]}-pinned` ) ).toBe( false );
|
||||
expect( header.classList.contains( pinnableElement.UNPINNED_HEADER_CLASS ) ).toBe( true );
|
||||
expect( document.body.classList.contains( `${simpleData[ 'data-name' ]}-unpinned` ) ).toBe( true );
|
||||
} );
|
||||
|
||||
test( 'doesnt move pinnable element when data attributes arent defined', () => {
|
||||
|
@ -143,43 +126,33 @@ describe( 'Pinnable header', () => {
|
|||
/* eslint-enable no-restricted-properties */
|
||||
} );
|
||||
|
||||
test( 'calls features.js when data-feature-name is set', () => {
|
||||
initializeHTML( {
|
||||
...simpleData,
|
||||
'data-name': 'vector-page-tools',
|
||||
'data-feature-name': 'page-tools-pinned'
|
||||
} );
|
||||
pinnableElement.initPinnableElement();
|
||||
const pinButton = /** @type {HTMLElement} */ ( document.querySelector( '.vector-pinnable-header-pin-button' ) );
|
||||
const unpinButton = /** @type {HTMLElement} */ ( document.querySelector( '.vector-pinnable-header-unpin-button' ) );
|
||||
|
||||
pinButton.click();
|
||||
|
||||
expect( features.toggle ).toHaveBeenCalledTimes( 1 );
|
||||
expect( features.toggle ).toHaveBeenCalledWith( 'page-tools-pinned' );
|
||||
|
||||
// @ts-ignore
|
||||
features.toggle.mockClear();
|
||||
unpinButton.click();
|
||||
|
||||
expect( features.toggle ).toHaveBeenCalledTimes( 1 );
|
||||
expect( features.toggle ).toHaveBeenCalledWith( 'page-tools-pinned' );
|
||||
} );
|
||||
|
||||
test( 'isPinned() returns whether the element is pinned or not', () => {
|
||||
test( 'calls features.toggle() when toggle is pressed', () => {
|
||||
initializeHTML( simpleData );
|
||||
pinnableElement.initPinnableElement();
|
||||
const pinButton = /** @type {HTMLElement} */ ( document.querySelector( '.vector-pinnable-header-pin-button' ) );
|
||||
const unpinButton = /** @type {HTMLElement} */ ( document.querySelector( '.vector-pinnable-header-unpin-button' ) );
|
||||
const header = /** @type {HTMLElement} */ ( document.querySelector( `.${simpleData[ 'data-name' ]}-pinnable-header` ) );
|
||||
|
||||
pinButton.click();
|
||||
expect( features.toggle ).toHaveBeenCalledTimes( 1 );
|
||||
expect( features.toggle ).toHaveBeenCalledWith( simpleData[ 'data-feature-name' ] );
|
||||
|
||||
expect( pinnableElement.isPinned( header ) ).toBe( true );
|
||||
|
||||
// @ts-ignore
|
||||
features.toggle.mockClear();
|
||||
unpinButton.click();
|
||||
expect( features.toggle ).toHaveBeenCalledTimes( 1 );
|
||||
expect( features.toggle ).toHaveBeenCalledWith( simpleData[ 'data-feature-name' ] );
|
||||
} );
|
||||
|
||||
expect( pinnableElement.isPinned( header ) ).toBe( false );
|
||||
test( 'isPinned() calls features.isEnabled()', () => {
|
||||
initializeHTML( simpleData );
|
||||
pinnableElement.initPinnableElement();
|
||||
const header = /** @type {HTMLElement} */ ( document.querySelector( `.${simpleData[ 'data-pinnable-element-id' ]}-pinnable-header` ) );
|
||||
|
||||
// @ts-ignore
|
||||
features.isEnabled.mockClear();
|
||||
pinnableElement.isPinned( header );
|
||||
expect( features.isEnabled ).toHaveBeenCalledTimes( 1 );
|
||||
expect( features.isEnabled ).toHaveBeenCalledWith( simpleData[ 'data-feature-name' ] );
|
||||
} );
|
||||
|
||||
test( 'setFocusAfterToggle() sets focus on appropriate element after pinnableElement is toggled', () => {
|
||||
|
|
|
@ -77,11 +77,12 @@ function render( templateProps = {} ) {
|
|||
id: 'vector-toc',
|
||||
'data-pinnable-header': {
|
||||
'is-pinned': true,
|
||||
'data-feature-name': 'pinned',
|
||||
'data-pinnable-element-id': 'vector-toc',
|
||||
label: 'Contents',
|
||||
'label-tag-name': 'h2',
|
||||
'pin-label': 'move to sidebar',
|
||||
'unpin-label': 'hide',
|
||||
'data-name': 'vector-toc'
|
||||
'unpin-label': 'hide'
|
||||
}
|
||||
}, templateProps );
|
||||
|
||||
|
|
|
@ -87,7 +87,6 @@ class VectorComponentPageToolsTest extends \MediaWikiUnitTestCase {
|
|||
'label-tag-name' => 'div',
|
||||
'pin-label' => 'vector-pin-element-label',
|
||||
'unpin-label' => 'vector-unpin-element-label',
|
||||
'data-name' => 'vector-page-tools',
|
||||
'data-feature-name' => 'page-tools-pinned',
|
||||
'data-pinnable-element-id' => 'vector-page-tools',
|
||||
'data-unpinned-container-id' => 'vector-page-tools-unpinned-container',
|
||||
|
|
|
@ -113,7 +113,7 @@ class VectorComponentTableOfContentsTest extends \MediaWikiUnitTestCase {
|
|||
'id' => 'vector-toc',
|
||||
'data-pinnable-header' => [
|
||||
'is-pinned' => true,
|
||||
'data-name' => 'vector-toc',
|
||||
'data-pinnable-element-id' => 'vector-toc',
|
||||
'data-feature-name' => 'toc-pinned',
|
||||
'label' => 'vector-toc-label',
|
||||
'unpin-label' => 'vector-unpin-element-label',
|
||||
|
|
Loading…
Reference in a new issue