Skip to content
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

Writing Flow: Fix vertical arrow navigation skips #7877

Merged
merged 1 commit into from
Jul 17, 2018

Conversation

aduth
Copy link
Member

@aduth aduth commented Jul 10, 2018

Fixes #7838
Fixes #6524
Salvaged from #6467

This pull request seeks to pull in improvements to the isHorizontalEdge and isVerticalEdge proposed in #6467 to resolve multiple issues around navigating multi-line content within contenteditables.

Testing instructions:

Repeat testing instructions from #7838 and #6524, observing expected results.

@aduth aduth added [Type] Bug An existing feature does not function as intended [Feature] Writing Flow Block selection, navigation, splitting, merging, deletion... labels Jul 10, 2018
@aduth aduth requested a review from ellatrix July 10, 2018 20:51
@iandunn
Copy link
Member

iandunn commented Jul 12, 2018

This tested well for me, thanks!

@aduth
Copy link
Member Author

aduth commented Jul 12, 2018

This was a bit of a challenge to author end-to-end tests for, due to some unrelated bugginess (#6524 (comment)) and the fact that the arrow skipping wasn't always predictable for me. It seems to be relatively predictable with the implemented test (a preformatted block with at least one blank line).

@aduth aduth requested a review from a team July 16, 2018 17:29
Copy link
Member

@tofumatt tofumatt left a comment

Choose a reason for hiding this comment

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

I have some thoughts about comments and API stuff, but nothing that blocks merging, so address what you think needs to be addressed but overall looks good.

I tested locally and both issues were fixed by this branch 👍

return (
// Compare whether anchor node precedes focus node.
position !== DOCUMENT_POSITION_PRECEDING &&

Copy link
Member

Choose a reason for hiding this comment

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

This empty newline strikes me as a bit odd. 🤷‍♂️

Copy link
Member Author

Choose a reason for hiding this comment

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

This empty newline strikes me as a bit odd. 🤷‍♂️

It's probably more symptomatic of it being an issue to need such descriptions in a multi-line return value, which could be achieved in a more verbose / easy-to-understand format by simply splitting out the return statements. I've done so in the rebased 52b8f97.

* Check whether the selection is horizontally at the edge of the container.
*
* @param {Element} container Focusable element.
* @param {boolean} isReverse Set to true to check left, false for right.
Copy link
Member

Choose a reason for hiding this comment

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

This seems like an odd variable name–we aren't setting if something isReverse, we're checking for it. Would we want checkForReverse or maybe to specify the direction? eg. isHorizontalEdge( container, direction='left' )? I know it's a more verbose API but it's also easier to grok. Supplying a binary to this function doesn't provide much context in isolation. (isHorizontalEdge( container, false )–what is false in that bit?)

Copy link
Member Author

Choose a reason for hiding this comment

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

I'd probably tend to agree, but it's not within scope of the pull request, and since this is a published module, such a change would qualify as breaking. Since I'm already touching the documentation, I'll at least try to make the boolean-ness more clear.

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, that's fair. I just figured I'd point it out either way. If I still feel strongly about it I'll file a code quality issue later 😉

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, it's good to point out. I think it's easy to fall into the trap of accepting "simple" values as arguments when authoring the function originally, and not considering that it would be difficult to interpret the intent of the statement isHorizontalEdge( container, false ).


return true;
// Edge reached if effective caret position is at expected extreme.
Copy link
Member

Choose a reason for hiding this comment

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

"extreme" is maybe an odd word to use here–I guess it's alright but maybe rephrasing this to something like:

// Check if the caret position is at the expected start/end position (depending on the
// value of `isReverse`). If so we consider the horizontal edge to be reached.

🤷‍♂️

* @param {boolean} isReverse Set to true to check top, false for bottom.
* @param {boolean} collapseRanges Whether or not to collapse the selection range before the check.
* @param {Element} container Focusable element.
* @param {boolean} isReverse Set to true to check top, false for bottom.
Copy link
Member

Choose a reason for hiding this comment

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

Same here, I just find this API a bit odd. If we have to do deprecations to change it we could file an issue, but I just find it hard to understand in isolation.

// `getClientRects` can be empty in some browsers. This can be resolved
// by adding a temporary text node to the range.
if ( ! rect ) {
const padNode = document.createTextNode( '\u200b' );
Copy link
Member

Choose a reason for hiding this comment

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

What is that character and why is it used? It's probably just worth documenting whether it matters for future devs.

Copy link
Member Author

Choose a reason for hiding this comment

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

Good call. I'll add some clarification with a link to the resource where I'd found the tip (StackOverflow).

@aduth aduth merged commit caaf204 into master Jul 17, 2018
@aduth aduth deleted the fix/6524-vertical-nav branch July 17, 2018 18:28
@aduth aduth added this to the 3.3 milestone Jul 17, 2018
// Check if the caret position is at the expected start/end position based
// on the value of `isReverse`. If so, consider the horizontal edge to be
// reached.
const caretOffset = range.toString().length;
Copy link
Contributor

Choose a reason for hiding this comment

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

This doesn't work properly when the paragraph block starts with <br />

Related #8388

Copy link
Member Author

Choose a reason for hiding this comment

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

Would appreciate your review at #8461

Copy link
Contributor

Choose a reason for hiding this comment

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

Cool missed that PR :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Writing Flow Block selection, navigation, splitting, merging, deletion... [Type] Bug An existing feature does not function as intended
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Up and down keys skip several lines Blocks: Arrow up from quote citation empty newline skips to quoted text
4 participants