History Keeper – Deep Linking in Flash & JavaScript

December 11th, 2009 Leave a comment Go to comments

Update: Beta 4 is out.

unFocus History Keeper – a JavaScript tool for managing browser history (back button) and deep linking in Flash and Ajax applications, enabling SEO.

You can check out an example page in SVN or check out adcSTUDO or Terminal Design’s fonts catalog for a demo. The test page contains a small JavaScript application that takes what you put in a text box, and makes a history entry out of it – a deep link will display that history entry in the body of the page as well.

Download the latest release archive from the downloads page on the google code site. You will find two packer compressed JavaScript files in the root of the archives, unFocus-History-p.js and unFocus-HistorySwf-p.js.

unFocus-History-p.js contains:

  • EventManager.js
  • History.js

unFocus-HistorySwf-p.js contains:

  • EventManager.js
  • History.js
  • FlashPlayerInfo.js
  • SwfUtilities.js
  • SwfHTML.js

NOTE: You should include only one of the two files, not both.

You can also check out the latest version from SVN from either the trunk (I try to keep it working there, but no guarantees) or one of the tagged releases (each release gets a tag) if you want to be cutting edge.

Features:

  • Enables back button support, for your client-side web apps!
  • Hash based deep linking (Anchor Style – index.html#/foo/bar)
  • Event driven – Event Dispatcher
  • Support for all current browsers:
    • Opera
    • Firefox
    • Safari 1.2+
    • IE 5.5+
    • Google Chrome

Known Limitations: (I have to confirm if many of these are still a problem)

  • All history entries (back button states) modify the location string.
  • Doesn’t remember last entry if you leave the app and come back in some browsers (that’s a bug, I’ll fix it).
  • Editing the url manually will stop further updates to the url in some browsers.
  • Konqueror support is still a bit flaky (this history is off by one in an odd way).
  • Deep linking and back  button functionality relies on ExternalInterface – so “allowScriptAccess” has to be set and working (platform defendant) for History Keeper to work (though you can actually get deep linking to work using flashvars, in a pinch).
  • Make sure whatever embed solution you are using, you have set the “id” attribute on your object or embed tag.

Related Links – Note: I’m trying to put links to everyone who helped me out over the years. If I left you out, please let me know.

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • Reddit
  • StumbleUpon
  • Technorati
  • Yahoo! Buzz
  • Slashdot
  • LinkedIn
  • Live
  • Suggest to Techmeme via Twitter
  • Twitter
  • Yahoo! Bookmarks
  1. herfmarc
    March 12th, 2009 at 13:51 | #1

    — swf communicating with html on runtime —

    … first-of-all: thanks for all of your work !!!

    i wonder if/how one may send/receive data to/from the embedded swf on runtime
    without reloading the swf – may you please let me know ?

  2. March 13th, 2009 at 12:18 | #2

    There are a number of ways to do that. I used to have something in the unFocus tool set that would allow for that, but have discontinued it, since there is a built in (and more reliable) way to do that since Flash Player 8.

    It’s called External Interface, and is fairly easy to use, once you wrap your head around it.

    To send info into the swf from javascript, you’ll need to use ExternalInterface.addCallback to add a javascript function handle, then call that from Javascript by getting a reference to the embedded swf’s DOM object, and calling that method. Here is an example: unFocus.SwfUtilities.getSwfReference(“swfID”).yourCallbackFunction();

    You’ll need to make sure you set Allowscriptaccess to a value that allows that communication with the script.

    (Akizmet marked this as SPAM, LOL)

  3. Egor
    June 23rd, 2009 at 23:09 | #3

    I’m change your method “_getHash” in “unFocus-History-p.js”. See changes. My variant is more correctly:

    var _getHash = function() {

    if (/MSIE/.test(navigator.userAgent) || window.opera) {

    var result = /\?([^\?\#]*)$/.exec( location.href );
    var search = (result && result[0]) ? result[0] : ”;

    return location.hash.substring(1) + search;
    }

    return location.hash.substring(1);
    };

  4. June 28th, 2009 at 22:59 | #4

    Hi! What bug or issue does that address? I’ll take acloser look at that soon. Thanks! :-)

  5. Egor
    June 29th, 2009 at 01:40 | #5

    @Kevin Newman
    Hi. Yes. You will see bag if:

    http://www.yoursite.com/something?a=1&b=2#/something-anohter/?a=3&b=4

    In IE & Opera a = 1 and b = 2. Params get from first “?” symbol. My variant fix this problem .

  6. June 29th, 2009 at 10:26 | #6

    Egor, I added a ticket in google code for this, and will investigate soon. Thanks! :-)

    http://code.google.com/p/unfocus-history-keeper/issues/detail?id=7

  7. July 25th, 2009 at 17:33 | #7

    We tried several scripts and yours was the simplest to implement and bug free: congrats.

  8. July 26th, 2009 at 14:54 | #8

    Thanks! :-)

  9. riciapd
    August 25th, 2009 at 11:48 | #9

    It’s possible I am blind…. But have tried finding instructions on this site in regard to implementing History Keeper, with no luck. I am new to flash and AS3, the examples provided in the download folder are not self-explanatory to myself… Advice/Insight/Direct me to further information? Would be much appreciated…

  10. August 25th, 2009 at 23:36 | #10

    I’m so sorry. There are none. It has been on my todo list for many years to get something like a guide or tutorial, but I just can’t seem to get to it.

    If you like to follow an example, you can check out the test pages, and go from there.

    http://code.google.com/p/unfocus-history-keeper/source/browse/#svn/trunk/tests

    Other that than, I really do want to get some documentation up of some kind, but it simply hasn’t been easy to find the time. :-(

  11. riciapd
    August 26th, 2009 at 09:24 | #11

    Totally understand. Thanks anyway!

  12. Egor
    August 27th, 2009 at 01:22 | #12

    Hi! It’s me again!

    Released IE8 and it took some refinement :( Now hash parsing your code in my app looks like this:

    var _getHash = function() {

    var ua = navigator.userAgent;

    if (/MSIE/.test(ua))
    {
    var index = ua.indexOf(‘MSIE’);
    var MSIE = parseFloat( ua.substring(index + 5) );
    }

    if ( (MSIE && MSIE<8) || window.opera)
    {
    var result = /?([^?#]*)$/.exec( location.href );
    var search = (result && result[0]) ? result[0] : ”;

    return location.hash.substring(1) + search;
    }

    return location.hash.substring(1);
    };

    In IE8 hash (params after “?” symbol) presented like in any normal browser. But in IE < 8 this problem anyway exist.

    Sorry for my English :)

    (Note: This got caught up in Akismet for some reason. Sorry about that. I wonder what else gets lost in there.)

  13. Sreejith Nair
    August 27th, 2009 at 06:14 | #13

    Hi

    I understand
    unFocus-History-p.js contains, EventManager.js and History.js .

    but unFocus-History-p.js is in a minimized format. Can i get the original version of unFocus-History-p.js ?

    Thanks
    Sree

  14. August 28th, 2009 at 11:12 | #14

    Sure, you can find the original version in the archive in the javascript folder (you’ll find both EventManager.js and History.js). You can also find them in SVN (linked in this comment).

    All I did before packing them, was to copy them to one file – EventManager first, then History Keeper. In the future I’ll try to remember to leave the compiled js file in the archive.

  15. September 16th, 2009 at 05:09 | #15

    This code works great… except after document.domain is set in IE.

    If you set document.domain then IE gives ‘Access is denied’ when trying to read (but, bizarrely, not change) window.location.

    The reason we set document.domain is so that the main document on example.com can communicate with a child iframe on ajax.example.com. Both the main and child iframe documents need document.domain explicitly set to ‘example.com’, even if the main document is at http://example.com already (i.e. although the domain is example.com, it still needs to be explicitly set).

    To clarify, the problem can be recreated just be running these two lines of JSript on a page:
    document.domain = ‘yourdomainhere’;
    alert(window.location); // will throw an access denied error in IE

    Hoping someone can help!

    Jake.

  16. Sreejith Nair
    September 24th, 2009 at 07:14 | #16

    Hi,

    If I leave the current page (say Page1.aspx, that implemented the history Keeper), and go to Page2.aspx.
    Now if I try hitting the history back button and come back to Page1.aspx. I could see that the history is lost!
    Is there any fix for this? Thanks in advance.

    Also history is nto workgin in Opera Version 9.25

    Regards
    Sree

  17. October 2nd, 2009 at 13:45 | #17

    Hi Sreejith. I’m not sure what is causing that. I don’t remember this being a problem, but I was able to reproduce this easily enough. I have some work to do it looks like. Thanks for the bug report. Opera is a PIA, but I’ll look into that too.

  18. October 2nd, 2009 at 16:03 | #18

    About that bug – This seems to only apply to IE6 and 7, and it’s a bug in general with keeping a history using iframes, which affects other history scripts as well. I’ll keep looking for a fix, but it does look like Microsoft cleaned it up in IE8 (in IE8 mode), along with a bunch of other issues (like the title getting all screwed up).

    I have noticed that most RIAs that use flash and history/deep linking techniques are making external links open in a new window. Maybe it’s partly to deal with this.

  19. Sreejith Nair
    October 7th, 2009 at 09:13 | #19

    Kevin thanks for the response… Looking forward to hear from you, if there any update.

    ~Sree

  20. October 27th, 2009 at 22:57 | #20

    @Egor

    About that IE bug with “?” after the hash “#” – this appears to be a bug in IE that can’t be worked around. I’ll keep an eye out for a fix, but I think the answer will be that you simply can’t put a ? in the string after the hash, and maintain compatibility with IE < 8. Sorry about that. If you know of anyone that’s done it, please let me know. :-)

  21. December 24th, 2009 at 22:41 | #21

    Can this track the history of multiple iframes too? When you click on something in an iframe it is added to the history but when you look at the history array you can’t se the iframe url, only the main page url. Why is that? When you press back the iframe goes back, how did it know to what url to go back to?

  22. January 4th, 2010 at 00:55 | #22

    I haven’t looked at the history array in a while, but I suspect you are running up against the limits of what the browser can keep track of. Theoretically, all the browsers should be able to do what you are saying without error – but I bet reality is different. Most of the issues around that center on security issues – parent pages being able to access information about the content in an iframe – even the location – could be a security problem. So most of the browsers have erred on the side of caution and made it difficult or impossible to get that information across frames. Unfortunately, History Keeper really doesn’t deal with iframes too much, except to use a hidden iframe for IE5.5 – 7 compatibility, so I doubt it’ll be of any help.

  1. June 19th, 2008 at 02:05 | #1
  2. September 11th, 2008 at 13:52 | #2
  3. February 9th, 2009 at 10:21 | #3
  4. July 10th, 2009 at 01:16 | #4