Managing browser history in Dart - html

I'm building a single-page Dart web app that will essentially consist of 1 Dart file (cross-compiled to JS) and 1 HTML file that has several "views" (screens, pages, etc.). in it. Depending on what "view" the user is currently located at, I will hide/enable different DOM elements defined inside this HTML file. This way the user can navigate between views without triggering multiple page loads.
I would still like to use each browser's native history-tracking mechanism, so that the user click can the back- and forward-buttons in the browser, and I'll have a Dart Historian object figure out what view to load (again just hiding/enabling DOM elements) depending on what URL the browser has in its history.
I've pretty much figured everything out, with one exception:
Say the user is currently "at" View #3, which has a URL of, say, http://myapp.example.com/#view3. Then they click a button that should take them to View #4 at, say, http://myapp.example.com/#view4. I need a way, in Dart, to tell the browser to:
Set http://myapp.example.com/#view4 in the browser URL bar
Add http://myapp.example.com/#view4 to the browser's history
If not already enabled, enable the browser's back button
I believe I can accomplish #1 above like so:
window.location.href = "http://myapp.example.com/#view3";
...but maybe not. Either way, how can I accomplish this (Dart code communicates with browser's history API)?

Check out the route library.
angular.dart also has it's own routing mechanism, but it's part of a much larger framework, so unless you plan on using the rest of it, I would recommend the stand-alone route library.
If you want to build your own solution, you can take a look at route's client.dart for inspiration.
There are two methods of history navigation supported:
The page fragment method that you've used. Reassign the window location to the new page fragment: window.location.assign(newPathWithPageFragment). Doing this will automatically add a new item to the browser history (which will then enable the back button).
The newer History API, which allows for regular URLs without fragments (e.g. http://myapp.example.com/view3. You can use window.history to control the history.The History API is only supported by newer browsers so that may be a concern (although given that dart2js also only supports newer browsers, there are probably not too many instances of a browser that dart2js supports that doesn't support the History API).
One issue you will have to handle if you support History API is the initial page load. When a user navigates to http://myapp.example.com/view3, the browser expects to find a resource at that location. You will have to setup your server to respond to any page request by serving your Dart application and then navigate to the correct view on the client-side. This issue will apply whether you use route, angular.dart, or build your own solution, since this is a general server-side issue and the above are all client-side libraries.

Related

Create menu item link to card works on desktop but mobile app requires logging in again

We would like to make a menu item redirect to a card we created. When we put in the new redirect link it is prompting us to login on again but only on mobile app usage; Desktops work fine.
Thanks
REF CASE # 14307579
So when updating the OLB menu link, having one of the menu options go to one of our dashboard card URLs, the change works fine for Desktop users (as opposed to mobile app users where it works but requires logging in for a second time).
The second of three methods or platforms would be the rare method of going to OLB url via the mobile browser... there if going to the desired URL afterwards also seems to work.
However, the third method and encouraged why is to use the CUTX mobile app (which is just the same browser wrapped in an app pointing to the OLB URL for starters. The problem lies here when going to the menu and URL for that same item, it fails.
I believe the first two methods keeps the session information and everything works. The third and desired method fails due to session loss.
The question, I believe is how to have the URL keep and maintain the session as desired and hence the URL should work.
Or it could be something completely different. Either way, we need a solution for links to work from the mobile devices without requiring members to log in again.
The alternative way to interpret this question is 'how do I have one web server + URL handle authentication from Banno's Authentication Framework e.g. for a sidebar navigation menu item and a plugin card?'.
In that case, it would be possible but you would need to have two External Applications defined.
Recall that an External Application can have one, and only one, defined link type. As an example, plugin cards use the PluginCard link type. Creating an External Application with the PluginCard link type makes that External Application eligible to be configured as a plugin card for the Dashboard.
It sounds like you are hoping to use something like the DebtRelief (Loan assistance) link type, since that falls under the category of "Main navigation links". Unfortunately, there isn't any to have an External Application with two link types, nor is there a defined way to 'redirect from this link to that link' when it comes to plugin cards.
A way that you might handle the 'how do I have one web server + URL handle authentication from Banno's Authentication Framework e.g.
for a sidebar navigation menu item and a plugin card?' question:
Assume that your institution has its own web application server that can handle authentication requests at a Redirect URI, for example https://myawesomeinstitution.com/developerstuff.
In this case, you could set up an External Application with link type PluginCard and Redirect URI of https://myawesomeinstitution.com/developerstuff that you can use for the plugin card. You could set up a separate External Application with link type DebtRelief (as an example) with that same Redirect URI of https://myawesomeinstitution.com/developerstuff. This would give you the UX that you want, i.e. a sidebar navigation menu item and a plugin card, while keeping development costs pretty low since it all uses the same Authentication Framework.
If you wanted to somehow differentiate the UI presented to the user (e.g. if the UI you want for the plugin card wouldn't make sense as a launching point for when the user clicks the sidebar navigation menu item), then you could adjust the above by setting up slightly different paths such as https://myawesomeinstitution.com/developerstuff/sidebarthing for the sidebar navigation menu item and https://myawesomeinstitution.com/developerstuff/pluginotherthing for the plugin card. That would use the same web application server, just handling different routes so they can serve up different content.
As an aside, it's entirely possible that your web server may not be selecting the correct credentials (Client ID + Client Secret) if there is only a single URL being used (e.g. https://myawesomeinstitution.com/developerstuff from the example above). That would certainly explain why Banno Mobile seemingly requires an 'unnecessary' login since there is a mismatch between the credentials expected for the sidebar navigation item versus the plugin card (or vice versa). Using two different URLs (handled by the same server) would make it easier to ensure that the correct credentials are being served in the right context (e.g. the hypothetical examples from above of https://myawesomeinstitution.com/developerstuff/sidebarthing and https://myawesomeinstitution.com/developerstuff/pluginotherthing).

Communicating between a Chrome extension popup and an iFrame embedded in that popup

I have an iFrame embedded in my Chrome extension popup which displays a webpage that I am in control of. I am able to send data from the iFrame to the Chrome popup script using sendMessage from my embedded website and onMessageExternal from my popup script, but I would also like to send data the other way around (such as the extension id - I can’t access this value within an iframe).
I’ve read about methods such as using the window.postMessage() function available in HTML5, and have investigated the method discussed here, although I am not sure the second method would work in the context I intend to use it in. If I were to use postMessage, I would not be able to confirm that the message was sent by my extension as there is no domain for me to check against unless I hardcoded my plugin id in, which I would like to avoid.
Is there another method of doing what I am trying to do, or would postMessage be the best way? I want to avoid query strings to make it somewhat more difficult to send an illegitimate request to my webpage. I’m not doing anything with sensitive data, I’m just using the data to make changes to the behaviour of the webpage based on whether it is running in an extension or running natively in the browser, and using the extension id for logging purposes.

NaCl Module HTML Interface

I'm developing a Chrome packaged app which displays a certain kind of document as HTML. I have the app working to some degree, but would like to add a feature allowing the user to open a file by clicking on a link to an applicable file.
I am able to launch the app by MIME type as per the docs here, and am familiar with the pp::Instance::HandleDocumentLoad method to handle the clicked link's source, but am unsure how to display HTML I'm generating from the parsed document.
This is easy enough to do when the user manually launches the app and selects a file using an input element and the HTML file system since the HTML GUI is specified in the app manifest, but as far as I can tell, launching based on MIME type just embeds the NMF.
TL;DR: Is there a way to specify a HTML interface for (or a simple way to render HTML from) a NaCl module instance created by a nacl_modules manifest entry?
This is possible, but it's a bit of a hack. I copied the trick from here:
https://groups.google.com/d/msg/native-client-discuss/UJu7VXvV_bw/pLc19D50gbwJ
You can see how I did it here and here:
Basically, you listen on chrome.tabs.onCreated and chrome.tabs.onUpdated, then you inject a small bit of JavaScript that checks for the embed element with the correct mimetype. If it finds the element, it sends a message (via chrome.runtime.sendMessage) to your extension. When your extension gets that message, it injects the rest of your JavaScript into the page using chrome.tabs.executeScript. At this point you can display whatever you want.
You could do it earlier, by injecting your code into every page, but I found this was a bit nicer, as it only injects a small bit of code.

Difference between href="#!" and href="#" [duplicate]

I've just noticed that the long, convoluted Facebook URLs that we're used to now look like this:
http://www.facebook.com/example.profile#!/pages/Another-Page/123456789012345
As far as I can recall, earlier this year it was just a normal URL-fragment-like string (starting with #), without the exclamation mark. But now it's a shebang or hashbang (#!), which I've previously only seen in shell scripts and Perl scripts.
The new Twitter URLs now also feature the #! symbols. A Twitter profile URL, for example, now looks like this:
http://twitter.com/#!/BoltClock
Does #! now play some special role in URLs, like for a certain Ajax framework or something since the new Facebook and Twitter interfaces are now largely Ajaxified?
Would using this in my URLs benefit my Web application in any way?
This technique is now deprecated.
This used to tell Google how to index the page.
https://developers.google.com/webmasters/ajax-crawling/
This technique has mostly been supplanted by the ability to use the JavaScript History API that was introduced alongside HTML5. For a URL like www.example.com/ajax.html#!key=value, Google will check the URL www.example.com/ajax.html?_escaped_fragment_=key=value to fetch a non-AJAX version of the contents.
The octothorpe/number-sign/hashmark has a special significance in an URL, it normally identifies the name of a section of a document. The precise term is that the text following the hash is the anchor portion of an URL. If you use Wikipedia, you will see that most pages have a table of contents and you can jump to sections within the document with an anchor, such as:
https://en.wikipedia.org/wiki/Alan_Turing#Early_computers_and_the_Turing_test
https://en.wikipedia.org/wiki/Alan_Turing identifies the page and Early_computers_and_the_Turing_test is the anchor. The reason that Facebook and other Javascript-driven applications (like my own Wood & Stones) use anchors is that they want to make pages bookmarkable (as suggested by a comment on that answer) or support the back button without reloading the entire page from the server.
In order to support bookmarking and the back button, you need to change the URL. However, if you change the page portion (with something like window.location = 'http://raganwald.com';) to a different URL or without specifying an anchor, the browser will load the entire page from the URL. Try this in Firebug or Safari's Javascript console. Load http://minimal-github.gilesb.com/raganwald. Now in the Javascript console, type:
window.location = 'http://minimal-github.gilesb.com/raganwald';
You will see the page refresh from the server. Now type:
window.location = 'http://minimal-github.gilesb.com/raganwald#try_this';
Aha! No page refresh! Type:
window.location = 'http://minimal-github.gilesb.com/raganwald#and_this';
Still no refresh. Use the back button to see that these URLs are in the browser history. The browser notices that we are on the same page but just changing the anchor, so it doesn't reload. Thanks to this behaviour, we can have a single Javascript application that appears to the browser to be on one 'page' but to have many bookmarkable sections that respect the back button. The application must change the anchor when a user enters different 'states', and likewise if a user uses the back button or a bookmark or a link to load the application with an anchor included, the application must restore the appropriate state.
So there you have it: Anchors provide Javascript programmers with a mechanism for making bookmarkable, indexable, and back-button-friendly applications. This technique has a name: It is a Single Page Interface.
p.s. There is a fourth benefit to this technique: Loading page content through AJAX and then injecting it into the current DOM can be much faster than loading a new page. In addition to the speed increase, further tricks like loading certain portions in the background can be performed under the programmer's control.
p.p.s. Given all of that, the 'bang' or exclamation mark is a further hint to Google's web crawler that the exact same page can be loaded from the server at a slightly different URL. See Ajax Crawling. Another technique is to make each link point to a server-accessible URL and then use unobtrusive Javascript to change it into an SPI with an anchor.
Here's the key link again: The Single Page Interface Manifesto
First of all: I'm the author of the The Single Page Interface Manifesto cited by raganwald
As raganwald has explained very well, the most important aspect of the Single Page Interface (SPI) approach used in FaceBook and Twitter is the use of hash # in URLs
The character ! is added only for Google purposes, this notation is a Google "standard" for crawling web sites intensive on AJAX (in the extreme Single Page Interface web sites). When Google's crawler finds an URL with #! it knows that an alternative conventional URL exists providing the same page "state" but in this case on load time.
In spite of #! combination is very interesting for SEO, is only supported by Google (as far I know), with some JavaScript tricks you can build SPI web sites SEO compatible for any web crawler (Yahoo, Bing...).
The SPI Manifesto and demos do not use Google's format of ! in hashes, this notation could be easily added and SPI crawling could be even easier (UPDATE: now ! notation is used and remains compatible with other search engines).
Take a look to this tutorial, is an example of a simple ItsNat SPI site but you can pick some ideas for other frameworks, this example is SEO compatible for any web crawler.
The hard problem is to generate any (or selected) "AJAX page state" as plain HTML for SEO, in ItsNat is very easy and automatic, the same site is in the same time SPI or page based for SEO (or when JavaScript is disabled for accessibility). With other web frameworks you can ever follow the double site approach, one site is SPI based and another page based for SEO, for instance Twitter uses this "double site" technique.
I would be very careful if you are considering adopting this hashbang convention.
Once you hashbang, you can’t go back. This is probably the stickiest issue. Ben’s post put forward the point that when pushState is more widely adopted then we can leave hashbangs behind and return to traditional URLs. Well, fact is, you can’t. Earlier I stated that URLs are forever, they get indexed and archived and generally kept around. To add to that, cool URLs don’t change. We don’t want to disconnect ourselves from all the valuable links to our content. If you’ve implemented hashbang URLs at any point then want to change them without breaking links the only way you can do it is by running some JavaScript on the root document of your domain. Forever. It’s in no way temporary, you are stuck with it.
You really want to use pushState instead of hashbangs, because making your URLs ugly and possibly broken -- forever -- is a colossal and permanent downside to hashbangs.
To have a good follow-up about all this, Twitter - one of the pioneers of hashbang URL's and single-page-interface - admitted that the hashbang system was slow in the long run and that they have actually started reversing the decision and returning to old-school links.
Article about this is here.
I always assumed the ! just indicated that the hash fragment that followed corresponded to a URL, with ! taking the place of the site root or domain. It could be anything, in theory, but it seems the Google AJAX Crawling API likes it this way.
The hash, of course, just indicates that no real page reload is occurring, so yes, it’s for AJAX purposes. Edit: Raganwald does a lovely job explaining this in more detail.

What could be different ways of creating a user interface for a chrome extension?

I am trying to learn what could be the best ways of developing user interface for chrome extension for my application. The 2 approaches that I have come across are i)Using a browser action with default_popup html page or ii) Injecting some component into the page that is loaded in the tab. First approach is pretty straightforward but has some restricted use (like it is destroyed on tab/window switch which is useful in the context of my application). Coming to the second approach, it seems it requires every component which can be injected to be listed under web_accessible_resources. As the extension UI gets complex, this list is bound to increase. But surprisingly, Pocket extension's manifest does not seem to list any js files or html files though it does not use a popup page too. How does it work? Is there any other way of creating the user interface too?
Have you checked on the documentation regarding chrome.windows API? This API will allow you to create new windows and tabs in the browser, so you can create the html content from your extension. All you'll need is declaring the pertinent permissions on the manifest file. You can read more information here: https://developer.chrome.com/extensions/windows