Skip to content

Commit b1af472

Browse files
authored
Merge pull request #29 from badasswp/release-1.2.2
Release 1.2.2
2 parents 31c7c4c + 56540c0 commit b1af472

File tree

12 files changed

+186
-51
lines changed

12 files changed

+186
-51
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# Changelog
22

3+
## 1.2.2
4+
* Fix style issues for WP 6.6.2.
5+
* Fix timeout issues causing Icon not to load.
6+
* Fix backward compatibility issues due to WP upgrade.
7+
* Apply coding standards.
8+
* Update README notes.
9+
* Tested up to WP 6.7.1.
10+
311
## 1.2.1
412
* Fix in modal selection issue.
513
* Fix missing tooltip component.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "search-and-replace",
3-
"version": "1.2.1",
3+
"version": "1.2.2",
44
"description": "Search and Replace text within the Block Editor.",
55
"author": "badasswp",
66
"license": "GPL-2.0-or-later",

readme.txt

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Contributors: badasswp, anandraj
33
Tags: search, replace, text, block, editor.
44
Requires at least: 6.0
55
Tested up to: 6.7.1
6-
Stable tag: 1.2.1
6+
Stable tag: 1.2.2
77
Requires PHP: 7.4
88
License: GPLv2 or later
99
License URI: http://www.gnu.org/licenses/gpl-2.0.html
@@ -24,6 +24,17 @@ This plugin brings the familiar Search and Replace functionality that PC users h
2424

2525
Now you can easily search and replace text right in the Block Editor. Its easy and does exactly what it says. You can also match the text case using the 'Match Case | Expression' toggle.
2626

27+
= ✔️ Features =
28+
29+
Our plugin comes with everything you need to find and replace text quicker and more efficiently.
30+
31+
✔️ <strong>Search & Replace</strong> text, typos, keywords faster.
32+
✔️ <strong>Shortcut Keys</strong> - CMD + SHIFT + F.
33+
✔️ <strong>Match Case</strong> Sensitivity.
34+
✔️ <strong>Custom Hooks</strong> to help you customize plugin behaviour.
35+
✔️ Available in <strong>mutiple langauges</strong> such as Arabic, Chinese, Hebrew, Hindi, Russian, German, Italian, Croatian, Spanish & French languages.
36+
✔️ <strong>Backward compatible</strong>, works with most WP versions.
37+
2738
= ✨ Getting Started =
2839

2940
Create a new Post or open an existing Post. Locate the 'Search and Replace' icon at the <strong>top left</strong> corner of the Block Editor and click on it. Proceed to type in the text you wish to replace and click on 'Replace'.
@@ -50,6 +61,14 @@ Want to add your personal touch? All of our documentation can be found [here](ht
5061

5162
== Changelog ==
5263

64+
= 1.2.2 =
65+
* Fix style issues for WP 6.6.2.
66+
* Fix timeout issues causing Icon not to load.
67+
* Fix backward compatibility issues due to WP upgrade.
68+
* Apply coding standards.
69+
* Update README notes.
70+
* Tested up to WP 6.7.1.
71+
5372
= 1.2.1 =
5473
* Fix in modal selection issue.
5574
* Fix missing tooltip component.

search-replace-for-block-editor.php

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Plugin Name: Search and Replace for Block Editor
44
* Plugin URI: https://github.com/badasswp/search-and-replace
55
* Description: Search and Replace text within the Block Editor.
6-
* Version: 1.2.1
6+
* Version: 1.2.2
77
* Author: badasswp
88
* Author URI: https://github.com/badasswp
99
* License: GPL v2 or later
@@ -25,10 +25,13 @@
2525
*
2626
* @since 1.0.0
2727
* @since 1.0.2 Load asset via plugin directory URL.
28+
* @since 1.2.2 Localise WP version.
2829
*
2930
* @wp-hook 'enqueue_block_editor_assets'
3031
*/
3132
add_action( 'enqueue_block_editor_assets', function() {
33+
global $wp_version;
34+
3235
wp_enqueue_script(
3336
'search-replace-for-block-editor',
3437
trailingslashit( plugin_dir_url( __FILE__ ) ) . 'dist/app.js',
@@ -44,7 +47,7 @@
4447
'wp-edit-post',
4548
'wp-edit-site',
4649
],
47-
'1.2.1',
50+
'1.2.2',
4851
false,
4952
);
5053

@@ -53,6 +56,14 @@
5356
'search-replace-for-block-editor',
5457
plugin_dir_path( __FILE__ ) . 'languages'
5558
);
59+
60+
wp_localize_script(
61+
'search-replace-for-block-editor',
62+
'srfbe',
63+
[
64+
'wpVersion' => $wp_version,
65+
]
66+
);
5667
} );
5768

