dart-lang / web

Lightweight browser API bindings built around JS static interop.
https://pub.dev/packages/web
BSD 3-Clause "New" or "Revised" License
128 stars 22 forks source link

History.back() behaves differently than documentation says. #313

Closed busslina closed 53 minutes ago

busslina commented 2 hours ago

Docs says:

The back() method of the History interface causes the browser to move back one page in the session history.

It has the same effect as calling . If there is no previous page, this method call does nothing.

This method is . Add a listener for the Window.popstate_event event in order to determine when the navigation has completed.

I'm testing the case where there isn't previous page and it is doing something: moving to root path.

Tested on Edge and Chrome.

Demo:

https://github.com/user-attachments/assets/a31abb93-15e7-4167-a19c-15bbd65158aa

srujzs commented 1 hour ago

Looks like the docs are semi-malformed (missing asynchronous after "This method is "), but the MDN docs don't contain much more information. Is there a small repro you can share here? My only guess is that history is being modified somehow within the code.

The call to history.back() should correspond directly to JS' history.back(), so this is more of a discovery thing than anything actionable on the package's end.

busslina commented 1 hour ago

Is there a small repro you can share here?

Not easy because I'm developping my own Flutter routing lib.

But I'm just calling that method:

@override
  SynchronousFuture<NavigationResult> flashBack() {
    if (!kIsWeb) {
      throw ('Only implemented for web');
    }

    web.window.history.back();
    return SynchronousFuture(const NavigationResult.success());
  }
busslina commented 1 hour ago

And yeah, seems the doc error came from MDN. (If JavaScript is behaving equally, which I haven't tested yet).

srujzs commented 1 hour ago

Not easy because I'm developping my own Flutter routing lib.

Gotcha. One option is to explore the history object before calling back, like determining if history.length is actually 1. Might also be worth looking at the generated code to see if we do anything weird besides directly call the JS API.

busslina commented 1 hour ago

Thanks, I was worried to use that API as I tried to use the state object and it was a pain. But using length make it easy:

bool get canFlashBack => web.window.history.length >= 2;
srujzs commented 53 minutes ago

Great! I'm going to go ahead and close this for now since there's nothing actionable on package:web.