Skip to content
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

Navigation #31

Merged
merged 7 commits into from
Sep 7, 2023
Merged

Navigation #31

merged 7 commits into from
Sep 7, 2023

Conversation

nilslindemann
Copy link
Contributor

@nilslindemann nilslindemann commented Jun 15, 2023

Like promised here, I took a look at how navigation works in Mint, and I (hopefully) streamlined things a bit. It is best explained by example, so open

mint-navi-test.tar.gz

and compare dist now (current issues) with dist then 1 (issues resolved). Run e.g. npx serve in the folders, or use the tool of your choice. You may have to reload without cache, ctrl+f5.

If you want to check my changes using the mint development server,

  • Apply the PR in the Mint repo.
  • Apply this PR here.
  • Run yarn install here. (there is a new dependency)
  • Apply the three changes in the PR in the route-parser repo directly to node_modules/route-parser/lib/route/visitors/regexp.js here.
  • Run make here.
  • Run make development in the mint repo.
  • Run mint-dev start in the mint-navi-test folder from above.

(make sure these three folders – mint, mint-runtime, mint-navi-test – are side by side)

None of these changes are applied in dist now from the above zip. dist then 1 and dist then 2 have all of them applied. dist then 2 shows the differences between Window.setUrl(), Window.navigate() and Window.jump().

So, this is my suggestion how we could do the navigation.

Compare these with the changes in the 'navigation' PR in the 'mint' repo.
It is not perfect, code coverage is not all green. Some things are difficult to test.
@nilslindemann
Copy link
Contributor Author

nilslindemann commented Jun 15, 2023

Ok, I tried running that linter locally (yarn lint), but I get the same error message. And the SO answers suggesting fixes lead to other errors, like weird network connections. I resign on that, linter wins :-)

source/Program.js Outdated Show resolved Hide resolved
@gdotdesign
Copy link
Member

Ok, I tried running that linter locally (yarn lint), but I get the same error message. And the SO answers suggesting fixes lead to other errors, like weird network connections. I resign on that, linter wins :-)

You can format the files with yarn format

source/Program.js Outdated Show resolved Hide resolved
@gdotdesign
Copy link
Member

I've tried dist now and dist then 2 and can't seem to find differences in how they work. Can you summary what the differences are please?

@gdotdesign gdotdesign closed this Jul 25, 2023
@gdotdesign gdotdesign reopened this Jul 25, 2023
@nilslindemann
Copy link
Contributor Author

nilslindemann commented Jul 30, 2023

You can format the files with yarn format

Thank you, did so. yarn lint now doesn't complain anymore.

@nilslindemann
Copy link
Contributor Author

I've tried dist now and dist then 2 and can't seem to find differences in how they work. Can you summary what the differences are please?

Ignore dist then 2. I just included that because I tested with it most of the time. It is more confusing than helpful, I guess.

I have recreated mint-navi-test.tar.gz with hopefully better explanation. Run npx serve in dist now and then run it in dist then, as described in my first post. (Do not forget to press ctrl+f5, the Node.js server or the browser anyhow caches things).

  • dist now is based on the main branch, speak that is how it currently behaves.
  • dist then is all these commits and other changes applied, including the changes in the mint PR and in the route-parser PR. I show and explain the changes there.

@nilslindemann
Copy link
Contributor Author

And here is some manual explanation from memory, what this and the other PRs do:

  • When clicking links, if the link does not contain a hash, it now jumps to the top of the document.
  • history forward / back now works as expected.
  • triggering route logic is more intuitive. A route /route will be triggered by /route, /route#hash, /route?seach and /route?search#hash.
  • However, only if the path part was not already /route.
  • One can also define a more specific route like /route#foo which will then catch this specific hash, but e.g. \route#bar will still be catched by the generic /route.
  • Variables can be used everywhere, e.g. /route/:p?query=:q#:h.
  • A '#' will not be consumed by a variable anymore. So the hash will not be accidently consumed. So, e.g. the route /:p#hash will actually match e.g. /foo#hash and p will be foo. (and not foo#hash like before, which resulted in the route not matching)
  • Additionally to the Mint functions Window.setUrl() and Window.navigate() there is now also a function Window.jump(). setUrl() behaves like before, it just sets the URL in the browser address bar. navigate() additionally updates the history and maybe triggers the route logic. jump() additionally jumps to the hash or start of document.

