mirror of
https://gerrit.wikimedia.org/r/mediawiki/skins/Vector.git
synced 2024-09-24 10:49:25 +00:00
Merge "Update TOC to use PinnableHeader"
This commit is contained in:
commit
a0f7e2db32
|
@ -5,7 +5,7 @@
|
|||
},
|
||||
{
|
||||
"resourceModule": "skins.vector.styles",
|
||||
"maxSize": "11.3 kB"
|
||||
"maxSize": "11.1 kB"
|
||||
},
|
||||
{
|
||||
"resourceModule": "skins.vector.legacy.js",
|
||||
|
|
59
includes/Components/VectorComponentPinnableHeader.php
Normal file
59
includes/Components/VectorComponentPinnableHeader.php
Normal file
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
namespace MediaWiki\Skins\Vector\Components;
|
||||
|
||||
use MessageLocalizer;
|
||||
|
||||
/**
|
||||
* VectorComponentPinnableHeader component
|
||||
*/
|
||||
class VectorComponentPinnableHeader implements VectorComponent {
|
||||
/** @var MessageLocalizer */
|
||||
private $localizer;
|
||||
/** @var bool */
|
||||
private $pinned;
|
||||
/** @var string */
|
||||
private $name;
|
||||
/** @var bool */
|
||||
private $moveElement;
|
||||
|
||||
/**
|
||||
* @param MessageLocalizer $localizer
|
||||
* @param bool $pinned
|
||||
* @param string $name
|
||||
* @param bool|null $moveElement
|
||||
*/
|
||||
public function __construct(
|
||||
MessageLocalizer $localizer,
|
||||
bool $pinned,
|
||||
string $name,
|
||||
?bool $moveElement = true
|
||||
) {
|
||||
$this->localizer = $localizer;
|
||||
$this->pinned = $pinned;
|
||||
$this->name = $name;
|
||||
$this->moveElement = $moveElement;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getTemplateData(): array {
|
||||
$messageLocalizer = $this->localizer;
|
||||
$data = [
|
||||
'is-pinned' => $this->pinned,
|
||||
'label' => $messageLocalizer->msg( $this->name . '-label' ),
|
||||
'pin-label' => $messageLocalizer->msg( 'vector-pin-element-label' ),
|
||||
'unpin-label' => $messageLocalizer->msg( 'vector-unpin-element-label' ),
|
||||
'data-name' => $this->name
|
||||
];
|
||||
if ( $this->moveElement ) {
|
||||
// Assumes consistent naming standard for pinnable elements and their containers
|
||||
$data = array_merge( $data, [
|
||||
'data-pinnable-element-id' => $this->name . '-content',
|
||||
'data-unpinned-container-id' => $this->name . '-content-container',
|
||||
'data-pinned-container-id' => $this->name . '-pinned-container',
|
||||
] );
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
}
|
|
@ -365,11 +365,11 @@ abstract class SkinVector extends SkinMustache {
|
|||
$btns[] = $this->getAddSectionButtonData();
|
||||
|
||||
$tocPortletData = Hooks::updateDropdownMenuData( [
|
||||
'id' => 'p-sticky-header-toc',
|
||||
'id' => 'vector-sticky-header-toc',
|
||||
'class' => 'mw-portlet mw-portlet-sticky-header-toc vector-sticky-header-toc',
|
||||
'html-items' => '',
|
||||
'html-vector-menu-checkbox-attributes' => 'tabindex="-1"',
|
||||
'html-vector-menu-heading-attributes' => 'tabindex="-1"',
|
||||
'is-pinned' => true,
|
||||
'button' => true,
|
||||
'text-hidden' => true,
|
||||
'icon' => 'listBullet'
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace MediaWiki\Skins\Vector;
|
|||
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use MediaWiki\Skins\Vector\Components\VectorComponentMainMenu;
|
||||
use MediaWiki\Skins\Vector\Components\VectorComponentPinnableHeader;
|
||||
use MediaWiki\Skins\Vector\Components\VectorComponentSearchBox;
|
||||
|
||||
/**
|
||||
|
@ -126,6 +127,15 @@ class SkinVector22 extends SkinVector {
|
|||
}
|
||||
}
|
||||
|
||||
// ToC is pinned by default, hardcoded for now
|
||||
$isTocPinned = true;
|
||||
$pinnableHeader = new VectorComponentPinnableHeader(
|
||||
$this->getContext(),
|
||||
$isTocPinned,
|
||||
'vector-toc',
|
||||
false
|
||||
);
|
||||
|
||||
return array_merge( $tocData, [
|
||||
'is-vector-toc-beginning-enabled' => $this->getConfig()->get(
|
||||
'VectorTableOfContentsBeginning'
|
||||
|
@ -133,7 +143,8 @@ class SkinVector22 extends SkinVector {
|
|||
'vector-is-collapse-sections-enabled' =>
|
||||
$tocData[ 'number-section-count'] >= $this->getConfig()->get(
|
||||
'VectorTableOfContentsCollapseAtCount'
|
||||
)
|
||||
),
|
||||
'data-pinnable-header' => $pinnableHeader->getTemplateData(),
|
||||
] );
|
||||
}
|
||||
|
||||
|
@ -147,8 +158,8 @@ class SkinVector22 extends SkinVector {
|
|||
return [
|
||||
'is-pinned' => $isPinned,
|
||||
'label' => $this->msg( 'vector-page-tools-label' ),
|
||||
'unpin-label' => $this->msg( 'vector-toc-toggle-position-title' ),
|
||||
'pin-label' => $this->msg( 'vector-toc-toggle-position-sidebar' ),
|
||||
'unpin-label' => $this->msg( 'vector-unpin-element-label' ),
|
||||
'pin-label' => $this->msg( 'vector-pin-element-label' ),
|
||||
'data-name' => 'vector-page-tools',
|
||||
'data-pinnable-element-id' => 'vector-page-tools-content',
|
||||
'data-unpinned-container-id' => 'vector-page-tools-content-container',
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
<div
|
||||
{{#id}}id="{{.}}"{{/id}}
|
||||
class="vector-pinnable-header vector-pinnable-header-{{#is-pinned}}pinned{{/is-pinned}}{{^is-pinned}}unpinned{{/is-pinned}}{{#class}} {{.}}{{/class}}"
|
||||
{{#data-name}}data-name={{.}}{{/data-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}}
|
||||
class="vector-pinnable-header {{data-name}}-pinnable-header vector-pinnable-header-{{#is-pinned}}pinned{{/is-pinned}}{{^is-pinned}}unpinned{{/is-pinned}}{{#class}} {{.}}{{/class}}"
|
||||
data-name="{{data-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}}
|
||||
>
|
||||
<div class="vector-pinnable-header-label">{{label}}</div>
|
||||
<button class="vector-pinnable-header-toggle-button vector-pinnable-header-pin-button">{{pin-label}}</button>
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
<div class="vector-sticky-header-toc-container mw-ui-icon-flush-left">
|
||||
{{! TOC is cloned into this menu from the sidebar in stickyHeader.js. }}
|
||||
{{#data-sticky-header-toc}}
|
||||
{{>Dropdown}}
|
||||
{{>PinnableDropdown}}
|
||||
{{/data-sticky-header-toc}}
|
||||
</div>
|
||||
<div class="vector-sticky-header-context-bar-primary" {{{html-user-language-attributes}}}>{{{html-title}}}</div>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<nav id="mw-panel-toc" class="sidebar-toc" role="navigation" aria-label="{{ msg-vector-toc-label }}" data-event-name="ui.sidebar-toc">
|
||||
{{^is-page-tools-enabled}}
|
||||
<div id="sidebar-toc-label" class="sidebar-toc-header">
|
||||
<p class="sidebar-toc-title">
|
||||
{{ msg-vector-toc-label }}
|
||||
|
@ -6,6 +7,10 @@
|
|||
<button class="vector-toc-collapse-button">{{msg-vector-unpin-element-label}}</button>
|
||||
</p>
|
||||
</div>
|
||||
{{/is-page-tools-enabled}}
|
||||
{{#is-page-tools-enabled}}
|
||||
{{#data-pinnable-header}}{{>PinnableHeader}}{{/data-pinnable-header}}
|
||||
{{/is-page-tools-enabled}}
|
||||
<ul class="sidebar-toc-contents" id="mw-panel-toc-list">
|
||||
{{#is-vector-toc-beginning-enabled}}
|
||||
<li id="toc-mw-content-text"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<div class="mw-table-of-contents-container">
|
||||
{{! T313060 Additional container div needed to prevent the sticky element from being siblings with the footer }}
|
||||
{{#data-toc}}
|
||||
<div class="vector-sticky-toc-container">
|
||||
<div id="vector-toc-pinned-container" class="vector-sticky-toc-container">
|
||||
{{>TableOfContents}}
|
||||
</div>
|
||||
{{/data-toc}}
|
||||
|
|
|
@ -18,7 +18,6 @@ const
|
|||
TOC_SECTION_ID_PREFIX = 'toc-',
|
||||
TOC_LEGACY_PLACEHOLDER_SELECTOR = 'mw\\3Atocplace,meta[property="mw:PageProp/toc"]',
|
||||
TOC_SCROLL_HOOK = 'table_of_contents',
|
||||
TOC_COLLAPSED_CLASS = 'vector-toc-collapsed',
|
||||
PAGE_TITLE_SCROLL_HOOK = 'page_title',
|
||||
PAGE_TITLE_INTERSECTION_CLASS = 'vector-below-page-title',
|
||||
TOC_EXPERIMENT_NAME = 'skin-vector-toc-experiment';
|
||||
|
@ -118,13 +117,21 @@ function initStickyHeaderABTests( abConfig, isStickyHeaderFeatureAllowed, getEna
|
|||
* @return {void}
|
||||
*/
|
||||
const updateTocLocation = () => {
|
||||
const isTocCollapsed = document.body.classList.contains( TOC_COLLAPSED_CLASS );
|
||||
const isPageToolsEnabled = document.body.classList.contains( 'vector-feature-page-tools-enabled' );
|
||||
const TOC_PINNED_CLASS = isPageToolsEnabled ? 'vector-toc-pinned' : 'vector-toc-not-collapsed';
|
||||
const isPinned = document.body.classList.contains( TOC_PINNED_CLASS );
|
||||
const isStickyHeaderVisible = document.body.classList.contains( STICKY_HEADER_VISIBLE_CLASS );
|
||||
const isBelowDesktop = belowDesktopMedia.matches;
|
||||
if ( isTocCollapsed && isStickyHeaderVisible && !isBelowDesktop ) {
|
||||
stickyHeader.moveToc( 'stickyheader' );
|
||||
const moveTocToPinned = ( isPinned || !isStickyHeaderVisible || isBelowDesktop );
|
||||
|
||||
if ( isPageToolsEnabled ) {
|
||||
pinnableHeader.movePinnableElement( TOC_ID, 'vector-toc-pinned-container', 'vector-sticky-header-toc-content-container', moveTocToPinned );
|
||||
} else {
|
||||
stickyHeader.moveToc( 'sidebar' );
|
||||
if ( moveTocToPinned ) {
|
||||
stickyHeader.moveToc( 'sidebar' );
|
||||
} else {
|
||||
stickyHeader.moveToc( 'stickyheader' );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -300,7 +307,7 @@ const main = () => {
|
|||
onToggleClick: ( id ) => {
|
||||
tableOfContents.toggleExpandSection( id );
|
||||
},
|
||||
onToggleCollapse: updateTocLocation
|
||||
onTogglePinned: updateTocLocation
|
||||
} );
|
||||
const headingSelector = [
|
||||
'h1', 'h2', 'h3', 'h4', 'h5', 'h6'
|
||||
|
|
|
@ -49,6 +49,9 @@ function hide() {
|
|||
}
|
||||
|
||||
/**
|
||||
* FIXME: Delete this function after VectorPageTools is enabled everywhere
|
||||
* which replaces this function with the PinnableHeader JS
|
||||
*
|
||||
* Moves the TOC element to a new parent container.
|
||||
*
|
||||
* @param {string} position The position to move the TOC into: sidebar or stickyheader
|
||||
|
|
|
@ -7,8 +7,9 @@ const TOP_SECTION_CLASS = 'sidebar-toc-level-1';
|
|||
const ACTIVE_TOP_SECTION_CLASS = 'sidebar-toc-level-1-active';
|
||||
const LINK_CLASS = 'sidebar-toc-link';
|
||||
const TOGGLE_CLASS = 'sidebar-toc-toggle';
|
||||
const TOC_COLLAPSED_CLASS = 'vector-toc-collapsed';
|
||||
const TOC_NOT_COLLAPSED_CLASS = 'vector-toc-not-collapsed';
|
||||
const isPageToolsEnabled = document.body.classList.contains( 'vector-feature-page-tools-enabled' );
|
||||
const TOC_PINNED_CLASS = isPageToolsEnabled ? 'vector-toc-pinned' : 'vector-toc-not-collapsed';
|
||||
const TOC_UNPINNED_CLASS = isPageToolsEnabled ? 'vector-toc-unpinned' : 'vector-toc-collapsed';
|
||||
const TOC_ID = 'mw-panel-toc';
|
||||
/**
|
||||
* TableOfContents Mustache templates
|
||||
|
@ -31,7 +32,7 @@ const tableOfContentsConfig = require( /** @type {string} */ ( './tableOfContent
|
|||
*/
|
||||
|
||||
/**
|
||||
* @callback onToggleCollapse
|
||||
* @callback onTogglePinned
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -39,7 +40,7 @@ const tableOfContentsConfig = require( /** @type {string} */ ( './tableOfContent
|
|||
* @property {HTMLElement} container The container element for the table of contents.
|
||||
* @property {onHeadingClick} onHeadingClick Called when an arrow is clicked.
|
||||
* @property {onToggleClick} onToggleClick Called when a list item is clicked.
|
||||
* @property {onToggleCollapse} onToggleCollapse Called when collapse toggle buttons are clicked.
|
||||
* @property {onTogglePinned} onTogglePinned Called when pinned toggle buttons are clicked.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -327,15 +328,18 @@ module.exports = function tableOfContents( props ) {
|
|||
/**
|
||||
* Bind event listener for clicking on show/hide Table of Contents links.
|
||||
*/
|
||||
function bindCollapseToggleListeners() {
|
||||
function bindPinnedToggleListeners() {
|
||||
// Initialize toc collapsed status
|
||||
const showHideTocElement = document.querySelectorAll( '#sidebar-toc-label button' );
|
||||
const toggleButtonQuery = isPageToolsEnabled ? '.vector-toc-pinnable-header button' : '#sidebar-toc-label button';
|
||||
const showHideTocElement = document.querySelectorAll( toggleButtonQuery );
|
||||
showHideTocElement.forEach( function ( btn ) {
|
||||
btn.addEventListener( 'click', () => {
|
||||
document.body.classList.toggle( TOC_COLLAPSED_CLASS );
|
||||
document.body.classList.toggle( TOC_NOT_COLLAPSED_CLASS );
|
||||
if ( !isPageToolsEnabled ) {
|
||||
document.body.classList.toggle( TOC_PINNED_CLASS );
|
||||
document.body.classList.toggle( TOC_UNPINNED_CLASS );
|
||||
}
|
||||
|
||||
props.onToggleCollapse();
|
||||
props.onTogglePinned();
|
||||
} );
|
||||
} );
|
||||
}
|
||||
|
@ -384,7 +388,7 @@ module.exports = function tableOfContents( props ) {
|
|||
|
||||
// Bind event listeners.
|
||||
bindSubsectionToggleListeners();
|
||||
bindCollapseToggleListeners();
|
||||
bindPinnedToggleListeners();
|
||||
|
||||
mw.hook( 'wikipage.tableOfContents' ).add( reloadTableOfContents );
|
||||
}
|
||||
|
@ -416,7 +420,7 @@ module.exports = function tableOfContents( props ) {
|
|||
// Reexpand sections that were expanded before the table of contents was reloaded.
|
||||
reExpandSections();
|
||||
// Initialize Collapse toggle buttons
|
||||
bindCollapseToggleListeners();
|
||||
bindPinnedToggleListeners();
|
||||
} );
|
||||
}
|
||||
|
||||
|
|
|
@ -96,7 +96,8 @@
|
|||
}
|
||||
|
||||
// Only show TOC in sticky header when collapsed class is present
|
||||
.vector-toc-collapsed & {
|
||||
.vector-feature-page-tools-enabled.vector-toc-unpinned &,
|
||||
.vector-feature-page-tools-disabled.vector-toc-collapsed & {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
@ -190,7 +191,8 @@
|
|||
// @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.
|
||||
.vector-toc-not-collapsed .vector-sticky-toc-container,
|
||||
.vector-feature-page-tools-enabled.vector-toc-pinned .vector-sticky-toc-container,
|
||||
.vector-feature-page-tools-disabled.vector-toc-not-collapsed .vector-sticky-toc-container,
|
||||
.mw-sticky-header-element,
|
||||
.charts-stickyhead th {
|
||||
/* stylelint-disable-next-line declaration-no-important */
|
||||
|
|
|
@ -21,13 +21,15 @@
|
|||
top: 0;
|
||||
|
||||
@media ( min-width: @min-width-desktop ) {
|
||||
.vector-toc-not-collapsed & {
|
||||
.vector-feature-page-tools-enabled.vector-toc-pinned &,
|
||||
.vector-feature-page-tools-disabled.vector-toc-not-collapsed & {
|
||||
// Default spacing separating the sidebar TOC from the main menu or viewport.
|
||||
// Need to use padding in order for the spacing to apply when sticky
|
||||
padding-top: 1.5em;
|
||||
}
|
||||
|
||||
.vector-toc-not-collapsed @{selector-main-menu-closed} ~ .mw-table-of-contents-container & {
|
||||
.vector-feature-page-tools-enabled.vector-toc-pinned @{selector-main-menu-closed} ~ .mw-table-of-contents-container &,
|
||||
.vector-feature-page-tools-disabled.vector-toc-not-collapsed @{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;
|
||||
}
|
||||
|
@ -49,8 +51,13 @@
|
|||
overflow-x: hidden;
|
||||
background-color: @background-color-page-container;
|
||||
|
||||
.sidebar-toc-header {
|
||||
padding-bottom: 12px;
|
||||
// FIXME: Remove .sidebar-toc-header selector when the VectorPageTools feature flag is enabled everywhere
|
||||
.sidebar-toc-header,
|
||||
.vector-toc-pinnable-header {
|
||||
// Override default pinnable header styles
|
||||
padding: 0 0 12px 0;
|
||||
border: 0;
|
||||
line-height: initial;
|
||||
}
|
||||
|
||||
.sidebar-toc-title {
|
||||
|
@ -58,7 +65,6 @@
|
|||
font-size: @font-size-base;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.sidebar-toc-numb {
|
||||
|
@ -138,7 +144,8 @@
|
|||
// T302076: Add fade scrollable indicator when TOC is in sidebar
|
||||
// Avoid showing indicator when the TOC is floating, or collapsed in the page title/sticky header
|
||||
@media ( min-width: @min-width-desktop ) {
|
||||
.vector-toc-not-collapsed .sidebar-toc:after {
|
||||
.vector-feature-page-tools-enabled.vector-toc-pinned .sidebar-toc:after,
|
||||
.vector-feature-page-tools-disabled.vector-toc-not-collapsed .sidebar-toc:after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
|
|
|
@ -44,8 +44,8 @@
|
|||
}
|
||||
|
||||
// Styles for the "move to sidebar/hide" buttons, hidden by default.
|
||||
.vector-toc-collapse-button,
|
||||
.vector-toc-uncollapse-button {
|
||||
.vector-feature-page-tools-disabled .vector-toc-collapse-button,
|
||||
.vector-feature-page-tools-disabled .vector-toc-uncollapse-button {
|
||||
display: none;
|
||||
border: 0;
|
||||
padding: 0;
|
||||
|
@ -68,6 +68,13 @@
|
|||
}
|
||||
}
|
||||
|
||||
// Hide pin ToC toggles on smaller resolutions
|
||||
@media ( max-width: @max-width-tablet ) {
|
||||
.vector-feature-page-tools-enabled .sidebar-toc .vector-pinnable-header-toggle-button {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
// Shared collapsed TOC styles, applies across all collapsed cases (header, floating, sticky header)
|
||||
.mixin-toc-collapsed() {
|
||||
// T316056 Remove TOC menu fixed width and apply min/max-width
|
||||
|
@ -140,7 +147,8 @@
|
|||
@media ( min-width: @min-width-desktop ) {
|
||||
@supports ( display: grid ) {
|
||||
.client-js {
|
||||
.vector-toc-collapsed:not( .vector-sticky-header-visible ) {
|
||||
.vector-feature-page-tools-enabled.vector-toc-unpinned:not( .vector-sticky-header-visible ),
|
||||
.vector-feature-page-tools-disabled.vector-toc-collapsed:not( .vector-sticky-header-visible ) {
|
||||
//
|
||||
// Collapsed to header
|
||||
//
|
||||
|
@ -171,8 +179,8 @@
|
|||
}
|
||||
|
||||
// Show the "move to sidebar/hide" buttons
|
||||
.vector-toc-collapsed .vector-toc-uncollapse-button,
|
||||
.vector-toc-not-collapsed .vector-toc-collapse-button {
|
||||
.vector-feature-page-tools-disabled.vector-toc-collapsed .vector-toc-uncollapse-button,
|
||||
.vector-feature-page-tools-disabled.vector-toc-not-collapsed .vector-toc-collapse-button {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
@ -182,7 +190,8 @@
|
|||
//
|
||||
// Collapsed to sticky header
|
||||
//
|
||||
.vector-toc-collapsed .vector-sticky-header-toc-container .sidebar-toc {
|
||||
.vector-feature-page-tools-enabled.vector-toc-unpinned .vector-sticky-header-toc-container .sidebar-toc,
|
||||
.vector-feature-page-tools-disabled.vector-toc-collapsed .vector-sticky-header-toc-container .sidebar-toc {
|
||||
.mixin-toc-collapsed();
|
||||
// T316056 Use max-content because collapsed TOC is absolutely positioned, width is relative to the collapsed TOC button
|
||||
// max-content doesn't account for padding even when we use box-sizing, so use content-box instead
|
||||
|
|
|
@ -96,7 +96,8 @@
|
|||
}
|
||||
}
|
||||
|
||||
.vector-toc-collapsed @{selector-main-menu-closed} {
|
||||
.vector-feature-page-tools-enabled.vector-toc-unpinned @{selector-main-menu-closed},
|
||||
.vector-feature-page-tools-disabled.vector-toc-collapsed @{selector-main-menu-closed} {
|
||||
& ~ .mw-content-container,
|
||||
& ~ .mw-table-of-contents-container {
|
||||
.mixin-horizontally-centered();
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
"skin-vector",
|
||||
"skin-vector-search-vue",
|
||||
"vector-toc-not-collapsed",
|
||||
"vector-toc-pinned",
|
||||
"vector-page-tools-unpinned"
|
||||
],
|
||||
"menus": [
|
||||
|
|
|
@ -6,7 +6,7 @@ exports[`Pinnable header renders 1`] = `
|
|||
|
||||
</div>
|
||||
<div id=\\"unpinned-container\\">
|
||||
<div id=\\"pinnable-element\\"> <div id=\\"simple\\" class=\\"vector-pinnable-header vector-pinnable-header-unpinned\\" data-name=\\"simple\\" data-pinnable-element-id=\\"pinnable-element\\">
|
||||
<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 class=\\"vector-pinnable-header-label\\">simple pinnable element</div>
|
||||
<button class=\\"vector-pinnable-header-toggle-button vector-pinnable-header-pin-button\\">pin</button>
|
||||
<button class=\\"vector-pinnable-header-toggle-button vector-pinnable-header-unpin-button\\">unpin</button>
|
||||
|
|
|
@ -12,16 +12,15 @@ exports[`Sticky header renders 1`] = `
|
|||
</div>
|
||||
<div> </div> <div class=\\"vector-sticky-header-context-bar\\">
|
||||
<div class=\\"vector-sticky-header-toc-container mw-ui-icon-flush-left\\">
|
||||
<div id=\\"p-sticky-header-toc\\" class=\\"vector-menu vector-menu-dropdown mw-portlet mw-portlet-sticky-header-toc vector-sticky-header-toc\\">
|
||||
<input type=\\"checkbox\\" id=\\"p-sticky-header-toc-checkbox\\" role=\\"button\\" aria-haspopup=\\"true\\" data-event-name=\\"ui.dropdown-p-sticky-header-toc\\" class=\\"vector-menu-checkbox\\" tabindex=\\"-1\\">
|
||||
<label id=\\"p-sticky-header-toc-label\\" for=\\"p-sticky-header-toc-checkbox\\" class=\\"vector-menu-heading mw-ui-button mw-ui-quiet mw-ui-icon mw-ui-icon-element mw-ui-icon-wikimedia-listBullet\\" tabindex=\\"-1\\">
|
||||
<div id=\\"vector-sticky-header-toc\\" class=\\"vector-menu vector-menu-dropdown mw-portlet mw-portlet-sticky-header-toc vector-sticky-header-toc\\">
|
||||
<input type=\\"checkbox\\" id=\\"vector-sticky-header-toc-checkbox\\" role=\\"button\\" aria-haspopup=\\"true\\" data-event-name=\\"ui.dropdown-vector-sticky-header-toc\\" class=\\"vector-menu-checkbox\\" tabindex=\\"-1\\">
|
||||
<label id=\\"vector-sticky-header-toc-label\\" for=\\"vector-sticky-header-toc-checkbox\\" class=\\"vector-menu-heading mw-ui-button mw-ui-quiet mw-ui-icon mw-ui-icon-element mw-ui-icon-wikimedia-listBullet\\" tabindex=\\"-1\\">
|
||||
<span class=\\"vector-menu-heading-label\\"></span>
|
||||
</label>
|
||||
<div id=\\"p-sticky-header-toc-content-container\\" class=\\"vector-menu-content\\">
|
||||
<div id=\\"vector-sticky-header-toc-content-container\\" class=\\"vector-menu-content\\">
|
||||
|
||||
|
||||
<ul class=\\"vector-menu-content-list\\"></ul>
|
||||
|
||||
<div id=\\"vector-sticky-header-toc-content\\" class=\\"vector-dropdown-content\\">
|
||||
</div>
|
||||
</div>
|
||||
</div> </div>
|
||||
<div class=\\"vector-sticky-header-context-bar-primary\\"></div>
|
||||
|
|
|
@ -5,7 +5,6 @@ const pinnableHeader = require( '../../resources/skins.vector.es6/pinnableHeader
|
|||
|
||||
const simpleData = {
|
||||
'is-pinned': false,
|
||||
id: 'simple',
|
||||
'data-name': 'simple',
|
||||
'data-pinnable-element-id': 'pinnable-element',
|
||||
label: 'simple pinnable element',
|
||||
|
@ -15,7 +14,6 @@ const simpleData = {
|
|||
|
||||
const movableData = {
|
||||
'is-pinned': false,
|
||||
id: 'moveable-header',
|
||||
'data-name': 'movable',
|
||||
'data-pinnable-element-id': 'pinnable-element',
|
||||
'data-pinned-container-id': 'pinned-container',
|
||||
|
@ -57,7 +55,7 @@ describe( 'Pinnable header', () => {
|
|||
pinnableHeader.initPinnableHeader();
|
||||
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.getElementById( simpleData.id ) );
|
||||
const header = /** @type {HTMLElement} */ ( document.querySelector( `.${simpleData[ 'data-name' ]}-pinnable-header` ) );
|
||||
|
||||
expect( header.classList.contains( pinnableHeader.PINNED_HEADER_CLASS ) ).toBe( false );
|
||||
expect( document.body.classList.contains( `${simpleData[ 'data-name' ]}-pinned` ) ).toBe( false );
|
||||
|
|
|
@ -60,7 +60,7 @@ const editButtonsTemplateData = [ {
|
|||
|
||||
const templateData = {
|
||||
'data-sticky-header-toc': {
|
||||
id: 'p-sticky-header-toc',
|
||||
id: 'vector-sticky-header-toc',
|
||||
class: 'mw-portlet mw-portlet-sticky-header-toc vector-sticky-header-toc',
|
||||
'html-items': '',
|
||||
'html-vector-menu-checkbox-attributes': 'tabindex="-1"',
|
||||
|
@ -88,10 +88,11 @@ const templateData = {
|
|||
'data-buttons': defaultButtonsTemplateData.concat( editButtonsTemplateData )
|
||||
};
|
||||
|
||||
const renderedHTML = mustache.render( stickyHeaderTemplate, templateData, Object.assign( {}, dropdownPartials, {
|
||||
Button: buttonTemplate,
|
||||
SearchBox: '<div> </div>' // ignore SearchBox for this test
|
||||
} ) );
|
||||
const renderedHTML = mustache.render(
|
||||
stickyHeaderTemplate, templateData, Object.assign( {}, dropdownPartials, {
|
||||
Button: buttonTemplate,
|
||||
SearchBox: '<div> </div>' // ignore SearchBox for this test
|
||||
} ) );
|
||||
|
||||
beforeEach( () => {
|
||||
document.body.innerHTML = renderedHTML;
|
||||
|
|
|
@ -12,7 +12,7 @@ let /** @type {HTMLElement} */ container,
|
|||
/** @type {HTMLElement} */ quuxSection;
|
||||
const onHeadingClick = jest.fn();
|
||||
const onToggleClick = jest.fn();
|
||||
const onToggleCollapse = jest.fn();
|
||||
const onTogglePinned = jest.fn();
|
||||
|
||||
const SECTIONS = [
|
||||
{
|
||||
|
@ -95,7 +95,7 @@ function mount( templateProps = {} ) {
|
|||
container,
|
||||
onHeadingClick,
|
||||
onToggleClick,
|
||||
onToggleCollapse
|
||||
onTogglePinned
|
||||
} );
|
||||
}
|
||||
|
||||
|
|
|
@ -98,6 +98,7 @@ class SkinVectorTest extends MediaWikiIntegrationTestCase {
|
|||
'byteoffset' => 231,
|
||||
'anchor' => 'A',
|
||||
'linkAnchor' => 'A',
|
||||
'vector-button-label' => '(vector-toc-toggle-button-label: A)',
|
||||
'array-sections' => [
|
||||
'toclevel' => 2,
|
||||
'level' => '4',
|
||||
|
@ -121,14 +122,17 @@ class SkinVectorTest extends MediaWikiIntegrationTestCase {
|
|||
$expectedConfigData = [
|
||||
'is-vector-toc-beginning-enabled' => $config[ 'VectorTableOfContentsBeginning' ],
|
||||
'vector-is-collapse-sections-enabled' =>
|
||||
$tocData[ 'number-section-count' ] >= $config[ 'VectorTableOfContentsCollapseAtCount' ]
|
||||
$tocData[ 'number-section-count' ] >= $config[ 'VectorTableOfContentsCollapseAtCount' ],
|
||||
'data-pinnable-header' => [
|
||||
'is-pinned' => true,
|
||||
'data-name' => 'vector-toc',
|
||||
'label' => '(vector-toc-label)',
|
||||
'unpin-label' => '(vector-unpin-element-label)',
|
||||
'pin-label' => '(vector-pin-element-label)'
|
||||
]
|
||||
];
|
||||
$expectedNestedTocData = array_merge( $nestedTocData, $expectedConfigData );
|
||||
|
||||
// qqx output
|
||||
$buttonLabel = '(vector-toc-toggle-button-label: A)';
|
||||
$expectedNestedTocData[ 'array-sections' ][ 0 ][ 'vector-button-label' ] = $buttonLabel;
|
||||
|
||||
return [
|
||||
// When zero sections
|
||||
[
|
||||
|
|
Loading…
Reference in a new issue