From 408c665932a639a8d185c2aef3f9642217eda2f9 Mon Sep 17 00:00:00 2001 From: Kallyan Singha Date: Mon, 16 Dec 2024 02:10:47 +0530 Subject: [PATCH 1/2] Fix: Post title caret position issue --- .../editor/src/components/post-title/index.js | 80 ++++++++++++++++++- 1 file changed, 77 insertions(+), 3 deletions(-) diff --git a/packages/editor/src/components/post-title/index.js b/packages/editor/src/components/post-title/index.js index 090beb57f6170e..29daeb123aacc0 100644 --- a/packages/editor/src/components/post-title/index.js +++ b/packages/editor/src/components/post-title/index.js @@ -6,7 +6,7 @@ import clsx from 'clsx'; * WordPress dependencies */ import { __ } from '@wordpress/i18n'; -import { forwardRef, useState } from '@wordpress/element'; +import { forwardRef, useState, useEffect } from '@wordpress/element'; import { decodeEntities } from '@wordpress/html-entities'; import { useSelect, useDispatch } from '@wordpress/data'; import { store as blockEditorStore } from '@wordpress/block-editor'; @@ -44,7 +44,10 @@ const PostTitle = forwardRef( ( _, forwardedRef ) => { const { title, setTitle: onUpdate } = usePostTitle(); - const [ selection, setSelection ] = useState( {} ); + const [ history, setHistory ] = useState( [] ); + const [ currentHistoryIndex, setCurrentHistoryIndex ] = useState( -1 ); + const [ selection, setSelection ] = useState( { start: 0, end: 0 } ); + const [ editorAction, setEditorAction ] = useState( '' ); const { clearSelectedBlock, insertBlocks, insertDefaultBlock } = useDispatch( blockEditorStore ); @@ -52,6 +55,18 @@ const PostTitle = forwardRef( ( _, forwardedRef ) => { const decodedPlaceholder = decodeEntities( placeholder ) || __( 'Add title' ); + const updateHistory = ( position ) => { + const newHistory = [ ...history ]; + if ( position !== newHistory[ newHistory.length - 1 ]?.start ) { + newHistory.push( { + start: position, + end: position, + } ); + } + setHistory( newHistory ); + setCurrentHistoryIndex( newHistory.length - 1 ); + }; + const { value, onChange, @@ -60,6 +75,11 @@ const PostTitle = forwardRef( ( _, forwardedRef ) => { value: title, onChange( newValue ) { onUpdate( newValue.replace( REGEXP_NEWLINES, ' ' ) ); + + if ( editorAction !== ( 'undo' || 'redo' ) ) { + updateHistory( selection.start ); + } + updateHistory( selection.start ); }, placeholder: decodedPlaceholder, selectionStart: selection.start, @@ -79,6 +99,16 @@ const PostTitle = forwardRef( ( _, forwardedRef ) => { __unstableDisableFormats: false, } ); + useEffect( () => {}, [ history ] ); + + useEffect( () => {}, [ selection, currentHistoryIndex ] ); + + useEffect( () => { + if ( editorAction !== 'undo' && editorAction !== 'redo' ) { + updateHistory( selection.start ); + } + }, [ title ] ); + function onInsertBlockAfter( blocks ) { insertBlocks( blocks, 0 ); } @@ -90,18 +120,62 @@ const PostTitle = forwardRef( ( _, forwardedRef ) => { function onUnselect() { setIsSelected( false ); - setSelection( {} ); + setSelection( { start: 0, end: 0 } ); } function onEnterPress() { insertDefaultBlock( undefined, undefined, 0 ); } + const undo = () => { + if ( currentHistoryIndex > 0 ) { + const caretPos = history[ currentHistoryIndex - 1 ]; + + setSelection( caretPos ); + setCurrentHistoryIndex( currentHistoryIndex - 1 ); + } + }; + + const redo = () => { + if ( currentHistoryIndex < history.length - 1 ) { + const caretPos = history[ currentHistoryIndex + 1 ]; + + setSelection( caretPos ); + setCurrentHistoryIndex( currentHistoryIndex + 1 ); + } + }; + function onKeyDown( event ) { + // Detect undo (Ctrl+Z or Cmd+Z) + if ( + ( event.ctrlKey || event.metaKey ) && + ! event.shiftKey && + event.key === 'z' + ) { + event.preventDefault(); + undo(); + setEditorAction( 'undo' ); + return; // Exit to avoid triggering further conditions + } + + // Detect redo (Ctrl+Y or Cmd+Shift+Z) + if ( + ( event.ctrlKey && event.key === 'y' ) || // Windows/Linux redo + ( event.metaKey && event.shiftKey && event.key === 'z' ) // macOS redo + ) { + event.preventDefault(); + redo(); + setEditorAction( 'redo' ); + return; // Exit to avoid further processing + } + if ( event.keyCode === ENTER ) { event.preventDefault(); onEnterPress(); } + + // Set action to 'normal' for all other keys + setEditorAction( 'normal' ); } function onPaste( event ) { From 4e4d9294e2e78fc5676679851c2c3f3422ca62b4 Mon Sep 17 00:00:00 2001 From: Kallyan Singha Date: Mon, 16 Dec 2024 03:39:50 +0530 Subject: [PATCH 2/2] Chore: Removed unwanted debugging code --- packages/editor/src/components/post-title/index.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/editor/src/components/post-title/index.js b/packages/editor/src/components/post-title/index.js index 29daeb123aacc0..7b77a9daf3cb95 100644 --- a/packages/editor/src/components/post-title/index.js +++ b/packages/editor/src/components/post-title/index.js @@ -99,10 +99,6 @@ const PostTitle = forwardRef( ( _, forwardedRef ) => { __unstableDisableFormats: false, } ); - useEffect( () => {}, [ history ] ); - - useEffect( () => {}, [ selection, currentHistoryIndex ] ); - useEffect( () => { if ( editorAction !== 'undo' && editorAction !== 'redo' ) { updateHistory( selection.start );