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

[hint addon] Offset the hint to position it correctly when hintOptions.container is given #5857

Merged
merged 1 commit into from
Apr 25, 2019

Conversation

Nouzbe
Copy link
Contributor

@Nouzbe Nouzbe commented Apr 22, 2019

See #5854.

I tested it on the complete demo but did not commit changes to the demo file since I believe that having a container is not the most common usage. Let met know if you would prefer that this demo uses a container.

var pos = cm.cursorCoords(completion.options.alignWithWord ? data.from : null);
var left = pos.left, top = pos.bottom, below = true;
// We offset the cursor position because left and top are relative to the offsetParent's top left corner.
var left = pos.left - positionOffset.x, top = pos.bottom - positionOffset.y, below = true;
Copy link
Member

Choose a reason for hiding this comment

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

.x and .y don't exist on IE and Edge, so you'll want to use .left and .top instead.

@marijnh
Copy link
Member

marijnh commented Apr 22, 2019

Did you also test on a scrolled document? It seems that subtracting the top of document.body where nothing was subtracted before would break something.

@Nouzbe Nouzbe force-pushed the offset-hint-position branch 2 times, most recently from e7dcd58 to 9a252ab Compare April 22, 2019 18:50
@Nouzbe
Copy link
Contributor Author

Nouzbe commented Apr 22, 2019

You are right, the previous solution did not work with IE/Edge, nor on a scrolled document (whether container was given or not).

Here is a new attempt where all of this should be fixed:

  • Used .left and .top in place of .x and .y
  • Didn't change the existing behavior when hintOptions.container is undefined.
  • Used the position offset between the offsetParent and body in order to not inadvertently offset the scroll, as was previously the case.

var pos = cm.cursorCoords(completion.options.alignWithWord ? data.from : null);
var left = pos.left, top = pos.bottom, below = true;

if(container !== ownerDocument.body) {
var offsetParentPosition = container.offsetParent.getBoundingClientRect();

Choose a reason for hiding this comment

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

Hi, I tried this out locally and feel like this line should be container.getBoundingClientRect(); to get the hint to show up at the exact same position as before. I maybe wrong, but it didn't work for me as is.

Copy link
Member

Choose a reason for hiding this comment

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

I guess that depends on whether container is positioned or not—I guess we'd want the offsetParent of a child of the container.

@Nouzbe
Copy link
Contributor Author

Nouzbe commented Apr 23, 2019

As you pointed out, the previous did not work well if the container is positioned.

Here is a new attempt, that should work in this case too.

@marijnh
Copy link
Member

marijnh commented Apr 24, 2019

That should work better, but now you're introducing another layout cycle (changing the DOM first, then measuring it). I think using getComputedStyle to figure out whether the container is positioned would be a more efficient approach.

@Nouzbe Nouzbe force-pushed the offset-hint-position branch 2 times, most recently from 58fbe7c to 6c0f0cf Compare April 24, 2019 20:25
@Nouzbe
Copy link
Contributor Author

Nouzbe commented Apr 24, 2019

Here's a new possible option. It works well too as far as I tested and does not change the points at which the script interacts with the DOM.

Also, I realized that other style updates (aiming at repositioning the hint if it overflows) reassigned left and top and we need to apply the same offset there too. My bad for not seeing it earlier. Better late than never though.

var offsetLeft = 0, offsetTop = 0;
if(container !== ownerDocument.body) {
// We offset the cursor position because left and top are relative to the offsetParent's top left corner.
var offsetParent = ['absolute', 'relative', 'fixed'].includes(parentWindow.getComputedStyle(container).position) ? container : container.offsetParent;
Copy link
Member

Choose a reason for hiding this comment

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

Another nitpick: includes doesn't exist on all browsers that we support. Use indexOf instead, or a regexp.

Also, a space after if would make the code look more like the rest of the codebase.

@Nouzbe
Copy link
Contributor Author

Nouzbe commented Apr 24, 2019

Sorry about all these roundtrips, and thanks for your patience @marijnh 🙏

Here's a new one, including your last remarks.

@marijnh marijnh merged commit d76b461 into codemirror:master Apr 25, 2019
@marijnh
Copy link
Member

marijnh commented Apr 25, 2019

Thanks for bearing with me!

@codeStryke
Copy link

codeStryke commented Apr 25, 2019

@Nouzbe thanks for doing this. I was facing the same problem and now I can use this.
@marijnh thanks for the reviewing the changes. Is it released or any idea what release it will be in?

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.

3 participants