Create new sticky toc container
Bug: T313060 Change-Id: Ia263c606dce5a6060b6b29fbaedc49cef3e17a5c
This commit is contained in:
parent
990c7f72b9
commit
9c6f6709c6
|
@ -1,3 +1,6 @@
|
||||||
<div class="mw-table-of-contents-container mw-sticky-header-element">
|
<div class="mw-table-of-contents-container">
|
||||||
{{#data-toc}}{{>TableOfContents}}{{/data-toc}}
|
{{! T313060 Additional container div needed to prevent the sticky element from being siblings with the footer }}
|
||||||
|
<div class="vector-sticky-toc-container mw-sticky-header-element">
|
||||||
|
{{#data-toc}}{{>TableOfContents}}{{/data-toc}}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -60,8 +60,11 @@ function moveToc( position ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: Remove after Ia263c606dce5a6060b6b29fbaedc49cef3e17a5c has been in prod for 5 days
|
||||||
|
const isCachedHtml = document.querySelector( '.mw-table-of-contents-container.mw-sticky-header-element' );
|
||||||
|
|
||||||
let newTocContainer;
|
let newTocContainer;
|
||||||
const sidebarTocContainerClass = 'mw-table-of-contents-container';
|
const sidebarTocContainerClass = isCachedHtml ? 'mw-table-of-contents-container' : 'vector-sticky-toc-container';
|
||||||
const stickyHeaderTocContainerClass = 'vector-menu-content';
|
const stickyHeaderTocContainerClass = 'vector-menu-content';
|
||||||
// Avoid moving TOC if unnecessary
|
// Avoid moving TOC if unnecessary
|
||||||
if ( !currTocContainer.classList.contains( sidebarTocContainerClass ) && position === 'sidebar' ) {
|
if ( !currTocContainer.classList.contains( sidebarTocContainerClass ) && position === 'sidebar' ) {
|
||||||
|
@ -69,6 +72,7 @@ function moveToc( position ) {
|
||||||
} else if ( !currTocContainer.classList.contains( stickyHeaderTocContainerClass ) && position === 'stickyheader' ) {
|
} else if ( !currTocContainer.classList.contains( stickyHeaderTocContainerClass ) && position === 'stickyheader' ) {
|
||||||
newTocContainer = document.querySelector( `.vector-sticky-header-toc .${stickyHeaderTocContainerClass}` );
|
newTocContainer = document.querySelector( `.vector-sticky-header-toc .${stickyHeaderTocContainerClass}` );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( newTocContainer ) {
|
if ( newTocContainer ) {
|
||||||
newTocContainer.insertAdjacentElement( 'beforeend', toc );
|
newTocContainer.insertAdjacentElement( 'beforeend', toc );
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,11 +10,19 @@
|
||||||
@toc-subsection-toggle-icon-size: 1.834em;
|
@toc-subsection-toggle-icon-size: 1.834em;
|
||||||
|
|
||||||
.mw-table-of-contents-container {
|
.mw-table-of-contents-container {
|
||||||
|
// Needed for Grid-based layout
|
||||||
|
align-self: start;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Remove selector after Ia263c606dce5a6060b6b29fbaedc49cef3e17a5c has been in prod for 5 days
|
||||||
|
.mw-table-of-contents-container.mw-sticky-header-element {
|
||||||
// stylelint-disable-next-line plugin/no-unsupported-browser-features
|
// stylelint-disable-next-line plugin/no-unsupported-browser-features
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: 0;
|
top: 0;
|
||||||
// Needed for Grid-based layout
|
// Needed for Grid-based layout
|
||||||
align-self: start;
|
align-self: start;
|
||||||
|
height: unset;
|
||||||
|
|
||||||
// Needed to align TOC with bottom of title
|
// Needed to align TOC with bottom of title
|
||||||
// 1.5em from .mw-table-of-contents-container + 1.5em from .sidebar-toc = 3em
|
// 1.5em from .mw-table-of-contents-container + 1.5em from .sidebar-toc = 3em
|
||||||
|
@ -25,10 +33,32 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.vector-sticky-toc-container {
|
||||||
|
// stylelint-disable-next-line plugin/no-unsupported-browser-features
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
|
||||||
|
@media ( min-width: @min-width-desktop ) {
|
||||||
|
.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 & {
|
||||||
|
// Needed to align TOC with bottom of title, 1.5em padding + 1.5em margin = 3em
|
||||||
|
margin-top: 1.5em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Remove selector after Ia263c606dce5a6060b6b29fbaedc49cef3e17a5c has been in prod for 5 days
|
||||||
|
.mw-table-of-contents-container > .sidebar-toc {
|
||||||
|
margin-top: 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
.sidebar-toc {
|
.sidebar-toc {
|
||||||
max-height: 75vh;
|
max-height: 75vh;
|
||||||
// Default spacing separating the sidebar TOC from the main menu or viewport.
|
|
||||||
margin-top: 1.5em;
|
|
||||||
padding: @sidebar-toc-vertical-padding @sidebar-toc-right-padding @sidebar-toc-vertical-padding @sidebar-toc-left-padding;
|
padding: @sidebar-toc-vertical-padding @sidebar-toc-right-padding @sidebar-toc-vertical-padding @sidebar-toc-left-padding;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
|
|
@ -64,7 +64,9 @@
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mw-table-of-contents-container {
|
// FIXME: Remove this selector after Ia263c606dce5a6060b6b29fbaedc49cef3e17a5c has been in prod for 5 days
|
||||||
|
.mw-table-of-contents-container.mw-sticky-header-element,
|
||||||
|
.vector-sticky-toc-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
const mustache = require( 'mustache' );
|
const mustache = require( 'mustache' );
|
||||||
const fs = require( 'fs' );
|
const fs = require( 'fs' );
|
||||||
|
const tocContainerTemplate = fs.readFileSync( 'includes/templates/TableOfContentsContainer.mustache', 'utf8' );
|
||||||
const stickyHeaderTemplate = fs.readFileSync( 'includes/templates/StickyHeader.mustache', 'utf8' );
|
const stickyHeaderTemplate = fs.readFileSync( 'includes/templates/StickyHeader.mustache', 'utf8' );
|
||||||
const buttonTemplate = fs.readFileSync( 'includes/templates/Button.mustache', 'utf8' );
|
const buttonTemplate = fs.readFileSync( 'includes/templates/Button.mustache', 'utf8' );
|
||||||
const menuTemplate = fs.readFileSync( 'includes/templates/Menu.mustache', 'utf8' );
|
const menuTemplate = fs.readFileSync( 'includes/templates/Menu.mustache', 'utf8' );
|
||||||
|
@ -116,17 +117,19 @@ describe( 'sticky header', () => {
|
||||||
} );
|
} );
|
||||||
|
|
||||||
describe( 'moveToc', () => {
|
describe( 'moveToc', () => {
|
||||||
const sidebarTocContainerClass = 'mw-table-of-contents-container';
|
const sidebarTocContainerClass = 'vector-sticky-toc-container';
|
||||||
const stickyHeaderTocContainerClass = 'vector-menu-content';
|
const stickyTocContainerClass = 'vector-menu-content';
|
||||||
const tocId = 'mw-panel-toc';
|
const tocId = 'mw-panel-toc';
|
||||||
|
|
||||||
function setupToc() {
|
function setupToc() {
|
||||||
const sidebarTocContainer = document.createElement( 'div' );
|
const sidebarTocContainerHTML = mustache.render( tocContainerTemplate, {
|
||||||
sidebarTocContainer.classList.add( sidebarTocContainerClass );
|
'data-toc': [ '' ]
|
||||||
const toc = document.createElement( 'div' );
|
}, {
|
||||||
toc.setAttribute( 'id', tocId );
|
TableOfContents: '<div id="mw-panel-toc" class="sidebar-toc"></div>'
|
||||||
sidebarTocContainer.appendChild( toc );
|
} );
|
||||||
document.body.appendChild( sidebarTocContainer );
|
var sidebarTocContainerTemplate = document.createElement( 'template' );
|
||||||
|
sidebarTocContainerTemplate.innerHTML = sidebarTocContainerHTML;
|
||||||
|
document.body.appendChild( sidebarTocContainerTemplate.content );
|
||||||
}
|
}
|
||||||
|
|
||||||
test( 'moves toc to stickyheader and sidebar', () => {
|
test( 'moves toc to stickyheader and sidebar', () => {
|
||||||
|
@ -136,7 +139,7 @@ describe( 'sticky header', () => {
|
||||||
( toc.parentNode ).classList.contains( sidebarTocContainerClass ) ).toBeTruthy();
|
( toc.parentNode ).classList.contains( sidebarTocContainerClass ) ).toBeTruthy();
|
||||||
sticky.moveToc( 'stickyheader' );
|
sticky.moveToc( 'stickyheader' );
|
||||||
expect( /** @type {Element} */
|
expect( /** @type {Element} */
|
||||||
( toc.parentNode ).classList.contains( stickyHeaderTocContainerClass ) ).toBeTruthy();
|
( toc.parentNode ).classList.contains( stickyTocContainerClass ) ).toBeTruthy();
|
||||||
sticky.moveToc( 'sidebar' );
|
sticky.moveToc( 'sidebar' );
|
||||||
expect( /** @type {Element} */
|
expect( /** @type {Element} */
|
||||||
( toc.parentNode ).classList.contains( sidebarTocContainerClass ) ).toBeTruthy();
|
( toc.parentNode ).classList.contains( sidebarTocContainerClass ) ).toBeTruthy();
|
||||||
|
|
Loading…
Reference in New Issue