diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ce7f5f..ea6ef3c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 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. +* Tested up to WP 6.8. + ## 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/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 fff5b2e..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 @@ -63,6 +63,12 @@ Want to add your personal touch? All of our documentation can be found [here](ht == Changelog == += 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. +* Tested up to WP 6.8. + = 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/search-replace-for-block-editor.php b/search-replace-for-block-editor.php index 4575535..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 @@ -20,44 +20,39 @@ die; } +define( 'SRFBE', 'search-replace-for-block-editor' ); + /** * Load Search & Replace Script for Block Editor. * * @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', + SRFBE, 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, ); 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, @@ -74,8 +69,32 @@ */ add_action( 'init', function() { load_plugin_textdomain( - 'search-replace-for-block-editor', + SRFBE, false, 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; +} diff --git a/src/core/app.tsx b/src/core/app.tsx index 91ce729..801af19 100644 --- a/src/core/app.tsx +++ b/src/core/app.tsx @@ -2,7 +2,7 @@ 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 { useState, useEffect, useRef } from '@wordpress/element'; import { Modal, TextControl, @@ -40,6 +40,9 @@ const SearchReplaceForBlockEditor = (): JSX.Element => { const [ caseSensitive, setCaseSensitive ] = useState< boolean >( false ); const [ context, setContext ] = useState< boolean >( false ); + // Reference to the first field inside the modal + const searchFieldRef = useRef< HTMLInputElement | null >( null ); + /** * Open Modal. * @@ -49,7 +52,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 +74,6 @@ const SearchReplaceForBlockEditor = (): JSX.Element => { */ const closeModal = (): void => { setIsModalVisible( false ); - setReplacements( 0 ); }; /** @@ -91,6 +103,23 @@ const SearchReplaceForBlockEditor = (): JSX.Element => { // eslint-disable-next-line react-hooks/exhaustive-deps }, [ searchInput, caseSensitive ] ); + /** + * 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 ) { + requestAnimationFrame( () => { + searchFieldRef.current?.focus(); + } ); + } + }, [ isModalVisible ] ); + /** * Handle the implementation for when the user * clicks the 'Replace' button. @@ -204,7 +233,8 @@ const SearchReplaceForBlockEditor = (): JSX.Element => { return; } - const oldAttr = attributes[ attribute ].text || attributes[ attribute ]; + const oldAttr = + attributes[ attribute ].originalHTML || attributes[ attribute ]; /** * Replace Callback. @@ -343,11 +373,13 @@ const SearchReplaceForBlockEditor = (): JSX.Element => {