UNPKG

@wordpress/editor

Version:
145 lines (127 loc) 4.47 kB
/** * WordPress dependencies */ import { _x } from '@wordpress/i18n'; /** * Sanitizes a comment string by removing non-printable ASCII characters. * * @param {string} str - The comment string to sanitize. * @return {string} - The sanitized comment string. */ export function sanitizeCommentString( str ) { return str.trim(); } /** * A no-operation function that does nothing. */ export function noop() {} /** * Avatar border colors chosen to be visually distinct from each other and from * the editor's semantic UI colors (Delta E > 10 between all pairs). */ const AVATAR_BORDER_COLORS = [ '#C36EFF', // Purple '#FF51A8', // Pink '#E4780A', // Orange '#FF35EE', // Magenta '#879F11', // Olive '#46A494', // Teal '#00A2C3', // Cyan ]; /** * Gets the border color for an avatar based on the user ID. * * @param {number} userId - The user ID. * @return {string} - The border color. */ export function getAvatarBorderColor( userId ) { return AVATAR_BORDER_COLORS[ userId % AVATAR_BORDER_COLORS.length ]; } /** * Generates a comment excerpt from text based on word count type and length. * * @param {string} text - The comment text to generate excerpt from. * @param {number} excerptLength - The maximum length for the commentexcerpt. * @return {string} - The generated comment excerpt. */ export function getCommentExcerpt( text, excerptLength = 10 ) { if ( ! text ) { return ''; } /* * translators: If your word count is based on single characters (e.g. East Asian characters), * enter 'characters_excluding_spaces' or 'characters_including_spaces'. Otherwise, enter 'words'. * Do not translate into your own language. */ const wordCountType = _x( 'words', 'Word count type. Do not translate!' ); const rawText = text.trim(); let trimmedExcerpt = ''; if ( wordCountType === 'words' ) { trimmedExcerpt = rawText.split( ' ', excerptLength ).join( ' ' ); } else if ( wordCountType === 'characters_excluding_spaces' ) { /* * 1. Split the text at the character limit, * then join the substrings back into one string. * 2. Count the number of spaces in the text * by comparing the lengths of the string with and without spaces. * 3. Add the number to the length of the visible excerpt, * so that the spaces are excluded from the word count. */ const textWithSpaces = rawText.split( '', excerptLength ).join( '' ); const numberOfSpaces = textWithSpaces.length - textWithSpaces.replaceAll( ' ', '' ).length; trimmedExcerpt = rawText .split( '', excerptLength + numberOfSpaces ) .join( '' ); } else if ( wordCountType === 'characters_including_spaces' ) { trimmedExcerpt = rawText.split( '', excerptLength ).join( '' ); } const isTrimmed = trimmedExcerpt !== rawText; return isTrimmed ? trimmedExcerpt + '…' : trimmedExcerpt; } /** * Shift focus to the comment thread associated with a particular comment ID. * If an additional selector is provided, the focus will be shifted to the element matching the selector. * * @typedef {import('@wordpress/element').RefObject} RefObject * * @param {string} commentId The ID of the comment thread to focus. * @param {?HTMLElement} container The container element to search within. * @param {string} additionalSelector The additional selector to focus on. */ export function focusCommentThread( commentId, container, additionalSelector ) { if ( ! container ) { return; } // A thread without a commentId is a new comment thread. const threadSelector = commentId && commentId !== 'new' ? `[role=treeitem][id="comment-thread-${ commentId }"]` : '[role=treeitem]:not([id])'; const selector = additionalSelector ? `${ threadSelector } ${ additionalSelector }` : threadSelector; return new Promise( ( resolve ) => { if ( container.querySelector( selector ) ) { return resolve( container.querySelector( selector ) ); } let timer = null; // Wait for the element to be added to the DOM. const observer = new window.MutationObserver( () => { if ( container.querySelector( selector ) ) { clearTimeout( timer ); observer.disconnect(); resolve( container.querySelector( selector ) ); } } ); observer.observe( container, { childList: true, subtree: true, } ); // Stop trying after 3 seconds. timer = setTimeout( () => { observer.disconnect(); resolve( null ); }, 3000 ); } ).then( ( element ) => element?.focus() ); }