Active-CSS / active-css

The epic event-driven browser language for UI with functionality in one-liner CSS. Over 100 incredible CSS commands for DOM manipulation, ajax, reactive variables, single-page application routing, and lots more. Could CSS be the JavaScript framework of the future?
https://activecss.org
Other
42 stars 7 forks source link

Hash url not working correctly in SPA flow #132

Closed bob2517 closed 3 years ago

bob2517 commented 3 years ago

If the developer bypasses the SPA handling and converts the URL to a hash directly, while keeping the URL not with a hash, like I just did for the offline docs website, the SPA navigation doesn't work, but you would hope it would intuitively, if not completely logically.

So change the way the popstate works so that it doesn't influence the URL.

This is fixed on the branch - at least for now. I need to check one more scenario.

Basically the URL can look like anything now and the SPA \@pages will still work predictably with the link URLs. Quite weird really. But it means a hash can be placed in the URL and for the URL page to stay the same - ie. index.html, and never change. And I don't need to change the links in the \@pages declaration for the live and standalone file:// based site, even though the visible URL is different. So as long as the link tags and \@pages match up, it all works.

bob2517 commented 3 years ago

Found a bug - don't use the branch yet.

bob2517 commented 3 years ago

I think this is just a 2.5.1 thing, so marking as weirdness to fix and not a bug.

bob2517 commented 3 years ago

Something separate that I've not looked at yet, is the potential for when going back onto a #hash linked page after a different url page, is to trigger the underlying page prior to the hash link if specified in @pages. Like how photoswipe handles going to a page with an image that has an image open on the hash. It's not something for the issue I'm running into, but something to think about at some point.

bob2517 commented 3 years ago

Marking as done offline. It's in a better state than it was and it works well with the offline docs SPA. Will probably revisit this when a different use case is presented, which is inevitable.

bob2517 commented 3 years ago

Revisiting this now. There's an issue with a recent fix for 2.5.1 that has stopped the detection of regular hash changes. It's because of the implementation of the standalone single-page (literally) hash behaviour which now always navigates to a "fresh" page in an SPA context, for any change on the hash. Regular hashes now redraw the page, which isn't what we want.

Trying to work out a fix for this. Probably something to do with the hashchange event, which isn't in the core yet.

bob2517 commented 3 years ago

Hashchange happens after the popstate.

bob2517 commented 3 years ago

May not be an issue. There isn't even a visual effect I can see where I'm checking this. Set up a proper test page with multiple in-page link URLs and try popstate out with that.

bob2517 commented 3 years ago

This looks like it's more to do with the way I'm manually setting a hash that isn't triggering the hash or postate events. The hashchange doesn't fire on my hash change, as I'm just changing the url manually rather than doing anything official. This is good to know. Will try a different technique and document it. It's only on the modal examples that I'm getting this error.

bob2517 commented 3 years ago

Tried lots of ways around this going back to a hash when it's set up by an image popup rather than the normal function of a hash which is to move to an id.

Basically, the page needs to load as normal and then the hash needs to kick in. That's how the browser does it, and so I need to replicate it so it can be done with something like a popup. Some sort of url change is needed there if the back arrow is supposed to close the popup, and also if the page is refreshed once a popup is open. The state is that the popup is open, and so for bookmarking purposes the URL should be able to get there.

So I'm looking at adding this extra bit into the @pages syntax to indicate what to do with a page once it has loaded with just the regular @pages handling, which works brilliantly on its own but can't handle the hash.

In addition to the regular pages entry for that page, in theory all that is needed is for instructions to trigger off the next step after page render. An element on that page would have triggered off the popup.

Maybe something like this:

@pages {
    "#corridor": event="#imgCorridor:click";
}
bob2517 commented 3 years ago

I think that's the simplest handling - it's the breakdown of what needs to happen in simplest A to B terms. The original page draws. Then the events needed to put the hash into play is triggered. But it's a real brain-bender, this one, I dunno if this is going to cut the tofu. Will try it out. Needs to work on page refresh too, so that's a replication of functionality for both the popstate event and the initial page draw.

bob2517 commented 3 years ago

Created an if-hash conditional which returns true if there is a window.location.hash. Might be useful. It does the job that I need it to do on the docs site but wouldn't work on other types of sites.

bob2517 commented 3 years ago

The regular # hash, as used in the existing simple image modal demonstration is covered by the new upgrade that is currently offline. It's a fully working thing, and I'll be doing a new tutorial for that shortly. The syntax to add a hash page to the SPA is twofold:

  1. Put the underlying page that has a hash on it into the @pages per the existing tutorial (note: I need to do a proper docs section for the SPA stuff which I'll do for this release, as it's currently hidden away in a PHP tutorial).

  2. Put the information needed to trigger the results of the hash into the @pages like thwus (this is for a modal popup gallery which is fully bookmarkable):

/* SPA image modal */
@pages {
    "#corridor": event="#imgCorridor:click";
    "#horse": event="#imgHorse:click";
    "#house": event="#imgHouse:click";
    "#ville-france": event="#imgVilleFrance:click";
    "#autumn-leaves": event="#imgAutumnLeaves:click";
}

So eg. the "#corridor" is the hash reference. That's easy. The "event" bit is the event selector that when triggered internally with render the result of the hash.

The way it works is that it draws the underlying page first, always, and then if there's a hash value, it looks for that and because the underlying page was just drawn, it can trigger the appropriate event selector which now magically will have all the elements it needs to perform any of your target actions.

It's the Aist to Bist I could think of. It took a while to get to that point though. Almost went MVC! That was a joke.

It works on page refreshes too as long as your server is rendering the right underlying page. So pages with #hashes can be bookmarked.

There's one rule that must be followed though, like not having duplicates #hash values on one web site. Ever. I can expand the syntax if anyone finds that isn't workable for them. For most people it will be, so the default syntax will remain like this. I can add further syntax to specify the link file on request. But for the sake of typing and simplicity this will be the default.

Eh voila.

That's the first major thing. I want to do a tutorial on multiple page section navigation to previous states per page history too, but that's going to come with a later release and possibly have its own handling, maybe not.

It works with content delayed by an ajax request too, and will work automatically with any existing setups in place with popstate, as those are still relevant. It literally just does a page switch and then a hash render. So its fully backward compatible. All you have to do is add in the hashes and the hash trigger events as above.

This was done as part of the offline docs evolution that I'm doing so that you can download versions of the docs at any one time. As I'm a bit of a weird speed freak, I'm turning the whole thing into an offline SPA rather than individual files, so I thought I'd solve this issue now as I was working on a related thing for that.

bob2517 commented 3 years ago

This issue is now fixed and on the 2.5.1 branch along with the general SPA backward-compatible upgrade to handle hash url refreshes with the \@pages support.

bob2517 commented 3 years ago

Closing for milestone tracking.