From 48f604678fdcc348ae1c95ab34936b6a95bd3f96 Mon Sep 17 00:00:00 2001 From: badasswp Date: Mon, 9 Jun 2025 22:55:38 +0100 Subject: [PATCH 1/6] feat: add search & replace ft. for table block --- src/core/app.tsx | 54 +++++++++++++++++++++++++++++++++----------- src/core/filters.tsx | 53 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 92 insertions(+), 15 deletions(-) diff --git a/src/core/app.tsx b/src/core/app.tsx index c0c9995..950982c 100644 --- a/src/core/app.tsx +++ b/src/core/app.tsx @@ -1,6 +1,6 @@ import { __ } from '@wordpress/i18n'; import { search } from '@wordpress/icons'; -import { doAction } from '@wordpress/hooks'; +import { applyFilters, doAction } from '@wordpress/hooks'; import { dispatch, select } from '@wordpress/data'; import { useState, useEffect } from '@wordpress/element'; import { @@ -190,10 +190,13 @@ const SearchReplaceForBlockEditor = (): JSX.Element => { */ const replaceBlockAttribute = ( args: any, attribute: string ): void => { const property = {}; - const { pattern, text, element, status } = args; - const { attributes, clientId } = element; + const { + pattern, + text, + element: { attributes, clientId, name }, + status, + } = args; - // Bail out, if attribute is not defined. if ( undefined === attributes || undefined === attributes[ attribute ] @@ -201,22 +204,47 @@ const SearchReplaceForBlockEditor = (): JSX.Element => { return; } - // Get and replace matched strings. - const oldString: string = - attributes[ attribute ].text || attributes[ attribute ]; + const oldAttr = attributes[ attribute ].text || attributes[ attribute ]; - const newString: string = oldString.replace( pattern, () => { - setReplacements( ( items ) => items + 1 ); + /** + * Replace Callback. + * + * @return {string} Replacement Text. + */ + const handleAttributeReplacement = (): string => { + setReplacements( ( items: number ) => items + 1 ); return text; - } ); + }; + + /** + * Filter the way we handle the attribute replacement + * to cater for special types of blocks. + * + * @since 1.6.0 + * + * @param {any} oldAttr Old Attribute. + * @param {string} name Block Name. + * @param {RegExp} pattern Search pattern. + * @param {Function} handleAttributeReplacement Handle Attribute Replacement. + * + * @return {Object} + */ + const { newAttr, isChanged } = applyFilters( + 'search-replace-for-block-editor.handleAttributeReplacement', + oldAttr, + { + name, + pattern, + handleAttributeReplacement, + } + ) as { newAttr: any; isChanged: boolean }; - // Bail out, if no change. - if ( newString === oldString ) { + if ( ! isChanged ) { return; } // Set the property attribute. - property[ attribute ] = newString; + property[ attribute ] = newAttr; // Update block property or content (if replace). if ( status ) { diff --git a/src/core/filters.tsx b/src/core/filters.tsx index 2fa095e..cfe03f9 100644 --- a/src/core/filters.tsx +++ b/src/core/filters.tsx @@ -1,4 +1,4 @@ -import { addAction } from '@wordpress/hooks'; +import { addAction, addFilter } from '@wordpress/hooks'; /** * Replace Block Attribute. @@ -16,7 +16,7 @@ import { addAction } from '@wordpress/hooks'; */ addAction( 'search-replace-for-block-editor.replaceBlockAttribute', - 'yourBlock', + 'srfbe', ( replaceBlockAttribute, name, args ) => { switch ( name ) { case 'core/quote': @@ -32,9 +32,58 @@ addAction( replaceBlockAttribute( args, 'summary' ); break; + case 'core/table': + replaceBlockAttribute( args, 'body' ); + break; + default: replaceBlockAttribute( args, 'content' ); break; } } ); + +/** + * Filter the way we handle the attribute replacement + * to cater for special types of blocks. + * + * @since 1.6.0 + * + * @param {any} oldAttr Old Attribute. + * @param {string} name Block Name. + * @param {RegExp} pattern Search pattern. + * @param {Function} handleAttributeReplacement Handle Attribute Replacement. + * + * @return {Object} + */ +addFilter( + 'search-replace-for-block-editor.handleAttributeReplacement', + 'srfbe', + ( oldAttr, args ) => { + const { name, pattern, handleAttributeReplacement } = args; + + switch ( name ) { + case 'core/table': + const tableString: string = JSON.stringify( oldAttr ).replace( + pattern, + handleAttributeReplacement + ); + + return { + newAttr: JSON.parse( tableString ), + isChanged: tableString !== JSON.stringify( oldAttr ), + }; + + default: + const defaultString: string = oldAttr.replace( + pattern, + handleAttributeReplacement + ); + + return { + newAttr: defaultString, + isChanged: defaultString !== oldAttr, + }; + } + } +); From 9c440555cc9a54356fc232608d503538a2257525 Mon Sep 17 00:00:00 2001 From: badasswp Date: Mon, 9 Jun 2025 23:09:11 +0100 Subject: [PATCH 2/6] chore: update README notes --- README.md | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/README.md b/README.md index e32c4c5..29e71c6 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,47 @@ addAction( - args _`{Object}`_ By default, this is an object containing the `element`, `pattern`, `text` and `status`.
+#### `search-replace-for-block-editor.handleAttributeReplacement` + +This custom hook (filter) provides a way to modify how the search and replace functionality works for custom attributes for e.g. non-text attributes or objects. + +```js +import { addFilter } from '@wordpress/hooks'; + +addFilter( + 'search-replace-for-block-editor.handleAttributeReplacement', + 'yourNamespace', + ( oldAttr, args ) => { + const { name, pattern, handleAttributeReplacement } = args; + + if ( 'your-custom-block' === name ) { + const newAttr = oldAttr.replace( + pattern, + handleAttributeReplacement + ); + + return { + newAttr, + isChanged: oldAttr === newAttr, + }; + } + + return { + newAttr: oldAttr, + isChanged: false, + }; + } +); +``` + +**Parameters** + +- oldAttr _`{any}`_ Old Attribute. +- name _`{string}`_ Name of Block. +- pattern _`{RegExp}`_ Regular Expression pattern. +- handleAttributeReplacement _`{Function}`_ Replace Callback. +
+ #### `search-replace-for-block-editor.keyboardShortcut` This custom hook (filter) provides a way for users to specify their preferred keyboard shortcut option. For e.g to use the 'K' option on your keyboard, you could do like so: From 944bb9779e6328769955c9c5adc4d842fa91b1a1 Mon Sep 17 00:00:00 2001 From: badasswp Date: Mon, 9 Jun 2025 23:12:28 +0100 Subject: [PATCH 3/6] chore: enforce types --- src/core/app.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/core/app.tsx b/src/core/app.tsx index 950982c..91ce729 100644 --- a/src/core/app.tsx +++ b/src/core/app.tsx @@ -33,12 +33,12 @@ 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 ); /** * Open Modal. From 6daed4412b807ba46e07fbe5ac576d9ad8693e00 Mon Sep 17 00:00:00 2001 From: badasswp Date: Mon, 9 Jun 2025 23:14:06 +0100 Subject: [PATCH 4/6] docs: update change log entry --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 22a7f19..1ce7f5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 1.6.0 +* Feat: Add search and replace functionality for __Table Block__. +* Feat: Add new custom hook `search-replace-for-block-editor.handleAttributeReplacement`. +* Docs: Update README docs. +* Tested up to WP 6.8. + ## 1.5.0 * Fix: Missing icon due to recent WP 6.8 upgrade. * Feat: Add local WP dev env. From d2ac1392fae1f5febdc59bcb2b393cfd47cf25d9 Mon Sep 17 00:00:00 2001 From: badasswp Date: Mon, 9 Jun 2025 23:36:07 +0100 Subject: [PATCH 5/6] chore: update README notes --- readme.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/readme.txt b/readme.txt index c9f7f78..bed9a8d 100644 --- a/readme.txt +++ b/readme.txt @@ -63,6 +63,12 @@ Want to add your personal touch? All of our documentation can be found [here](ht == Changelog == += 1.6.0 = +* Feat: Add search and replace functionality for __Table Block__. +* Feat: Add new custom hook `search-replace-for-block-editor.handleAttributeReplacement`. +* Docs: Update README docs. +* Tested up to WP 6.8. + = 1.5.0 = * Fix: Missing icon due to recent WP 6.8 upgrade. * Feat: Add local WP dev env. From 8652e9db0c03114dad2112d81f06061e04c4f283 Mon Sep 17 00:00:00 2001 From: badasswp Date: Mon, 9 Jun 2025 23:37:24 +0100 Subject: [PATCH 6/6] chore: bump up plugin version --- package.json | 2 +- readme.txt | 4 ++-- search-replace-for-block-editor.php | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 82176fc..b021305 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "search-and-replace", - "version": "1.5.0", + "version": "1.6.0", "description": "Search and Replace text within the Block Editor.", "author": "badasswp", "license": "GPL-2.0-or-later", diff --git a/readme.txt b/readme.txt index bed9a8d..fff5b2e 100644 --- a/readme.txt +++ b/readme.txt @@ -2,8 +2,8 @@ Contributors: badasswp, rajanand346, jargovi Tags: search, replace, text, block, editor. Requires at least: 6.0 -Tested up to: 6.7.2 -Stable tag: 1.5.0 +Tested up to: 6.8 +Stable tag: 1.6.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 c3d350a..4575535 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.5.0 + * Version: 1.6.0 * Author: badasswp * Author URI: https://github.com/badasswp * License: GPL v2 or later @@ -46,7 +46,7 @@ 'wp-plugins', 'wp-edit-post', ], - '1.4.0', + '1.6.0', false, );