Implement github.com file seamless file navigation - javascript

I just noticed a recent change when browsing github repositorys. When you select a file or folder, the new file slides in and pushed the old file out. This is easy enough to do with jquery, but what's really different is that the URL itself actually changes so that bookmarks still work. I've been struggling to create this for a book navigating site I'm working on but haven't been able to update the url without a full page refresh. Any ideas on how github does this?

It's using the new HTML5 API history.pushState/history.replaceState for doing this (so it only works in modern browsers).
See https://developer.mozilla.org/en/DOM/Manipulating_the_browser_history#Adding_and_modifying_history_entries for more details.
If you want a solution for all browsers, then you have to stick to modifying the fragment (the bit after the #)

I haven't looked at the underlying code, but I believe it is a combination of the new HTML5 spec of web history and location (well, location is old, but it's an updated spec).
Mozilla docs
W3C history spec
W3C location spec
The W3C specs are very verbose (after all, they are specs), so that can be hard to read. I think this other answer on Stack Overflow is in the right direction.
You have to keep in mind that this is part of the HTML5 specs, so not every browser will be able to handle this functionality. We are building this type of navigation out on a project at work, and if the browser doesn't support this feature, it's just a regular page refresh.

Related

Changing the behaviour of History.js for HTML4 browsers

I'm using the history.js plugin (https://github.com/browserstate/history.js/) to give elements on a page a certain unique url when opened.
As expected, this works great in HTML5 browsers, but the plugin isn't quite doing what I need in HTML4 browsers (Internet Explorer, in other words).
Basically, I'm having the same pitfall that is outlined in the documentation for the plugin, as seen here:
These issues are unavoidable if hashes are used.
URLs get polluted if we did not start on the home page
http://www.facebook.com/balupton#!/balupton?sk=info
http://mywebsite.com/page1#/page2
Although, my URLs are not quite as bad as this, other than the hash being thrown in, the url is usable. Removing the suid at the end would also be nice, as it isn't necessary in my case, but it should be fine if that's not possible.
Here is what my URL needs to look like:
http://domain.com/sitename/main/item/109
And this is the result in IE:
http://domain.com/sitename/#main/idea/109?&_suid=13812466306670658...
As far as I could gather from the documentation was that my only option would be to disable the HTML4 fallback, which means that nothing will happen in IE.
I'm wondering if theres a way to just forgo the HTML4 fallback options, but still use the HTML5 solution in it's place (to change the url in the same way it does, just with a different method.. I know that the method used for the HTML5 solution won't work). Or, if there's any other way to alter the way that the HTML4 solution is implemented, to bend it to the needs of this project?
UPDATE: In my own research, I am seeming to find that it is impossible to alter an HTML4 compliant browser's url without using a hash. I'm currently in the process of integrating some workarounds into my project so that our URLs use hashes. I'm still leaving this question open as this isn't really an answer, and I don't even know if I am 100% right.
If it's still needed, the partial answer to cleaner URL for you would be solution below.
Try code below regarding to https://github.com/browserstate/history.js/
History.options.disableSuid
Force History not to append suid

HTML5 History API Implementation

This might sound like a duplicate, but I have searched through the forum questions and I haven't found what I was looking for.
So, I have been reading for a while now, and I still cannot decide what to do about the next situation. I'm building a one page website ( not my first ) which requires a smooth User Interface, so I have decide to load pages with AJAX for a better and more friendly navigation.
I have been using : SmartAjax ; for a while and it was good enough for me. It works nicely and I had no problems with it, but with it had problems handling a lot of JavaScript as callback. Also there was a lot of work to do when implementing it through the whole website.
And because now HTML5 is more stable than it was one year ago, and most of it's features are working in most of the browsers ( but some still require a polyfill ), I decided to start using HTML5 History API. A lot of websites use it and it's very easy to do so, but there some aspects I don't understand about it.
Therefore here's what I would like to know about it :
is it supported by all browsers by now, and most important, will touch devices and mobiles support it ?
is there a special library or a framework for it ?
is it safe to use for small websites ( a maximum of 6 pages ) but with a lot of JavaScript ?
does it behave when using it in combination with jQuery Plugins ?
what about hashbang and hashes ? aren't they the same as using History API ? and what are the differences ?
I would appreciate all the help and info I get about the points stated above.
Browser support
Forget it. Not even IE 9 supports history.pushState. Mobile browsers not very safe either. But there is a library (see below) that makes this incompatibility completely transparent to the developer.
Library
Well, in pure HTML 5 environments, the history api is pretty straightforward. For others, the history.js library has gotten quite some attention, plus it offers an automated fallback to the old hash-writing
On Small Websites
Well, you better have your JavaScript and your potential States organised, then. But if so, I see no problem.
History & jQuery & plugins
I have used the two together in a couple of projects now. I have not yet found any problem with using jQuery and jQuery Plugins, except for - of course - the typical issues associated with Injected HTML (i.e. event handlers must be rebound; $(document).ready() might or might not work in some environments, etc).
Hashes vs. history.pushState
The Hash-Notation has been used as a workaround (or nowadays, fallback). It becomes unnecessary when using history.pushState.
What I have found to be the major difference is, that the URL in the address bar is always directly understandable by the server, especially for bookmarking or link-sharing purposes. If you had http://example.org/#/my/fancy/site, then your index page would have to parse the hash (via javascript, as you can't access the hash server-side), and then inject/redirect to my/fancy/site.
However, if using using history.pushState, the Browser's address bar shows http://example.org/my/fancy/site - which is directly routable.
(and, imagine spelling out a hash, or hash-bang URL to someone via phone!)
Hope that clarifies some or your doubts with history! I can strongly recommend History.js as library a of choice.
I would prefer to use HTML5 History for browsers which support it (all current browsers and upcoming IE10), and use just static (non-Ajax) links for older ones. As browsers are updated, your site gets better automatically.
I wouldn't recommend using hash polyfills due to serious disadvantages of hashes (e.g. pointless referers that don't include hash part of URL, thus making stats rather useless).

