-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Navigation Refactor - First Pass #5091
Comments
@Wilto: if you want, I can share some stuff on what I did in multiview. The current version is tapping into JQM history (no container history mgt). In the previous version every container had it's own history. I eventually got both to work, although I'm finding container history inside JQM easier to manage. Let me know if you want some code samples with comments. |
I'll definitely ping you for review, after I get the basic navigation event structure in place. I'm really looking forward to getting this cleaned up and I your help could be invaluable. |
@johnbender: |
Let me sort out the |
@johnbender - you have a point :-) |
This will be really great, especially the ability to surface a consistent way to track an action in the history stack because we already have dialogs and popups that need this and I can see the list of potential widgets that may need history support - hide/show panels, menus, etc. |
aka "The history-dump" |
Make sure you take into account what happens should the user refresh the page at any point in history. Currently, we get all kinds of funky effects when the user refreshes mid-history. See #5122 for example. Also, it seems a refresh on a given location is not the same as starting with a deep link, because, if you refresh and then hit "Back", jqm is not reloaded, but the same pagestate is kept alive. What I mean is this:
|
@gabrielschulhof - do you know if double entries are allowed/possible/wanted in the URL history? After a transition, I'm running a cleanser, that clears out double entries in the URL history when they are last in stack, so: page 1 would clear out the last |
O_o ... how do you reach such a state? I'm talking about browser history, not |
@gabrielschulhof: Can't do browser history, only Hhaven't looked at this in a while...
|
@johnbender: In the source, the js file includes jquery, jqm and url.js (almost at the bottom - search for url.js v1.0.0 ). I haven't really looked into the code, but it performs nicely (probably a little to customized on the specific page content, but I guess this can be generalized). I can hook you up with the author if you like - sitting in the same room this week. @johnbender: |
Update: Here's what I have so far, all event/method names are up for discussion. First, I've wrapped both https://github.com/jquery/jquery-mobile/blob/simple-nav/js/navigation/events/navigate.js This by itself isn't super exciting though it does normalize the "shape" of the data and API so that folks who want to build on it down the stack have a reduced set of concerns. Importantly, this by itself doesn't allow us to track history. The key to tracking history within jQuery Mobile is that new history states are created and controlled by the library. Second, I've created the https://github.com/jquery/jquery-mobile/blob/simple-nav/js/navigation/navigate.js Along side the navigate method are two event bindings ( All of this taken together means that if users are willing to use Let's look at an example similar to something that jQuery Mobile does though we'll assume that the content associated with each page state can be loaded directly without concern for scripts, etc: $( "a" ).click(function( event ){
event.preventDefault();
// Here we set the hash, call replaceState where supported
// and also track a new history entry with our extra data from the
// anchor "data-foo"
$.navigate( this.attr( "href" ), { foo: this.attr("data-foo") });
// ostensibly this method call takes the href and loads the content from the server
// altering the document to reflect the proper page state
MyApp.loadContent( this.attr("href") );
}); Here we've done a link hijack that participates in our history tracking by using the First some markup: <a href="/dogs" data-foo="bar">Dogs</a>
<a href="/cats" data-foo="baz">Cats</a> When the first link is clicked, navigate is called and the url is updated:
Assuming those links are still available and the second link is then clicked:
Now assuming an event binding like: $( window ).on( "navigate", function( event, data ){
// NOTE I need to address namespacing in the data so that it doesn't collide with the
// attached history information
console.log( data.foo );
console.log( data.url );
console.log( data.direction );
MyApp.loadContent( data.url );
}); Hitting the back button, or calling
And with the call to If the user were to then hit the forward button the output would then be:
And the call to `loadContent with the url could handle the visual state of the application. Hopefully this illustrates what I've come up with so far. There are a lot of details to sort, but I wanted to get some feedback before I proceed to rework the navigation internals based on this model. I think this will remove alot of the complexity from the core navigation code. |
Nice work, John! I really like this approach so far and am happy to chip-in as things progress. It's definitely easier to follow than our first pass. I'm not entirely sure whether triggering the Anyway, looking great at first glimpse. |
You raise an important issue, and it's something I've considered while working on this. I'm primarily addressing/normalizing/improving the browser's concept of navigation because at some level in the library and for other developers at large it all has to boil down to that anyhow. That is, when we get to the point that we have many page containers, they will have to derive their "navigation state" from a single url change event even if it's associated with complex state in the background. I think that dealing with what a page container does when it get's a "navigate" event is a bit further down the stack and later in the refactor, but I have a branch that started out allowing arbitrary objects as the trigger point for the nav event and I ran into a complexity wall when considering the issue with page containers. Hopefully we'll be able to derive the correct information with these tools at the page container level, and provide a second derivative event that applies only to a given container. Or at least that's my current thinking. |
okay. Well, keep going and let's see how it shakes out, then! :) |
@johnbender: Nice work! Some late night thinking on using (1)
While I figured out a way to use JQMs current navigation to work with this setup, I like the idea of using (2) Say you have:
If you navigate:
This can be fixed by exposing Again, I think running the navigation from the (3) Say you'd use the (4) Say you are using a wrapper page vs. running things from
I guess once popups will be available globally, global toolbars won't be far behind, so I don't think this is really a problem down the road. Therefore: |
Thanks for the notes and the vote of confidence, this is super useful stuff to know up front 👍 |
@johnbender: thx. One important point I want to add: (5) Using above example:
Loading this page will create an entry for
you will get a 2nd entry in the Now go back. You don't have What happens is inside I spend forever on this and I spare you the details, but you need a fwd/backwards transition counter, have a terrible check for the last panel backwards transition, hijack the trailing hashchange (it trails nothing, cause there is no This handler is about half of my panel navigation, so if using |
We'll have to revisit that issue once I get this merged so I can fully understand it. It sounds like what we need in that case is a history stack per page container, which is something I had planned to push down to the container widget (1.4) I could be way off there though. |
ok. I did my first multiview version like this = with every container keeping it's own urlHistory. I later switched to using JQMs urlHistory, which only required to add the container to the urlHistory like so (from almost latest):
Both variants have their pros and cons :-) |
Per your request an executive summary of the nav work: There are two new additions to the navigation functionality in jQuery Mobile. A The The Both the event and the method are available as modules apart from other navigation functionality in jQuery Mobile, with minor dependencies on other parts of the library. |
Nav sequence regressions wrt. master (I'll maintain a list in this comment): Dialog hash key:
Page 1/Page 2&dialog hash key: |
This is merged into master so closing as complete for the first pass per @johnbender |
Goals
Ordered by priority.
Abstract pushstate/hashchange handling
I'd like to unify these two events into one internally ("navigate"). Additionally I was considering providing namespaced events "forward.navigate", and "back.navigate" where appropriate but that will require review since it's tightly coupled to our hashchange handling. Again, these events will initially be internal until we decide that the module is ready for general consumption.
This likely includes the following deliverables:
Container
I'd like to provide a container widget that manages its history and content transitions. The idea is to have this respond to navigation events and possibly delegate to changePage. This is important as we make a run at multiple container documents.
This likely includes the following deliverables:
The text was updated successfully, but these errors were encountered: