8000 feat(docs-infra): saves the scroll position before the change of loca… by wKoza · Pull Request #28037 · angular/angular · GitHub
[go: up one dir, main page]

Skip to content

feat(docs-infra): saves the scroll position before the change of loca… #28037

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

Closed

Conversation

wKoza
Copy link
Contributor
@wKoza wKoza commented Jan 10, 2019

…tion or after a reload

closes #27916

PR Checklist

Please check if your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • angular.io application / infrastructure changes
  • Other... Please describe:

What is the current behavior?

Issue Number: N/A

What is the new behavior?

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

@wKoza wKoza requested a review from a team as a code owner January 10, 2019 07:30
@petebacondarwin petebacondarwin added this to the docs-infra-aio-app milestone Jan 10, 2019
@ngbot ngbot bot removed this from the docs-infra-aio-app milestone Jan 10, 2019
@petebacondarwin
Copy link
Contributor

Fixes #17308

@petebacondarwin petebacondarwin added this to the docs-infra-aio-app milestone Jan 10, 2019
@ngbot ngbot bot removed this from the docs-infra-aio-app milestone Jan 10, 2019
@googlebot
Copy link

We found a Contributor License Agreement for you (the sender of this pull request), but were unable to find agreements for all the commit author(s) or Co-authors. If you authored these, maybe you used a different email address in the git commits than was used to sign the CLA (login here to double check)? If these were authored by someone else, then they will need to sign a CLA as well, and confirm that they're okay with these being contributed to Google.
In order to pass this check, please resolve this problem and have the pull request author add another comment and the bot will run again. If the bot doesn't comment, it means it doesn't think anything has changed.

@wKoza
Copy link
Contributor Author
wKoza commented Jan 10, 2019

Hi @petebacondarwin ,
What do you think about this kind of implementation / behavior ? I'm agree with @IgorMinar, use history API is more usual but It's currently more tricky because of the current mechanical of displaying.

@mary-poppins
Copy link

You can preview 4ecf896 at https://pr28037-4ecf896.ngbuilds.io/.
You can preview 9ac71d8 at https://pr28037-9ac71d8.ngbuilds.io/.

@petebacondarwin petebacondarwin added this to the docs-infra-aio-app milestone Jan 10, 2019
@ngbot ngbot bot removed this from the docs-infra-aio-app milestone Jan 10, 2019
@petebacondarwin
Copy link
Contributor

@wKoza - it seems that your second commit came from a different account to the first commit, and does not have CLA approval. Could you squash the commits into one committed by the appropriate account?
I have triggered the AIO preview so we can see this in action, before I give an opinion on the appoach :-)

@petebacondarwin
Copy link
Contributor

One problem I note immediately in the preview is that this is not working when you use the forward button to navigate.

@wKoza wKoza force-pushed the save_scroll_position_during_change_location branch from 9ac71d8 to 4ecf896 Compare January 10, 2019 16:35
@googlebot
Copy link

CLAs look good, thanks!

@wKoza
Copy link
Contributor Author
wKoza commented Jan 10, 2019

It's Ok with the CLAs. Can you give me an example of reproduction steps ?

@petebacondarwin
Copy link
Contributor
  1. Navigate to any guide, scroll down
  2. Navigate to another guide, scroll down
  3. Navigate to a third guide, scroll down
  4. Click back button: the second guide is scrolled correctly
  5. Click back button again: the first guide is scrolled correctly
  6. Click the forward button: the second guide is displayed but not scrolled.

@googlebot
Copy link

We found a Contributor License Agreement for you (the sender of this pull request), but were unable to find agreements for all the commit author(s) or Co-authors. If you authored these, maybe you used a different email address in the git commits than was used to sign the CLA (login here to double check)? If these were authored by someone else, then they will need to sign a CLA as well, and confirm that they're okay with these being contributed to Google.
In order to pass this check, please resolve this problem and have the pull request author add another comment and the bot will run again. If the bot doesn't comment, it means it doesn't think anything has changed.

