Coder Social home page Coder Social logo

browserstate / history.js Goto Github PK

View Code? Open in Web Editor NEW
10.8K 307.0 1.4K 3 MB

History.js gracefully supports the HTML5 History/State APIs (pushState, replaceState, onPopState) in all browsers. Including continued support for data, titles, replaceState. Supports jQuery, MooTools and Prototype. For HTML5 browsers this means that you can modify the URL directly, without needing to use hashes anymore. For HTML4 browsers it will revert back to using the old onhashchange functionality.

Home Page: http://browserstate.github.com/history.js/demo/

License: Other

CoffeeScript 1.37% JavaScript 96.42% PHP 0.29% HTML 1.92%
html5-history-api html5-history javascript polyfill hashchange

history.js's Introduction

Memo

While there are some legitimate bugs and differences in state handling even in modern browsers, they are relatively small enough now that you can just use the native HTML5 History API. If you intend to support legacy browsers, then History.js is your bet.

This notice is here as History.js does not receive enough funding to be maintained, so it exists only in legacy condition for legacy browsers. Perhaps it still works for modern browsers, but it could really do with maintenance. Maintenance is very difficult as the library requires manual testing in HTML5 and HTML4 modes, and for each adapter, and for each browser. So that means 2^(# of adapters)^(# of browsers and their versions) tests that need to be run by a human. Tests need to be run by a human as certain failures require browser interactions, such as navigating from the test suite to a different domain and back again, or clicking the physical back buttons, or checking if the physical back buttons actually work. This takes a lot of time.

Despite History.js being one of the most popular JavaScript libraries there is, and has been used by even multi-million-user companies in its time - the reality of economy and company practices seems to be that companies prefer to fork their own internal versions and fix locally with their own devs rather than fund open-source maintainers what they would pay their own devs to make things better for everyone, including themselves, which would be cheaper - but no, that would require too many tiers of company approval that don't understand the need.

As such, if you are an open-source developer, I'd recommend just working on open-source projects that are paid for by your own consulting work or your own company (e.g. every successful open-source project). As otherwise, when they become popular, you better hope they are easily maintainable and testable, otherwise the cost of maintenance is higher than the free time of the maintainers.

So with all that said, this repo still exists for archival purposes, legacy browsers, and a hub for anarachistic issue & fork maintenance.

Cheers, Benjamin Lupton, founder of Bevry, creator of History.js

Welcome to History.js
v1.8b2, June 22 2013

Slack community badge Patreon donate button Gratipay donate button Flattr donate button PayPal donate button Bitcoin donate button Wishlist browse button

News

  • 22/06/2013: Beta 2 of v1.8 is released. Fixes and uncompressed bundled files.
  • 31/05/2013: Beta 1 of v1.8 is released. Fixes.
  • 14/02/2013: Alpha 4 of v1.8 is released. Fixes.
  • 05/02/2013: Alpha 3 of v1.8 is released. Tests updated.
  • 21/01/2013: Alpha 2 of v1.8 is released. Correct statechange behaviour.
  • 19/01/2013: Alpha 1 of v1.8 is released. Started to categorize old balupton's issues.

History

See the HISTORY.md file for a detailed list of features, changes, solved issues and bugs

Involve

Please create an issue if something doesn't work or if there is a browser specific bug. I'll try to fix it as soon as possible. Please send me your Pull requests if you have a nice solution! I'm also going to review old issues in balupton's repository and try to solve them too.

Aims

  • Follow the HTML5 History API as much as possible
  • Provide a cross-compatible experience for all HTML5 Browsers (they all implement the HTML5 History API a little bit differently causing different behaviours and sometimes bugs - History.js fixes this ensuring the experience is as expected / the same / great throughout the HTML5 browsers)
  • Provide a backwards-compatible experience for all HTML4 Browsers using a hash-fallback (including continued support for the HTML5 History API's data, title, pushState and replaceState) with the option to remove HTML4 support if it is not right for your application
  • Provide a forwards-compatible experience for HTML4 States to HTML5 States (so if a hash-fallbacked url is accessed by a HTML5 browser it is naturally transformed into its non-hashed url equivalent)
  • Provide support for as many javascript frameworks as possible via adapters; especially Dojo, ExtJS, jQuery, MooTools, Right.js and Zepto.

Quick Install

Via Ajaxify Script

To ajaxify your entire website with the HTML5 History API, History.js and jQuery the Ajaxify script is all you need. It's that easy.

Via Ajaxify Extension

If you don't have access to your server, or just want to try out the Ajaxify script first, you can install the History.js It! Google Chrome Extension to try out History.js via Ajaxify on select websites without actually installing History.js/Ajaxify on your server.

Via Ruby On Rails Gem

If you are using Rails, then the easiest way for you to try History.js would be to use Wiselinks gem. Wiselinks integrates into Rails application and allows you to start using History.js with three lines of code.

Direct Install

Working with History.js directly

(function(window,undefined){

	// Bind to StateChange Event
	History.Adapter.bind(window,'statechange',function(){ // Note: We are using statechange instead of popstate
		var State = History.getState(); // Note: We are using History.getState() instead of event.state
	});

	// Change our States
	History.pushState({state:1}, "State 1", "?state=1"); // logs {state:1}, "State 1", "?state=1"
	History.pushState({state:2}, "State 2", "?state=2"); // logs {state:2}, "State 2", "?state=2"
	History.replaceState({state:3}, "State 3", "?state=3"); // logs {state:3}, "State 3", "?state=3"
	History.pushState(null, null, "?state=4"); // logs {}, '', "?state=4"
	History.back(); // logs {state:3}, "State 3", "?state=3"
	History.back(); // logs {state:1}, "State 1", "?state=1"
	History.back(); // logs {}, "Home Page", "?"
	History.go(2); // logs {state:3}, "State 3", "?state=3"

})(window);

How would the above operations look in a HTML5 Browser?

  1. www.mysite.com
  2. www.mysite.com/?state=1
  3. www.mysite.com/?state=2
  4. www.mysite.com/?state=3
  5. www.mysite.com/?state=4
  6. www.mysite.com/?state=3
  7. www.mysite.com/?state=1
  8. www.mysite.com
  9. www.mysite.com/?state=3

Note: These urls also work in HTML4 browsers and Search Engines. So no need for the hashbang (#!) fragment-identifier that google "recommends".

How would they look in a HTML4 Browser?

  1. www.mysite.com
  2. www.mysite.com/#?state=1&_suid=1
  3. www.mysite.com/#?state=2&_suid=2
  4. www.mysite.com/#?state=3&_suid=3
  5. www.mysite.com/#?state=4
  6. www.mysite.com/#?state=3&_suid=3
  7. www.mysite.com/#?state=1&_suid=1
  8. www.mysite.com
  9. www.mysite.com/#?state=3&_suid=3

Note 1: These urls also work in HTML5 browsers - we use replaceState to transform these HTML4 states into their HTML5 equivalents so the user won't even notice :-)

Note 2: These urls will be automatically url-encoded in IE6 to prevent certain browser-specific bugs.

Note 3: Support for HTML4 browsers (this hash fallback) is optional - why supporting HTML4 browsers could be either good or bad based on my app's use cases

What's the deal with the SUIDs used in the HTML4 States?

  • SUIDs (State Unique Identifiers) are used when we utilise a title and/or data in our state. Adding a SUID allows us to associate particular states with data and titles while keeping the urls as simple as possible (don't worry it's all tested, working and a lot smarter than I'm making it out to be).
  • If you aren't utilising title or data then we don't even include a SUID (as there is no need for it) - as seen by State 4 above :-)
  • We also shrink the urls to make sure that the smallest url will be used. For instance we will adjust http://www.mysite.com/#http://www.mysite.com/projects/History.js to become http://www.mysite.com/#/projects/History.js automatically. (again tested, working, and smarter).
  • It works with domains, subdomains, subdirectories, whatever - doesn't matter where you put it. It's smart.
  • Safari 5 will also have a SUID appended to the URL, it is entirely transparent but just a visible side-effect. It is required to fix a bug with Safari 5.

Is there a working demo?

  • Sure is, give it a download and navigate to the demo directory in your browser :-)
  • If you are after something a bit more adventurous than a end-user demo, open up the tests directory in your browser and editor - it'll rock your world and show all the vast use cases that History.js supports.

Download & Installation

  • Download History.js and upload it to your webserver. Download links: tar.gz or zip

  • Include History.js

    • For Dojo v1.8+

       <script src="http://www.yourwebsite.com/history.js/scripts/bundled/html4+html5/dojo.history.js"></script>
    • For ExtJs v1.8+

       <script src="http://www.yourwebsite.com/history.js/scripts/bundled/html4+html5/extjs.history.js"></script>
    • For jQuery v1.3+

       <script src="http://www.yourwebsite.com/history.js/scripts/bundled/html4+html5/jquery.history.js"></script>
    • For Mootools v1.3+

       <script src="http://www.yourwebsite.com/history.js/scripts/bundled/html4+html5/mootools.history.js"></script>
    • For Right.js v2.2+

       <script src="http://www.yourwebsite.com/history.js/scripts/bundled/html4+html5/right.history.js"></script>
    • For Zepto v0.5+

       <script src="http://www.yourwebsite.com/history.js/scripts/bundled/html4+html5/zepto.history.js"></script>
    • For everything else

       <script src="http://www.yourwebsite.com/history.js/scripts/bundled/html4+html5/native.history.js"></script>

Note: If you want to only support HTML5 Browsers and not HTML4 Browsers (so no hash fallback support) then just change the /html4+html5/ part in the urls to just /html5/. See Why supporting HTML4 browsers could be either good or bad based on my app's use cases

Get Updates

Get Support

  • History.js is maintained by people like you. If you find a bug, report it to the GitHub Issue Tracker. If you've fixed a bug submit a Pull Request and add your fork to the Network Wiki Page.

  • If you would like paid support and trainings, or have job offers, then refer to the Network Wiki Page. If you are qualified with History.js, then be sure to add your details to that page too.

  • If your company uses History.js on your projects, and would like to see it grow and prosper (better documentation, bugfixes, upgrades, maintenance, etc.) and would love to become a corporate sponsor then do email [email protected]

  • If you would like free support for History.js, then post your question on Stackoverflow and be sure to use the history.js tag when asking your question.

  • If you've created a website that uses History.js, or know of one, be sure to add it to the Showcase Wiki Page.

  • If you'd love to +1 or like this project, then be sure to tweet about it and click the "watch" button up the top of its Project Page.

  • For anything else, refer to the History.js GitHub Wiki Site.

Thanks! every bit of help really does make a difference!

Browsers: Tested and Working In

HTML5 Browsers

  • Firefox 4+
  • Chrome 8+
  • Opera 11.5+
  • Safari 5.0+
  • Safari iOS 4.3+

HTML4 Browsers

  • IE 6, 7, 8, 9, (10)
  • Firefox 3
  • Opera 10, 11.0
  • Safari 4
  • Safari iOS 4.2, 4.1, 4.0, 3.2

Exposed API

Functions

States

  • History.pushState(data,title,url)
    Pushes a new state to the browser; data can be null or an object, title can be null or a string, url must be a string
  • History.replaceState(data,title,url)
    Replaces the existing state with a new state to the browser; data can be null or an object, title can be null or a string, url must be a string
  • History.getState()
    Gets the current state of the browser, returns an object with data, title and url
  • History.getStateByIndex
    Gets a state by the index
  • History.getCurrentIndex
    Gets the current index
  • History.getHash()
    Gets the current hash of the browser

Adapter

  • History.Adapter.bind(element,event,callback)
    A framework independent event binder, you may either use this or your framework's native event binder.
  • History.Adapter.trigger(element,event)
    A framework independent event trigger, you may either use this or your framework's native event trigger.
  • History.Adapter.onDomLoad(callback)
    A framework independent onDomLoad binder, you may either use this or your framework's native onDomLoad binder.

Navigation

  • History.back()
    Go back once through the history (same as hitting the browser's back button)
  • History.forward()
    Go forward once through the history (same as hitting the browser's forward button)
  • History.go(X)
    If X is negative go back through history X times, if X is positive go forwards through history X times

Debug

  • History.log(...)
    Logs messages to the console, the log element, and fallbacks to alert if neither of those two exist
  • History.debug(...)
    Same as History.log but only runs if History.options.debug === true

Options

  • History.options.hashChangeInterval
    How long should the interval be before hashchange checks
  • History.options.safariPollInterval
    How long should the interval be before safari poll checks
  • History.options.doubleCheckInterval
    How long should the interval be before we perform a double check
  • History.options.disableSuid
    Force History not to append suid
  • History.options.storeInterval
    How long should we wait between store calls
  • History.options.busyDelay
    How long should we wait between busy events
  • History.options.debug
    If true will enable debug messages to be logged
  • History.options.initialTitle
    What is the title of the initial state
  • History.options.html4Mode
    If true, will force HTMl4 mode (hashtags)
  • History.options.delayInit
    Want to override default options and call init manually.

Events

  • window.onstatechange
    Fired when the state of the page changes (does not include hash changes)
  • window.onanchorchange
    Fired when the anchor of the page changes (does not include state hashes)

Known Issues

  • Opera 11 fails to create history entries when under stressful loads (events fire perfectly, just the history events fail) - there is nothing we can do about this
  • Mercury iOS fails to apply url changes (hashes and HTML5 History API states) - there is nothing we can do about this

Notes on Compatibility

  • History.js solves the following browser bugs:
    • HTML5 Browsers
      • Chrome 8 sometimes does not contain the correct state data when traversing back to the initial state
      • Safari 5, Safari iOS 4 and Firefox 3 and 4 do not fire the onhashchange event when the page is loaded with a hash
      • Safari 5 and Safari iOS 4 do not fire the onpopstate event when the hash has changed unlike the other browsers
      • Safari 5 and Safari iOS 4 fail to return to the correct state once a hash is replaced by a replaceState call / bug report
      • Safari 5 and Safari iOS 4 sometimes fail to apply the state change under busy conditions / bug report
      • Google Chrome 8,9,10 and Firefox 4 prior to the RC will always fire onpopstate once the page has loaded / change recommendation
      • Safari iOS 4.0, 4.1, 4.2 have a working HTML5 History API - although the actual back buttons of the browsers do not work, therefore we treat them as HTML4 browsers
      • None of the HTML5 browsers actually utilise the title argument to the pushState and replaceState calls
    • HTML4 Browsers
      • Old browsers like MSIE 6,7 and Firefox 2 do not have a onhashchange event
      • MSIE 6 and 7 sometimes do not apply a hash even it was told to (requiring a second call to the apply function)
      • Non-Opera HTML4 browsers sometimes do not apply the hash when the hash is not urlencoded
    • All Browsers
      • State data and titles do not persist once the site is left and then returned (includes page refreshes)
      • State titles are never applied to the document.title
  • ReplaceState functionality is emulated in HTML4 browsers by discarding the replaced state, so when the discarded state is accessed it is skipped using the appropriate History.back() / History.forward() call
  • Data persistance and synchronisation works like so: Every second or so, the SUIDs and URLs of the states will synchronise between the store and the local session. When a new session opens a familiar state (via the SUID or the URL) and it is not found locally then it will attempt to load the last known stored state with that information.
  • URLs will be unescaped to the maximum, so for instance the URL ?key=a%20b%252c will become ?key=a b c. This is to ensure consistency between browser url encodings.
  • Changing the hash of the page causes onpopstate to fire (this is expected/standard functionality). To ensure correct compatibility between HTML5 and HTML4 browsers the following events have been created:
    • window.onstatechange: this is the same as the onpopstate event except it does not fire for traditional anchors
    • window.onanchorchange: this is the same as the onhashchange event except it does not fire for states

License

Licensed under the New BSD License
Copyright ยฉ 2014+ Bevry Pty Ltd [email protected]
Copyright ยฉ 2011-2013 Benjamin Arthur Lupton [email protected]

For support see the Getting Support section.

history.js's People

Contributors

andebians avatar andrew-sayers--slando avatar asapach avatar balupton avatar bencorlett avatar billmag avatar daniel15 avatar deleteme avatar doits avatar elnur avatar holic avatar hrunting avatar igor-alexandrov avatar jamie-pate avatar jayphelps avatar jwlrs avatar katt avatar labaneilers avatar markashleybell avatar markjaquith avatar sbearcsiro avatar strml avatar vovcat avatar zepheiryan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

history.js's Issues

Is it possible to disable the initial auto-hash in HTML4 browsers?

First I load this URL in a HTML4 browser
example.com/a/b/c

The hash is automatically added to my URL
example.com/a/b/c#/a/b/c

Can I disable this automatic hash?

I still want to be able to pushState like this
History.pushState(null,null,'/a/b/c?x=1');

Which will change the URL to this
example.com/a/b/c#/a/b/c?x=1

I just don't want the hash added until the first pushState is called. I don't use pushState that often so I would like to keep my URLs short and clean until a pushState is called.

Thanks!

demo php not loading

I tried accessing the demo index.php (using php version 5.3.0 on os x) and the page ignores some of the php tags. Not sure if this is my php version to blame or a setting but it was easy to fix by using <?php instead of <? and <?php echo instead of <?=.

permalink

Can't pass Mootools Element for the state data

If you pass a Mootools element to be save with the state, the object is gone and all you are left with is an uid.

The change occurs on history.js:310 when it stringifies the obj. Is there a good reason for it?

Few issues with replaceState

Hi,

Thanks a lot for 1.6! It fixed the issue that I reported and more :)

I'm testing 1.6 in FF 3 and Safari 5. I call replaceState when the page loads so that I can save state for back/forward. I pass null for the title and url parameters.

First, I noticed that in Safari, the url gets "?&_suid=493" appended to it. I would expect that in an HTML5 browser, the url shouldn't change since I'm passing null for the url parameter to replaceState.

Second, in both FF and Safari, the statechange event is not called when I refresh the page. The replaceState method is being called in my code, but the statechange event never gets triggered. In Safari, when I look at web inspector, I see:
TypeError: Result of expression 'newState' [undefined] is not an object. history.js:820
In FF, I don't see an error in firebug, but statechange does not get triggered.

Thanks a lot,

Avi

Question about license.txt and compressed scripts

Are the files in scripts/compressed acceptable for use in a production environment, given that both license.txt and the New BSD License state that the terms of the license must be included in all source distributions?

Thanks,

Matt

IE and iframe problem

When using history.js in an iframe with IE8-9 ( i didn't test with older browser but the same issue is expected ), If we hit the back button, IE go back one state but the change event is not fired.

History.js v1.7 - Windows Vista - IE8 - IE9

history.html4.js calling History.getShortUrl() with no url parameter

While using the latest in the dev branch I'm getting an error on HTML4 browsers due to history.html4.js calling History.getShortUrl() at line 560.

I naively tried to comment out the check which then sent the script into a looping frenzy until it locked up (last I saw my hash was like //////////////the-original-address-requested).

Any suggestions for a proper fix? Thanks for all your hard work - this project works great for me on Chrome :)

IE9 and History.replaceState

I'm trying to work out how to do AJAX based page redirects (my endpoint tells the page it needs to redirect through a json object). In order to make it so it behaves like a normal redirect, I need to discard the state from the history so that back button doesn't bring you back onto the redirected page, causing another redirect and effectively killing the back button.

It goes something like this:

$.getJSON(url, function(data){
  if(data.redirect){
     History.replaceState({}, "", data.redirect); // redirect is something like /users/1
     // trigger ajaxy redirect
  }
});

This works fine with HTML5 history browsers, but is having trouble with hashchange browsers (IE 9 is the one I've tested with). The back button still triggers the discared state to be hit. I stepped into the code and found that it's because of the way History.js handles the shortened urls to create the state hash. When the state is added to the discarded states, the hash is something like (assuming redirected page was the root url): '/', whereas when the back button is pressed, it compares it to the hash './'... so it doesn't think it's a discarded state.

Any ideas how to fix or work around this?

Safari 5 breaks when loading hashed History.js URL

If you take a URL that's been produced by History.js using an HTML4 browser and copy/paste to Safari it throws an exception. For example, in the demo:
file:///Users/palexander/Downloads/balupton-History.js-a9ccf1d/demo/index.html#/Users/palexander/Downloads/balupton-History.js-a9ccf1d/demo/index.html%3Fstate%3D2/uid%3D344

This URL is produced using Firefox 3.6, copying and pasting the same URL to Safari 5 results in the following error:
Error: History.js does not support states with fragement-identifiers (hashes/anchors).

The error happens when the initial state change happens after the page load.

Commenting out lines below fixes the issue, but I would imagine it will cause something else to break if I leave it that way.
if ( History.extractHashFromUrl(url) ) {
throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).');
}

I saw another issue where Safari support had problems, but I believe they were resolved. Please let me know if there's any other information I can provide to assist in troubleshooting.

Using encodeURI() instead of escape()

Hi,

v1.7, I was wondering if you foresee any problems with changing line 1004 from:

tmp = window.unescape(result);
to:
tmp = window.decodeURI(result);

and 1114 from:

result = window.escape(result);
to:
result = window.encodeURI(result);

When using URLs with Unicode in them, I was encountering errors in Chrome and Firefox. In Chrome, if I would encodeURI() the unicode part of the URL that I passed to History.js, it would look corrupt in the location bar. In Firefox, using the straight unicode or encoding it would cause History.js to stop updating the location bar hashtag once it hit a URL with unicode in it. I'm not sure if my fix is correct, but it seems to be working as I desire in both Chrome and Firefox, so I wanted to see if you think this presents any issues?

Thanks,

Matt

Semicolons

Hi,

It would be helpful to add semicolons to the ends of the minified files. While this makes no difference if the files are including via separate script tags, it causes problems if they are combined into a single file.

Thanks.

[support] jQuery 1.3.2

Does History work with jQuery 1.3.2? If currently no, is there any workaround worth to try?

Queuing instead of Timeouts

Queuing should be used instead of timeouts due to the time it takes for History.go emulation, History.back and History.forward IE6 checks - can cause the current process to be interrupted by a new event. That new event should not interrupt and instead be pushed to a queue of events.

IPad Hangs on Browser Navigation Back/Forward Buttons

Everything is fine; I have the whole setup working on HTML4/5 platforms but for some reason the address doesn't change nor stops loading when I navigate via the native browser buttons - the page does load but I don't seem to be able to stop the browser continously loading.

I would assume this is iOS only at this point - apologies if this issue has already been raised and covered

Data Parameter in History.pushState Must Have 'state' Attribute

Hi there,

It seems to me like the data parameter which is provided to the History.pushState method should be able to be any arbitrary Javascript object. However, the only way I was ever able to get it to work was if the data parameter has a state key.

e.g. I tried to do...
History.pushData('some string','My Title','?my+url')

But History.Adapter.bind(window,'statechange', ...) got bugged out state data unless I did...
History.pushData({state:'some string','My Title','?my+url')

If this is intentional then I think it should be documented in the description of History.pushData.

PS: Thanks for this great script, I think it's going to be very useful!

Problem with data object on HTML4 browsers, when title is null

I noticed a possible issue when using pushState with a data object, but no title (set to null) on HTML4 browsers. It works fine on HTML5 browsers.

It seems that the data object does not get saved unless there is also a string given for title. If I give a title, the data object is available and the URLs have the uid present. With no title specified, the URLs do not have the uid value and the data object is empty.

This is on FF 3 Mac and IE 8. No problem with Chrome or Safari.

..jon

HTML4 handling inserts "/uid=N" instead of "&uid=N" into URL

Just curious why the "/" is used instead of the "&"? If someone (like me! :) is trying to get the HTML4-based hash URLs to work across browsers it really breaks things when the translation happens to HTML5 and you get something like this:
?p=notes/uid=977

Rails (and I would assume other back-end systems?) interprets this as:
params[:p] = "notes/uid=977"

Which means I have to do extra processing rather than just ignoring the uid param. I can work around if necessary but it would be really nice to just have the uid as a normal parameter.

Thanks for the great work!

Refreshing breaks forward/back buttons

Worked fine in 1.5, broken when upgraded to 1.6, works when reverted to 1.5. Tested on FF4 and Chrome10 on mac

To reproduce:

  • Click on stuff to create new states
  • Refresh
  • Click back (nothing happens except you should get a javascript error)

I narrowed it down to the onPopState function around line 1475:
// Fetch State
if ( event.state ) {
// Vanilla: Back/forward button was used
newState = History.getStateById(event.state);
}

newState ends up being undefined. I borrowed some code from 1.5 to create this:
// Fetch State
if ( event.state ) {
// Vanilla: Back/forward button was used
newState = History.getStateById(event.state);
if (typeof newState === 'undefined') {
stateData = event.state;
stateTitle = stateData.title||'';
stateUrl = stateData.url||document.location.href;
newState = History.createStateObject(stateData,stateTitle,stateUrl);
}
}

which works for me but probably isn't the correct solution..

Navigating away from the site and then back breaks the history

No 'statechange' events are generated in when the user navigates away from the site using the 'Back' button, then back again using the 'Forward' button. I noticed the issue in the following browsers:

Safari 5.04 (Mac)
Chrome 10.0.648.204 (OS X)
Chromium 10.0.648.133 (77742) (Ubuntu 10.10)

Note that this works correctly in Firefox 5 (tested on OS X and Ubuntu 10.10).

How to reproduce:

  1. Open http://www.google.com/.
  2. Open the history.js demo in the same tab/window.
  3. Click a pushState button.
  4. Click 'Back' twice -- now we're on the initial google page again.
  5. Click 'Forward' -- we're on the demo start page.
  6. Click 'Forward' again -- no 'statechange' events are generated anymore...

Hashed urls do not trigger a state change in Firefox/IE8

I don't know if this is something that is intended behaviour or not but when I arrive at a url containing a state in IE8 or Firefox it does not trigger a statechange event that I can use to load in the appropriate content.

In IE6/7 it seems to do this automatically but I am having to add following code in on my onload to catch all browsers:

if ('' != History.getHash()) {
    History.Adapter.trigger(window, 'statechange');
}

I am also seeing the issue with a js error being thrown if I paste an html4 url into Safari.

Another quick question was why does the system add a hash state when on the same url as the state? e.g. /foo/bar becomes /foor/bar#/foo/bar just after load. This seems a little ugly and unnecessary when the state is yet to be set.

Sorry if this all sounds negative, other than these tiny niggles this is a great plugin!

Identify that no state is going to change

Hey mate,

I'm not sure if this is the right place to ask since it is not an issue, but a question. ON my application, I have an onclick event triggering a function which will process the state data and add a new state. I do an AJAX call to get some stuff from the server after the statechange. So far great. But sometimes an user might one to click the same link again, to see if there is new data on the server, but since it is exact the same state data, the 'statechange' is not triggered.

So my question is how can I check if the state I want to push is the same as the current state, so I can sent it to another function?

Thanks for a fantastic plugin

Sol

encoded URLs for all HTML4 browsers?

I just installed History.js on a development site of mine and I am loving what I have seen so far.

One possible issue, or maybe it's just my unfamiliarity with how things should work. I've tested with both the Master and Dev branches.

My anchor href is like: /packaging/timex.php

I'm calling pushState with a data object, a title and the url. On an HTML4 browser (Firefox 3 Mac) The URL ends up looking like:
/#/packaging/timex.php/uid%3D90

I'm seeing similar encoding on the URL for the demo as well, but I'm also seeing other strangeness of the demo URLs. My demo is hosted on a development server and has a path like:
/history/demo/
When I click on the 'Stage 1' button, I get:
/history/demo/#/history/demo/%3Fstate%3D1/uid%3D677
Shouldn't I be getting something like:
/history/demo/#?state=1/uid=1
So not only is the URL being encoded (FF 3 Mac), but it also looks like it is doubling up.

It's a little worse on the dev branch. With dev I actually get:
/history/demo/#/history/demo/%3Fstate%3D1%26_state%3D787

Similiar results on IE 8.

Safari , history.js and iframe problem

When we use history.js in an iframe ( like application in facebook iframe for exemple ) it's working fine in all browser except Safari.

In Safari , when we hit the back button, the browser refresh the window and load the iframe content as the main page.

Any known fix about that ?


Safari 5.0.4 on OSX 10.6.6 with history.js v1.7

The artificial triggering of 'onpopstate' in pushState() causes losing of steps

Hi,

Initially I posted my problem first at http://getsatisfaction.com/balupton/topics/history_js_back_button_goes_two_states_steps_back.
After some research I found the the problem is caused by the manually triggered 'onpopstate' event in the end of the body of History.pushState(). Triggering the event consumes the state too early and later when the user clicks browser's back button there is no notification for the last registered event.
I.e. there is a single link clicking on which pushes a new state. Clicking three times on this link and then clicking browser's back button will call twice my 'statechange' handler - once for the second click and once for the first one, but none for the third.

In IE7 and lower the hashchange state is lost unless hash is included in path

When you start from any URL in IE7 (or lower) that doesn't include the hash path the state change event can no longer be triggered in any matter.

This is only resolved when you include a hashed file in the path and does not happen in IE8.

It may be caused by the additional functionality of not setting a state change on first page load.

statechange triggering problems on page load on different browsers, and other issues

Hi!

I am trying to use the master branch in one of our development. I find this library really good looking.

I noticed a few issues during my experiment. I am not sure if these are really bugs though, I am not seeing the code in its total depth yet. So, maybe, I misunderstand things. But, I like to write my observations here.

First of all, I started to write the demo application with the assumption that the statechange event is supposed to trigger on the initial page load as well. (By initial page load I mean what happens when an url representing a given state is force-reloaded in the browser, or such an url is visited as a link from another page, ie, when a page is loaded first, or reloaded completely.)

I think that this is true, the statechange should trigger on the initial page load, and this is a Good Thing. However, during my experimentation I had to realize that this does not happen so in all the browsers which is a pita. I tried to understand things better, and discovered a few issues.

1). On Safari, there is a problem (Safari 5 on MaxOSX). The event is not triggered on the page load. After research, it seems that this is not a problem of History.js, but rather a bug in Safari itself. (Have not tested yet if other WebKit browsers, such as Chrome, are also affected or not.)

I worked this around in our demo by triggering the missing statechange on the domload, on Safari. However, such a problem defies the real beauty of statechange. As an application developer, I would like to use statechange to set a given state in my widget, independently if this happens on the initial page load, or later during popping a given state in the history. I would not need or want to take care of the initial state, I'd rather just implement a single handler. In addition, it is very difficult for an application or widget to find out if the initial event has happened at all or not.

So, for this reason, I believe it would be nice to "fix" this problem of Safari with the initial popstate event from History.js. Then, statechange could work as expected on all HTML5 browsers, in the same way.

2). Without more explanation at this point, I need to mention that I also have problems with the page load on HTML4 browsers, I tested on IE8 only. It seems that in order to make history work correctly on IE, on the initial page load as well, I need to implement both the statechange and the anchorchange handlers. It would be nice not to need this. I still need further experimentation and a deeper understanding on this issue.

3). On HTML4 browsers, it seems that the current code does not create the hash fragments as shown in the documentation. They should be something like this:

www.mysite.com#?state=3/uid=3

  • but the hash part gets url encoded (not sure if a problem really, but is this really necessary?) so you end up with this ugliness: ...#/this/path%3Fstate%3D3/uid%3D3
  • and, the url path gets repeated after the hashmark. ie: you get
    www.mysite.com/this/path#/this/path%3Fstate%3D3/uid%3D3

... notice how the /this/path is repeated after the #, again, is this really desired, and, needed?

So, I am not saying this is a problem for sure, just pointing out the inconsistency with what you write (imo, correctly) in the documentation page.

4). Finally, a definite bug: line 1121 in History.js is

History.Adapter.trigger('anchorchange');

where, it should be:

History.Adapter.trigger(window, 'anchorchange');

which results in this event not triggered at all.

To close it, thanks a lot in advance if you can take some time in enlightening me about what I think right or what I think wrong in my above observations. I am also willing to contribute to the code and/or tests as needed.

Best wishes,

Balazs Ree

Query string required for html4 browsers?

Hi,

Great plugin! I am just starting to test it out in FF 3 and Safari 5.

The issue I am seeing is that pushState does not work in FF when I use a URL like "/some/path". It does work for url "/some/path?", as well as your example "?state=3". When I dont include a query string, nothing happens in FF. It works fine (with or without query string) in the html5 browser (Safari).

I am calling pushState with no state or title params. I am using FF 3.6 on Mac.

Although its not the biggest deal to include a "?" at the end of the url, it looks ugly in both html4 and html5. As you mention in your documentation, html4 browsers url encode it. And in html5 browsers, all my urls end up having this extra "?" even though I have no query string.

Thanks!

prototype adapter - Internet Explorer Problem with window.fireEvent

You can test ist with the demo files on Internet Explorer, when using prototypeJS and history.adapter.prototype.js.
On line 126 "element.fireEvent" throws an error, when "element" is "window", because window.fireEvent doesn't work in Internet Explorer. Haven't found a solution yet.

Complex URLs do not function correctly for HTML4 browsers

https://gist.github.com/883759

Couple of issues that these address:

  1. String.replace() only replaces the first occurrence
  2. When comparing hashes, make sure both are escaped

Please take a look at these commits:

https://github.com/robmadole/history.js/commit/d626142e6322504c917118188a87bc46f5b64a5c

https://github.com/robmadole/history.js/commit/a7b3b02e44b24ef2e97db499951a8cc3c566376a

The first commit went down the wrong path. The second I think is correct. I wasn't able to run the tests, I'm just not going to mess with setting up PHP :D

README FIRST

If you are to file a bug report, or request a new feature this is the right place.

If you would like help implementing History.js within your application, or general help accomplishing a task please use the GetSatisfaction forum instead:
http://getsatisfaction.com/balupton

Before filing an issue here, be sure to include the following:

  • The version of History.js that is affected, if you are using the dev branch then the commit that is affected.
  • Which browsers and versions of the browsers are affected and which are not
  • Place any sample code on http://gist.github.com (for snippets) or http://jsfiddle.net/ (for reproducible demos) or provide a live direct link to the problem

If you are wanting to contribute code to History.js then be sure to read:
https://github.com/balupton/history.js/wiki/Developers-Guide

Cheers, and thanks for reading!

incorrect URLs in html4 browsers

Hi,

using v1.7.0, problem boiled down to following example:

$("#one").click(function(e){
History.pushState(null,null,'one');
return false;
});

$("#two").click(function(e){
History.pushState(null, null, History.getState().hash+"/two");
return false;
});

Works fine in html5 browsers
In html4 browsers, clicking #one produces http://localhost:9393/#./one where I'd expect http://localhost:9393/#/one (without that dot)
clicking #two produces http://localhost:9393/#one/two instead of http://localhost:9393/#/one/two (missing slash)

tried v1.6 (checked out commit 910f8ff) and that seems to work ok.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.