Wednesday 18 February 2009

True Runtime CSS ( without compiling it to swf file)

Here is a simple way . yet not perfect, to load a CSS file at run time.
The only flaw is berried within the StyleSheet function "parseCSS".
It converts the entire file to lowercase letters; Thus, without hard coding it, it's impossible to apply styles to all UIComponenets since the convention is using capitals.
The StyleManager would look for "button" even if you wrote in the CSS file "Button".
Same problem goes with styleNames. But here, you may consider to only use lowerCase names.

There is a bit of an ugly solution for this problem - you can modify the first letter into capital.
That would only solve components with only a noun (Button, Canvas, Label vs LinkButton, HBox etc.) .
If you can presume what the CSS file contains - you might want to use switch/case and for every UIComponent - update its string representation to the correct way the StyleManager recognizes it.
The perfect solution would be to write your own CSS parser.... G'luck :)



private function loadRunTimeCSS(cssURL:String):void{
var loader:URLLoader;
var req:URLRequest = new URLRequest(cssURL);
loader = new URLLoader();
loader.addEventListener(Event.COMPLETE, onCSSFileLoaded);
loader.addEventListener(IOErrorEvent.IO_ERROR, onLoadPartitionError);
loader.load(req);
}

private function onCSSFileLoaded(event:Event):void{
var sheet:StyleSheet = new StyleSheet();
try{
// Important Notice - the parseCSS function takes the entire CSS file
// and converts it all to lowerCase letters.
// Therefor - if you have a styleName for Button
// the style whould be recognized as button - thus- will be ingnored for all Button classes
// Also - is you created a style name - e.g. - .myStyle - then
// when applying to it - you must lowercase it
// e.g. - myButton.styleName = "mystyle"
//
sheet.parseCSS(event.currentTarget.data);

for each (var style:String in sheet.styleNames){
var generalStyle:CSSStyleDeclaration = new CSSStyleDeclaration(style + "_CSS_Style");
var styleObj:Object = sheet.getStyle(style);
for (var styleProp:String in styleObj){
var styleValue:String = styleObj[styleProp];
var regExp:RegExp = new RegExp("'\"","gi");
// we must take off any remainings of "" / ' in the string since the styleManager
// does not recognize it nor does the parseCSS function takes it off....
styleValue = styleValue.replace(regExp,'');

generalStyle.setStyle(styleProp, styleValue);
}

StyleManager.setStyleDeclaration(style, generalStyle, true);

}

_logger.info("**Done loading private labeling!");
}catch(e:Error){
_logger.info("Count not process runtime lableing: " + e.message);
}finally{

}

}

private function onLoadPartitionError(event:IOErrorEvent):void
{
_logger.info("Count not load runtime lableing.css: " + event.text);
}