Plugin Directory

Changeset 3496250


Ignore:
Timestamp:
04/01/2026 07:21:18 AM (17 hours ago)
Author:
kasuga16
Message:

Update 1.6.2 -> 1.6.3

Location:
livedraft-search-replace
Files:
10 added
3 edited

Legend:

Unmodified
Added
Removed
  • livedraft-search-replace/trunk/livedraft-search-replace.js

    r3495312 r3496250  
    99 * @copyright         2026 Kasuga
    1010 * @license           GPL-2.0-or-later
    11  * @version           2.1.1
     11 * @version           2.1.2
     12 *
    1213 */
    1314
     
    4344        }
    4445        return window;
     46    };
     47
     48    // Return the root writing-flow element where block content lives.
     49    // Shared by performScan, the click handler, and the autoPopulate listener.
     50    const getEditorElement = () => {
     51        const d = getEditorDocument();
     52        return (
     53            d.querySelector('.block-editor-writing-flow') ||
     54            d.querySelector('.editor-writing-flow') ||
     55            d.querySelector('.is-root-container') ||
     56            d.querySelector('.block-editor-block-list__layout') ||
     57            d.body
     58        );
    4559    };
    4660
     
    131145        }, []);
    132146
    133         // Auto-populate: update the search field when text is selected in the editor.
    134         // Listens on both the top-level doc and the iframe doc.
     147        // Auto-populate: update the search field only on drag-selection.
    135148        useEffect(() => {
    136149            if (!autoPopulate) return;
     150
     151            const editorDoc = getEditorDocument();
     152            const editorEl = getEditorElement();
     153
     154            let isDragging = false;
     155
     156            const handleMouseDown = () => {
     157                isDragging = false;
     158            };
     159
     160            const handleMouseMove = () => {
     161                isDragging = true;
     162            };
     163
     164            const handleMouseUp = () => {
     165                setTimeout(() => { isDragging = false; }, 0);
     166            };
     167
    137168            const handleSelectionChange = () => {
     169                if (!isDragging) return;
    138170                if (isInternalUpdating.current) return;
    139171                const activeEl = document.activeElement;
    140172                if (activeEl && (activeEl.tagName === 'INPUT' || activeEl.tagName === 'TEXTAREA')) return;
    141173
    142                 const selection = window.getSelection();
    143                 if (selection && selection.rangeCount > 0) {
    144                     const text = selection.toString();
    145                     if (text && text.length > 0) {
    146                         setSearch(text);
    147                         lastSearchedRef.current = text;
    148                     }
    149                 }
     174                // Read selected text; for iframe-based themes (e.g. Astra) use the iframe's window.
     175                let text = '';
    150176                try {
    151177                    const editorWin = getEditorWindow();
    152                     if (editorWin !== window) {
    153                         const iframeSel = editorWin.getSelection();
    154                         if (iframeSel && iframeSel.rangeCount > 0) {
    155                             const text = iframeSel.toString();
    156                             if (text && text.length > 0) {
    157                                 setSearch(text);
    158                                 lastSearchedRef.current = text;
    159                             }
    160                         }
    161                     }
     178                    const sel = editorWin.getSelection();
     179                    if (sel) text = sel.toString();
    162180                } catch(e) {}
    163             };
    164 
     181                if (!text) {
     182                    const sel = window.getSelection();
     183                    if (sel) text = sel.toString();
     184                }
     185
     186                if (!text) return;
     187
     188                setSearch(text);
     189                lastSearchedRef.current = text;
     190            };
     191
     192            if (editorEl) {
     193                editorEl.addEventListener('mousedown', handleMouseDown);
     194                editorEl.addEventListener('mousemove', handleMouseMove);
     195                editorEl.addEventListener('mouseup', handleMouseUp);
     196            }
    165197            document.addEventListener('selectionchange', handleSelectionChange);
    166198            try {
    167                 const editorDoc = getEditorDocument();
    168199                if (editorDoc !== document) {
    169200                    editorDoc.addEventListener('selectionchange', handleSelectionChange);
     
    172203
    173204            return () => {
     205                if (editorEl) {
     206                    editorEl.removeEventListener('mousedown', handleMouseDown);
     207                    editorEl.removeEventListener('mousemove', handleMouseMove);
     208                    editorEl.removeEventListener('mouseup', handleMouseUp);
     209                }
    174210                document.removeEventListener('selectionchange', handleSelectionChange);
    175211                try {
    176                     const editorDoc = getEditorDocument();
    177212                    if (editorDoc !== document) {
    178213                        editorDoc.removeEventListener('selectionchange', handleSelectionChange);
     
    204239                }
    205240
    206                 const editor =
    207                     editorDoc.querySelector('.block-editor-writing-flow') ||
    208                     editorDoc.querySelector('.editor-writing-flow') ||
    209                     editorDoc.querySelector('.is-root-container') ||
    210                     editorDoc.querySelector('.block-editor-block-list__layout') ||
    211                     editorDoc.body;
     241                const editor = getEditorElement();
    212242
    213243                if (!editor) { ticking.current = false; return; }
     
    363393
    364394        // Replace current or all matches. Writes to block attributes to integrate with undo/redo.
    365         //
    366         // HTML entity handling:
    367         //   Standard mode: flexible pattern matching both raw chars and entity equivalents.
    368         //   Regex mode: decode entities before matching so the regex sees plain text.
    369395        const handleReplace = useCallback((all = false, specificMatch = null) => {
    370396            if (editorMode !== 'visual' || matchesRef.current.length === 0) return;
     
    463489            } else {
    464490                performUpdate(targetMatch.clientId, targetMatch);
    465                 try {
    466                     const editorWin = getEditorWindow();
    467                     if (editorWin.getSelection) editorWin.getSelection().removeAllRanges();
    468                 } catch(e) {}
    469                 if (window.getSelection) window.getSelection().removeAllRanges();
    470491            }
    471492
    472493            setTimeout(() => {
    473                 try {
    474                     const editorWin = getEditorWindow();
    475                     if (editorWin.getSelection) editorWin.getSelection().removeAllRanges();
    476                 } catch(e) {}
    477                 if (window.getSelection) window.getSelection().removeAllRanges();
    478 
    479494                if (all) {
    480495                    setCurrent(0);
     
    506521        useEffect(() => {
    507522            const editorDoc = getEditorDocument();
    508             const editorEl =
    509                 editorDoc.querySelector('.block-editor-writing-flow') ||
    510                 editorDoc.querySelector('.editor-writing-flow') ||
    511                 editorDoc.querySelector('.is-root-container') ||
    512                 editorDoc.querySelector('.block-editor-block-list__layout');
     523            const editorEl = getEditorElement();
    513524            if (!editorEl) return;
    514 
    515             const handleMouseDown = (e) => {
    516                 if (e.detail >= 2) {
    517                     e.preventDefault();
    518                 }
    519             };
    520525
    521526            const handleEditorAction = (e) => {
     
    550555                }
    551556            };
    552 
    553             editorEl.addEventListener('mousedown', handleMouseDown);
    554557            editorEl.addEventListener('click', handleEditorAction);
    555558            return () => {
    556                 editorEl.removeEventListener('mousedown', handleMouseDown);
    557559                editorEl.removeEventListener('click', handleEditorAction);
    558560            };
     
    560562
    561563        // Re-scan on every block change (including Undo/Redo and after Replace).
    562         useEffect(() => {
     564            useEffect(() => {
    563565            if (isInternalUpdating.current) return;
    564566
  • livedraft-search-replace/trunk/livedraft-search-replace.php

    r3495312 r3496250  
    33 * Plugin Name: LiveDraft Search & Replace
    44 * Description: A high-performance, real-time Search and Replace tool for the Block Editor sidebar.
    5  * Version: 1.6.2
     5 * Version: 1.6.3
    66 * Author: Kasuga
    77 * License: GPLv2 or later
  • livedraft-search-replace/trunk/readme.txt

    r3495312 r3496250  
    66Tested up to: 6.9
    77Requires PHP: 7.4
    8 Stable tag: 1.6.2
     8Stable tag: 1.6.3
    99License: GPLv2 or later
    1010License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    101101== Changelog ==
    102102
     103= 1.6.3 =
     104* Fixed: The fix in version 1.6.2 was insufficient, so an additional fix was applied.
     105
    103106= 1.6.2 =
    104107* Fixed: Prevented double-click from triggering browser word-selection, which was causing the Auto-populate feature to overwrite the search field before replacement.
Note: See TracChangeset for help on using the changeset viewer.