Skip to content
Open
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
34 changes: 34 additions & 0 deletions packages/e2e/src/find-widget-enter-focus-context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import type { Test } from '@lvce-editor/test-with-playwright'

export const name = 'find-widget-enter-focus-context'

export const test: Test = async ({ Editor, expect, FileSystem, KeyBoard, Locator, Main, Workspace }) => {
// arrange
const tmpDir = await FileSystem.getTmpDir()
await FileSystem.writeFile(
`${tmpDir}/file1.txt`,
`content 1
content 2
content 3`,
)
await Workspace.setPath(tmpDir)
await Main.openUri(`${tmpDir}/file1.txt`)
await Editor.setSelections(new Uint32Array([0, 0, 0, 7]))
await Editor.openFind()

const findWidgetInput = Locator('.FindWidget .MultilineInputBox')
const findWidgetMatchCount = Locator(`.FindWidgetMatchCount`)
await expect(findWidgetInput).toBeFocused()
await expect(findWidgetInput).toHaveValue('content')
await expect(findWidgetMatchCount).toHaveText('1 of 3')

// act
await KeyBoard.press('Enter')

// assert
await expect(findWidgetInput).toBeFocused()
await expect(findWidgetMatchCount).toHaveText('2 of 3')
await Editor.shouldHaveText(`content 1
content 2
content 3`)
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,35 @@ const commandsToForward = [
'Viewlet.focusSelector',
]

// The find-widget worker emits onFocus: 9, but older bundles omit the matching listener registration.
const FindWidgetHandleFocus = 9

const findWidgetFocusListener = {
name: FindWidgetHandleFocus,
params: ['executeWidgetCommand', 'FindWidget', 'FindWidget.handleFocus', 0, WidgetId.Find],
}

const withFindWidgetFocusListener = (command: readonly any[]): readonly any[] => {
if (command[0] !== RenderMethod.RegisterEventListeners) {
return command
}
const eventListeners = command[2]
if (!Array.isArray(eventListeners) || eventListeners.some((listener) => listener.name === FindWidgetHandleFocus)) {
return command
}
return [command[0], command[1], [...eventListeners, findWidgetFocusListener]]
}

export const render = (widget: IFindWidget) => {
const commands: readonly any[] = FindWidgetRender.renderFull(widget.oldState, widget.newState)
const wrappedCommands = []
const { uid } = widget.newState
for (const command of commands) {
if (commandsToForward.includes(command[0])) {
wrappedCommands.push(command)
const normalizedCommand = withFindWidgetFocusListener(command)
if (commandsToForward.includes(normalizedCommand[0])) {
wrappedCommands.push(normalizedCommand)
} else {
wrappedCommands.push(['Viewlet.send', uid, ...command])
wrappedCommands.push(['Viewlet.send', uid, ...normalizedCommand])
}
}
return wrappedCommands
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ViewletCommand, WhenExpression } from '@lvce-editor/constants'
import { ViewletCommand } from '@lvce-editor/constants'
import type { EditorState } from '../State/State.ts'

export const renderFocusContext = (oldState: EditorState, newState: EditorState): readonly any[] => {
return [ViewletCommand.SetFocusContext, newState.uid, WhenExpression.FocusEditorText]
return [ViewletCommand.SetFocusContext, newState.uid, newState.focus, 0, newState.uid, 'Editor']
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import type { EditorState } from '../State/State.ts'
import * as RenderWidget from '../RenderWidget/RenderWidget.ts'

const normalizeWidgetCommand = (command: readonly any[], editorUid: number): readonly any[] => {
if (command[0] === 'Viewlet.setFocusContext' && command.length === 2) {
return [command[0], editorUid, command[1], 0, editorUid, 'Editor']
}
return command
}

export const renderWidgets = (oldState: EditorState, newState: EditorState): readonly any[] => {
const addedWidgets = []
const changedWidgets = []
Expand Down Expand Up @@ -51,5 +58,5 @@ export const renderWidgets = (oldState: EditorState, newState: EditorState): rea
}
}
const allCommands = [...addCommands, ...changeCommands, ...removeCommands]
return allCommands.filter((item) => item[0] !== 'Viewlet.setFocusContext')
return allCommands.map((command) => normalizeWidgetCommand(command, newState.uid))
}
63 changes: 63 additions & 0 deletions packages/editor-worker/test/EditorFindWidget.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { expect, test } from '@jest/globals'
import { WidgetId } from '@lvce-editor/constants'
import * as EditorFindWidget from '../src/parts/EditorFindWidget/EditorFindWidget.ts'

const FindWidgetHandleFocus = 9

test('render adds missing find widget focus listener', () => {
const widget: any = {
newState: {
commands: [
[
'Viewlet.registerEventListeners',
100,
[
{
name: 12,
params: ['executeWidgetCommand', 'FindWidget', 'FindWidget.handleInput', 0, WidgetId.Find, 'event.target.value'],
},
],
],
],
uid: 100,
},
oldState: {
commands: [],
},
}

expect(EditorFindWidget.render(widget)).toEqual([
[
'Viewlet.registerEventListeners',
100,
[
{
name: 12,
params: ['executeWidgetCommand', 'FindWidget', 'FindWidget.handleInput', 0, WidgetId.Find, 'event.target.value'],
},
{
name: FindWidgetHandleFocus,
params: ['executeWidgetCommand', 'FindWidget', 'FindWidget.handleFocus', 0, WidgetId.Find],
},
],
],
])
})

test('render does not duplicate find widget focus listener', () => {
const focusListener = {
name: FindWidgetHandleFocus,
params: ['executeWidgetCommand', 'FindWidget', 'FindWidget.handleFocus', 0, WidgetId.Find],
}
const widget: any = {
newState: {
commands: [['Viewlet.registerEventListeners', 100, [focusListener]]],
uid: 100,
},
oldState: {
commands: [],
},
}

expect(EditorFindWidget.render(widget)).toEqual([['Viewlet.registerEventListeners', 100, [focusListener]]])
})
23 changes: 23 additions & 0 deletions packages/editor-worker/test/RenderFocusContext.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { expect, test } from '@jest/globals'
import { ViewletCommand, WhenExpression } from '@lvce-editor/constants'
import * as RenderFocusContext from '../src/parts/RenderFocusContext/RenderFocusContext.ts'

test('renderFocusContext uses the new editor focus context', () => {
const oldState: any = {
focus: WhenExpression.FocusEditorText,
uid: 1,
}
const newState: any = {
focus: WhenExpression.FocusFindWidget,
uid: 1,
}

expect(RenderFocusContext.renderFocusContext(oldState, newState)).toEqual([
ViewletCommand.SetFocusContext,
1,
WhenExpression.FocusFindWidget,
0,
1,
'Editor',
])
})
9 changes: 7 additions & 2 deletions packages/editor-worker/test/RenderWidgets.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ test('renderWidgets renders added, changed, and removed widgets', () => {
])
})

test('renderWidgets filters focus context commands', () => {
test('renderWidgets preserves focus context commands', () => {
const widgetId = 804
WidgetRegistry.set(widgetId, {
add: () => [
Expand All @@ -68,9 +68,11 @@ test('renderWidgets filters focus context commands', () => {
],
})
const oldState: any = {
uid: 1,
widgets: [],
}
const newState: any = {
uid: 1,
widgets: [
{
id: widgetId,
Expand All @@ -81,5 +83,8 @@ test('renderWidgets filters focus context commands', () => {
],
}

expect(RenderWidgets.renderWidgets(oldState, newState)).toEqual([['add-widget', 1]])
expect(RenderWidgets.renderWidgets(oldState, newState)).toEqual([
['Viewlet.setFocusContext', 1, 1, 0, 1, 'Editor'],
['add-widget', 1],
])
})
Loading