@wKoza wKoza force-pushed the save_scroll_position_during_change_location branch from b9407ca to f10e0d8 Compare January 11, 2019 11:07
@googlebot
Copy link

CLAs look good, thanks!

@petebacondarwin
Copy link
Contributor

It was a flake! So if you don't mind squashing these commits (as you see fit) and then we'll double-check with @IgorMinar before merging. Great work!

@wKoza wKoza force-pushed the save_scroll_position_during_change_location branch from 5bcda90 to a9d0785 Compare January 21, 2019 14:54
@mary-poppins
Copy link

You can preview a9d0785 at https://pr28037-a9d0785.ngbuilds.io/.

Copy link
Member
@gkalpak gkalpak left a comment

Choose a reason for hiding this comment

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

Sorry to crash the party, but I was passing by and thought I'd add some comments 😁
The implementation seems a little complicated (I am not even 100% sure how it works 😁), but the end result looks correct ✔️
Nice one, @wKoza 👍

// The previous document has been removed.
// Scroll to top to restore a clean visual state for the new document.
this.scrollService.scrollToTop();
this.scrollService.removeStoredScrollPosition();
Copy link
Member

Choose a reason for hiding this comment

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

Why remove the comment from here? I think this is the right place for it.

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 name of the method is onDocRemoved. I think the first line is redundant.
The second line have to be removed. We stop to scrollToTop() when the Doc is removed.

