From eb3ffc4f27a1f42c17963662a2f61be060835736 Mon Sep 17 00:00:00 2001 From: sivard donkers Date: Thu, 16 Oct 2025 15:04:45 +0200 Subject: [PATCH 01/14] replaced text for originalHTML, set the focus to the first field when opening the modal. --- src/core/app.tsx | 195 +++++++++++++++++++++++++---------------------- 1 file changed, 105 insertions(+), 90 deletions(-) diff --git a/src/core/app.tsx b/src/core/app.tsx index 91ce729..b2fa9b6 100644 --- a/src/core/app.tsx +++ b/src/core/app.tsx @@ -1,8 +1,8 @@ -import { __ } from '@wordpress/i18n'; -import { search } from '@wordpress/icons'; -import { applyFilters, doAction } from '@wordpress/hooks'; -import { dispatch, select } from '@wordpress/data'; -import { useState, useEffect } from '@wordpress/element'; +import {__} from '@wordpress/i18n'; +import {search} from '@wordpress/icons'; +import {applyFilters, doAction} from '@wordpress/hooks'; +import {dispatch, select} from '@wordpress/data'; +import {useState, useEffect, useRef} from '@wordpress/element'; import { Modal, TextControl, @@ -11,7 +11,7 @@ import { Tooltip, } from '@wordpress/components'; -import { Shortcut } from './shortcut'; +import {Shortcut} from './shortcut'; import { getAllowedBlocks, getBlockEditorIframe, @@ -33,12 +33,15 @@ import '../styles/app.scss'; * @return {JSX.Element} Search & Replace for Block Editor. */ const SearchReplaceForBlockEditor = (): JSX.Element => { - const [ replacements, setReplacements ] = useState< number >( 0 ); - const [ isModalVisible, setIsModalVisible ] = useState< boolean >( false ); - const [ searchInput, setSearchInput ] = useState< string >( '' ); - const [ replaceInput, setReplaceInput ] = useState< string >( '' ); - const [ caseSensitive, setCaseSensitive ] = useState< boolean >( false ); - const [ context, setContext ] = useState< boolean >( false ); + const [replacements, setReplacements] = useState(0); + const [isModalVisible, setIsModalVisible] = useState(false); + const [searchInput, setSearchInput] = useState(''); + const [replaceInput, setReplaceInput] = useState(''); + const [caseSensitive, setCaseSensitive] = useState(false); + const [context, setContext] = useState(false); + + // Reference to the first field inside the modal + const searchFieldRef = useRef(null); /** * Open Modal. @@ -48,8 +51,8 @@ const SearchReplaceForBlockEditor = (): JSX.Element => { * @return {void} */ const openModal = (): void => { - setIsModalVisible( true ); - setReplacements( 0 ); + setIsModalVisible(true); + setReplacements(0); }; /** @@ -60,8 +63,8 @@ const SearchReplaceForBlockEditor = (): JSX.Element => { * @return {void} */ const closeModal = (): void => { - setIsModalVisible( false ); - setReplacements( 0 ); + setIsModalVisible(false); + setReplacements(0); }; /** @@ -74,8 +77,8 @@ const SearchReplaceForBlockEditor = (): JSX.Element => { * @param {boolean} newValue * @return {void} */ - const handleCaseSensitive = ( newValue: boolean ): void => { - setCaseSensitive( newValue ); + const handleCaseSensitive = (newValue: boolean): void => { + setCaseSensitive(newValue); }; /** @@ -86,10 +89,21 @@ const SearchReplaceForBlockEditor = (): JSX.Element => { * * @return {void} */ - useEffect( () => { + useEffect(() => { replace(); // eslint-disable-next-line react-hooks/exhaustive-deps - }, [ searchInput, caseSensitive ] ); + }, [searchInput, caseSensitive]); + + /** + * Focus handling + */ + useEffect(() => { + if (isModalVisible && searchFieldRef.current) { + requestAnimationFrame(() => { + searchFieldRef.current?.focus(); + }); + } + }, [isModalVisible]); /** * Handle the implementation for when the user @@ -101,11 +115,11 @@ const SearchReplaceForBlockEditor = (): JSX.Element => { * @param {boolean} status The status of the context. * @return {void} */ - const replace = ( status: boolean = false ): void => { - setContext( status ); - setReplacements( 0 ); + const replace = (status: boolean = false): void => { + setContext(status); + setReplacements(0); - if ( ! searchInput ) { + if (!searchInput) { return; } @@ -114,11 +128,11 @@ const SearchReplaceForBlockEditor = (): JSX.Element => { isCaseSensitive() || caseSensitive ? 'g' : 'gi' ); - select( 'core/block-editor' ) + select('core/block-editor') .getBlocks() - .forEach( ( element: any ) => { - recursivelyReplace( element, pattern, replaceInput, status ); - } ); + .forEach((element: any) => { + recursivelyReplace(element, pattern, replaceInput, status); + }); }; /** @@ -143,10 +157,10 @@ const SearchReplaceForBlockEditor = (): JSX.Element => { text: string, status: boolean ): void => { - const { name, innerBlocks } = element; + const {name, innerBlocks} = element; - if ( getAllowedBlocks().indexOf( name ) !== -1 ) { - const args = { element, pattern, text, status }; + if (getAllowedBlocks().indexOf(name) !== -1) { + const args = {element, pattern, text, status}; /** * Replace Block Attribute. @@ -169,10 +183,10 @@ const SearchReplaceForBlockEditor = (): JSX.Element => { ); } - if ( innerBlocks.length ) { - innerBlocks.forEach( ( innerElement: any ) => { - recursivelyReplace( innerElement, pattern, text, status ); - } ); + if (innerBlocks.length) { + innerBlocks.forEach((innerElement: any) => { + recursivelyReplace(innerElement, pattern, text, status); + }); } }; @@ -188,23 +202,23 @@ const SearchReplaceForBlockEditor = (): JSX.Element => { * * @return {void} */ - const replaceBlockAttribute = ( args: any, attribute: string ): void => { + const replaceBlockAttribute = (args: any, attribute: string): void => { const property = {}; const { pattern, text, - element: { attributes, clientId, name }, + element: {attributes, clientId, name}, status, } = args; if ( undefined === attributes || - undefined === attributes[ attribute ] + undefined === attributes[attribute] ) { return; } - const oldAttr = attributes[ attribute ].text || attributes[ attribute ]; + const oldAttr = attributes[attribute].originalHTML || attributes[attribute]; /** * Replace Callback. @@ -212,7 +226,7 @@ const SearchReplaceForBlockEditor = (): JSX.Element => { * @return {string} Replacement Text. */ const handleAttributeReplacement = (): string => { - setReplacements( ( items: number ) => items + 1 ); + setReplacements((items: number) => items + 1); return text; }; @@ -229,7 +243,7 @@ const SearchReplaceForBlockEditor = (): JSX.Element => { * * @return {Object} */ - const { newAttr, isChanged } = applyFilters( + const {newAttr, isChanged} = applyFilters( 'search-replace-for-block-editor.handleAttributeReplacement', oldAttr, { @@ -239,16 +253,16 @@ const SearchReplaceForBlockEditor = (): JSX.Element => { } ) as { newAttr: any; isChanged: boolean }; - if ( ! isChanged ) { + if (!isChanged) { return; } // Set the property attribute. - property[ attribute ] = newAttr; + property[attribute] = newAttr; // Update block property or content (if replace). - if ( status ) { - ( dispatch( 'core/block-editor' ) as any ).updateBlockAttributes( + if (status) { + (dispatch('core/block-editor') as any).updateBlockAttributes( clientId, property ); @@ -265,19 +279,19 @@ const SearchReplaceForBlockEditor = (): JSX.Element => { * * @return {void} */ - useEffect( () => { + useEffect(() => { const editor = getBlockEditorIframe(); - if ( ! editor || editor === document ) { + if (!editor || editor === document) { return; } - editor.addEventListener( 'selectionchange', handleSelection ); + editor.addEventListener('selectionchange', handleSelection); return () => { - editor.removeEventListener( 'selectionchange', handleSelection ); + editor.removeEventListener('selectionchange', handleSelection); }; - } ); + }); /** * On Selection. @@ -294,8 +308,8 @@ const SearchReplaceForBlockEditor = (): JSX.Element => { .getSelection() .toString(); - if ( selectedText && ! isSelectionInModal() ) { - setSearchInput( selectedText ); + if (selectedText && !isSelectionInModal()) { + setSearchInput(selectedText); } }; @@ -309,108 +323,109 @@ const SearchReplaceForBlockEditor = (): JSX.Element => { * @return {JSX.Element|null} Shortcut. */ const SafeShortcut = (): JSX.Element | null => - isWpVersionGreaterThanOrEqualTo( '6.4.0' ) ? ( - + isWpVersionGreaterThanOrEqualTo('6.4.0') ? ( + ) : null; return ( <> - + - - ) } + )} ); }; From ae235a9e0e266b62aa976991edab49a1927cb0d0 Mon Sep 17 00:00:00 2001 From: sivard donkers Date: Mon, 20 Oct 2025 14:10:17 +0200 Subject: [PATCH 02/14] fix lint:js --- src/core/app.tsx | 193 ++++++++++++++++++++++++----------------------- 1 file changed, 97 insertions(+), 96 deletions(-) diff --git a/src/core/app.tsx b/src/core/app.tsx index b2fa9b6..a9f5523 100644 --- a/src/core/app.tsx +++ b/src/core/app.tsx @@ -1,8 +1,8 @@ -import {__} from '@wordpress/i18n'; -import {search} from '@wordpress/icons'; -import {applyFilters, doAction} from '@wordpress/hooks'; -import {dispatch, select} from '@wordpress/data'; -import {useState, useEffect, useRef} from '@wordpress/element'; +import { __ } from '@wordpress/i18n'; +import { search } from '@wordpress/icons'; +import { applyFilters, doAction } from '@wordpress/hooks'; +import { dispatch, select } from '@wordpress/data'; +import { useState, useEffect, useRef } from '@wordpress/element'; import { Modal, TextControl, @@ -11,7 +11,7 @@ import { Tooltip, } from '@wordpress/components'; -import {Shortcut} from './shortcut'; +import { Shortcut } from './shortcut'; import { getAllowedBlocks, getBlockEditorIframe, @@ -33,15 +33,15 @@ import '../styles/app.scss'; * @return {JSX.Element} Search & Replace for Block Editor. */ const SearchReplaceForBlockEditor = (): JSX.Element => { - const [replacements, setReplacements] = useState(0); - const [isModalVisible, setIsModalVisible] = useState(false); - const [searchInput, setSearchInput] = useState(''); - const [replaceInput, setReplaceInput] = useState(''); - const [caseSensitive, setCaseSensitive] = useState(false); - const [context, setContext] = useState(false); + const [ replacements, setReplacements ] = useState< number >( 0 ); + const [ isModalVisible, setIsModalVisible ] = useState< boolean >( false ); + const [ searchInput, setSearchInput ] = useState< string >( '' ); + const [ replaceInput, setReplaceInput ] = useState< string >( '' ); + const [ caseSensitive, setCaseSensitive ] = useState< boolean >( false ); + const [ context, setContext ] = useState< boolean >( false ); // Reference to the first field inside the modal - const searchFieldRef = useRef(null); + const searchFieldRef = useRef< HTMLInputElement | null >( null ); /** * Open Modal. @@ -51,8 +51,8 @@ const SearchReplaceForBlockEditor = (): JSX.Element => { * @return {void} */ const openModal = (): void => { - setIsModalVisible(true); - setReplacements(0); + setIsModalVisible( true ); + setReplacements( 0 ); }; /** @@ -63,8 +63,8 @@ const SearchReplaceForBlockEditor = (): JSX.Element => { * @return {void} */ const closeModal = (): void => { - setIsModalVisible(false); - setReplacements(0); + setIsModalVisible( false ); + setReplacements( 0 ); }; /** @@ -77,8 +77,8 @@ const SearchReplaceForBlockEditor = (): JSX.Element => { * @param {boolean} newValue * @return {void} */ - const handleCaseSensitive = (newValue: boolean): void => { - setCaseSensitive(newValue); + const handleCaseSensitive = ( newValue: boolean ): void => { + setCaseSensitive( newValue ); }; /** @@ -89,21 +89,21 @@ const SearchReplaceForBlockEditor = (): JSX.Element => { * * @return {void} */ - useEffect(() => { + useEffect( () => { replace(); // eslint-disable-next-line react-hooks/exhaustive-deps - }, [searchInput, caseSensitive]); + }, [ searchInput, caseSensitive ] ); /** * Focus handling */ - useEffect(() => { - if (isModalVisible && searchFieldRef.current) { - requestAnimationFrame(() => { + useEffect( () => { + if ( isModalVisible && searchFieldRef.current ) { + requestAnimationFrame( () => { searchFieldRef.current?.focus(); - }); + } ); } - }, [isModalVisible]); + }, [ isModalVisible ] ); /** * Handle the implementation for when the user @@ -115,11 +115,11 @@ const SearchReplaceForBlockEditor = (): JSX.Element => { * @param {boolean} status The status of the context. * @return {void} */ - const replace = (status: boolean = false): void => { - setContext(status); - setReplacements(0); + const replace = ( status: boolean = false ): void => { + setContext( status ); + setReplacements( 0 ); - if (!searchInput) { + if ( ! searchInput ) { return; } @@ -128,11 +128,11 @@ const SearchReplaceForBlockEditor = (): JSX.Element => { isCaseSensitive() || caseSensitive ? 'g' : 'gi' ); - select('core/block-editor') + select( 'core/block-editor' ) .getBlocks() - .forEach((element: any) => { - recursivelyReplace(element, pattern, replaceInput, status); - }); + .forEach( ( element: any ) => { + recursivelyReplace( element, pattern, replaceInput, status ); + } ); }; /** @@ -157,10 +157,10 @@ const SearchReplaceForBlockEditor = (): JSX.Element => { text: string, status: boolean ): void => { - const {name, innerBlocks} = element; + const { name, innerBlocks } = element; - if (getAllowedBlocks().indexOf(name) !== -1) { - const args = {element, pattern, text, status}; + if ( getAllowedBlocks().indexOf( name ) !== -1 ) { + const args = { element, pattern, text, status }; /** * Replace Block Attribute. @@ -183,10 +183,10 @@ const SearchReplaceForBlockEditor = (): JSX.Element => { ); } - if (innerBlocks.length) { - innerBlocks.forEach((innerElement: any) => { - recursivelyReplace(innerElement, pattern, text, status); - }); + if ( innerBlocks.length ) { + innerBlocks.forEach( ( innerElement: any ) => { + recursivelyReplace( innerElement, pattern, text, status ); + } ); } }; @@ -202,23 +202,24 @@ const SearchReplaceForBlockEditor = (): JSX.Element => { * * @return {void} */ - const replaceBlockAttribute = (args: any, attribute: string): void => { + const replaceBlockAttribute = ( args: any, attribute: string ): void => { const property = {}; const { pattern, text, - element: {attributes, clientId, name}, + element: { attributes, clientId, name }, status, } = args; if ( undefined === attributes || - undefined === attributes[attribute] + undefined === attributes[ attribute ] ) { return; } - const oldAttr = attributes[attribute].originalHTML || attributes[attribute]; + const oldAttr = + attributes[ attribute ].originalHTML || attributes[ attribute ]; /** * Replace Callback. @@ -226,7 +227,7 @@ const SearchReplaceForBlockEditor = (): JSX.Element => { * @return {string} Replacement Text. */ const handleAttributeReplacement = (): string => { - setReplacements((items: number) => items + 1); + setReplacements( ( items: number ) => items + 1 ); return text; }; @@ -243,7 +244,7 @@ const SearchReplaceForBlockEditor = (): JSX.Element => { * * @return {Object} */ - const {newAttr, isChanged} = applyFilters( + const { newAttr, isChanged } = applyFilters( 'search-replace-for-block-editor.handleAttributeReplacement', oldAttr, { @@ -253,16 +254,16 @@ const SearchReplaceForBlockEditor = (): JSX.Element => { } ) as { newAttr: any; isChanged: boolean }; - if (!isChanged) { + if ( ! isChanged ) { return; } // Set the property attribute. - property[attribute] = newAttr; + property[ attribute ] = newAttr; // Update block property or content (if replace). - if (status) { - (dispatch('core/block-editor') as any).updateBlockAttributes( + if ( status ) { + ( dispatch( 'core/block-editor' ) as any ).updateBlockAttributes( clientId, property ); @@ -279,19 +280,19 @@ const SearchReplaceForBlockEditor = (): JSX.Element => { * * @return {void} */ - useEffect(() => { + useEffect( () => { const editor = getBlockEditorIframe(); - if (!editor || editor === document) { + if ( ! editor || editor === document ) { return; } - editor.addEventListener('selectionchange', handleSelection); + editor.addEventListener( 'selectionchange', handleSelection ); return () => { - editor.removeEventListener('selectionchange', handleSelection); + editor.removeEventListener( 'selectionchange', handleSelection ); }; - }); + } ); /** * On Selection. @@ -308,8 +309,8 @@ const SearchReplaceForBlockEditor = (): JSX.Element => { .getSelection() .toString(); - if (selectedText && !isSelectionInModal()) { - setSearchInput(selectedText); + if ( selectedText && ! isSelectionInModal() ) { + setSearchInput( selectedText ); } }; @@ -323,109 +324,109 @@ const SearchReplaceForBlockEditor = (): JSX.Element => { * @return {JSX.Element|null} Shortcut. */ const SafeShortcut = (): JSX.Element | null => - isWpVersionGreaterThanOrEqualTo('6.4.0') ? ( - + isWpVersionGreaterThanOrEqualTo( '6.4.0' ) ? ( + ) : null; return ( <> - + - - )} + ) } ); }; From 07bf1614809430966602d28f141a9bc82c80bdad Mon Sep 17 00:00:00 2001 From: badasswp Date: Wed, 22 Oct 2025 10:59:48 +0100 Subject: [PATCH 03/14] chore: add changelog entry --- CHANGELOG.md | 3 +++ readme.txt | 3 +++ 2 files changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ce7f5f..1cae360 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Changelog +## 1.7.0 +* Fix: Issue with search & replace on HTML bearing string. + ## 1.6.0 * Feat: Add search and replace functionality for __Table Block__. * Feat: Add new custom hook `search-replace-for-block-editor.handleAttributeReplacement`. diff --git a/readme.txt b/readme.txt index fff5b2e..58b2c59 100644 --- a/readme.txt +++ b/readme.txt @@ -63,6 +63,9 @@ Want to add your personal touch? All of our documentation can be found [here](ht == Changelog == += 1.7.0 = +* Fix: Issue with search & replace on HTML bearing string. + = 1.6.0 = * Feat: Add search and replace functionality for __Table Block__. * Feat: Add new custom hook `search-replace-for-block-editor.handleAttributeReplacement`. From e01e1ae3befc4906a904d506de56a2463b24f442 Mon Sep 17 00:00:00 2001 From: badasswp Date: Wed, 22 Oct 2025 11:04:16 +0100 Subject: [PATCH 04/14] chore: update changelog entries --- CHANGELOG.md | 2 +- readme.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1cae360..a77e7d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # Changelog ## 1.7.0 -* Fix: Issue with search & replace on HTML bearing string. +* Fix: Issue with rich content replacement (HTML bearing string). ## 1.6.0 * Feat: Add search and replace functionality for __Table Block__. diff --git a/readme.txt b/readme.txt index 58b2c59..4ebde4d 100644 --- a/readme.txt +++ b/readme.txt @@ -64,7 +64,7 @@ Want to add your personal touch? All of our documentation can be found [here](ht == Changelog == = 1.7.0 = -* Fix: Issue with search & replace on HTML bearing string. +* Fix: Issue with rich content replacement (HTML bearing string). = 1.6.0 = * Feat: Add search and replace functionality for __Table Block__. From 184fe800c1eb9ee5aa07ed8517b90d2b95d94894 Mon Sep 17 00:00:00 2001 From: sivard donkers Date: Thu, 23 Oct 2025 09:28:48 +0200 Subject: [PATCH 05/14] update comment for focus. --- src/core/app.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/core/app.tsx b/src/core/app.tsx index a9f5523..eca320c 100644 --- a/src/core/app.tsx +++ b/src/core/app.tsx @@ -95,7 +95,13 @@ const SearchReplaceForBlockEditor = (): JSX.Element => { }, [ searchInput, caseSensitive ] ); /** - * Focus handling + * Modal Focus. + * + * Automatically focus the user's cursor on the + * modal's first text-field input when the modal + * becomes visible. + * + * @since 1.7.0 */ useEffect( () => { if ( isModalVisible && searchFieldRef.current ) { From 99f9cf9f1c5e20c184402543f77c4aa48243b3de Mon Sep 17 00:00:00 2001 From: badasswp Date: Mon, 27 Oct 2025 16:45:14 +0100 Subject: [PATCH 06/14] refactor: use webpack generated file to load JS assets --- search-replace-for-block-editor.php | 41 ++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/search-replace-for-block-editor.php b/search-replace-for-block-editor.php index 4575535..6303a09 100644 --- a/search-replace-for-block-editor.php +++ b/search-replace-for-block-editor.php @@ -26,27 +26,20 @@ * @since 1.0.0 * @since 1.0.2 Load asset via plugin directory URL. * @since 1.2.2 Localise WP version. + * @since 1.7.0 Use webpack generated PHP asset file. * * @wp-hook 'enqueue_block_editor_assets' */ add_action( 'enqueue_block_editor_assets', function() { global $wp_version; + $assets = get_assets( plugin_dir_path( __FILE__ ) . './dist/app.asset.php' ); + wp_enqueue_script( 'search-replace-for-block-editor', trailingslashit( plugin_dir_url( __FILE__ ) ) . 'dist/app.js', - [ - 'wp-i18n', - 'wp-element', - 'wp-blocks', - 'wp-components', - 'wp-editor', - 'wp-hooks', - 'wp-compose', - 'wp-plugins', - 'wp-edit-post', - ], - '1.6.0', + $assets['dependencies'], + $assets['version'], false, ); @@ -79,3 +72,27 @@ dirname( plugin_basename( __FILE__ ) ) . '/languages' ); } ); + +/** + * Get Asset dependencies. + * + * @since 1.7.0 + * + * @param string $path Path to webpack generated PHP asset file. + * @return array + */ +function get_assets( string $path ): array { + $assets = [ + 'version' => strval( time() ), + 'dependencies' => [], + ]; + + if ( ! file_exists( $path ) ) { + return $assets; + } + + // phpcs:ignore WordPressVIPMinimum.Files.IncludingFile.UsingVariable + $assets = require_once $path; + + return $assets; +} From 10e55a0b1990806f465560976b817a9fed2ca49f Mon Sep 17 00:00:00 2001 From: badasswp Date: Mon, 27 Oct 2025 16:45:48 +0100 Subject: [PATCH 07/14] chore: use defined constant --- search-replace-for-block-editor.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/search-replace-for-block-editor.php b/search-replace-for-block-editor.php index 6303a09..30244fc 100644 --- a/search-replace-for-block-editor.php +++ b/search-replace-for-block-editor.php @@ -20,6 +20,8 @@ die; } +define( 'SRFBE', 'search-replace-for-block-editor' ); + /** * Load Search & Replace Script for Block Editor. * @@ -36,7 +38,7 @@ $assets = get_assets( plugin_dir_path( __FILE__ ) . './dist/app.asset.php' ); wp_enqueue_script( - 'search-replace-for-block-editor', + SRFBE, trailingslashit( plugin_dir_url( __FILE__ ) ) . 'dist/app.js', $assets['dependencies'], $assets['version'], @@ -44,13 +46,13 @@ ); wp_set_script_translations( - 'search-replace-for-block-editor', - 'search-replace-for-block-editor', + SRFBE, + SRFBE, plugin_dir_path( __FILE__ ) . 'languages' ); wp_localize_script( - 'search-replace-for-block-editor', + SRFBE, 'srfbe', [ 'wpVersion' => $wp_version, @@ -67,7 +69,7 @@ */ add_action( 'init', function() { load_plugin_textdomain( - 'search-replace-for-block-editor', + SRFBE, false, dirname( plugin_basename( __FILE__ ) ) . '/languages' ); From b392b2da2f5b5f6f1f023d7081178d9102a35dd9 Mon Sep 17 00:00:00 2001 From: badasswp Date: Mon, 27 Oct 2025 16:46:14 +0100 Subject: [PATCH 08/14] feat: ensure count is shown for text selection on modal open --- src/core/app.tsx | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/core/app.tsx b/src/core/app.tsx index 91ce729..1de741f 100644 --- a/src/core/app.tsx +++ b/src/core/app.tsx @@ -49,7 +49,17 @@ const SearchReplaceForBlockEditor = (): JSX.Element => { */ const openModal = (): void => { setIsModalVisible( true ); - setReplacements( 0 ); + + // Get selected text, if any. + const selectedText: string = getBlockEditorIframe() + .getSelection() + .toString(); + + // By default, reset count and search input. + if ( ! selectedText ) { + setReplacements( 0 ); + setSearchInput( '' ); + } }; /** @@ -61,7 +71,6 @@ const SearchReplaceForBlockEditor = (): JSX.Element => { */ const closeModal = (): void => { setIsModalVisible( false ); - setReplacements( 0 ); }; /** From a3292e8ef4a0f0b1fc64179de17e05f008919081 Mon Sep 17 00:00:00 2001 From: badasswp Date: Mon, 27 Oct 2025 17:06:43 +0100 Subject: [PATCH 09/14] chore: update changelog entries --- CHANGELOG.md | 1 + readme.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a77e7d9..f3fad2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## 1.7.0 * Fix: Issue with rich content replacement (HTML bearing string). +* Feat: On Modal open, show items found for Highlighted text. ## 1.6.0 * Feat: Add search and replace functionality for __Table Block__. diff --git a/readme.txt b/readme.txt index 4ebde4d..1421899 100644 --- a/readme.txt +++ b/readme.txt @@ -65,6 +65,7 @@ Want to add your personal touch? All of our documentation can be found [here](ht = 1.7.0 = * Fix: Issue with rich content replacement (HTML bearing string). +* Feat: On Modal open, show items found for Highlighted text. = 1.6.0 = * Feat: Add search and replace functionality for __Table Block__. From 4a2658695672aff02cde979b9c0d0fa94c7b5753 Mon Sep 17 00:00:00 2001 From: badasswp Date: Mon, 27 Oct 2025 17:16:54 +0100 Subject: [PATCH 10/14] chore: fix console error --- src/core/app.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/app.tsx b/src/core/app.tsx index 627f5ad..801af19 100644 --- a/src/core/app.tsx +++ b/src/core/app.tsx @@ -379,6 +379,7 @@ const SearchReplaceForBlockEditor = (): JSX.Element => { onChange={ ( value ) => setSearchInput( value ) } placeholder="Lorem ipsum..." __nextHasNoMarginBottom + __next40pxDefaultSize /> { value={ replaceInput } onChange={ ( value ) => setReplaceInput( value ) } __nextHasNoMarginBottom + __next40pxDefaultSize /> From 67aaa12893e0f89a8fe795eb23cc2be7d9d5fda2 Mon Sep 17 00:00:00 2001 From: badasswp Date: Mon, 27 Oct 2025 17:17:56 +0100 Subject: [PATCH 11/14] chore: add changelog entries --- CHANGELOG.md | 1 + readme.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f3fad2b..0c03c02 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## 1.7.0 * Fix: Issue with rich content replacement (HTML bearing string). * Feat: On Modal open, show items found for Highlighted text. +* Fix: Console warnings/errors. ## 1.6.0 * Feat: Add search and replace functionality for __Table Block__. diff --git a/readme.txt b/readme.txt index 1421899..bc5e829 100644 --- a/readme.txt +++ b/readme.txt @@ -66,6 +66,7 @@ Want to add your personal touch? All of our documentation can be found [here](ht = 1.7.0 = * Fix: Issue with rich content replacement (HTML bearing string). * Feat: On Modal open, show items found for Highlighted text. +* Fix: Console warnings/errors. = 1.6.0 = * Feat: Add search and replace functionality for __Table Block__. From f7c76699e5e460ba0b84360c8712976f8619cb68 Mon Sep 17 00:00:00 2001 From: badasswp Date: Mon, 27 Oct 2025 17:25:37 +0100 Subject: [PATCH 12/14] chore: update changelog --- CHANGELOG.md | 2 +- readme.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c03c02..9349cde 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ## 1.7.0 * Fix: Issue with rich content replacement (HTML bearing string). * Feat: On Modal open, show items found for Highlighted text. -* Fix: Console warnings/errors. +* Fix: Console warnings & errors. ## 1.6.0 * Feat: Add search and replace functionality for __Table Block__. diff --git a/readme.txt b/readme.txt index bc5e829..d242d58 100644 --- a/readme.txt +++ b/readme.txt @@ -66,7 +66,7 @@ Want to add your personal touch? All of our documentation can be found [here](ht = 1.7.0 = * Fix: Issue with rich content replacement (HTML bearing string). * Feat: On Modal open, show items found for Highlighted text. -* Fix: Console warnings/errors. +* Fix: Console warnings & errors. = 1.6.0 = * Feat: Add search and replace functionality for __Table Block__. From e0b002e50e29def58ce99842dec665866cc57765 Mon Sep 17 00:00:00 2001 From: badasswp Date: Mon, 27 Oct 2025 17:30:47 +0100 Subject: [PATCH 13/14] chore: update changelog entries --- CHANGELOG.md | 1 + readme.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9349cde..ea6ef3c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * Fix: Issue with rich content replacement (HTML bearing string). * Feat: On Modal open, show items found for Highlighted text. * Fix: Console warnings & errors. +* Tested up to WP 6.8. ## 1.6.0 * Feat: Add search and replace functionality for __Table Block__. diff --git a/readme.txt b/readme.txt index d242d58..8aa3c9b 100644 --- a/readme.txt +++ b/readme.txt @@ -67,6 +67,7 @@ Want to add your personal touch? All of our documentation can be found [here](ht * Fix: Issue with rich content replacement (HTML bearing string). * Feat: On Modal open, show items found for Highlighted text. * Fix: Console warnings & errors. +* Tested up to WP 6.8. = 1.6.0 = * Feat: Add search and replace functionality for __Table Block__. From 85d777533d2c6012ecbcee4260c5ca816aac39cf Mon Sep 17 00:00:00 2001 From: badasswp Date: Mon, 27 Oct 2025 17:31:32 +0100 Subject: [PATCH 14/14] chore: bump up plugin version --- package.json | 4 ++-- readme.txt | 2 +- search-replace-for-block-editor.php | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index b021305..39e007c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "search-and-replace", - "version": "1.6.0", + "version": "1.7.0", "description": "Search and Replace text within the Block Editor.", "author": "badasswp", "license": "GPL-2.0-or-later", @@ -70,4 +70,4 @@ "block", "editor" ] -} +} \ No newline at end of file diff --git a/readme.txt b/readme.txt index 8aa3c9b..4e8327a 100644 --- a/readme.txt +++ b/readme.txt @@ -3,7 +3,7 @@ Contributors: badasswp, rajanand346, jargovi Tags: search, replace, text, block, editor. Requires at least: 6.0 Tested up to: 6.8 -Stable tag: 1.6.0 +Stable tag: 1.7.0 Requires PHP: 7.4 License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html diff --git a/search-replace-for-block-editor.php b/search-replace-for-block-editor.php index 30244fc..2cd0563 100644 --- a/search-replace-for-block-editor.php +++ b/search-replace-for-block-editor.php @@ -3,7 +3,7 @@ * Plugin Name: Search and Replace for Block Editor * Plugin URI: https://github.com/badasswp/search-and-replace * Description: Search and Replace text within the Block Editor. - * Version: 1.6.0 + * Version: 1.7.0 * Author: badasswp * Author URI: https://github.com/badasswp * License: GPL v2 or later