@gdotdesign
Copy link
Member

Thanks for the explanation, it's clearer to me now (also I had to hard hard refresh Shift+Ctrl 😅 )

I agree with most of the changes, however not with this:

However, only if the path part was not already /route

I usually have the search value as a query parameter ?search=xxx and when that parameter changes I reload the content matching that search and currently it means that the route will be triggered. I do this because I believe the URL should be the source of truth of the UI (everything can be derived from it). Also, in this case I replace the URL instead of pushing a new one, so the history remains correct.

The second use case is hash based navigation /#/route, which would not work with this change (it doesn't work now because of the bug you discovered).

@gdotdesign gdotdesign requested a review from Sija August 8, 2023 07:55
@nilslindemann
Copy link
Contributor Author

nilslindemann commented Aug 10, 2023

@gdotdesign

I forgot to mention this: A route gets (re-)triggered in three cases:

  • first load of the app
  • the path part changed
  • an argument for a parameter changed.

This is done here in the code. (I call the parameters vars there)

So, If one defines a route /foobar?search=:xxx then it will get triggered, whenever the argument for the :xxx parameter changes. If one only defines a route /foobar then it will not get triggered again when something in the search (or hash) part changes.

It is also possible to define a route /foobar#:hash, and it will get triggered again, whenever the argument for :hash changes.

It is correct, a variable can not catch a / see this regex. But my PR actually did not change that, I just added the '#' to the regex. We may change it to allow .*, which seems to be ok, because the hash is always at the end, but I have not yet tested if that works.


Also, in this case I replace the URL instead of pushing a new one, so the history remains correct.

So, trigger route handler, but do not update history. I actually thought of this use case but did not implement it. It suggests a fourth Mint function triggerHandler.

  • setUrl (sets the url in the addressbar)
  • triggerHandler (also triggers the route handler)
  • navigate (also updates the history)
  • jump (also jumps to the hash or start of document)

(all in the Window namespace)

However, one may for example just want to set the URL and update the history but not trigger the route handler, so it is probably best to have all this combined in one function Window.navigate (as it already is on the javascript side), but this would suggest that mint gets named parameters, so that we can for example do something like Window.navigate(updateHistory=false, jump=false).


Addon 2023-9-4:

hash based navigation

I guess you are referring to the fact that a route defined inside the application, e.g. /another-route in the above example, can not be reached from outside the app. And you want to replace the first '/' in the path part with /#/, so that this is possible. Correct? I think this should work. The specific regex to be changed would be this one, and we would have to replace it with something like (\\/(?:#\\/)?[^?#]*?), where \\/(?:#\\/)? matches / or /#/. Then, somewhere (where?) in the code, we would have to insert this #/ after the first slash of the path part.

Copy link
Member

@Sija Sija left a comment

Choose a reason for hiding this comment

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

LGTM 🚀

@Sija Sija added the enhancement New feature or request label Sep 3, 2023
@nilslindemann
Copy link
Contributor Author

nilslindemann commented Sep 4, 2023

There is one issue: Currently, no one is reacting to the PR in the route-parser repo. So these changes will not be applied when one does yarn install here. The simplest solution would probably be to fork that repo as e.g. mint-route-parser, apply the PR and use that forked repo instead as dependency in package.json. There is also something like patch-package, but I have not tested that.

The other questions, should we add a fourth function triggerHandler, should we merge these four functions into one if Mint gets named arguments, what about hash based navigation, can be answered later.

@Sija
Copy link
Member

Sija commented Sep 4, 2023

I'd take over the library or use patch-package.

@nilslindemann
Copy link
Contributor Author

nilslindemann commented Sep 4, 2023

I have just tried replacing the dependency (^0.0.5) with nilslindemann/route-parser#let-hash-not-be-part-of-parameters, which is the above PR. Then deleted node_modules folder and ran yarn install. This worked. (using yarn version 1.22.19)

So something like mint-lang/mint-route-parser#master should probably work.

@Sija Sija requested a review from gdotdesign September 4, 2023 14:28
@gdotdesign gdotdesign merged commit 60538f6 into mint-lang:master Sep 7, 2023
1 check passed
@nilslindemann
Copy link
Contributor Author

Great stuff 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Development

Successfully merging this pull request may close these issues.

3 participants