Scenario A)
Following URLs pointing to fragments on the current page causes a full page reload before locating the fragments..
E.g. while on page www.example.com/pageA clicking www.example.com/pageA#Section1 cause a full page reload and then take you to Section1.

Scenario B)
Following URLs pointing to fragments on different pages fail to load. An ajax error is output in the browser log.
E.g. while on page www.example.com/pageA clicking www.example.com/pageB#Section2 appears to do nothing and creates a browser Ajax error.

Last checked against Version: 8x-1.0-alpha2+7dev

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

serg2 created an issue. See original summary.

serg2’s picture

Issue summary: View changes
serg2’s picture

Issue summary: View changes
Wim Leers’s picture

By "anchor links", do you mean things like <a href="#heading-to-jump-to">Go to X</a>? I've known them to be called "jump links" or "fragment links" or just "fragments", but never "anchor links". Just verifying :)

serg2’s picture

Yes, that is what I meant.

I think "fragment identifier" is the official name for the "#example" bit and the anchor is the Id it links to. (https://www.w3.org/TR/html401/intro/intro.html#fragment-uri).

I should have made the issue clearer. If the URI is on the same page it works as normal. Where the URI refers to a specific location on a different page then the link is broken.

Wim Leers’s picture

Title: Anchor Links are broken » URLs pointing to fragments in other pages are not working

If the URI is on the same page it works as normal. Where the URI refers to a specific location on a different page then the link is broken.

Aha! That helps :)

Wim Leers’s picture

Priority: Normal » Critical
Wim Leers’s picture

Title: URLs pointing to fragments in other pages are not working » Following URLs pointing to fragments on the current page unnecessarily reloads the page
Priority: Critical » Major
Status: Active » Postponed (maintainer needs more info)

The notice in the IS was due to #2692317-17: Make everything in <head> update: <title>, <meta> tags, etc.. Fixed that in that issue. But this issue is still relevant: any fragment link on the current page causes the entire page to be reloaded needlessly, due to RefreshLess's onpopstate event handler.

Please confirm in the mean time that with HEAD, that's indeed the only remaining problem with fragment URLs.

serg2’s picture

I have done more testing this morning and this comment appears incorrect, please see next comment.
Against head (Version: 8.x-1.0-alpha2+5-dev):

Links with URL fragments pointing to destinations on the current page work perfectly.

Links with URL fragments pointing to destinations on different pages do not work. Clicking them appears to do nothing in the browser. They produce an Ajax Error.

That is the only problem I can find with URL fragments.

serg2’s picture

With head (Version: 8.x-1.0-alpha2+5-dev)

Scenario A)
URL Fragments pointing to locations on the current page cause a full page reload and then finds the correct location.
E.g. while on page www.example.com/pageA clicking www.example.com/pageA#Section1 cause a full page reload and then take you to Section1.

Scenario B)
Links with URL fragments pointing to locations on different pages fail to load. An ajax error is output in the browser log.
E.g. while on page www.example.com/pageA clicking www.example.com/pageB#Section2 appears to do nothing and creates a browser Ajax error.

Could someone else please reproduce the result of Scenarios A & B.

serg2’s picture

Status: Postponed (maintainer needs more info) » Active
serg2’s picture

Issue summary: View changes
Wim Leers’s picture

Title: Following URLs pointing to fragments on the current page unnecessarily reloads the page » Fragments URLs fail: local fragments cause unnecessary page load, remote fragments cause HTTP 500 response
Assigned: Unassigned » Wim Leers

Confirmed both. On this now.

Many thanks for #9 + #10, that was very helpful!

Wim Leers’s picture

I first had to do #2713439: Allow navigating back to the original page without doing a full reload, because thanks to this issue, I started to see how having a cohesive, comprehensive way to deal with the state at each History position would make solving this issue simpler.

Wim Leers’s picture

Status: Active » Needs review
FileSize
1.79 KB

Here is my super rough, super naïve solution.

It works… as long as you don't use the backward/forward buttons. Then it completely breaks. That's of course not acceptable.

Wim Leers’s picture

The reason #15 doesn't work, is because it doesn't track state for fragment-based navigation.

Specifically, if you navigate like this:

/foo -> /foo#llama -> /bar

… then the corresponding history entries look like this:

Drupal.refreshless.state.1 -> null -> Drupal.refreshless.state.3

… because #15 leaves the fragment-based navigation to the browser.

What's the problem then? Well, if you go back from /bar to /foo#llama, the browser will just scroll back to the position that #llama was in, but it will not restore the content for /foo!


So, what we need is:

  • track fragment-based navigation in History API: Drupal.refreshless.state.1 -> Drupal.refreshless.state.2 -> Drupal.refreshless.state.3
  • when navigating back, be smart enough to know that going from 3 to 2 is not feasible, because 2 doesn't contain HTML changes, it only contains the fragment URL navigation (i.e. it has intra-page navigation, not inter-page navigation). So, instead, RefreshLess' JS should backtrack through the history until it finds the entry where that URL was first loaded, because the fragment-based navigation happens relative to that.

As you can imagine, this is easier said than done. The biggest hurdle is the fact that the History API PopStateEvent does not tell you what the state is you're coming from. Not even the position. So we have to track this outside the History API.

In other words: the History API is poorly designed. It's good that it's restricted, but it is too restricted. Which is exactly why almost nobody in the world seems to have ever attempted this: 99% of examples are crappy, silly, simple: they simply perform an AJAX request on every page load.

serg2’s picture

Tested this against the current dev(which has #2713439: Allow navigating back to the original page without doing a full reload applied) and works as you described with the issues you described. Also, the changes you made to the loading of the libraries seem great.

Wim Leers’s picture

FileSize
12.78 KB
13.08 KB

This took me several days to figure out! (Including the explanation in #16.)

Wim Leers’s picture

Priority: Major » Critical

I think it's fair to say this is critical, actually. Some sites heavily rely on fragment navigation, and without this, it'd be painfully broken.

Wim Leers’s picture

FileSize
13.56 KB
834 bytes

Let's document this at a very high level, to allow people to understand roughly how this all works without having to read the code.

Wim Leers’s picture

Status: Needs review » Reviewed & tested by the community

After thorough manual testing and having worked on this for many days, I think this is ready. Any remaining problems should be reported as new issues.

Wim Leers’s picture

Status: Reviewed & tested by the community » Fixed

  • Wim Leers committed 08148cb on 8.x-1.x
    Issue #2705363 by Wim Leers: Fragments URLs fail: local fragments cause...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.