this.location.subscribe(state => {
if (state.type === 'hashchange') {
this.popStateFired = false;
this.scrollToPosition();
Copy link
Member

Choose a reason for hiding this comment

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

Why do we need to call scrolToPosition() here? How was this handled before?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Before, we called autoscroll() if I recall

Copy link
Member

Choose a reason for hiding this comment

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

Do you mean here? If so, why do we need both calls?
More importantly, why do we need to scroll to this.scrollPosition, whent the hash changes (and not scroll to the target element or to the top)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

After, when a location had a hash, we called autoscroll() to scroll to the target element. Now, we can go back and return to a location which has a hash BUT, we can be to a another position (we have scrolled after have been to target element (anchor)). It's clear ?

Copy link
Member

Choose a reason for hiding this comment

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

But doesn't hashchange mean we are still on the same page (and only the hash has changed)? This path shouldn't be hit when we go back, right?

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, but wouldn't the scrolling be taken care of this line in that case?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes ,This line is called at the last step but it scrolls to the top since there is no more hash. But I'm agree, sometimes, this line is called for nothing.

Copy link
Member

Choose a reason for hiding this comment

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

I don't understand in what circumstances this could have an effect.
AFAICT, this line is enough for scrolling to the top. It seems to me that one of the two has to go. Am I missing something?

Copy link
Contributor Author
@wKoza wKoza Jan 23, 2019

Choose a reason for hiding this comment

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

this line provides the scroll to hash (step 3). This line is not called.
And this line provides the scroll to the link (step 7).
If you remove one of this lines , either the step3 or 7 will fail

Copy link
Member

Choose a reason for hiding this comment

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

I see. I played with this locally and the emitted events are very different from what I expected.
Let's leave it as is for now (since it seems to work fine). We can always tweak it later is needed 😉

} else {
this.popStateFired = true;
// we always should have a scrollPosition in our state history
this.scrollPosition = state.state ? state.state['scrollPosition'] : null;
Copy link
Member

Choose a reason for hiding this comment

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

It is an edge-case, but I believe we should store the new scrollPosition to sessionStorage. As it is now, if the user reloads before the 500ms delay, they will end up to the previous page's scroll position.

Copy link
Contributor

Choose a reason for hiding this comment

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

Good catch

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In this case, we doesn't have a delay. You can see this line

Copy link
Member

Choose a reason for hiding this comment

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

The scrolling is synchronous in scrollAfterDelay() (which is not a great name for a method that scrolls synchronously 😛), but calling scrollAfterDelay() is not synchronous wrt this line here. I was able to reproduce this by clicking the back button and reloading quickly.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Your comment is outofdate. The name is now scrollAfterRender() 😇.
I 'm not able to reproduce this. For me, It would mean rather that the event onDocRemoved was been fired .

@wKoza
Copy link
Contributor Author
wKoza commented Jan 21, 2019

Sorry to keep pushing back on this. It is a very good PR!

  1. I just wondered, why are you using session storage rather than history to store the current page position? Is that because unless you move elsewhere there is no item in the history?
  2. Regarding the jank when loading - can we not work out that we are reloading rather than navigating to a new page via a URL, and then avoid the setTimeout(..., scrollDelay)?

@petebacondarwin , finally, the setTimeOut here seems to be unnecessary. I'll remove it.

@petebacondarwin
Copy link
Contributor

OK, great!

@mary-poppins
Copy link

You can preview 09b3d1f at https://pr28037-09b3d1f.ngbuilds.io/.

@@ -348,6 +342,9 @@ export class AppComponent implements OnInit {
// Dynamically change height of table of contents container
@HostListener('window:scroll')
onScroll() {

this.scrollService.updateScrollPositionInHistory();
Copy link
Member

Choose a reason for hiding this comment

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

Since updateScrollPositionInHistory() isn't trivial, it might be a good idea to do some debouncing here. WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I had asked me the question when I wanted to use the scroll event. For the moment, I did not feel any lag. But, it is an option.

Copy link
Member

Choose a reason for hiding this comment

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

On Chrome (desktop), after some scrolling, I start to get the following warnings in the console:

Throttling history state changes to prevent the browser from hanging.

So, I believe it is a good idea to do some throttling/debouncing here.

this.location.subscribe(state => {
if (state.type === 'hashchange') {
this.popStateFired = false;
this.scrollToPosition();
Copy link
Member

Choose a reason for hiding this comment

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

Do you mean here? If so, why do we need both calls?
More importantly, why do we need to scroll to this.scrollPosition, whent the hash changes (and not scroll to the target element or to the top)?

@wKoza
Copy link
Contributor Author
wKoza commented Jan 23, 2019

@gkalpak, I've covered all of your questions. Notify me before my (last?) commit ;)

@gkalpak
Copy link
Member
gkalpak commented Jan 23, 2019

@wKoza, I think you are good to go for that (last?) commit 💪

@mary-poppins
Copy link

You can preview bf6bc41 at https://pr28037-bf6bc41.ngbuilds.io/.


try {
this.supportManualScrollRestoration = !!window && !!window.scrollTo && 'scrollX' in window
&& 'scrollY' in window && !!history && !!history.scrollRestoration;
Copy link
Member

Choose a reason for hiding this comment

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

OOC, under what circumstances do we expect this line to throw?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This code come from here. So, maybe window.scrollTo might throw an error or is "just in case". @vsavkin can maybe explain its choice.

Copy link
Member

Choose a reason for hiding this comment

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

It seems redundant (unless there are environments where window is defined and has a scrollTo getter, but trying to access window.scrollTo throws an error.

(Not that I haven't seen such strange limitations in certain environments 😉 angular/angular.js#13945)

Copy link
Member
@gkalpak gkalpak left a comment

Choose a reason for hiding this comment

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

Awesome work, @wKoza 💯
Thx so much ❤️ ❤️ ❤️

@gkalpak
Copy link
Member
gkalpak commented Jan 24, 2019

BTW, I have created #28332 to track possible improvements to scroll position restoration (but nothing that should block this PR) 😉

@gkalpak gkalpak dismissed IgorMinar’s stale review January 24, 2019 10:49

Comments have been addressed.

@gkalpak gkalpak added action: merge The PR is ready for merge by the caretaker and removed action: cleanup The PR is in need of cleanup, either due to needing a rebase or in response to comments from reviews labels Jan 24, 2019
@jasonaden jasonaden closed this in 3414316 Jan 24, 2019
@petebacondarwin
Copy link
Contributor

🎉

vetom pushed a commit to vetom/angular that referenced this pull request Jan 31, 2019
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 14, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker cla: yes feature Issue that requests a new feature target: patch This PR is targeted for the next patch release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Feature request: Maintain scroll position in docs
6 participants
0