Skip to content

Conversation

@vinguyen12
Copy link
Contributor

@vinguyen12 vinguyen12 commented Sep 17, 2025

If we let browser define selection first, the cursor will be placed in the touched position then being moved by our touch plugin handler. This would cause cursor flashing and moving.

Therefore, to avoid that issue, we have to handle the entire flow of touch selection but not rely on browser.

Changes in PR:

  • No longer using adjustWordSelection since it is relied on selection after browser moving the cursor
  • Trigger plugin event in mouseDown handler instead of mouseUp handler
  • move setTimeout to recognize double click and prevent default event behavior inside Touch Plugin -> to avoid impact other scenarios
  • double click event is triggered by touch but attached with a MouseEvent so better define it is in MouseEvent instead of PointerEvent
  • reuse getNodePositionFromEvent to get the node at x, y value provided by event
  • to find the starting and ending of word at selection, traverse to left until get to a white space, and traverse to right until get to a white space.

Previous PRs:

@vinguyen12 vinguyen12 requested a review from Copilot September 17, 2025 22:12
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR refactors the touch selection handling to eliminate cursor flashing and improve touch interaction by handling the entire touch selection flow instead of relying on the browser's default behavior.

Key changes:

  • Replace the complex repositionTouchSelection function with direct selection handling in the TouchPlugin
  • Move touch event handling from pointer up to pointer down events for immediate response
  • Replace pointerDoubleClick event with a standard doubleClick event

Reviewed Changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
packages/roosterjs-content-model-types/lib/index.ts Exports DoubleClickEvent, removes PointerDoubleClickEvent
packages/roosterjs-content-model-types/lib/event/PointerEvent.ts Adds originalEvent property, removes PointerDoubleClickEvent
packages/roosterjs-content-model-types/lib/event/PluginEventType.ts Changes from pointerDoubleClick to doubleClick
packages/roosterjs-content-model-types/lib/event/PluginEvent.ts Updates type imports to use DoubleClickEvent
packages/roosterjs-content-model-types/lib/event/MouseEvent.ts Adds DoubleClickEvent interface
packages/roosterjs-content-model-plugins/test/touch/TouchPluginTest.ts Removes outdated test file
packages/roosterjs-content-model-plugins/lib/touch/repositionTouchSelection.ts Removes complex repositioning logic
packages/roosterjs-content-model-plugins/lib/touch/TouchPlugin.ts Complete rewrite with inline selection handling
packages/roosterjs-content-model-core/lib/corePlugin/domEvent/DOMEventPlugin.ts Simplifies event handling, removes pointer timing logic
packages/roosterjs-content-model-api/lib/modelApi/selection/adjustWordSelection.ts Marks function as internal
packages/roosterjs-content-model-api/lib/index.ts Removes adjustWordSelection from public exports

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@vinguyen12 vinguyen12 requested a review from Copilot September 17, 2025 22:31
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 4 comments.


Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines 225 to 230
while (start > 0 && /\w/.test(text[start - 1])) {
start--;
}

// Move end forward to find word end
while (end < text.length && /\w/.test(text[end])) {
Copy link

Copilot AI Sep 17, 2025

Choose a reason for hiding this comment

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

The regex /\w/ only matches ASCII word characters (a-z, A-Z, 0-9, _) and doesn't handle Unicode word characters like accented letters or characters from other languages. Consider using a more comprehensive word boundary detection approach for international text support.

Suggested change
while (start > 0 && /\w/.test(text[start - 1])) {
start--;
}
// Move end forward to find word end
while (end < text.length && /\w/.test(text[end])) {
while (start > 0 && /[\p{L}\p{N}_]/u.test(text[start - 1])) {
start--;
}
// Move end forward to find word end
while (end < text.length && /[\p{L}\p{N}_]/u.test(text[end])) {

Copilot uses AI. Check for mistakes.
Comment on lines 225 to 230
while (start > 0 && /\w/.test(text[start - 1])) {
start--;
}

// Move end forward to find word end
while (end < text.length && /\w/.test(text[end])) {
Copy link

Copilot AI Sep 17, 2025

Choose a reason for hiding this comment

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

The regex /\w/ only matches ASCII word characters (a-z, A-Z, 0-9, _) and doesn't handle Unicode word characters like accented letters or characters from other languages. Consider using a more comprehensive word boundary detection approach for international text support.

Suggested change
while (start > 0 && /\w/.test(text[start - 1])) {
start--;
}
// Move end forward to find word end
while (end < text.length && /\w/.test(text[end])) {
while (
start > 0 &&
/[\p{L}\p{N}_]/u.test(text[start - 1])
) {
start--;
}
// Move end forward to find word end
while (
end < text.length &&
/[\p{L}\p{N}_]/u.test(text[end])
) {

Copilot uses AI. Check for mistakes.
@vinguyen12 vinguyen12 requested a review from Copilot September 17, 2025 22:58
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 5 comments.

Comments suppressed due to low confidence (1)

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

if (caretPosition) {
const { node, offset } = caretPosition;
const nodeTextContent = node.textContent || '';
const wordAtFocus = nodeTextContent[offset];
Copy link

Copilot AI Sep 17, 2025

Choose a reason for hiding this comment

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

Accessing nodeTextContent[offset] without bounds checking could cause runtime errors if offset is greater than or equal to the text length. Add bounds checking before accessing the character.

Suggested change
const wordAtFocus = nodeTextContent[offset];
let wordAtFocus: string | undefined = undefined;
if (
offset >= 0 &&
offset < nodeTextContent.length
) {
wordAtFocus = nodeTextContent[offset];
}

Copilot uses AI. Check for mistakes.
@microsoft microsoft deleted a comment from Copilot AI Sep 17, 2025
@microsoft microsoft deleted a comment from Copilot AI Sep 17, 2025
@microsoft microsoft deleted a comment from Copilot AI Sep 17, 2025
@vinguyen12 vinguyen12 merged commit bd21095 into master Sep 18, 2025
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants