Ghost9
Ghost9

Reputation: 259

Can I make swf address be a real URL and not use a #?

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?

Upvotes: 3

Views: 794

Answers (2)

Nathan Ostgard
Nathan Ostgard

Reputation: 8406

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.

Upvotes: 5

Chunky Chunk
Chunky Chunk

Reputation: 17217

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.

Upvotes: 0

Related Questions