3

Is it possible to make swfaddress, or any script really, to allow flash to change the URL displayed(without actually switching to a new page) in the browser to anything I choose? I realize that swfaddress makes the url so that it will always refer back to an originating swf file, which is great, but a web template I'm working on will always load a swf, no matter what URL you visit on the site. The difference will be what content is immediately loaded. As you navigate through the flash to different articles, I want to be able to change the URL to be that of the article as if it was an html page, as I'm going to have matching html content for SEO purposes. This is going to be a large site and I want to optimize it for sharing and searchability.

So as an example, rather than "site.com/#/news-just-in", I want a URL of "site.com/2011/3/news-just-in".

Is this possible?

Ghost9
  • 249
  • 3
  • 7
  • 15
  • for what reason are you making a flash website? – zzzzBov Mar 14 '11 at 22:12
  • 1
    To make a site that goes beyond the standard boring html. Flash offers more in the way of text layout and graphics, but I want to have all of the alternate content as well for searchability and also usability if noone has flash. Essentially I will have the flash version, and the html version, and I have the majority of the logistics worked out, but I'm stuck on the web address portion. I realize some don't like flash and may down talk it, but this is the platform I am currently going with and I am just looking for help with this issue, and not a debate about flash. – Ghost9 Mar 14 '11 at 22:18
  • 1
    I wasn't trying to down-talk flash, but I get the feeling you're jamming a square peg in a round hole and asking why it wont fit. "standard boring html" doesn't have to be boring if you use a bit of DHTML and effects. Flash *does* offer more as far as typeface management and text rendering, but I wouldn't say that flash beats HTML at graphics in any meaningful way. Additionally, you're looking at a significant drop in accessibility with a flash site. I'd recommend making the site in HTML and embed flash for the parts that need to be flashy. – zzzzBov Mar 14 '11 at 22:23
  • 2
    I appreciate you trying to help with your opinions, but you do not know the full extent of the project and what I'm trying to do with it. All I'm looking for in this post, is help with the issue described above. – Ghost9 Mar 14 '11 at 22:27
  • 1
    you may rationalize your decisions any way that you'd like. The effect you're looking for would require the flash movieclip to load on every new page, additionally you'd need to use a server script to identify what page is being requested, and set a parameter for flash during load. Alternatively, you could use javascript to check the window location and pass it to flash via ExternalInterface (unless flash has a built in mechanism for determining the webpage location, in which case you could use that.) If you want to keep the flash loaded, you'll have to stick to hashtags. – zzzzBov Mar 14 '11 at 22:40

2 Answers2

5

You can do this, but only in browsers that support the new HTML5 History API. You would need to use ExternalInterface to cooperate with a JavaScript layer. The Flash side of things might look like this:

package {
  import flash.display.Sprite;
  import flash.events.MouseEvent;
  import flash.external.ExternalInterface;
  import flash.text.TextField;
  import flash.text.TextFieldAutoSize;

  public class Test extends Sprite {
    protected var _text:TextField;

    function Test() {
      var b:Sprite = new Sprite;
      b.graphics.beginFill(0xff0000);
      b.graphics.drawRect(0, 0, 32, 32);
      b.graphics.endFill();
      b.addEventListener(MouseEvent.MOUSE_DOWN, function(e:MouseEvent):void {
        pushState('/test/foo');
      });
      addChild(b);

      b = new Sprite;
      b.x = 64;
      b.graphics.beginFill(0x0000ff);
      b.graphics.drawRect(0, 0, 32, 32);
      b.graphics.endFill();
      b.addEventListener(MouseEvent.MOUSE_DOWN, function(e:MouseEvent):void {
        pushState('/test/bar');
      });
      addChild(b);

      _text = new TextField();
      _text.autoSize = TextFieldAutoSize.LEFT;
      _text.y = 64;
      addChild(_text);

      if (ExternalInterface.available) {
        ExternalInterface.addCallback('onPopState', onPopState);
        ExternalInterface.call('test.onReady');
      } else {
        _text.text = 'external interface not available';
      }
    }

    protected function onPopState(path:String):void {
      _text.appendText("flash onPopState: " + path + "\n");
    }

    protected function pushState(path:String):void {
      _text.appendText("flash pushState: " + path + "\n");
      ExternalInterface.call('history.pushState', null, null, path);
    }
  }
}

And the JavaScript side might look like this:

<!DOCTYPE html>
<html>

<body>
  <script type="text/javascript">
  if (!!(window.history && history.pushState)) {
    var test = {
      onPopState: function(event) {
        if (this.embed) {
          this.embed.onPopState(location.pathname);
        }
      },

      onReady: function() {
        var embed = document.getElementById('flash');
        this.embed = embed.getElementsByTagName('object')[0] || embed;
        this.embed.onPopState(location.pathname);
      }
    };

    window.addEventListener('popstate', function(event) {
      test.onPopState(event);
    }, false);
  } else {
    alert('This browser does not support the history API');
  }
  </script>
  <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
          id="flash" width="780" height="420">
    <param name="movie" value="test.swf" />
    <!--[if !IE]>-->
    <object type="application/x-shockwave-flash"
            data="test.swf" width="780" height="420">
    <!--<![endif]-->
      <p>Flash is required</p>
    <!--[if !IE]>-->
    </object>
    <!--<![endif]-->
  </object>
</body>

</html>

In this example, onPopState is called whenever the path changes, and pushState is called to change the URL. You can click the red and blue boxes in the example to change the URL from Flash.

If you wanted to do this and had to support older browsers, you would want to fallback on the hash tag when the history API is not supported. Ideally, you could abstract this in the JS layer, so that the Flash code doesn't have to know which is being used. I would recommend using a third party library like History.js for something like this, as it will handle the hash fallback for you.

Matt
  • 74,352
  • 26
  • 153
  • 180
Nathan Ostgard
  • 8,258
  • 2
  • 27
  • 19
0

you can change the hash tag to whatever you want, but a constant character or string is required for it to work as intended:

/*
Provides the deep linking value without the query string.
*/
public static function getPath():String {
    var value:String = SWFAddress.getValue();
    if (value.indexOf('?') != -1) {
        return value.split('?')[0];
    } else if (value.indexOf('#') != -1) {
        return value.split('#')[0];
    } else {
        return value;
    }

you'll also have to change all instances of "#" in SWFAddress.js and SWFAddressOptimizer.js to match your new character or string value.

keep in mind that it's not encouraged to change this value, and replacing it with a simple value (like "3") will likely cause problems.

Chunky Chunk
  • 16,553
  • 15
  • 84
  • 162