Skip to content

Note: check e.relatedTarget before setting editing: false #2894

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 17 additions & 5 deletions src/components/Note.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,11 +114,23 @@ const Note = React.memo(
)

/** Set editing to false onBlur, if keyboard is closed. */
const onBlur = useCallback(() => {
if (isTouch && !selection.isActive()) {
setTimeout(() => dispatch(editing({ value: false })))
}
}, [dispatch])
const onBlur = useCallback(
(e: React.FocusEvent) => {
if (isTouch) {
// if we know that the focus is changing to another editable or note then do not set editing to false
// (does not work when clicking a bullet as it is set to null)
const isRelatedTargetEditableOrNote =
e.relatedTarget &&
((e.relatedTarget as Element).hasAttribute?.('data-editable') ||
!!(e.relatedTarget as Element).querySelector('[aria-label="note-editable"]'))

if (!isRelatedTargetEditableOrNote) {
setTimeout(() => dispatch(editing({ value: false })))
}
}
},
[dispatch],
)

if (note === null) return null

Expand Down
20 changes: 20 additions & 0 deletions src/e2e/puppeteer/__tests__/caret.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { KnownDevices } from 'puppeteer'
import click from '../helpers/click'
import clickBullet from '../helpers/clickBullet'
import clickNote from '../helpers/clickNote'
import clickThought from '../helpers/clickThought'
import emulate from '../helpers/emulate'
import getEditingText from '../helpers/getEditingText'
import getSelection from '../helpers/getSelection'
import paste from '../helpers/paste'
import press from '../helpers/press'
import refresh from '../helpers/refresh'
import swipe from '../helpers/swipe'
import waitForEditable from '../helpers/waitForEditable'
import waitForHiddenEditable from '../helpers/waitForHiddenEditable'
import waitForSelector from '../helpers/waitForSelector'
Expand Down Expand Up @@ -272,4 +274,22 @@ describe('mobile only', () => {
const focusNode = await getSelection().focusNode
expect(focusNode).toBeUndefined()
})

describe('when caret moves from inside a note', () => {
it('cursorForward should move the cursor to the next thought', async () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test confirmed ✓

const importText = `
- a
- b
- =note
- Hello world`
await paste(importText)
await clickNote('Hello world')
await clickThought('a')

await swipe('l')

const textContext = await getSelection().focusNode?.textContent
expect(textContext).toBe('b')
})
})
})
2 changes: 1 addition & 1 deletion src/e2e/puppeteer/__tests__/commandPalette.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ it('open with gesture', async () => {
await page.emulate(KnownDevices['iPhone 15 Pro'])
await paste(importText)

await swipe('r')
await swipe('r', false)

// the command palette should open
const popupValue = await page.locator('[data-testid=popup-value]').wait()
Expand Down
24 changes: 24 additions & 0 deletions src/e2e/puppeteer/helpers/clickNote.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { page } from '../setup'

/**
* Click the note for the given note value. Waits for the note at the beginning in case it hasn't been rendered yet.
*/
const clickNote = async (value: string) => {
// use a short timeout to make time for a render and async page communication
// precede clickNote by a longer waitForEditable for steps that are known to take time, such as refreshing the page
const editableNode = await page.waitForFunction(
(value: string) => {
return Array.from(document.querySelectorAll('[aria-label=note-editable]')).find(
element => element.innerHTML === value,
)
},
{
timeout: 1000,
},
value,
)
// @ts-expect-error - https://github.com/puppeteer/puppeteer/issues/8852
await editableNode.asElement()?.click()
}

export default clickNote
30 changes: 5 additions & 25 deletions src/e2e/puppeteer/helpers/swipe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,33 +17,13 @@ const swipePoints = async (points: { x: number; y: number }[], complete: boolean

/** Swipe right. */
// TODO: Support other directions and multiple swipes.
const swipe = async (direction: 'r') => {
const swipe = async (direction: 'r' | 'l', complete: boolean = true) => {
const anchor = direction === 'l' ? 250 : 100
const delta = direction === 'l' ? -10 : 10
const y = 100
await swipePoints(
[
{ x: 100, y },
{ x: 110, y },
{ x: 120, y },
{ x: 130, y },
{ x: 140, y },
{ x: 150, y },
{ x: 160, y },
{ x: 170, y },
{ x: 180, y },
{ x: 190, y },
{ x: 200, y },
{ x: 210, y },
{ x: 220, y },
{ x: 230, y },
{ x: 240, y },
{ x: 250, y },
{ x: 260, y },
{ x: 270, y },
{ x: 280, y },
{ x: 290, y },
{ x: 300, y },
],
false,
new Array(15).fill(0).map((_, i) => ({ x: anchor + delta * i, y })),
complete,
)
}

Expand Down