The Artima Developer Community
Sponsored Link

Web Buzz Forum
Switching stylesheets on the fly

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Manish Jethani

Posts: 53
Nickname: jethani
Registered: Aug, 2005

Manish Jethani is an engineer in the Flex team at Adobe.
Switching stylesheets on the fly Posted: Sep 24, 2005 2:16 PM
Reply to this message Reply

This post originated from an RSS feed registered with Web Buzz by Manish Jethani.
Original Post: Switching stylesheets on the fly
Feed Title: Manish Jethani
Feed URL: http://feeds.feedburner.com/manish/artima
Feed Description: Software. RIA. Flex.
Latest Web Buzz Posts
Latest Web Buzz Posts by Manish Jethani
Latest Posts From Manish Jethani

Advertisement

One of the features I envy HTML for is the ability to switch CSS stylesheets at runtime. Doesn’t matter how often it’s used or if it even works reliably in most web browsers — it’s just very cool from a developer’s perspective.

I’ve often wondered why we don’t have support for runtime loading of stylesheets in Flex. It should be safe to assume that it didn’t make it into the 20% of features for 80% of our customers.

So, we don’t parse the CSS file on the client; instead, we parse it on the server and convert it to our own internal ActionScript representation, which is then loaded in the client at runtime. It’s obviously much faster to parse CSS on the server than on the client (but wait for the next version of the Player and I might be wrong).

The reason I stressed on “runtime” in the previous paragraph is that I have a solution that I stumbled upon in a eureka moment while taking a walk and thinking about the compile-time vs. runtime issue. No, it does not involve writing a CSS parser in ActionScript (though I’d love to do that some day). You might be surprised at how simple it is to implement runtime switching of stylesheets once you know the internals of Flex’s CSS implementation.

Without further ado, here’s the trick: Load the multiple CSS files into multiple Flex applications, then load the applications into a Loader component within the main application, and then just point the global styles object of the main application to that of the sub-application (containing the new CSS rules).

Umm… that was English. In ActionScript it means you write a faceless component like the following (or just use mine):

import mx.controls.Loader;
import mx.core.MXMLObject;
import mx.utils.Delegate;

class RuntimeStyle implements MXMLObject
{
  private var _document:Object;
  private var loader:Loader;

  public function initialized(document:Object, id:String):Void
  {
    _document = document;
  }

  private var _source:String;

  public function get source():String
  {
    return _source;
  }

  public function set source(value:String):Void
  {
    if (_source != value)
    {
      _source = value;

      if (loader == undefined)
      {
        loader = Loader(_document.createClassObject(Loader,
              "runtimeStyleLoader", 21983));
        loader.width = loader.height = 0;
        loader.addEventListener("complete",
            Delegate.create(this, loader_complete));
      }

      loader.source = _source + ".swf";
    }
  }

  private function loader_complete(event:Object):Void
  {
    _global.styles = Loader(event.target).content._global.styles;
    _document.styleName = _document.styleName == "!" ? "@" : "!";
  }
}

What’s happening here? Let’s use it in the Flex Store sample (yes) and then I’ll explain. Once you’ve saved the above code into a RuntimeStyle.as file, insert the following code snippet into your flexstore.mxml.

<local:RuntimeStyle xmlns:local="*"
  source="{stylesWrappers.selectedItem.source}" />
<mx:Model id="alternateStyles"
  source="alternateStyles.xml" />
<mx:ComboBox id="stylesWrappers"
  dataProvider="{alternateStyles.stylesheet}"
  labelField="name" selectedIndex="-1" />

Here’s what the alertnateStyles.xml file looks like:

<?xml version="1.0"?>
<styles>
  <stylesheet>
    <name>Autumn</name>
    <source>/samples/flexstore/css/autumn.mxml</source>
  </stylesheet>
  <stylesheet>
    <name>Club Orange</name>
    <source>/samples/flexstore/css/cluborange.mxml</source>
  </stylesheet>
  <stylesheet>
    <name>HTML Classic</name>
    ...
</styles>

It contains links to the 5 themes: Autumn, Club Orange, HTML Classic, Industrial, and Institutional. But really these files don’t exist in the css directory, so they have to be created. Here’s the autumn.mxml file — others should be similar:

<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml">
  <mx:Style source="autumn.css" />
</mx:Application>

When you run Flex Store and select “Autumn” from the dropdown… it works!

Autumn

Then try adding some products to your shopping cart and then switching the stylesheet to, say, “Club Orange.” It works!

Club Orange

And how it works? Figuring that out by looking at the code should be a fun 2-minute exercise. If you have any questions, just leave a comment and I’ll be happy to respond.

Institutional

Forward compatibility note: This hack is almost guaranteed not to work in Flex 2.0. I’ll try to ensure there’s some equivalent, but no promises!

Read: Switching stylesheets on the fly

Topic: Brainespot: Meta Search Engine Previous Topic   Next Topic Topic: Tim Berners-Lee on the read/write Web

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use