mazey-wordpress-utils
Version:
WordPress utilities.
209 lines (201 loc) • 8.03 kB
text/typescript
import { throttle } from 'mazey';
import copy from 'copy-to-clipboard';
/**
* Sets a copy button for all <p> tags within the specified element.
* The copy button allows users to copy the text content of the <p> tag.
*
* @returns {boolean} True if the copy buttons were successfully set, false otherwise.
*/
export function setCopyBtnForAllTagP(): boolean {
const allTagP = document.querySelectorAll('.entry-content p');
if (!allTagP || allTagP.length === 0) return false;
allTagP.forEach(p => {
const text = p.innerText;
const btn = document.createElement('button');
btn.innerText = 'Copy';
btn.classList.add('mazey-wp-btn-copy');
btn.addEventListener('click', () => {
copy(text);
btn.innerText = 'Copied';
setTimeout(() => {
btn.innerText = 'Copy';
}, 1000);
});
p.appendChild(btn);
});
return true;
}
/**
* Set the 'loading' attribute of all images within a specified element to 'lazy', enabling lazy loading.
* The function only runs once after the page has loaded.
*
* ```javascript
* setImgLazyLoadingWhenDomReady('.site-content');
* ```
*
* @param selector - CSS selector for the element that contains the images. Default is '.site-content'.
* @returns {boolean} - Returns `true` if the function was able to set the images' lazy loading and it hasn't been run before, `false` otherwise.
*/
export function setImgLazyLoadingWhenDomReady(selector = '.site-content'): boolean {
function handleLoad () {
const images = document.querySelectorAll(`${selector} img`);
if (images.length === 0) return false;
images.forEach(image => {
image.setAttribute('loading', 'lazy');
});
return true;
}
return handleLoad();
}
/**
* The variable that stores whether the header has been hidden.
*/
let loadedHideHeaderInTOC = false;
/**
* Hide the header when it meets one of these two conditions:
*
* - Use WordPress Plugin [Easy Table of Contents](https://wordpress.org/plugins/easy-table-of-contents/) and open it in this page.
* - The page's URL is matched with one of the `urlContainList`.
*
* Example: <https://example.com/home?hide_header_in_toc>
*
* ```javascript
* hideHeaderInTOC({
* urlContainList: ['hide_header_in_toc', 'no_header_in_toc'],
* headerSelector: '.site-header'
* });
* ```
*
* @param options - Configuration options for hiding the header.
* @param options.urlContainList - List of strings. If the current URL contains any of these strings, the header will be hidden. Default is ['hide_header_in_toc'].
* @param options.headerSelector - CSS selector for the header. Default is '.site-header'.
* @returns {boolean} - Returns `true` if the header was successfully hidden, `false` otherwise.
*/
export function hideHeaderInTOC(options = {}): boolean {
const { urlContainList = [], headerSelector } = Object.assign({
urlContainList: [ 'hide_header_in_toc' ],
headerSelector: '.site-header',
}, options);
let isIncludeUrls = false;
if (urlContainList.length === 0) {
isIncludeUrls = true;
} else {
isIncludeUrls = urlContainList.some(urlContainString => isIncludeInUrl({ urlContainString }));
}
const isEzTocContainerDomExist = document.querySelector('#ez-toc-container');
const isHideHeader = isIncludeUrls || isEzTocContainerDomExist;
const SiteHeaderDom = document.querySelector(headerSelector);
if (!SiteHeaderDom) return false;
// Handle Event
function handleScroll () {
if (!SiteHeaderDom) return;
const scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
const visibility = SiteHeaderDom.style.visibility;
if (scrollTop > 100) {
if (visibility !== 'hidden') SiteHeaderDom.style.visibility = 'hidden';
} else {
if (visibility !== 'visible') SiteHeaderDom.style.visibility = 'visible';
}
}
if (isHideHeader && SiteHeaderDom && loadedHideHeaderInTOC === false) {
// Listen
window.addEventListener('scroll', throttle(handleScroll, 50, { leading: true }));
// Init when page loaded
setTimeout(() => {
handleScroll();
}, 25);
loadedHideHeaderInTOC = true;
return true;
}
return false;
}
/**
* Hide the sidebar on the webpage.
*
* Example: <https://example.com/home?hide_sidebar>
*
* ```javascript
* hideSidebar({
* urlContainList: ['hide_sidebar', 'no_sidebar'],
* primarySelector: '#main-content',
* secondarySelector: '#sidebar'
* });
* ```
*
* @param options - Configuration options for hiding the sidebar.
* @param options.urlContainList - List of strings. If the current URL contains any of these strings, the sidebar will be hidden. Default is ['hide_sidebar'].
* @param options.primarySelector - CSS selector for the primary content area. Default is '#primary'.
* @param options.secondarySelector - CSS selector for the sidebar. Default is '#secondary'.
* @returns {boolean} - Returns `true` if the sidebar was successfully hidden, `false` otherwise.
*/
export function hideSidebar(options = {}): boolean {
const { urlContainList = [], primarySelector, secondarySelector } = Object.assign({
urlContainList: [ 'hide_sidebar' ],
primarySelector: '#primary',
secondarySelector: '#secondary',
}, options);
const isHideSidebar = urlContainList.some(urlContainString => isIncludeInUrl({ urlContainString }));
const secondaryDom = document.querySelector(secondarySelector);
if (!secondaryDom) return false;
const primaryDom = document.querySelector(primarySelector);
if (!primaryDom) return false;
if (isHideSidebar && secondaryDom && primaryDom) {
secondaryDom.style.display = 'none';
primaryDom.style.width = '100%';
return true;
}
return false;
}
/**
* Check if the current URL includes a specified string.
*
* Example: <https://example.com/home?example>
*
* ```javascript
* isIncludeInUrl({
* urlContainString: 'example'
* });
* ```
*
* @param options.urlContainString - The string to check for in the URL. Default is an empty string.
* @returns {boolean} - Returns `true` if the URL contains the specified string, `false` otherwise.
*/
export function isIncludeInUrl(options = {}): boolean {
const { urlContainString = '' } = Object.assign({
urlContainString: '',
}, options);
const Url = location.href;
return Url.includes(urlContainString);
}
/**
* Set the width and height of an image based on the parameters specified in the image's URL.
*
* Use jQuery to select all `img` elements on the page and then checks each image's `src` attribute for `width` and `height` parameters. If these parameters are found, the function sets the image's width and height accordingly.
*
* The width and height parameters in the URL should be in the format `width=<value><unit>` and `height=<value><unit>`, where `<value>` is a number and `<unit>` is a CSS unit like `px`, `rem`, or `vw`.
*
* Example 1:
* For an image with the URL `<img src="https://example.com/image.png?width=400px&height=200px" alt="file" />`, the function will execute `window.jQuery('img').width('400px')` and `window.jQuery('img').height('200px')`.
*
* Example 2:
* For an image with the URL `<img src="https://example.com/image.png?width=400rem&height=20vw" alt="file" />`, the function will execute `window.jQuery('img').width('400rem')` and `window.jQuery('img').height('20vw')`.
*
* @returns {boolean} - Returns `true` if jQuery is available and the function was able to run, `false` otherwise.
*/
export function setImgWidthHeight(): boolean {
const $ = window.jQuery || window.$;
if ($) {
$('img').each(function () {
const $this = $(this);
if (!$this) return;
const src = $this.attr('src');
if (!src) return;
const width = src.match(/width=([0-9]+[a-z%]+)/);
const height = src.match(/height=([0-9]+[a-z%]+)/);
if (width && width[1]) $this.width(width[1]);
if (height && height[1]) $this.height(height[1]);
});
return true;
}
return false;
}