Automattic / Automattic/jetpack

Infinite scroll: URL updated on scroll when paused

Open
#26,706 0 comments 0 reactions 0 assignees View on GitHub
[Feature] Infinite Scroll [Plugin] Jetpack [Pri] Low Bug
Dominant language
PHP
Stars
1.8k
Forks
898
Avg merge
1d 18h
Merged PRs (30d)
774

Description

### Impacted plugin

Jetpack

### Steps to Reproduce

1. Visit a website with infinite scroll enabled.
2. Open the developer tools console.
3. Pause infinite-scroll with the provided method `infiniteScroll.scroller.pause();`.
4. Change the browser URL with `history.pushState({}, 'About', './about');` or method of choice.
5. Scroll (browser URL will be reset).

### A clear and concise description of what you expected to happen.

Most functionality is in fact paused when using the provided `scroller.pause() method`.
For example, [the refresh method](https://github.com/Automattic/jetpack/blob/trunk/projects/plugins/jetpack/modules/infinite-scroll/infinity.js#L303) is paused since it has a check for `this.disabled` which the `infiniteScroll.scroller.pause();` sets.

Since infinite scroll is paused, the browser URL update should not occur when custom `history.pushState()` is used while it is paused and the custom browser URL should stay until `infiniteScroll.scroller.resume();` is called.

### What actually happened

While paused and custom code triggers `history.pushState()`, the URL gets updated/reset once any scroll action occurs.

### Browser

Google Chrome/Chromium, Mozilla Firefox, Apple Safari

### Other information

The source of the issue is here:
https://github.com/Automattic/jetpack/blob/a5df28bc939057e720557f6ee79892cb0c5eb20e/projects/plugins/jetpack/modules/infinite-scroll/infinity.js#L78-L88

Specifically the call to `self.determineURL();`

A possible solution would be to check for `this.disabled` before doing most of the things inside the `determineURL()` method, similar to what is done in the [.refresh() method](https://github.com/Automattic/jetpack/blob/a5df28bc939057e720557f6ee79892cb0c5eb20e/projects/plugins/jetpack/modules/infinite-scroll/infinity.js#L310-L313).

Example:
```js
Scroller.prototype.determineURL = function () {
var self = this,
pageNum = -1,
currentFullScreenState = fullscreenState(),
wrapperEls,
maxFactor = 0;

if ( this.disabled ) {
return;
}

// xor - check if the state has changed
if ( previousFullScrenState ^ currentFullScreenState ) {
```

Edited the [infinity.js source file](https://github.com/Automattic/jetpack/blob/trunk/projects/plugins/jetpack/modules/infinite-scroll/infinity.js) with that edit and works as expected.

## Use case
Trying to implement an "expand single article" from the infinite scroll temporarily with a preview. User engagement is to scroll to read the rest of the article. Once the article is no longer on screen, the scroller `.resume()` method is triggered so everything goes back to normal.

### Platform (Simple, Atomic, or both?)

_No response_

### Reproducibility

Consistent

### Severity

_No response_

### Available workarounds?

Yes, difficult/complicated to implement.

### Workaround details

One override that isn't too obvious is to toggle the property/setting `infiniteScroll.scroller.throttle` between false/true but it needs to be done inside the scroll event but through a callback so that `.removeEventListener()` can be used.
Example:
```js
const toggleScrollerThrottle = function () {
infiniteScroll.scroller.throttle = !infiniteScroll.scroller.throttle;
};

window.addEventListener('scroll', toggleScrollerThrottle);

// ... Do rest of code like history.pushState({}, 'About', './about');

window.removeEventListener('scroll', toggleScrollerThrottle);
```

Contributor guide

Open the contributing guide

Research direction

Start in projects/plugins/jetpack/modules/infinite-scroll/infinity.js, especially the scroll handler around the linked determineURL() call and the disabled check in refresh(). Reproduce the issue with scroller.pause(), history.pushState(), and a scroll event. Done means the custom URL remains while paused and normal URL behavior resumes after scroller.resume().

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
frontend
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.