1. Supporting native browser rendering of custom fonts

    I’ve just been reading an article from Jeff Veen on a font-embedding technology coming up shortly. We’re going to be in a situation soon where every major browser is about to support the ability to link to a font hosted on a web server, which is downloaded and used by the browser to render text. Although the technology is almost there, legal and copyright issues will take a lot longer to catch up. It looks like this could provide an interim solution, definately worth keeping an eye on.

    Posted at 8:33 am on 3/06/09

    Tags: , ,

    Comments: None

  2. Configuring a virtual application within an ASP.NET MVC site

    I recently had to look into how to get requests to /TestApp within an ASP.NET MVC site resolving to another application, instead of picking up the default routing rule and trying to find the Index action on a TestApp controller class. A scenario where this may occur would be setting up a wiki application to run on /wiki off your main domain name.

    First off, we need to ensure that the routing module doesn’t kick in and attempt to handle the request. This can be achieved by making the following change in global.asax of the MVC app…

    routes.IgnoreRoute("{*path}", new { path = @"TestApp\/(.*)" });

    You can then create a new virtual directory in IIS under the main site, and convert it into an application to ensure it’s running in a seperate AppPool etc.

    The final step is to ensure that web application settings in the parent application don’t cascade and get applied to the child application. This is achieved by wrapping all of the main configuration in a location block, and setting inheritInChildApplications to false like so…

    <location path="." inheritInChildApplications="false">
       <system.web>Blah</system.web>
       <system.webServer>Blah</system.webServer>
    </location>

    The most useful reading on this I could find was this forum post.

    Posted at 4:40 pm on 1/06/09

    Tags: , , ,

    Comments: None

  3. Team Explorer 2008 timeout and COM exception after installing October TFS PowerTools

    I had been experiencing massive delays after connecting to a TFS server in Team Explorer 2008. These usually ended up with a COM exception – Creating an instance of the COM component with CLSID {B69003B3-C55E-4B48-836C-BC5946FC3B28} from the IClassFactory failed due to the following error:80004005.

    This turned out to be a problem with the October release of the TFS PowerTools. I found the solution here which was based on disabling the new ‘Collaboration’ feature that was added to Team Explorer.

    Posted at 3:54 pm on 31/03/09

    Tags: , ,

    Comments: None

  4. Unable to fade text in Flash player 9

    I was looking into a bizarre problem recently in Flash where I couldn’t get the simplest thing to work – fading text. I tried everything I could think of – motion tweens, classic tweens, changing the Alpha effect, changing the alpha channel in the text colour.

    The weird thing was that targetting Flash 10 in the publishing settings meant the animation worked fine, but switching to flash 9 caused it to stop working.

    It turns out that in order to animate the opacity of dynamic text for Flash 9, you need to explicitly specify which character glyphs to embed in the swf. Select the dynamic text element, then hit the ‘Character Embedding’ button in the properties pane.

    When I stop to think about it, this makes a lot of sense. By default I would imagine flash is using the operating system to draw the text with the specified font. This is why the font needs to exist on the end machine. However, as soon as you do things like fade opacity, I think flash must take responsibility for rendering the text. In order to do that, flash needs the vector information for drawing different characters in the font, so you have to explicitly embed that information. In order for this to work in Flash player 10, they must make some kind of default assumption that you need the vector information embedded, and do this for you.

    Posted at 3:48 pm on 31/03/09

    Tags:

    Comments: None

  5. Problems with javascript minification that affects SwfObject 2.1 in Internet Explorer

    This is actually a more general issue with javascript minification that can affect a number of scripts, but I noticed it while tracking down weird behaviour with the minified version of SwfObject that only affected Internet Explorer.

    Basically, standard behaviour with most javascript minifiers is to strip out anything contained within comments. I finally tracked down this piece of code in the swfobject library that was getting stripped out (incorrectly) by the minifier…

    /*@cc_on
    ie = true;
    @if (@_win32)
    windows = true;
    @elif (@_mac)
            mac = true;
        @end
    @*/

    This library carries out browser detection by using the proprietary Conditional Compilation feature in Internet Explorer. In order to stop other browsers from choking, the code is wrapped in a comment.

    I’m not commenting whether this is a good or bad idea, simply that it does appear in existing scripts, and causes a bunch of javascript minifiers to strip out functional code.

    I think my approach will be to revise the set of regular expressions that control what gets stripped out to cater for this variation.

    Posted at 12:01 pm on 26/03/09

    Tags: , ,

    Comments: None

  6. Problem with SWFObject 2.1 in IE7 / Vista

    I have a site where I’m using the SWFObject javascript library to handle Flash detection and embedding of flash movies. I noticed a javascript error in IE7 that was preventing the alternate content being replaced with the flash movie - the end result was a banner showing ‘get a new version of flash’ etc.

    After a little investigation the problem appears to only affect the minified version of the library. I haven’t found the exact issue, but it looks like a problem with the obfuscation applied in publishing the minified js file.

    I have a custom endpoint handling minification and caching of the javascript anyhow, so after switching to the source version of the library and handling minification myself, all is good in IE7.

    Posted at 12:03 pm on 18/03/09

    Tags: ,

    Comments: 2

  7. Webtrends tracking from Flash

    I’ve been working on a Flash widget, and the majority of the sites it will be hosted on use WebTrends for analytics. I recently had to look into capturing certain interaction events from the Flash movie and passing them through to WebTrends for reporting.

    Flash events are tracked as fake page impressions in WebTrends based on unique URLs that you define. The flash movie doesn’t talk to WebTrends directly - it calls through to javascript on the host page which logs the event via standard WebTrends javascript.

    In my case I’m working on a widget that could be hosted on a variety of pages that may or may not implement WebTrends. The required behaviour is for tracking to automatically kick in if the host page implements WebTrends, but gracefully degrade if not. I have a javascript file that handles interaction with the flash movie, so I can guarantee certain js functions exist on the host page.

    The solution looks like so…

    Add an ActionScript class to pass events through to host page

    package {
    
    
        import flash.external.ExternalInterface;
    
    
        public class Analytics {
    
    
            public static const WIDGET_LOADED:String = "/Video/Widget/WidgetLoaded";
            public static const PLAYER_LAUNCHED:String = "/Video/Widget/PlayerLaunched";
    
    
            public function Analytics(): void {
            }
    
    
            public static function captureEvent(eventType:String) {
    
    
                if (ExternalInterface.available) {
                    ExternalInterface.call("mycompany.video.captureAnalyticsEvent",  eventType);
                }
            }
        }
    }

    An example of passing an event to this class…

    Analytics.captureEvent(Analytics.WIDGET_LOADED);

    Implement javascript functions on the host page

    /* set up namespace for new functions */
    if (window["mycompany"] == null) {
        window["mycompany"] = {};
    }
    
    
    mycompany.video = {
    
    
        webtrendsTrackingFunction: {},
    
    
        captureAnalyticsEvent: function(eventType) {
    
    
            var uriParam = 'DCS.dcsuri';
    
    
            if (typeof (this.webtrendsTrackingFunction) == 'function') {
    
    
                // if user has nominated a specific tracking function
                this.webtrendsTrackingFunction(uriParam, eventType);
            } else if (window["dcsMultiTrack"] != null) {
    
    
                // if dcsMultiTrack already implemented on page
                window.dcsMultiTrack(uriParam, eventType);
            } else if (window["dcsTag"] != null) {
    
    
                // otherwise if webtrends implemented on page, use default implementation
                mycompany.video.analytics.dcsMultiTrack(uriParam, eventType);
            }
        }
    }
    
    
    mycompany.video.analytics = {
    
    
        dcsMultiTrack: function() {
            for (var i = 0; i < arguments.length; i++) {
                if (arguments[i].indexOf('WT.') == 0) {
                    WT[arguments[i].substring(3)] = arguments[i + 1]; i++;
                }
                if (arguments[i].indexOf('DCS.') == 0) {
                    DCS[arguments[i].substring(4)] = arguments[i + 1]; i++;
                }
                if (arguments[i].indexOf('DCSext.') == 0) {
                    DCSext[arguments[i].substring(7)] = arguments[i + 1]; i++;
                }
            }
            var dCurrent = new Date();
            DCS.dcsdat = dCurrent.getTime();
            dcsTag();
        }
    }

    The key points above the script above…

    • To report events from Flash, WebTrends require an additional function on the host page that they provide - dcsMultiTrack
    • If the host page has implemented dcsMultiTrack already, the existing function will be used
    • If the host page implements standard WT js but not the additional function, a fresh implementation of the dcsMultiTrack function will be used
    • If WebTrends javascript has not been implemented on the host page, nothing bad happens

    In addition, we have a standard function that the flash movie will always call, so if we need to extend functionality to cater for different analytics systems etc, then we have a single place to implement this.

    This is probably the least sexy post I’ve ever written, but it seemed worthwhile to document this. I’ll follow up with some sexified content sometime soon.

    Posted at 12:07 pm on 27/02/09

    Tags: , , ,

    Comments: 2

  8. Testing IE rendering

    I have to admit until recently I’ve been using virtual machines for testing rendering in different versions of IE - just came across IETester which lets you open new tabs running the rendering engine from different versions. You probably know all about this already, but it was new to me. Last time I looked into this it was still a major headache.

    I’d really recommend taking a look if you’re doing any client-side dev work.

    Update: There isn’t a huge amount of information about exactly how this is implemented and whether you can solely rely on this for testing rendering + javascript of a major application. The closest I could find was this from the author on a forum… ‘I am hooking win32 functions to override standard calls and launch custom versions of IE instead of standard version.’ Everything I’ve tried so far has been accurate, but I think better documentation would really help adoption.

    There may be info I haven’t found in the forums.

    Posted at 1:22 pm on 26/02/09

    Tags: ,

    Comments: 2

  9. Using ExternalInterface to call Javascript from Actionscript - ‘null’ is null or not an object in IE

    If you are using ExternalInterface in Actionscript 3 to call through to a javascript function, the original object tag that instantiated the flash runtime needs to have an explicit id attribute. Otherwise you’ll get the above error when running the movie in Internet Explorer.

    Posted at 11:00 am on 26/02/09

    Tags: ,

    Comments: 4

  10. Added object tag to page via DOM methods - IE chaos

    I’ve been working on a widget project that involves Flash and Javascript, and came across some very strange behaviour in IE6 / 7. The object tag to render the flash movie is dynamically added to the page at runtime using standard DOM methods - document.createElement, setAttribute, appendChild etc. Life was wonderful until I opened Internet Explorer, which hangs with what looks like a request for a file with no timeout (progress bar moving very slowly but never completing). This is identical behaviour to how IE behaves when the location of the SWF is invalid.

    The markup

    The markup I was generating was based on Flash Satay. Including this as static markup in a page works fine. Simple example below…

    <object type='application/x-shockwave-flash' data='test.swf' width='420' height='155'>
        <param name='movie' value='test.swf' />
    </object>

    DOM approach that chokes IE

    The following approach causes IE to choke…

    <script type="text/javascript">
    
    
        var object = document.createElement('object');
        object.setAttribute('type', 'application/x-shockwave-flash');
        object.setAttribute('data', 'test.swf');
        object.setAttribute('width', '100');
        object.setAttribute('height', '100');
    
    
        var param = document.createElement('param');
        param.setAttribute('name', 'movie');
        param.setAttribute('value', 'test.swf');
        object.appendChild(param);
    
    
        document.body.appendChild(object);
    
    
    </script>

    The solution / workaround

    For some reason if the object tag + params are parsed at the same time everything works fine, so the solution involves using the alternate approach to manipulating the DOM - innerHTML. This wouldn’t have been my first choice given the situation, but it seems to be the only way to get this working. A version that works in IE…

    <script type="text/javascript">
    
    
        var fragment =
            "<object type='application/x-shockwave-flash' data='test.swf' width='100' height='100'>" +
                "<param name='movie' value='test.swf' />" +
            "</object>";
    
    
        var container = document.createElement('div');
        container.innerHTML = fragment;
        document.body.appendChild(container);
    
    
    </script>

    This achieves the same end result - a DOM element node that can be inserted anyway you wish, but avoid the problem in IE.

    Posted at 10:51 am on 26/02/09

    Tags: , , , ,

    Comments: 2