Detalhes do pacote

historyjs

browserstate2.8k1.8.0-b2

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

javascript, html5 history api, hashchange, popstate

readme (leia-me)

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

Flattr this project

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 sponsor@bevry.me

  • 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 us@bevry.me
Copyright © 2011-2013 Benjamin Arthur Lupton b@lupton.cc

For support see the Getting Support section.

changelog (log de mudanças)

History

  • v1.8b2 - June 22 2013

    • Introduced uncompressed bundled files #287
    • Copied component.json to bower.json #291 and used right tag #286
    • Fixed wrong argument passed to History.getHash() #305, #297, #292 (@Izkata)
  • v1.8b1 - May 31 2013

    • Fixed "encoded string automatically unencoded on html5 browsers" #282, #236, #272
  • v1.8a4 - February 13 2013

    • Fixed coffee script warnings (ExtJS & Dojo adapter, IE 6 iFrame)
    • Updated qUnit to release 1.11.0, jQuery to release 1.9.1
  • v1.8a3 - February 5 2013

    • Added tests for Dojo and ExtJS
    • Changed setting of title and url
    • Testing status
      • All HTML5 Native Adapter fail in all browsers on Test 10
      • All other HTML5 tests work fine
      • All other HTML4 tests fail in Test 4 (in IE)
  • v1.8a2 - January 21 2013

    • Fixed hashchange / statechange triggers: e.g. if a user in a HTML5 browser clicks a link, statechange is fired, in a HTML4 browser only hashchange, but state has also changed
    • UTF8 / url encoding / decoding tested and so resolved: #64, #107, #108, #162, #177, #187, #205, #207, #210, #228, #251
    • Fixed #244
  • v1.8a1 - January 19 2013

    • Pass options to init() as json is now supported
    • Added unicode demo
    • Introduced getCurrentIndex(), so you can get previous state by History.getStateByIndex(getCurrentIndex()-1)
    • Fixed HTML4 endless loop when url starts with a slash (e.g. /welcome/hello) #239, #232, #185
    • Bundled and compressed all scripts
    • Responsed (and therefore solved) or old issues from balupton repository: #250, #242, #238, #234, #224, #213, #206, #195, #183, #181, #180, #179, #175, #168
    • Fixed (or merged and therefore fixed) old issues from balupton repository: #248, #239, #236, #235, #229, #221, #220, #218, #215, #214, #212, #203, #191, #189, #172, #171, #166
    • Feedback for UTF8 / url encode issues necessary, related problems (thanks to riyad)
      • 64, #107, #108, #162, #177, #187, #205, #207, #210, #228

  • v1.7.2 - January 18 2013

    • Updated project README
    • Integrated ExtJS Adapter (thanks to @seanadkinson!)
    • Merged from forks
      • added option to force no suid (@hrunting, @sbearcsiro)
      • provide a consistent URI-encoded document.location.href (@hrunting, @sbearcsiro)
      • Change History.getHash to return consistent hash, ala History.getLocationHref (@sbearcsiro)
      • Fix an issue where HTML4 replaceState wasn't firing when SUIDs were disabled and the url didn't change (@sbearcsiro)
      • Make extractId ignore the fragment if one is present (normally the hash is passed without an fragment) (@sbearcsiro)
      • Remove all encoding / decoding of URLs except when creating or extracting a fragment, based on the assumption that all inputs to replaceState / pushState are appropriately encoded (@sbearcsiro)
      • Change escapeHash/unescapeHash methods to use encodeURI/decodeURI instead of window.escape/unescape (@sbearcsiro)
      • Fixed issue #158 (@sbearcsiro)
      • isEmptyObject should use hasOwnProperty: prevents from always returning true if the Object.prototype is extended (@Alexander Johansson)
      • Add potential fix for IE8 not returning full hashed url from getLocationHref when hash contains encoded characters (@sbearcsiro)
      • Match current W3C popState event semantics for HTML4 (@STRML)
      • Added History.options.html4Mode for easier debugging (@gigafied)
      • Added History.options.delayInit (Boolean). (@gigafied)
      • Added error testing and quota relief for sessionStorage.setItem (@jamie-pate)
      • Fix IE 6 HTTPS warning (@Daniel15)
      • Fixed bug in html4 pushState function which left History in a busy state (@joelarson4)
      • Disable session storage if it's present but not working, thanks to @paulschreiber (@sbearcsiro)
      • Add Lakin Wecker's dojo adapter (@sbearcsiro)
      • Add dojo 1.8 tests (@sbearcsiro)
      • Change dojo adapter to not use dojo events, it seems to break other parts of dojo (@sbearcsiro)
      • Removes stray spaces so that the build script can run. (@billmag)
      • fixed an issue in Safari's Private Browsing mode where setItem throws an exception (@billmag)
      • Adds better error handling for the quota exceeded problem seen with the iPad. (@billmag)
      • Consolidated var in sessionStorage to the top of the function. Re-build compressed and bundled. (@billmag)
  • v1.7.1 - October 4 2011

    • Added a new native adapter which is framework agnostic (can be used with, or without any framework)
    • Provided bundled files
    • Added RightJS adapter
    • Updated supported browser listing
    • Added sessionStorage support in core instead of optional Amplify.js Store support
    • Fixed issue with state id generation growing slower over time
    • Closes #104, #95, #102, #92, #81, #90, #94, #93, #91, #67, #83, #54, #45
  • v1.7.0 - April 1 2011

    • Added History.enabled property (refer to usage section). This reflects whether or not History.js is enabled for our particular browser. For instance, if we have not included support for a HTML4 browser and we are accessing through a HTML4 browser then History.enabled will be false.
    • Added (optional but recommended) Data Persistance and Synchronisation Support thanks to AppendTo's Amplify.js (refer to installation and compatibility sections for details)
    • Made HTML5 SUIDs more transparent - Reported by azago and Mark Jaquith
    • Fixed Session Storage Issue - Reported by a whole bunch of different people; one, two, three
    • Fixed URL Encoding Issue - Reported by Rob Madole
    • Disabled support for IE6,7,8 when using the Prototype Adapter (there is nothing we can do about this, it is due to a bug in the prototype library) - Reported by Sindre Wimberger
    • URLs in the State Hashes for HTML4 Browsers are now even shorter - Discussion
    • Fixed a issue with the MooTools Adapter and JSON with IE7 and IE8
  • v1.6.0 - March 22 2011

    • Added Zepto adapter thanks to Matt Garrett
    • The readme now references the supported versions of the libraries we use
    • Updated vendors to the most recent versions. jQuery 1.5.1 and Mootools 1.3.1
    • Reverted versions of Safari iOS prior to version 4.3 to be HTML4 browsers, Safari iOS 4.3 is a HTML5 browser
    • Refined code in History.js and its adapters
    • Fixed issue with extra state being inserted on Safari 5 requiring an extra click on the back button to go home - Reported by Rob Madole
    • Fixed issue with Safari 5 and Safari iOS 4 sometimes failing to apply the state change under busy conditions - Solution conceived with Matt Garrett
    • Fixed issue with HTML4 browsers requiring a query-string in the urls of states - Reported by azago
    • Fixed issue with HTML4 browsers requiring title in the states in order to use state data - Reported by Jonathan McLaughlin
    • Fixed issue with HTML4 browsers failing is a state is pushed/replaced twice in a row - Reported by Joey Baker
    • B/C BREAK: The statechange event now only fires if the state has changed; it no longer fires on page initialisation. This is following the Firefox 4 History API Changes which we agree with - this breaks standard, but makes more sense.
  • v1.5.0 - February 12 2011

    • Moved to UglifyJS instead of Google Closure
    • Split HTML4 functionality from HTML5 functionality
    • Installation details have changed (the filenames are different)
  • v1.4.1 - February 10 2011

    • Added HTML History API Support for Safari 5 and Safari iOS 4.2.1
    • Cleaned code a bit (mostly with unit tests)
  • v1.4.0 - February 10 2011

    • Unit Testing now uses QUnit
    • Corrected Safari 5 Support
    • Now uses queues instead of timeouts
      • This means the API works exactly as expected, no more need to wrap calls in timeouts
    • Included a Subscribe Form in the Demo for Version Updates via Email
    • Small updates to Documentation
  • v1.3.1 - February 4 2011

    • Improved Documentation
  • v1.3.0 - January 31 2011

    • Support for cleaner HTML4 States
  • v1.2.1 - January 30 2011

    • Fixed History.log always being called - reported by dlee
    • Re-Added History.go(index) support
  • v1.2.0 - January 25 2011

    • Support for HTML4 States in HTML5 Browsers (added test)
    • Updates of Documentation
  • v1.1.0 - January 24 2011

    • Developed a series of automated test cases
    • Fixed issue with traditional anchors
    • Fixed issue with differing replaceState functionality in HTML4 Browsers
    • Fixed issue with Google Chrome artefacts being carried over to the initial state
    • Provided onstatechange and onanchorchange events
  • v1.0.0 - January 22 2011

    • Supported History.pushState and History.replaceState degradation
    • Supported jQuery, MooTools and Prototype Frameworks