5869
/**

src/app.tsx renamed to src/core/app.tsx

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { dispatch, select } from '@wordpress/data';
44
import { useState, useEffect } from '@wordpress/element';
55
import { Modal, TextControl, ToggleControl, Button, Tooltip } from '@wordpress/components';
66

7-
import './styles/app.scss';
7+
import '../styles/app.scss';
88

99
import { getAllowedBlocks, getBlockEditorIframe, isCaseSensitive, inContainer } from './utils';
1010
import { Shortcut } from './shortcut';
@@ -19,7 +19,7 @@ import { Shortcut } from './shortcut';
1919
*
2020
* @returns {JSX.Element}
2121
*/
22-
const SearchReplaceForBlockEditor = () => {
22+
const SearchReplaceForBlockEditor = (): JSX.Element => {
2323
const [replacements, setReplacements] = useState(0);
2424
const [isModalVisible, setIsModalVisible] = useState(false);
2525
const [searchInput, setSearchInput] = useState('');
@@ -60,9 +60,9 @@ const SearchReplaceForBlockEditor = () => {
6060
*
6161
* @returns {void}
6262
*/
63-
const handleSelection = () => {
64-
const selectedText = getBlockEditorIframe().getSelection().toString();
65-
const modalSelector = '.search-replace-modal';
63+
const handleSelection = (): void => {
64+
const selectedText: string = getBlockEditorIframe().getSelection().toString();
65+
const modalSelector: string = '.search-replace-modal';
6666

6767
if (selectedText && !inContainer(modalSelector)) {
6868
setSearchInput(selectedText);
@@ -77,6 +77,7 @@ const SearchReplaceForBlockEditor = () => {
7777
* @since 1.1.0
7878
*
7979
* @param {boolean} newValue
80+
* @returns {void}
8081
*/
8182
const handleCaseSensitive = (newValue: boolean): void => {
8283
setCaseSensitive( newValue );
@@ -97,7 +98,7 @@ const SearchReplaceForBlockEditor = () => {
9798
return;
9899
}
99100

100-
const pattern = new RegExp(
101+
const pattern: RegExp = new RegExp(
101102
`(?<!<[^>]*)${searchInput}(?<![^>]*<)`,
102103
isCaseSensitive() || caseSensitive ? 'g' : 'gi'
103104
);
@@ -116,12 +117,12 @@ const SearchReplaceForBlockEditor = () => {
116117
* @since 1.0.1 Handle edge-cases for quote, pullquote & details block.
117118
*
118119
* @param {Object} element Gutenberg editor block.
119-
* @param {string} pattern Search pattern.
120+
* @param {RegExp} pattern Search pattern.
120121
* @param {string} text Replace pattern.
121122
*
122123
* @returns {void}
123124
*/
124-
const recursivelyReplace = (element, pattern, text) => {
125+
const recursivelyReplace = (element, pattern, text): void => {
125126
if (getAllowedBlocks().indexOf(element.name) !== -1) {
126127
const args = { element, pattern, text };
127128

@@ -160,7 +161,7 @@ const SearchReplaceForBlockEditor = () => {
160161
*
161162
* @returns {void}
162163
*/
163-
const replaceBlockAttribute = (args, attribute) => {
164+
const replaceBlockAttribute = (args, attribute): void => {
164165
const { attributes, clientId } = args.element;
165166

166167
if (undefined === attributes || undefined === attributes[attribute]) {

src/shortcut.tsx renamed to src/core/shortcut.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { useDispatch } from '@wordpress/data';
22
import { useCallback } from '@wordpress/element';
33
import { useShortcut } from '@wordpress/keyboard-shortcuts';
44

5-
import { getShortcut } from './utils';
5+
import { getShortcut, isWpVersion } from './utils';
66

77
/**
88
* Shortcut for Block Editor.
@@ -17,7 +17,11 @@ import { getShortcut } from './utils';
1717
*
1818
* @returns {JSX.Element|null}
1919
*/
20-
export const Shortcut = ({ onKeyDown }) => {
20+
export const Shortcut = ({ onKeyDown }): JSX.Element | null => {
21+
if (!isWpVersion('6.4.0')) {
22+
return null;
23+
}
24+
2125
const dispatch = useDispatch();
2226

2327
dispatch( 'core/keyboard-shortcuts' ).registerShortcut( {

src/utils.tsx renamed to src/core/utils.tsx

Lines changed: 58 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -114,23 +114,27 @@ export const isCaseSensitive = (): boolean => {
114114
*
115115
* @since 1.2.0
116116
*
117-
* @returns Promise<HTMLElement>
117+
* @returns Promise<HTMLElement | Error>
118118
*/
119-
export const getEditorRoot = () => {
120-
let elapsedTime = 0;
121-
const interval = 100;
119+
export const getEditorRoot = (): Promise<HTMLElement | Error> => {
120+
let elapsedTime: number = 0;
121+
const interval: number = 100;
122+
123+
const selector: string = isWpVersion('6.6.0')
124+
? '.editor-header__toolbar'
125+
: '.edit-post-header__toolbar';
122126

123127
return new Promise((resolve, reject) => {
124128
const intervalId = setInterval(() => {
125129
elapsedTime += interval;
126-
const root = document.getElementById('editor').querySelector('.editor-header__toolbar');
130+
const root = document.querySelector(selector) as HTMLElement | null;
127131

128132
if (root) {
129133
clearInterval(intervalId);
130134
resolve(root);
131135
}
132136

133-
if (elapsedTime > (10 * interval)) {
137+
if (elapsedTime > (600 * interval)) {
134138
clearInterval(intervalId);
135139
reject(new Error('Unable to get Editor root container...'));
136140
}
@@ -149,8 +153,8 @@ export const getEditorRoot = () => {
149153
* @param {HTMLElement} parent - The Parent DOM element.
150154
* @returns {HTMLDivElement}
151155
*/
152-
export const getAppRoot = (parent) => {
153-
const container = document.createElement('div');
156+
export const getAppRoot = (parent: HTMLElement): HTMLDivElement => {
157+
const container: HTMLDivElement = document.createElement('div');
154158
container.id = 'search-replace';
155159
parent.appendChild(container);
156160

@@ -167,7 +171,7 @@ export const getAppRoot = (parent) => {
167171
*
168172
* @returns {Document}
169173
*/
170-
export const getBlockEditorIframe = () => {
174+
export const getBlockEditorIframe = (): Document => {
171175
const editor = document.querySelector('iframe[name="editor-canvas"]');
172176

173177
return editor && editor instanceof HTMLIFrameElement
@@ -182,18 +186,57 @@ export const getBlockEditorIframe = () => {
182186
* @since 1.2.1
183187
*
184188
* @param {string} selector Target selector.
185-
*
186189
* @returns {boolean}
187190
*/
188-
export const inContainer = (selector) => {
189-
const selection = window.getSelection();
190-
const targetDiv = document.querySelector(selector);
191+
export const inContainer = (selector: string): boolean => {
192+
const selection = window.getSelection() as Selection | null;
193+
const targetDiv = document.querySelector(selector) as HTMLElement | null;
191194

192-
if (!selection.rangeCount || !targetDiv) {
195+
if (!selection?.rangeCount || !targetDiv) {
193196
return false;
194197
}
195198

196-
const range = selection.getRangeAt(0);
199+
const range: Range = selection.getRangeAt(0);
197200

198201
return targetDiv.contains(range.startContainer) && targetDiv.contains(range.endContainer);
199202
}
203+
204+
/**
205+
* Check if it's up to WP version.
206+
*
207+
* @since 1.2.2
208+
*
209+
* @param {string} version WP Version.
210+
* @returns {boolean}
211+
*/
212+
export const isWpVersion = (version: string) => {
213+
const { wpVersion } = srfbe as { wpVersion: string };
214+
215+
const argVersion: number = getNumberToBase10(
216+
version.split('.').map(Number)
217+
);
218+
219+
const sysVersion: number = getNumberToBase10(
220+
wpVersion.split('.').map(Number)
221+
);
222+
223+
return ! (sysVersion < argVersion);
224+
}
225+
226+
/**
227+
* Given an array of numbers, get the Radix
228+
* (converted to base 10). For e.g. [5, 6, 1] becomes
229+
* 561 or [2, 7, 4] becomes 274.
230+
*
231+
* @since 1.2.2
232+
*
233+
* @param {number[]} values Array of positive numbers.
234+
* @returns {number}
235+
*/
236+
export const getNumberToBase10 = (values: number[]): number => {
237+
const radix: number = values.reduce((sum: number, value: number, index: number) => {
238+
return sum + (value * Math.pow(10, ((values.length - 1) - index)));
239+
}, 0);
240+
241+
return radix;
242+
}

src/index.tsx

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
1+
import ReactDOM from 'react-dom';
12
import { createRoot } from 'react-dom/client';
23

3-
import SearchReplaceForBlockEditor from './app';
4-
import { getAppRoot, getEditorRoot } from './utils'
4+
import SearchReplaceForBlockEditor from './core/app';
5+
import { getAppRoot, getEditorRoot, isWpVersion } from './core/utils'
56

67
(async () => {
78
try {
8-
const container = await getEditorRoot();
9-
const app = getAppRoot(container);
10-
createRoot(app).render(<SearchReplaceForBlockEditor />);
9+
const app = getAppRoot(await getEditorRoot() as HTMLElement);
10+
if (!isWpVersion('6.2.0')) {
11+
ReactDOM.render(<SearchReplaceForBlockEditor />, app);
12+
} else {
13+
createRoot(app).render(<SearchReplaceForBlockEditor />);
14+
}
1115
} catch (e) {
1216
console.error(e);
1317
}

0 commit comments

Comments
 (0)