How facebook overwrite link? [duplicate]

Go to http://www.facebook.com/facebook?v=wall, then click on the info tab. The content will be loaded, and the address bar now becomes http://www.facebook.com/facebook?v=info but the webpage didn't reload.
At first I think it is Ajax, but my question is, how do you change the address bar without reloading? I know I can change anchor (#wall) using JS but querystring (?v=wall), how?
It's using HTML5's new history.pushState() feature to allow the page to masquerade as being at a different URL to that from which it was originally fetched.
This seems only to be supported by WebKit at the moment, which is why the rest of us are seeing ?v=wall#!/facebook?v=info instead of ?v=info.
The feature allows dynamically-loaded pages to be properly bookmarked, exchanged etc between JS-supporting and non-JS-supporting user agents. Because if you as a JS user linked someone to ?v=wall#!/facebook?v=info and their browser didn't support JS and XMLHttpRequest, the page wouldn't work for them. The #! is also used as a tip to search engines to download the non-AJAX version.
#Snoob - I'd appreciate it if you accepted #bobince's answer instead, he's was on the right track about the specifics first here. Since I can't delete/remove this until it's unaccepted I'll update it to be as correct as possible.
At the moment it's a WebKit (Chrome, Safari, etc.) specific thing you're seeing (or rather, not seeing), as #bobince points out in other browsers you can see the real URL in the bar:
http://www.facebook.com/facebook?v=wall#!/facebook?v=info\
Where Chrome just shows:
http://www.facebook.com/facebook?v=info
It makes a bit of sense, given this is how you make AJAX Content crawlable with the Google search engine, so their browser recognizes where the content comes from as well.
Correction on the specifics: Webkit browsers are showing the shortened URL facebook wants using the HTML 5 history features you can see the code here (take a look at the HistoryManager) in this case specifically they're using .replaceState() to replace the URL you went to with the direct one available.
Note: This answer may not be valid later (the WebKit specific bit), as other browsers support HTML5 features more and more this may become outdated quickly.
For MooTools developers I recommend checking out cpojer's mootools-history plugin which provides support for the native history API when available, with a fallback to hashes.
I don't have Facebook so I can't check. But I'm 95% sure that it has to be a full page request, the location bar is unwritable because this would be a very useful feature to absure for phishing websites (instead of http://fakeonlinebank.com it rewrite to http://yourtrustybank). It's probably just so fast that your browser appears to only load that part?
But I'm curious to see if someone will correct me on this, because that would mean they have the answer you do want to hear ;)

How to build a full screen html 5 web app?

Are there any currently accepted methods for building full screen web applications in HTML 5 using just JavaScript and CSS?
If so, what are the pros and cons of each? What cross-browser quirks are there?
This is bleeding edge, but the latest chrome builds have a Fullscreen API. See this slide deck for details:
http://html5-demos.appspot.com/static/html5-whats-new/template/index.html#42
Also, it looks like these dudes figured out a way to do it without resorting to unsupported features:
http://www.html5rocks.com/en/tutorials/casestudies/gopherwoord-studios-resizing-html5-games.html
There is a proposal which is based on discussions on the WHATWG mailing list. This was originally triggered by this WebKit API, but as far as I'm aware that only works on iOS and there are no other implementations at present.
As it stands, Full Screen mode can only be induced by the user directly telling the browser to go into that mode.
It's like back in the slave days. You're the slave, the user is the master, and pixels are your food. They may not give you much, but they give you some, and you have to savor every last bit.
This used to be possible back in the day - IE 4 did "Chromeless Windows" - but is no longer possible in pure HTML for security reasons.
If you can have the user install local software, something like Mozilla Prism might work - I've never tried it myself though.

How does facebook rewrite the source URL of a page in the browser address bar?

Go to http://www.facebook.com/facebook?v=wall, then click on the info tab. The content will be loaded, and the address bar now becomes http://www.facebook.com/facebook?v=info but the webpage didn't reload.
At first I think it is Ajax, but my question is, how do you change the address bar without reloading? I know I can change anchor (#wall) using JS but querystring (?v=wall), how?
It's using HTML5's new history.pushState() feature to allow the page to masquerade as being at a different URL to that from which it was originally fetched.
This seems only to be supported by WebKit at the moment, which is why the rest of us are seeing ?v=wall#!/facebook?v=info instead of ?v=info.
The feature allows dynamically-loaded pages to be properly bookmarked, exchanged etc between JS-supporting and non-JS-supporting user agents. Because if you as a JS user linked someone to ?v=wall#!/facebook?v=info and their browser didn't support JS and XMLHttpRequest, the page wouldn't work for them. The #! is also used as a tip to search engines to download the non-AJAX version.
#Snoob - I'd appreciate it if you accepted #bobince's answer instead, he's was on the right track about the specifics first here. Since I can't delete/remove this until it's unaccepted I'll update it to be as correct as possible.
At the moment it's a WebKit (Chrome, Safari, etc.) specific thing you're seeing (or rather, not seeing), as #bobince points out in other browsers you can see the real URL in the bar:
http://www.facebook.com/facebook?v=wall#!/facebook?v=info\
Where Chrome just shows:
http://www.facebook.com/facebook?v=info
It makes a bit of sense, given this is how you make AJAX Content crawlable with the Google search engine, so their browser recognizes where the content comes from as well.
Correction on the specifics: Webkit browsers are showing the shortened URL facebook wants using the HTML 5 history features you can see the code here (take a look at the HistoryManager) in this case specifically they're using .replaceState() to replace the URL you went to with the direct one available.
Note: This answer may not be valid later (the WebKit specific bit), as other browsers support HTML5 features more and more this may become outdated quickly.
For MooTools developers I recommend checking out cpojer's mootools-history plugin which provides support for the native history API when available, with a fallback to hashes.
I don't have Facebook so I can't check. But I'm 95% sure that it has to be a full page request, the location bar is unwritable because this would be a very useful feature to absure for phishing websites (instead of http://fakeonlinebank.com it rewrite to http://yourtrustybank). It's probably just so fast that your browser appears to only load that part?
But I'm curious to see if someone will correct me on this, because that would mean they have the answer you do want to hear ;)

Categories

Resources