Issue #3173832 by Pooja Ganjage, mherchel, adamzimmermann, paulocs, KapilV, markdorison, Sakthivel M, Gauravmahlawat, nod_, kostyashupenko, sulfikar_s, bnjmnm: Ensure Olivero's JS documentation matches standards

merge-requests/900/head^2
Lauri Eskola 2021-07-06 13:57:16 +03:00
parent d523586d78
commit f0a97d0cdd
No known key found for this signature in database
GPG Key ID: 382FC0F5B0DF53F8
8 changed files with 135 additions and 22 deletions

View File

@ -1,6 +1,6 @@
/**
* @file
* Theme override for checkbox.
* Customization of checkbox.
*/
((Drupal) => {

View File

@ -1,14 +1,14 @@
/**
* @file
* Adds show/hide functionality for indented comments.
* Customization of comments.
*/
((Drupal, once) => {
/**
* Init function for comments.
* Initialize show/hide button for the comments.
*
* @param {object} comments
* The comment section.
* @param {Element} comments
* The comment wrapper element.
*/
function init(comments) {
comments

View File

@ -1,11 +1,11 @@
/**
* @file
* Messages.
* Customization of messages.
*/
((Drupal, once) => {
/**
* Adds close button to the message.
* Adds a close button to the message.
*
* @param {object} message
* The message object.
@ -108,7 +108,12 @@
};
/**
* Getting messages from context.
* Get messages from context.
*
* @type {Drupal~behavior}
*
* @prop {Drupal~behaviorAttach} attach
* Attaches the close button behavior for messages.
*/
Drupal.behaviors.messages = {
attach(context) {

View File

@ -1,8 +1,15 @@
/**
* @file
* Customization of navigation.
*/
((Drupal, once, tabbable) => {
/**
* Checks if navWrapper contains "is-active" class.
* @param {object} navWrapper
*
* @param {Element} navWrapper
* Header navigation.
*
* @return {boolean}
* True if navWrapper contains "is-active" class, false if not.
*/
@ -12,6 +19,7 @@
/**
* Opens or closes the header navigation.
*
* @param {object} props
* Navigation props.
* @param {boolean} state
@ -33,7 +41,8 @@
}
/**
* Init function for header navigation.
* Initialize the header navigation.
*
* @param {object} props
* Navigation props.
*/
@ -45,7 +54,7 @@
toggleNav(props, !isNavOpen(props.navWrapper));
});
// Closes any open sub navigation first, then close header navigation.
// Close any open sub-navigation first, then close the header navigation.
document.addEventListener('keyup', (e) => {
if (e.key === 'Escape' || e.key === 'Esc') {
if (props.olivero.areAnySubNavsOpen()) {
@ -107,7 +116,12 @@
}
/**
* Initialize the navigation JS.
* Initialize the navigation.
*
* @type {Drupal~behavior}
*
* @prop {Drupal~behaviorAttach} attach
* Attach context and settings for navigation.
*/
Drupal.behaviors.oliveroNavigation = {
attach(context) {

View File

@ -1,3 +1,11 @@
/**
* @file
* Controls the visibility of desktop navigation.
*
* Shows and hides the desktop navigation based on scroll position and controls
* the functionality of the button that shows/hides the navigation.
*/
/* eslint-disable no-inner-declarations */
((Drupal) => {
/**
@ -7,6 +15,12 @@
*/
Drupal.olivero = {};
/**
* Checks if the mobile navigation button is visible.
*
* @return {boolean}
* True if navButtons is hidden, false if not.
*/
function isDesktopNav() {
const navButtons = document.querySelector(
'[data-drupal-selector="mobile-buttons"]',
@ -25,6 +39,12 @@
'[data-drupal-selector="site-header-fixable"]',
);
/**
* Checks if the sticky header is enabled.
*
* @return {boolean}
* True if sticky header is enabled, false if not.
*/
function stickyHeaderIsEnabled() {
return stickyHeaderToggleButton.getAttribute('aria-checked') === 'true';
}
@ -33,7 +53,8 @@
* Save the current sticky header expanded state to localStorage, and set
* it to expire after two weeks.
*
* @param {boolean} expandedState - Current state of the sticky header button.
* @param {boolean} expandedState
* Current state of the sticky header button.
*/
function setStickyHeaderStorage(expandedState) {
const now = new Date();
@ -52,7 +73,8 @@
* Toggle the state of the sticky header between always pinned and
* only pinned when scrolled to the top of the viewport.
*
* @param {boolean} pinnedState - State to change the sticky header to.
* @param {boolean} pinnedState
* State to change the sticky header to.
*/
function toggleStickyHeaderState(pinnedState) {
if (isDesktopNav()) {
@ -70,7 +92,8 @@
/**
* Return the sticky header's stored state from localStorage.
*
* @return {boolean} Stored state of the sticky header.
* @return {boolean}
* Stored state of the sticky header.
*/
function getStickyHeaderStorage() {
const stickyHeaderState = localStorage.getItem(
@ -91,7 +114,8 @@
return item.value;
}
// Only enable scroll effects if the browser supports Intersection Observer.
// Only enable scroll interactivity if the browser supports Intersection
// Observer.
// @see https://github.com/w3c/IntersectionObserver/blob/master/polyfill/intersection-observer.js#L19-L21
if (
'IntersectionObserver' in window &&
@ -106,7 +130,7 @@
if (!isDesktopNav()) return;
entries.forEach((entry) => {
// FF doesn't seem to support entry.isIntersecting properly,
// Firefox doesn't seem to support entry.isIntersecting properly,
// so we check the intersectionRatio.
if (entry.intersectionRatio < 1) {
fixableElements.forEach((el) => el.classList.add('is-fixed'));
@ -116,6 +140,12 @@
});
}
/**
* Gets the root margin by checking for various toolbar classes.
*
* @return {string}
* Root margin for the Intersection Observer options object.
*/
function getRootMargin() {
let rootMarginTop = 72;
const { body } = document;
@ -134,6 +164,9 @@
return `${rootMarginTop}px 0px 0px 0px`;
}
/**
* Monitor the navigation position.
*/
function monitorNavPosition() {
const primaryNav = document.querySelector(
'[data-drupal-selector="site-header"]',

View File

@ -1,3 +1,8 @@
/**
* @file
* Customization of search.
*/
((Drupal) => {
const searchWideButton = document.querySelector(
'[data-drupal-selector="block-search-wide-button"]',
@ -6,11 +11,20 @@
'[data-drupal-selector="block-search-wide-wrapper"]',
);
/**
* Determine if search is visible.
*
* @return {boolean}
* True if the search wrapper contains "is-active" class, false if not.
*/
function searchIsVisible() {
return searchWideWrapper.classList.contains('is-active');
}
Drupal.olivero.searchIsVisible = searchIsVisible;
/**
* Set focus for the search input element.
*/
function handleFocus() {
if (searchIsVisible()) {
searchWideWrapper.querySelector('input[type="search"]').focus();
@ -19,6 +33,12 @@
}
}
/**
* Toggle search functionality visibility.
*
* @param {boolean} visibility
* True if we want to show the form, false if we want to hide it.
*/
function toggleSearchVisibility(visibility) {
searchWideButton.setAttribute('aria-expanded', visibility === true);
searchWideWrapper.addEventListener('transitionend', handleFocus, {

View File

@ -1,3 +1,8 @@
/**
* @file
* Provides functionality for second level submenu navigation.
*/
((Drupal) => {
const { isDesktopNav } = Drupal.olivero;
const secondLevelNavMenus = document.querySelectorAll(
@ -7,8 +12,10 @@
/**
* Shows and hides the specified menu item's second level submenu.
*
* @param {element} topLevelMenuItem - the <li> element that is the container for the menu and submenus.
* @param {boolean} [toState] - Optional state where we want the submenu to end up.
* @param {Element} topLevelMenuItem
* The <li> element that is the container for the menu and submenus.
* @param {boolean} [toState]
* Optional state where we want the submenu to end up.
*/
function toggleSubNav(topLevelMenuItem, toState) {
const buttonSelector =
@ -60,7 +67,8 @@
* Sets a timeout and closes current desktop navigation submenu if it
* does not contain the focused element.
*
* @param {object} e - event object
* @param {Event} e
* The event object.
*/
function handleBlur(e) {
if (!Drupal.olivero.isDesktopNav()) return;
@ -147,7 +155,9 @@
/**
* Checks if any sub navigation items are currently active.
* @return {boolean} If sub nav is currently open.
*
* @return {boolean}
* If sub navigation is currently open.
*/
function areAnySubNavsOpen() {
let subNavsAreOpen = false;
@ -168,7 +178,7 @@
Drupal.olivero.areAnySubNavsOpen = areAnySubNavsOpen;
// Ensure that desktop submenus close when ESC key is pressed.
// Ensure that desktop submenus close when escape key is pressed.
document.addEventListener('keyup', (e) => {
if (e.key === 'Escape' || e.key === 'Esc') {
if (isDesktopNav()) closeAllSubNav();

View File

@ -1,13 +1,36 @@
/**
* @file
* Provides interactivity for showing and hiding the tabs at mobile widths.
*/
((Drupal, once) => {
/**
* Initialize the tabs.
*
* @param {HTMLElement} el
* The DOM element containing the tabs.
*/
function init(el) {
const tabs = el.querySelector('.tabs');
const expandedClass = 'is-expanded';
const activeTab = tabs.querySelector('.is-active');
/**
* Determines if tabs are expanded for mobile layouts.
*
* @return {boolean}
* Whether the tabs trigger element is expanded.
*/
function isTabsMobileLayout() {
return tabs.querySelector('.tabs__trigger').clientHeight > 0;
}
/**
* Controls tab visibility on click events.
*
* @param {Event} e
* The event object.
*/
function handleTriggerClick(e) {
if (!tabs.classList.contains(expandedClass)) {
e.currentTarget.setAttribute('aria-expanded', 'true');
@ -30,6 +53,14 @@
.addEventListener('click', handleTriggerClick);
}
/**
* Initialize the tabs.
*
* @type {Drupal~behavior}
*
* @prop {Drupal~behaviorAttach} attach
* Display tabs according to the screen width.
*/
Drupal.behaviors.tabs = {
attach(context) {
once('olivero-tabs', '[data-drupal-nav-tabs]', context).forEach(init);