Skip to content

FIX: improves text selection of posts #33143

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

Open
wants to merge 13 commits into
base: main
Choose a base branch
from

Conversation

jjaffeux
Copy link
Contributor

This commit is applying different techniques to make selecting text of a post less error prone:

  • disables text selection of all the page BUT the current post
  • ensures the selection menu is not interfering with text selection
  • ensures the d-header is not interfering with text selection

The situation was very bad on android but it should also improve other situations.

Comment on lines -137 to -152
// ensure we selected content inside 1 post *only*
let postId;
for (let r = 0; r < selection.rangeCount; r++) {
const range = selection.getRangeAt(r);
const selectionStart = getElement(range.startContainer);
const ancestor = getElement(range.commonAncestorContainer);

if (!selectionStart.closest(".cooked")) {
return await this.hideToolbar();
}

postId ||= ancestor.closest(".boxed, .reply")?.dataset?.postId;

if (!ancestor.closest(".contents") || !postId) {
return await this.hideToolbar();
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

we now receive the cooked from the onSelectionChanged event

Comment on lines -155 to -159
const _selectedElement = getElement(selectedNode());
const cooked =
_selectedElement.querySelector(".cooked") ||
_selectedElement.closest(".cooked");

Copy link
Contributor Author

Choose a reason for hiding this comment

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

cooked is received from onSelectionChange event

@@ -220,7 +232,8 @@ export default class PostTextSelection extends Component {
// so we need more space
// - the end of the selection is not in viewport, in this case our menu will be shown at the top
// of the screen, so we need more space to avoid overlapping with the native menu
offset = 70;
const { isAndroid } = this.capabilities;
offset = isAndroid ? 90 : 70;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

THe menu needs more spacing on android

Copy link
Member

Choose a reason for hiding this comment

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

Should we just increase it everywhere for consistency?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's just the native toolbar on android is bigger, but we can try the same if you think that's better

Comment on lines 283 to 284
cooked.classList.add("post-text-selection-active");
this.disableTextSelection = true;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

These lines do:

  • disable text selection for the whole page
  • force enable current text post selection

}
}

html.mobile-device {
Copy link
Member

Choose a reason for hiding this comment

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

This doesn't seem related to viewport-width, so I don't think we should be using .mobile-device here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

how do I target android?

Copy link
Member

Choose a reason for hiding this comment

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

Could we only apply the -has-post-text-selection class for affected devices?

Comment on lines 760 to 761
&:not(.ios-device) body.-disable-global-text-selection {
// prevents hovering toolbar menu to confuse text selection on android
Copy link
Member

Choose a reason for hiding this comment

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

Can we just do the same thing on iOS for consistency? Or does it cause issues there?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it does nothing on iOS I think so yes I can probably just add it too

Comment on lines 82 to 85
if (touch) {
if (isAndroid) {
// fires when user finishes adjusting text seleciton on android
// ios has no such event
Copy link
Member

Choose a reason for hiding this comment

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

Could we just add the event listeners anyway? Or do they cause issues on other devices?

(Reducing code differences between devices makes things a lot easier to test/debug IMO)

@@ -737,8 +737,32 @@ aside.quote {
opacity: 0.4;
}

.fk-d-menu[data-identifier="post-text-selection-toolbar"] {
// disabling user select on the whole page while selecting a post text
body.-disable-global-text-selection * {
Copy link
Member

Choose a reason for hiding this comment

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

This is a very expensive selector... shows up as the 4th-most-expensive in the whole of Discourse in chrome dev tools. (browsers evaluate selectors right-to-left, so this is a big cost even if -disable-global-text-selection is not set)

Not sure there's anything we can do about it... but wanted to note it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants