Wednesday, September 1, 2010

How to view source for an embedded SWF hosted on a different domain

This is second in a series of blogs that attempt to capture all the aspects of making a good blog even better. The first one covered how to Add SWFs to your blogger posts.

Today we will cover how to allow the SWFs in your blog to provide the users with the option to with the source. You can start by following the instructions provided here, in order to make sure that when users right-click on a SWF file, they would see the "View Source" option.

But this brings up a new challenge if your SWF file itself is embedded in the blog but is actually hosted elsewhere because right-clicking and selecting "view source" results in a URL which is broken because it is generated relative to the blog (http://www.blog.com/article/srcview/index.html) ... instead of the hosting webspace url (https://some.website.com/hosting/srcview/index.html).
  1. You might notice that when you use Flash Builder to publish the code, it adds the viewSourceURL property to your main application file. What you need to do in addition to that is:
    1. Leave the original property in place because setting it later for the first time in an event handler, such as the one for applicationComplete, does not add it to the context-menu so one must still have the original attribute/propety in the application tag.
    2. Set the viewSourceURL again in a handler for the applicationComplete event so that the value is updated correctly.
    3. Build the host URL as shown here in the handler when updating the viewSourceURL value.
    <s:Application
                   ...
                   viewSourceURL="srcview/index.html"
                   applicationComplete="applicationCompleteHandler(event)"
                   >
        <fx:Script>
            <![CDATA[
                protected function applicationCompleteHandler(event:FlexEvent):void
                {
                    var swfURL:String = FlexGlobals.topLevelApplication.loaderInfo.url;
                    swfURL = swfURL.substr(0, swfURL.lastIndexOf("/") + 1)
                    var tempDom:Array = swfURL.split("/");
                    var domURL:String = tempDom.slice(0,3).join("/") + "/";
                    viewSourceURL = domURL+ "srcview/index.html";
                }
            ]]>
        </fx:Script>
        ...
    </s:Application>
  2. A workaround is to use the <iframe/> tag instead of <embed/> tag because that way the url generated to "view source" will be relative to the hosting website and not the embedding website.
  3. Also there is some speculation that if one uses swfobject instead of the embed tag. This blog seems to have a non-standard URL specified for the source versus the SWF but it is relative and not absolute, so again it may or may not work for absolute URLs. Following this example, it could probably be accomplished like so:
    var flashvars = {};
    flashvars.srcUrl = "https://some.website.com/hosting/srcview/index.html";
    ...
    swfobject.embedSWF(arg1,arg2,arg3,arg4,arg5,arg6,flashvars,arg8,arg9);

As a side-note here's an article that makes a very convincing argument for using SWF Object 2.

Flex4: How to build a Stop Watch Timer

Here's a working sample:

The following blog offered a series of very convincing arguments that led me to use flash.utils.getTimer() to build the Stopwatch demonstrated above.

The component constantly resets the time based on when it is made visible/invisible (click here twice to see it get reset +/-). If your components show a custom busy / loading skin rather than just a simple busy cursor, then you can leverage this component to also track how long your activities usually take visually.

Here's the source code:
  1. main.mxml
  2. StopWatch.as
  3. StopWatchSkin.mxml