Functional and Design SpecificationGlossary | Summary and Background | Usage Scenarios | Detailed Description | API Description | Examples and Usage | Additional Implementation Details | Prototype Work | Compiler Work | Flex Feature Dependencies | Backwards Compatibility | Performance
GlossaryStyleManager: Class responsible for managing style declarations. Summary and BackgroundThere are two goals for this feature. The first is prevent type compatibility errors when spark components are used in modules. The second goal of the feature to solve modules leaks associated with styles. The StyleManager was a singleton that tracks style declarations. If a style declaration was added from a module, that created a reference from StyleManager to the module which would keep the module in memory. The plan is to implement this feature by creating a StyleManager for every application and module. This means the current StyleManager will no longer be a singleton. Usage Scenarios
Detailed DescriptionSystem OverviewIn Flex 3 a single StyleManager exists for a top-level application and its child applications and modules. In Flex 4 there will be a StyleManager for every application and module. The below picture shows an overview of the different configurations a StyleManager can be present in.
In the above diagram, application A has four children, A.1, A.2, A.3, and M.1. Application A.1 is an application loaded by SWFLoader with default settings. Applications A.2 and A.3 are Marshall Plan applications. Module M.1, represents a module loaded into a child ApplicationDomain. Style Inheritance Model
What about cases where an application or module is loaded into an existing ApplicationDomain? Styles still inherit but the application or module can't be unloaded. A StyleManager will hold the set of styles for the components of each application or module. The styles would typically apply to all the components below the application or module although this can be changed programmically by changing the module factory of a component. The inheritence of styles extends to sub-applications and sub-modules as well. To compute the set of styles that apply to any given component you would first need to merge the styles of each StyleManager that parents a component. The styles are merged on a per-property basis starting with the closest parent StyleManager of a component and working upwards to the top-level StyleManager. Example) Application A: @namespace s "library://ns.adobe.com/flex/spark"; @namespace mx "library://ns.adobe.com/flex/halo"; mx|Button { cornerRadius: 4; textAlign: "center"; } s|Button { errorSkin: ClassReference("MyErrorSkin"); skinClass: ClassReference("spark.skins.spark.ButtonSkin"); } Application A.1: @namespace s "library://ns.adobe.com/flex/spark"; @namespace mx "library://ns.adobe.com/flex/halo"; mx|Button { textAlign: "left"; } s|Button { skinClass: ClassReference("MyLeftButtonSkin"); } Module M.1: @namespace s "library://ns.adobe.com/flex/spark"; @namespace mx "library://ns.adobe.com/flex/halo"; mx|Button { textAlign: "right"; } s|Button { skinClass: ClassReference("MyLeftButtonSkin"); } For a component in module M.1, the effective styles after merging module M.1 with application A are: @namespace s "library://ns.adobe.com/flex/spark"; @namespace mx "library://ns.adobe.com/flex/halo"; mx|Button { cornerRadius: 4; textAlign: "right"; } s|Button { errorSkin: ClassReference("MyErrorSkin"); skinClass: ClassReference("MyLeftButtonSkin"); } The cornerRadius property is added to mx|Button from application A. The textAlign property with a value of "right" came from module M.1. Notice that application A also declared a textAlign property with a value of "center". Since the textAlign property is already specified in module M.1, the property in application A is ignored during the merge of styles. The properties for s|Button are merged in the same way as mx|Button. Property errorSkin comes from application A and skinClass comes from module M.1. The same style property merging applies to application A.1 as well. StyleManager API ModelIn the context of multiple StyleManagers the StyleManager API will return the merged properties from each property or function call. The properties are merged by consulting each parent StyleManager until the top-level StyleManager is reached. The exception of this rule is getStyleDeclaration(). It will only return the styles of the local StyleManager. This was done to support previous coding patterns. To get a style declaration that is the result of merging with parent style managers a new function, getMergedStyleDeclaration() has been added to IStyleManager2. All functions that modify properties will only affect the local StyleManager. Since getMergedStyleDeclaration() returns the result of merging StyleManager properties you will no longer be able to modify the returned reference to set styles. Application and Module Style InitializationThe compiler generates code to initialize the styles of an application or module based on the classes linked in to that application or module. The generated style classes follow a mixin pattern. Each mixin class sets appropriate style selectors based on the default styles for that selector. When getting and setting the mixin styles only the local StyleManager will be used since each StyleManager can have different values for the same selector. Finding the current StyleManagerSince there are many StyleManagers in the system, each component will need a way to access its relevant StyleManager. A component will need to get its StyleManager when it is on the display list and when it is off the display list. To get the current StyleManager use the StyleManager.getStyleManager() function. The getStyleManager function takes a component's module factory as an argument. The module factory will be used to find the StyleManager associated with a SystemManager or FlexModuleFactory. If a component does not have a moduleFactory or the StyleManager property is not set, the StyleManager of the top-level SystemManager will be used. Loading CSS ModulesWhen using the singleton StyleManager the loadStyleDeclarations() function loaded styles into the singleton StyleManager. Now the loadStyleDeclarations() will be called on some instance of a StyleManager. The styles will be loaded into that StyleManager instance. It is recommended to load a style module into the application domain of the current application so the classes loaded by the style module can be shared by all the sub-applications and modules of the current application. The down-side to this is the style module cannot be unloaded. API DescriptionStyleManager
public class StyleManager { ... /** * Returns an Array of all the CSS selectors that are registered with the StyleManager. * You can pass items in this Array to the <code>getStyleDeclaration()</code> method * to get the corresponding CSSStyleDeclaration object. * Class selectors are prepended with a period. * * @return An Array of all of the selectors * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Deprecated( replacement="IStyleManager2.selectors on a style manager instance from IAdvancedStyleClient.styleManager", since="4.0")] public static function get selectors():Array { return impl.selectors; } ... /** * Returns the style manager for an object. * * @param moduleFactory The module factory of an object you want the * style manager for. If null, the top-level style manager is returned. * * @return the style manager for the given module factory. * * @langversion 3.0 * @playerversion Flash 10 * @playerversion AIR 1.5 * @productversion Flex 4 */ public static function getStyleManager(moduleFactory:IFlexModule):IStyleManager2 { ... } } IStyleManager2
public interface IStyleManager2 extends IStyleManager { //-------------------------------------------------------------------------- // // Properties // //-------------------------------------------------------------------------- /** * The style manager that is the parent of this style manager. * * @return the parent style manager or null if this is the top-level style manager. */ function get parent():IStyleManager2; /** * @private */ function set parent(parent:IStyleMananger2):void; ... /** * Gets a CSSStyleDeclaration object that stores the rules * for the specified CSS selector. The CSSStyleDeclaration object is the created by merging * the properties of the specified CSS selector of this style manager with all of the parent * style managers. * * <p>If the <code>selector</code> parameter starts with a period (.), * the returned CSSStyleDeclaration is a class selector and applies only to those instances * whose <code>styleName</code> property specifies that selector * (not including the period). * For example, the class selector <code>".bigMargins"</code> * applies to any UIComponent whose <code>styleName</code> * is <code>"bigMargins"</code>.</p> * * <p>If the <code>selector</code> parameter does not start with a period, * the returned CSSStyleDeclaration is a type selector and applies to all instances * of that type. * For example, the type selector <code>"Button"</code> * applies to all instances of Button and its subclasses.</p> * * <p>The <code>global</code> selector is similar to a type selector * and does not start with a period.</p> * * @param selector The name of the CSS selector. * @param localOnly Controls whether the returned style declaration is the result of merging * the properties of this and any parent style managers or if the style declaration is only * from this style manager. * * @return The style declaration whose name matches the <code>selector</code> property. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ function getMergedStyleDeclaration(selector:String):CSSStyleDeclaration; ... IFlexModuleFactory
public interface IFlexModuleFactory { ... /** * Register an implementation for an interface. * Similar to Singleton.registerClass, but per- * ISystemManager, and takes an instance not a class * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ function registerImplementation(interfaceName:String, impl:Object):void; /** * Get the implementation for an interface. * Similar to Singleton.getInstance, but per- * ISystemManager * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ function getImplementation(interfaceName:String):Object; ... } ISystemManager
IModuleInfo
/**
* Requests that the module be loaded. If the module is already loaded,
* the call does nothing. Otherwise, the module begins loading and dispatches
* <code>progress</code> events as loading proceeds.
*
* @param applicationDomain The current application domain in which your code is executing.
*
* @param securityDomain The current security "sandbox".
*
* @param bytes A ByteArray object. The ByteArray is expected to contain
* the bytes of a SWF file that represents a compiled Module. The ByteArray
* object can be obtained by using the URLLoader class. If this parameter
* is specified the module will be loaded from the ByteArray. If this
* parameter is null the module will be loaded from the url specified in
* the url property.
*
* @param moduleFactory The module factory that parents the load. The loaded
* module's parent style manager will be determined from this argument.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
function load(applicationDomain:ApplicationDomain = null,
securityDomain:SecurityDomain = null,
bytes:ByteArray = null,
moduleFactory:IFlexModuleFactory = null):void;
Request
/** * This is an event that is expects its data property to be set by * a responding listener */ public class Request extends Event { /** * Dispatched from a sub-application or module to find the module factory of its parent * application or module. The recipient of this request should set the data property to * their module factory. * * The message is dispatched from the content of a loaded module or application. */ public static const GET_PARENT_FLEX_MODULE_FACTORY_REQUEST:String = "getParentFlexModuleFactoryRequest"; UIComponent
public function get styleManager():IStyleManager2 { // TODO: } IStyleModule
/**
* Creates and sets style declarations from the styles modules into the given
* style manager.
*
* @param styleManager The style manager where the style declarations will be
* loaded into. The style declarations will be created relative to the this
* style manager. The unload() function will unload styles from this style
* manager. If null is passed the top-level style manager is used.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 4
*/
function setStyleDeclarations(styleManager:IStyleManager2):void;
CSSStyleDeclaration
/**
* Constructor.
*
* @param selector - If the selector is a CSSSelector then advanced
* CSS selectors are supported. If a String is used for the selector then
* only simple CSS selectors are supported. If the String starts with a
* dot it is interpreted as a universal class selector, otherwise it must
* represent a simple type selector. If not null, this CSSStyleDeclaration
* will be registered with StyleManager.
*
* @param styleManager - The style manager to set this declaration into. If the
* styleManager is null the top-level style manager will be used.
*
* @param autoRegisterWithStyleManager - If true set the selector in the styleManager. If setSelector
* is false this style declaration can be set in the styleManager at a later time.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function CSSStyleDeclaration(selector:Object=null,
styleManager:IStyleManager2=null,
autoRegisterWithStyleManager:Boolean = true)
Examples and UsageThis is an example of an application that loads two modules, "LeftModule" and "RightModule". The main application contains no styles. Both "LeftModule" and "RightModule" declare styles to modify the text alignment of Buttons. The example shows how modules can have different values for the same selector. Prior to this feature, the module that was loaded first would have its styles loaded and the other modules would have to use those styles as well. Main ApplicationThe main application contains two buttons. The two buttons toggle the loaded state of modules. <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/halo" minWidth="1024" minHeight="768"> <fx:Script> <![CDATA[ private function toggleLeftModule():void { if (lml.url == null) lml.url = "LeftModule.swf"; else lml.url = null; } private function toggleRightModule():void { if (rml.url == null) rml.url = "RightModule.swf"; else rml.url = null; } ]]> </fx:Script> <s:layout> <s:VerticalLayout/> </s:layout> <mx:Button label="Left Module" width="300" click="toggleLeftModule()" /> <mx:Button label="Right Module" width="300" click="toggleRightModule()" /> <mx:ModuleLoader id="lml" /> <mx:ModuleLoader id="rml" /> </s:Application> LeftModuleThis module contains a Style block that sets the Halo Button to be left aligned and sets a skinClass for the Spark button that makes the Spark Button left aligned. <?xml version="1.0" encoding="utf-8"?> <mx:Module xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/halo" layout="vertical" width="400" height="100"> <fx:Style> @namespace s "library://ns.adobe.com/flex/spark"; @namespace mx "library://ns.adobe.com/flex/halo"; mx|Button { textAlign: "left"; } s|Button { skinClass: ClassReference("MyLeftButtonSkin"); } </fx:Style> <mx:Button label="Left Button" width="300" /> <s:Button label="Left Skinned Button" width="300" /> </mx:Module> RightModuleThis module contains a Style block that sets the Halo Button to be right aligned and sets a skinClass for the Spark button that makes the Spark Button right aligned. <?xml version="1.0" encoding="utf-8"?> <mx:Module xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/halo" layout="vertical" width="400" height="100"> <fx:Style> @namespace s "library://ns.adobe.com/flex/spark"; @namespace mx "library://ns.adobe.com/flex/halo"; mx|Button { textAlign: "right"; } s|Button { skinClass: ClassReference("MyRightButtonSkin"); } </fx:Style> <mx:Button label="Right Button" width="300" /> <s:Button label="Right Skinned Button" width="300" /> </mx:Module> Additional Implementation DetailsCreation and initialization of StyleManagerThe steps involved in creating and initializing a new StyleManager for an application.
The steps involved in creating and initializing a new StyleManager for a module.
Prototype WorkGlenn did a prototype of StyleManager using an approach where the StyleManager is modified to track the styles of all modules. This specification describes a different design where each application has its own StyleManager. There is not prototype for this method. Compiler WorkThe generated code for styles will need to be updated. Compiler Options-isolate-styles Flex Feature DependenciesNone. Backwards Compatibility
Behavior
Performance
|
|
| You must be logged in to comment. |
|---|


hi. Is there a problem with this document? I dont seem to be able to get it to render correctly. Tried many browsers. Right hand has cropped text.
Thanks g.