classes

XMLSkin.as

Stiahnuť XMLSkin.as

package sk.yoz.data
{
    import flash.display.Loader;
    import flash.display.LoaderInfo;
    import flash.events.Event;
    import flash.events.IOErrorEvent;
    import flash.events.SecurityErrorEvent;
    import flash.net.URLRequest;
    import flash.system.ApplicationDomain;
    import flash.system.LoaderContext;
    import flash.utils.getDefinitionByName;
    
    /**
     * XMLSkin class makes runtime settings/skinning easy
     * get latest version and examples on:
     * http://blog.yoz.sk/2009/10/xml-skin/
     * updated: 2010-03-07
     */
    
    public class XMLSkin extends Object
    {
        protected var assets:Object;
        protected var assetsSource:String;
        protected var root:Object;
        protected var skin:XML;
        protected var autoApply:Boolean;
        protected var loader:Loader;
        
        public function XMLSkin(root:Object, skin:XML)
        {
            super();
            this.root = root;
            this.skin = skin;
        }
        
        public function apply():void
        {
            XMLSkin.apply(root, skin, loader);
        }
        
        public static function apply(root:Object, skin:XML, 
            assetsLoader:Loader = null):void
        {
            if(!skin)
                return;
            for each(var a:XML in skin.@*)
                doApply(root, a.name(), a.toString(), assetsLoader);
            var children:XMLList = skin.children();
                
            if(!children.length())
                return;
            var childName:String;
            for each(var child:XML in children)
            {
                childName = child.name();
                if(!childName)
                    continue;
                if(child.text().toString())
                    doApply(root, childName, child.text().toString(), 
                        assetsLoader);
                if(root.hasOwnProperty(childName))
                    XMLSkin.apply(root[childName], child, assetsLoader);
                else if(getDefinitionByName(childName))
                    XMLSkin.apply(getDefinitionByName(childName), child, 
                        assetsLoader);
            }
        }
        
        protected static function doApply(root:Object, attribute:String, 
            value:String, assetsLoader:Loader = null):void
        {
            var name:String = attributeToName(attribute);
            if(isStyle(attribute))
                root.setStyle(name, castStyle(root, value, attribute, 
                    assetsLoader));
            else if(root.hasOwnProperty(name))
                root[name] = castProperty(root, value, attribute, assetsLoader);
        }
        
        protected static function castProperty(object:Object, value:String, 
            attribute:String, assetsLoader:Loader = null):*
        {
            var name:String = attributeToName(attribute);
            switch(typeof object[name])
            {
                case "boolean":
                    return Boolean(value.toLowerCase() == "true");
                case "number":
                case "string":
                    return value;
                default:
                    return getClassFromLibrary(value, assetsLoader)
                        || getClassFromAssets(value, assetsLoader)
                        || value;
            }
        }
        
        protected static function castStyle(object:Object, value:String, 
            attribute:String, assetsLoader:Loader = null):*
        {
            var name:String = attributeToName(attribute);
            if(!assetsLoader && isAsset(attribute))
                return null;
            if(isAsset(attribute))
                return getClassFromLibrary(value, assetsLoader)
                    || getClassFromAssets(value, assetsLoader);
            return value;
        }
        
        protected static function getClassFromLibrary(value:String, 
            assetsLoader:Loader):Class
        {
            var assetClass:Class;
            try
            {
                assetClass = getDefinitionByName(value) as Class;
            }
            catch(error:Error){}
            return assetClass;
        }
        
        protected static function getClassFromAssets(value:String, 
            assetsLoader:Loader):Class
        {
            var assetClass:Class;
            try
            {
                var applicationDomain:ApplicationDomain = 
                    assetsLoader.contentLoaderInfo.applicationDomain;
                var assetsClass:Class = 
                    applicationDomain.getDefinition("Assets") as Class;
                assetClass = assetsClass[value];
            }
            catch(error:Error){}
            return assetClass;
        }
        
        public function loadAssets(assetsSource:String):Loader
        {
            this.assetsSource = assetsSource;
            loader = new Loader();
            
            var info:LoaderInfo = loader.contentLoaderInfo;
            info.addEventListener(Event.COMPLETE, assetsComplete, false, 
                int.MAX_VALUE);
            info.addEventListener(IOErrorEvent.IO_ERROR, assetsIOError, false, 
                int.MAX_VALUE);
            info.addEventListener(SecurityErrorEvent.SECURITY_ERROR, 
                assetsSecurityError, false, int.MAX_VALUE);
            
            var request:URLRequest = new URLRequest(assetsSource);
            var context:LoaderContext = new LoaderContext(false, 
                ApplicationDomain.currentDomain);
            loader.load(request, context);
            return loader;
        }
        
        protected function assetsComplete(event:Event):void
        {
            apply();
        }
        
        protected function assetsIOError(event:IOErrorEvent):void
        {
        }
        
        protected function assetsSecurityError(event:SecurityErrorEvent):void
        {
        }
        
        protected static function isStyle(attribute:String):Boolean
        {
            attribute = stripAsset(attribute);
            return attribute.toLowerCase().substr(0, 6) == "style.";
        }
        
        protected static function stripStyle(attribute:String):String
        {
            if(isStyle(attribute))
                return attribute.substr(6);
            return attribute;
        }
        
        protected static function isAsset(attribute:String):Boolean
        {
            return attribute.toLowerCase().substr(0, 6) == "asset.";
        }
        
        protected static function stripAsset(attribute:String):String
        {
            if(isAsset(attribute))
                return attribute.substr(6);
            return attribute;
        }
        
        public static function attributeToName(attribute:String):String
        {
            return stripStyle(stripAsset(attribute));
        }
    }
}