Monday, April 23, 2012

Jquery Mobile - Refactor: navigation.js A4.1 extensibility


This document serves to list places where extensibility of jQuery Mobile could be improved.

List of triggers fired by jquery.mobile.navigation.js @ A4.1

In function transitionPages() definition:

  • from.data( "page" )._trigger( "beforehide", null, { nextPage: to } ); on L442
  • to.data( "page" )._trigger( "beforeshow", null, { prevPage: from || $( "" ) } ); on L444.
    Notes
  • These two triggers are co-located and occur essentially at the same juncture.
  • It's widely agreed that the beforeshow trigger, implementation-named pagebeforeshow via the widget factory, needs to be moved until the page is, in fact, right before show.

In function pageChangeComplete() definition:

  • from.data( "page" )._trigger( "hide", null, { nextPage: to } ); on L477
  • to.data( "page" )._trigger( "show", null, { prevPage: from || $( "" ) } ); on L480.
Notes
  • These two triggers are co-located and occur essentially at the same juncture.

List of clear junctures in jquery.mobile.navigation.js @ A4.1

These locations are good candidates for extensibility hooks because they are at critical junctures hence likely effective, as well as being atpredictable junctures hence usable by developers who aren't jQuery Mobile ninjas.
  • At the very top of changePage() to allow for situation specific overrides or pre-empting. For example,
    • overriding the current constraint on navigating to the same url, or
    • forcing a user gesture-consistent transition.
    • Setup and state-setting tasks we're already doing at the top of changePage(), like the call to defaultTransition()
  • At the very bottom of enhancePage(), after the call to the page plugin, to allow for injection of further custom markup by plugins or by developers.
  • In the error callback of the new $.mobile.loadPage function (formerly part of $.mobile.changePage) injquery.mobile.navigation.js we display a hard-coded dialog to the user. We might like to expose that for customization and extension, for example maybe the developer wants to POST the error details to a server-side error log.
  • See Issue 1687 Expose the options for widgets called in mainline code https://github.com/jquery/jquery-mobile/issues/1687.

URL handling hook (for data passing)

See this https://developers.jivesoftware.com/community/blogs/engineering/2011/04/15/jivin-with-jquery-mobile-inter-page-navigation. Here Sam Meder alludes to a small change in jQuery Mobile code to allow using url queryString sections that don't interfere with the hash, to pass data.
As mentioned above, the most significant challenge is passing data to each template page in order to have it load the correct content into the template. The obvious mechanism for this level of data-passing is HTTP query string parameters, i.e., "?name=value". However, if you naively try to add this style of parameter after a hash like "#document-template?documentId=1234", jQuery Mobile will interpret the query string as part of the page ID hash and get confused. Placing the query string before the hash ("?documentId=1234#document-template") is handled correctly by jQuery Mobile -- i.e., "documentId" is ignored. However, if links from one jQuery Mobile application page to another application page are constructed like this ("index.html?param=value#pageId"), the web browser will think it needs to make a new request to the page, and therefore reload all of index.html, which was not acceptable. So, we made a small change to the code in jQuery Mobile that identifies the target page, causing jQuery Mobile to ignore "?name=value"-style HTTP query string parameters when processing the hash fragment string.
Read the whole thing. TL;DR A URL processing hook would be nice.
Implementation: A pre-hook to allow the user to extract data from the url prior to jQuery Mobile's normal url processing.

Hook to allow transitioning and re-displaying the same page.

From IRC ... user wants to change the contents of the current page and re-display it.
I am trying to create a shopping cart, where u can swipe left or right, and u see items of different category on each page.

Email with extensibility suggestions - Please read and integrate into the section above
From: okoskimi reply+m-6541631-1d395c6dee5977f05ae64ca420288b4ece502b60@reply.github.com Date: May 8, 2011 10:24:39 PM GMT+02:00 To: scott@scottjehl.com Subject: Re: Ajax navigation re-write and Issue 1024 / Pull req 1456
Hi Scott,
You are welcome. By the way, since you are working on the navigation, here's one thing to think about:
In our project we are very much making use of HTML5 offline manifests. We also want pages to be able to send parameters to each other, that are interpreted by JavaScript code on the page itself, not by the server (since the server is not available in offline). For example, in a master-detail view type of situation, there would be master page which sends item data as a parameter to a detail page.
Obviously, the general way to do this is to encode the parameters in the hash part of the URL (it also has to work between domains, so using JavaScript context is not an option) and have the recipient page decode it (e.g. in showpage event handler). The problem is that jQuery Mobile already uses the hash part for its own purposes. While url parameters are supported, those are (AFAIK) also used in the XHR request for the page, which breaks caching (since whole URL is used as cache key).
So for example, I would like to be able to have a master page (http://example.com/my-app/#master.html) which loads a detail page like so:
$.mobile.changePage({ url: "detail.html", parameters: { itemName: "Foo", itemId: "123" } });
And this would result in an XHR request for just http://example.com/my-app/detail.html, without any URL parameters (so that caching works correctly), but the resulting page would (after the transition) still have the parameters available in the hash part of the url (so that the page can retrieve the parameters from location.hash): http://example.com/my-app/#detail.html?itemName=Foo&itemId=123
Note, this should of course also work when I switch to another site, so there has to be some way that the hash part of a full URL encodes whether the parameters should be used in the XHR or not. One possibility might be simply to say that a URL may carry two sets of parameters, one for the server and another for the result page, and each begins with a question mark. So:
(note, I'm not saying two question marks is a good scheme, since I just came up with it for the sake of the example, but this illustrates that we have two types of parameters which may need to be supported simultaneously)
API-wise, the simplest approach would seem to be to support for this purpose only the variant of changePage that takes an object as first parameter. Then it is easy to differentiate between parameters meant for the next page (the case advocated here) and parameters meant for the server.
While this is an issue specifically for our project, I don't think we are the only ones who would like to pass information in the URL hash part to the next page. I'm willing to work on this issue and submit patches, but it doesn't make sense to do so if you are right now redesigning the system. So I hope you take this issue into account when doing your redesign, so that even if you don't implement it right away, the design supports it.
Thanks,

No comments:

Post a Comment