blob: ad70490160dbbb161d7c224b05ae029e15acd098 [file] [log] [blame]
////////////////////////////////////////////////////////////////////////////////
//
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
package mx.styles
{
import flash.display.DisplayObject;
import flash.display.LoaderInfo;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IEventDispatcher;
import flash.events.TimerEvent;
import flash.system.ApplicationDomain;
import flash.system.SecurityDomain;
import flash.utils.Timer;
import flash.utils.describeType;
import mx.core.FlexVersion;
import mx.core.IFlexModuleFactory;
import mx.core.mx_internal;
import mx.events.FlexChangeEvent;
import mx.events.ModuleEvent;
import mx.events.Request;
import mx.events.StyleEvent;
import mx.managers.ISystemManager;
import mx.managers.SystemManagerGlobals;
import mx.modules.IModuleInfo;
import mx.modules.ModuleManager;
import mx.resources.IResourceManager;
import mx.resources.ResourceManager;
import mx.styles.IStyleManager2;
import mx.styles.IStyleModule;
import mx.utils.MediaQueryParser;
use namespace mx_internal;
[ExcludeClass]
[ResourceBundle("styles")]
[Mixin]
/**
* @private
*/
public class StyleManagerImpl extends EventDispatcher implements IStyleManager2
{
include "../core/Version.as";
//--------------------------------------------------------------------------
//
// Class constants
//
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
//
// Class variables
//
//--------------------------------------------------------------------------
/**
* @private
*/
private static var instance:IStyleManager2;
//--------------------------------------------------------------------------
//
// Class methods
//
//--------------------------------------------------------------------------
/**
* @private
*/
public static function init(fbs:IFlexModuleFactory):void
{
var styleDataClassName:String = fbs.info()["styleDataClassName"];
if (styleDataClassName)
{
var sm:StyleManagerImpl = fbs.getImplementation("mx.styles::IStyleManager2") as StyleManagerImpl;
if (!sm)
sm = new StyleManagerImpl(fbs);
var styleDataClass:Class = fbs.info()["currentDomain"].getDefinition(styleDataClassName);
var styleNames:Array = styleDataClass["inheritingStyles"];
for each (var s:String in styleNames)
{
sm.registerInheritingStyle(s);
}
generateCSSStyleDeclarations(sm, styleDataClass["factoryFunctions"], styleDataClass["data"]);
sm.initProtoChainRoots();
}
}
public static function generateCSSStyleDeclarations(styleManager:StyleManagerImpl, factoryFunctions:Object, data:Array, newSelectors:Array = null, overrideMap:Object = null):void
{
var arr:Array = data;
var conditions:Array = null;
var condition:CSSCondition = null;
var selector:CSSSelector = null;
var style:CSSStyleDeclaration;
var declarationName:String = "";
var segmentName:String = "";
var effects:Array;
var mergedStyle:CSSStyleDeclaration;
var conditionCombiners:Object = {};
conditionCombiners[CSSConditionKind.CLASS] = ".";
conditionCombiners[CSSConditionKind.ID] = "#";
conditionCombiners[CSSConditionKind.PSEUDO] = ':';
var n:int = arr.length;
for (var i:int = 0; i < n; i++)
{
var className:int = arr[i];
if (className == CSSClass.CSSSelector)
{
var selectorName:String = arr[++i];
selector = new CSSSelector(selectorName, conditions, selector);
segmentName = selectorName + segmentName;
if (declarationName != "")
declarationName += " ";
declarationName += segmentName;
segmentName = "";
conditions = null;
}
else if (className == CSSClass.CSSCondition)
{
if (!conditions)
conditions = [];
var conditionType:String = arr[++i];
var conditionName:String = arr[++i];
condition = new CSSCondition(conditionType, conditionName);
conditions.push(condition);
segmentName = segmentName + conditionCombiners[conditionType] + conditionName;
}
else if (className == CSSClass.CSSStyleDeclaration)
{
var factoryName:int = arr[++i]; // defaultFactory or factory
var defaultFactory:Boolean = factoryName == CSSFactory.DefaultFactory;
if (defaultFactory)
{
mergedStyle = styleManager.getMergedStyleDeclaration(declarationName);
style = new CSSStyleDeclaration(selector, styleManager, mergedStyle == null);
}
else
{
style = styleManager.getStyleDeclaration(declarationName);
if (!style)
{
style = new CSSStyleDeclaration(selector, styleManager, mergedStyle == null);
if (factoryName == CSSFactory.Override)
newSelectors.push(style);
}
}
if (defaultFactory)
{
if (style.defaultFactory == null)
style.defaultFactory = factoryFunctions[declarationName];
}
else
{
if (factoryName == CSSFactory.Factory)
{
if (style.factory == null)
style.factory = factoryFunctions[declarationName];
}
else
{
// apply overrides from CSS StyleModule
var moduleStyles:Object = new factoryFunctions[declarationName];
for (var styleProp:String in moduleStyles)
{
style.setLocalStyle(styleProp, moduleStyles[styleProp]);
if (!overrideMap[declarationName])
overrideMap[declarationName] = [];
overrideMap[declarationName].push(styleProp);
}
}
}
if (defaultFactory && mergedStyle != null &&
(mergedStyle.defaultFactory == null ||
compareFactories(new style.defaultFactory(), new mergedStyle.defaultFactory())))
{
styleManager.setStyleDeclaration(style.mx_internal::selectorString, style, false);
}
selector = null;
conditions = null;
declarationName = "";
mergedStyle = null;
}
}
}
private static var propList1:Vector.<String> = new Vector.<String>();
private static var propList2:Vector.<String> = new Vector.<String>();
/**
* @private
*/
private static function compareFactories(obj1:Object, obj2:Object):int
{
propList1.length = propList2.length = 0;
for (var p:String in obj1)
propList1.push(p);
for (p in obj2)
propList2.push(p);
if (propList1.length != propList2.length)
return 1;
for each (p in propList1)
{
if (obj1[p] !== obj2[p])
return 1;
}
return 0;
}
/**
* @private
*/
public static function getInstance():IStyleManager2
{
if (!instance)
{
// In Flex 4 each application/module creates its own style manager.
// There will be no style manager if the application/module was compiled for
// Flex 3 compatibility. In that case create there will be no instance
// associated with the top-level application so create a new instance.
instance = IStyleManager2(IFlexModuleFactory(SystemManagerGlobals.topLevelSystemManagers[0]).
getImplementation("mx.styles::IStyleManager2"));
if (!instance)
instance = new StyleManagerImpl(SystemManagerGlobals.topLevelSystemManagers[0]);
}
return instance;
}
//--------------------------------------------------------------------------
//
// Constructor
//
//--------------------------------------------------------------------------
/**
* @private
*
* @param moduleFactory The module factory that is creating this instance. May not be null.
*/
public function StyleManagerImpl(moduleFactory:IFlexModuleFactory = null)
{
super();
if (!moduleFactory) return;
this.moduleFactory = moduleFactory;
this.moduleFactory.registerImplementation("mx.styles::IStyleManager2", this);
// get our parent styleManager
if (moduleFactory is DisplayObject)
{
var request:Request = new Request(Request.GET_PARENT_FLEX_MODULE_FACTORY_REQUEST);
DisplayObject(moduleFactory).dispatchEvent(request);
var parentModuleFactory:IFlexModuleFactory = request.value as IFlexModuleFactory;
if (parentModuleFactory)
{
_parent = IStyleManager2(parentModuleFactory.
getImplementation("mx.styles::IStyleManager2"));
if (_parent is IEventDispatcher)
{
IEventDispatcher(_parent).addEventListener(FlexChangeEvent.STYLE_MANAGER_CHANGE, styleManagerChangeHandler, false, 0, true);
}
}
}
}
//--------------------------------------------------------------------------
//
// Variables
//
//--------------------------------------------------------------------------
/**
* @private
* Used to assign the selectorIndex in CSSStyleDeclaration so we can track
* the order they were added to the StyleManager.
* MatchStyleDeclarations has to return the declarations in the order
* they were declared
*/
private var selectorIndex:int = 0;
/**
* @private
*/
private var mqp:MediaQueryParser;
/**
* @private
* Set of inheriting non-color styles.
* This is not the complete set from CSS.
* Some of the omitted we don't support at all,
* others may be added later as needed.
* The <code>isInheritingTextFormatStyle()</code> method queries this set.
*/
private var inheritingTextFormatStyles:Object =
{
align: true,
bold: true,
color: true,
font: true,
indent: true,
italic: true,
size: true
};
/**
* @private
* Set of styles for which setStyle() causes
* invalidateSize() to be called on the component.
* The method registerSizeInvalidatingStyle() adds to this set
* and isSizeInvalidatingStyle() queries this set.
*/
private var sizeInvalidatingStyles:Object =
{
alignmentBaseline: true,
baselineShift: true,
blockProgression: true,
borderStyle: true,
borderThickness: true,
breakOpportunity : true,
cffHinting: true,
columnCount: true,
columnGap: true,
columnWidth: true,
digitCase: true,
digitWidth: true,
direction: true,
dominantBaseline: true,
firstBaselineOffset: true,
fontAntiAliasType: true,
fontFamily: true,
fontGridFitType: true,
fontLookup: true,
fontSharpness: true,
fontSize: true,
fontStyle: true,
fontThickness: true,
fontWeight: true,
headerHeight: true,
horizontalAlign: true,
horizontalGap: true,
justificationRule: true,
justificationStyle: true,
kerning: true,
leading: true,
leadingModel: true,
letterSpacing: true,
ligatureLevel: true,
lineBreak: true,
lineHeight: true,
lineThrough: true,
listAutoPadding: true,
listStylePosition: true,
listStyleType: true,
locale: true,
marginBottom: true,
marginLeft: true,
marginRight: true,
marginTop: true,
paddingBottom: true,
paddingLeft: true,
paddingRight: true,
paddingTop: true,
paragraphEndIndent: true,
paragraphStartIndent: true,
paragraphSpaceAfter: true,
paragraphSpaceBefore: true,
renderingMode: true,
strokeWidth: true,
tabHeight: true,
tabWidth: true,
tabStops: true,
textAlign: true,
textAlignLast: true,
textDecoration: true,
textIndent: true,
textJustify: true,
textRotation: true,
tracking: true,
trackingLeft: true,
trackingRight: true,
typographicCase: true,
verticalAlign: true,
verticalGap: true,
wordSpacing:true,
whitespaceCollapse: true
}
/**
* @private
* Set of styles for which setStyle() causes
* invalidateSize() to be called on the component's parent.
* The method registerParentSizeInvalidatingStyle() adds to this set
* and isParentSizeInvalidatingStyle() queries this set.
*/
private var parentSizeInvalidatingStyles:Object =
{
baseline: true,
bottom: true,
horizontalCenter: true,
left: true,
right: true,
top: true,
verticalCenter: true
}
/**
* @private
* Set of styles for which setStyle() causes
* invalidateDisplayList() to be called on the component's parent.
* The method registerParentDisplayListInvalidatingStyle() adds to this set
* and isParentDisplayListInvalidatingStyle() queries this set.
*/
private var parentDisplayListInvalidatingStyles:Object =
{
baseline: true,
bottom: true,
horizontalCenter: true,
left: true,
right: true,
top: true,
verticalCenter: true
}
/**
* @private
* Set of color names.
* The method registerColorName() adds to this set
* and isColorName() queries this set.
* All color names in this set are lowercase in order to support
* case-insensitive mapping in the StyleManager methods getColorName(),
* getColorNames(), registerColorName(), and isColorName().
* We handle color names at runtime in a case-insensitive way
* because the MXML compiler does this at compile time,
* in conformance with the CSS spec.
*/
private var colorNames:Object =
{
transparent: "transparent",
black: 0x000000,
blue: 0x0000FF,
green: 0x008000,
gray: 0x808080,
silver: 0xC0C0C0,
lime: 0x00FF00,
olive: 0x808000,
white: 0xFFFFFF,
yellow: 0xFFFF00,
maroon: 0x800000,
navy: 0x000080,
red: 0xFF0000,
purple: 0x800080,
teal: 0x008080,
fuchsia: 0xFF00FF,
aqua: 0x00FFFF,
magenta: 0xFF00FF,
cyan: 0x00FFFF,
// IMPORTANT: Theme colors must also be updated
// in the Flex compiler's CSS parser
// (in \src\java\macromedia\css\Descriptor.java)
// and possibly other places as well. Grep for them!
halogreen: 0x80FF4D,
haloblue: 0x009DFF,
haloorange: 0xFFB600,
halosilver: 0xAECAD9
};
/**
* @private
* Whether any advanced selectors have been registered with this style
* manager.
*/
private var _hasAdvancedSelectors:Boolean;
/**
* @private
* A map of CSS pseudo states. If a pseudo selector exists for a
* particular state name, it is likely that styles need to be recalculated.
*/
private var _pseudoCSSStates:Object;
/**
* @private
* A map of CSS selectors -- such as "global", "Button", and ".bigRed" --
* to CSSStyleDeclarations.
* This collection is accessed via getStyleDeclaration(),
* setStyleDeclaration(), and clearStyleDeclaration().
*/
private var _selectors:Object = {};
/**
* @private
*/
private var styleModules:Object = {};
/**
* @private
* A map of selector "subjects" to an ordered map of selector Strings and
* their associated CSSStyleDeclarations.
* The subject is the right most simple type selector in a potential chain
* of selectors.
*/
private var _subjects:Object = {};
/**
* @private
* Used for accessing localized Error messages.
*/
private var resourceManager:IResourceManager =
ResourceManager.getInstance();
/**
* @private
* Cache merged styles between this and parent.
*/
private var mergedInheritingStylesCache:Object;
/**
* @private
* This style manager's flex module factory.
*/
private var moduleFactory:IFlexModuleFactory;
//--------------------------------------------------------------------------
//
// Properties
//
//--------------------------------------------------------------------------
//----------------------------------
// parent
//----------------------------------
/**
* @private
*/
private var _parent:IStyleManager2;
/**
* @private
*
* The style manager that is the parent of this StyleManager.
*
* @return the parent StyleManager or null if this is the top-level StyleManager.
*/
public function get parent():IStyleManager2
{
return _parent;
}
//----------------------------------
// qualifiedTypeSelectors
//----------------------------------
/**
* @private
*/
private static var _qualifiedTypeSelectors:Boolean = true;
public function get qualifiedTypeSelectors():Boolean
{
if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0)
return false;
if (_qualifiedTypeSelectors)
return _qualifiedTypeSelectors;
if (parent)
return parent.qualifiedTypeSelectors;
return false;
}
public function set qualifiedTypeSelectors(value:Boolean):void
{
_qualifiedTypeSelectors = value;
}
//----------------------------------
// stylesRoot
//----------------------------------
/**
* @private
*/
private var _stylesRoot:Object;
/**
* @private
* The root of all proto chains used for looking up styles.
* This object is initialized once by initProtoChainRoots() and
* then updated by calls to setStyle() on the global CSSStyleDeclaration.
* It is accessed by code that needs to construct proto chains,
* such as the initProtoChain() method of UIComponent.
*/
public function get stylesRoot():Object
{
return _stylesRoot;
}
public function set stylesRoot(value:Object):void
{
_stylesRoot = value;
}
//----------------------------------
// inheritingStyles
//----------------------------------
/**
* @private
*/
private var _inheritingStyles:Object = {};
/**
* @private
* Set of inheriting non-color styles.
* This is not the complete set from CSS.
* Some of the omitted we don't support at all,
* others may be added later as needed.
* The method registerInheritingStyle() adds to this set
* and isInheritingStyle() queries this set.
*/
public function get inheritingStyles():Object
{
if (mergedInheritingStylesCache)
return mergedInheritingStylesCache;
var mergedStyles:Object = _inheritingStyles;
if (parent)
{
var otherStyles:Object = parent.inheritingStyles;
for (var obj:Object in otherStyles)
{
if (mergedStyles[obj] === undefined)
mergedStyles[obj] = otherStyles[obj];
}
}
mergedInheritingStylesCache = mergedStyles;
return mergedStyles;
}
public function set inheritingStyles(value:Object):void
{
_inheritingStyles = value;
mergedInheritingStylesCache = null;
if (hasEventListener(FlexChangeEvent.STYLE_MANAGER_CHANGE))
dispatchInheritingStylesChangeEvent();
}
//----------------------------------
// typeHierarchyCache
//----------------------------------
/**
* @private
*/
private var _typeHierarchyCache:Object;
/**
* @private
*/
public function get typeHierarchyCache():Object
{
if (_typeHierarchyCache == null)
_typeHierarchyCache = {};
return _typeHierarchyCache;
}
/**
* @private
*/
public function set typeHierarchyCache(value:Object):void
{
_typeHierarchyCache = value;
}
//----------------------------------
// typeSelectorCache
//----------------------------------
/**
* @private
*/
private var _typeSelectorCache:Object;
/**
* @private
*/
public function get typeSelectorCache():Object
{
if (_typeSelectorCache == null)
_typeSelectorCache = {};
return _typeSelectorCache;
}
/**
* @private
*/
public function set typeSelectorCache(value:Object):void
{
_typeSelectorCache = value;
}
//--------------------------------------------------------------------------
//
// Methods
//
//--------------------------------------------------------------------------
/**
* @private
* This method is called by code autogenerated by the MXML compiler,
* after StyleManager.styles is popuplated with CSSStyleDeclarations.
*/
public function initProtoChainRoots():void
{
if (!stylesRoot)
{
var style:CSSStyleDeclaration = getMergedStyleDeclaration("global");
if (style != null)
{
stylesRoot = style.addStyleToProtoChain({}, null);
}
}
}
/**
* Returns an array of strings of all CSS selectors registered with the StyleManager.
* Pass items in this array to the getStyleDeclaration function to get the corresponding CSSStyleDeclaration.
* Note that 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
*/
public function get selectors():Array
{
var theSelectors:Array = [];
for (var i:String in _selectors)
theSelectors.push(i);
if (parent)
{
var otherSelectors:Array = parent.selectors;
for (i in otherSelectors)
theSelectors.push(i);
}
return theSelectors;
}
/**
* Determines whether any of the selectors registered with the style
* manager have been advanced selectors (descendant selector, id selector,
* non-global class selector, pseudo selector).
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion Flex 4
*/
public function hasAdvancedSelectors():Boolean
{
if (_hasAdvancedSelectors)
return true;
if (parent)
return parent.hasAdvancedSelectors();
return false;
}
/**
* @private
* Determines whether at least one pseudo-condition has been specified for
* the given state.
*/
public function hasPseudoCondition(cssState:String):Boolean
{
if (_pseudoCSSStates != null && _pseudoCSSStates[cssState] != null)
return true;
if (parent)
return parent.hasPseudoCondition(cssState);
return false;
}
private static var propNames:Array = ["class", "id", "pseudo", "unconditional"];
/**
* Retrieve all style declarations applicable to this subject. The subject
* is the right most simple type selector in a selector chain. Returns a
* map of selectors with four properties: class for class selectors,
* id for id selectors, pseudo for pseudo selectors and unconditional
* for selectors without conditions
*
*
* @param subject The subject of the style declaration's selector.
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion Flex 4
*/
public function getStyleDeclarations(subject:String):Object
{
// For Flex 3 and earlier, if we were passed a subject with a package
// name, such as "mx.controls.Button", strip off the package name
// leaving just "Button" and look for that subject.
if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0)
{
if (subject.charAt(0) != ".")
{
var index:int = subject.lastIndexOf(".");
if (index != -1)
subject = subject.substr(index + 1);
}
}
// NOTE: It's important the parent declarations come before this style
// manager's styles because the order here is the order they are added to the
// prototype chain.
var theSubjects:Object = null;
if (parent)
theSubjects = parent.getStyleDeclarations(subject);
var subjectsObject:Object = _subjects[subject];
if (!theSubjects)
{
if (subjectsObject)
theSubjects = subjectsObject;
}
else if (subjectsObject)
{
var mergedSubjects:Object = {};
for each (var prop:String in propNames)
{
mergedSubjects[prop] = subjectsObject[prop];
}
mergedSubjects.parent = theSubjects;
theSubjects = mergedSubjects;
}
return theSubjects;
}
private function isUnique(element:*, index:int, arr:Array):Boolean {
return (arr.indexOf(element) >= 0);
}
/**
* Gets the CSSStyleDeclaration object that stores the rules
* for the specified CSS selector.
*
* <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.
*
* @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
*/
public function getStyleDeclaration(selector:String):CSSStyleDeclaration
{
// For Flex 3 and earlier, if we were passed a selector with a package
// name, such as "mx.controls.Button", strip off the package name
// leaving just "Button" and look for that type selector.
if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0)
{
if (selector.charAt(0) != ".")
{
var index:int = selector.lastIndexOf(".");
if (index != -1)
selector = selector.substr(index + 1);
}
}
return _selectors[selector];
}
/**
* 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 this style manager contains a style declaration for the given selector, its style properties
* will be updated with properties from the parent style manager's merged style declaration. If
* this style manager does not have a style declaration for a given selector, the parent's merged
* style declaration will be set into this style manager depending on the value of the <code>
* setSelector</code> parameter.
* </p>
*
* <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 4
*/
public function getMergedStyleDeclaration(selector:String):CSSStyleDeclaration
{
var style:CSSStyleDeclaration = getStyleDeclaration(selector);
var parentStyle:CSSStyleDeclaration = null;
// If we have a parent, get its style and merge them with our style.
if (parent)
parentStyle = parent.getMergedStyleDeclaration(selector);
if (style || parentStyle)
{
style = new CSSMergedStyleDeclaration(style, parentStyle,
style ? style.selectorString : parentStyle.selectorString, this, false);
}
return style;
}
/**
* Sets the CSSStyleDeclaration object that stores the rules
* for the specified CSS selector.
*
* <p>If the <code>selector</code> parameter starts with a period (.),
* the specified selector 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 specified selector 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>
*
* <p>Note that the provided selector will update the selector and subject
* of the styleDeclaration to keep them in sync.</p>
*
* @param selector The name of the CSS selector.
* @param styleDeclaration The new style declaration.
* @param update Set to <code>true</code> to force an immediate update of the styles.
* Set to <code>false</code> to avoid an immediate update of the styles in the application.
* The styles will be updated the next time this method or the <code>clearStyleDeclaration()</code> method
* is called with the <code>update</code> property set to <code>true</code>.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function setStyleDeclaration(selector:String,
styleDeclaration:CSSStyleDeclaration,
update:Boolean):void
{
// For Flex 3 and earlier, if we were passed a selector with a package
// name, such as "mx.controls.Button", strip off the package name
// leaving just "Button" and look for that type selector.
if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0)
{
if (selector.charAt(0) != ".")
{
var index:int = selector.lastIndexOf(".");
if (index != -1)
selector = selector.substr(index + 1);
}
}
// Populate the selectors Array for this style declaration
styleDeclaration.selectorRefCount++;
styleDeclaration.selectorIndex = selectorIndex++;
_selectors[selector] = styleDeclaration;
// We also index by subject to help match advanced selectors
var subject:String = styleDeclaration.subject;
if (selector)
{
if (!styleDeclaration.subject)
{
// If the styleDeclaration does not yet have a subject we
// update its selector to keep it in sync with the provided
// selector.
styleDeclaration.selectorString = selector;
subject = styleDeclaration.subject;
}
else if (selector != styleDeclaration.selectorString)
{
// The styleDeclaration does not match the provided selector, so
// we ignore the subject on the styleDeclaration and try to
// determine the subject from the selector
var firstChar:String = selector.charAt(0);
if (firstChar == "." || firstChar == ":" || firstChar == "#")
{
subject = "*";
}
else
{
// TODO: Support parsing Advanced CSS selectors for a
// subject...
subject = selector;
}
// Finally, we update the styleDeclaration's selector to keep
// it in sync with the provided selector.
styleDeclaration.selectorString = selector;
}
}
if (subject != null)
{
// determine the kind of selector and add it to the appropriate
// bin of selectors for this subject
var kind:String = styleDeclaration.selector.conditions ?
styleDeclaration.selector.conditions[0].kind :
"unconditional";
var declarations:Object = _subjects[subject];
if (declarations == null)
{
declarations = {};
declarations[kind] = [styleDeclaration];
_subjects[subject] = declarations;
}
else
{
var declarationList:Array = declarations[kind] as Array;
if (declarationList == null)
declarations[kind] = [styleDeclaration];
else
declarationList.push(styleDeclaration);
}
}
// Also remember subjects that have pseudo-selectors to optimize
// styles during component state changes.
var pseudoCondition:String = styleDeclaration.getPseudoCondition();
if (pseudoCondition != null)
{
if (_pseudoCSSStates == null)
_pseudoCSSStates = {};
_pseudoCSSStates[pseudoCondition] = true;
}
// Record whether this is an advanced selector so that style declaration
// look up can be optimized for when no advanced selectors have been
// declared
if (styleDeclaration.isAdvanced())
_hasAdvancedSelectors = true;
// Flush cache and start over.
if (_typeSelectorCache)
_typeSelectorCache = {};
if (update)
styleDeclarationsChanged();
}
/**
* Clears the CSSStyleDeclaration object that stores the rules
* for the specified CSS selector.
*
* <p>If the specified selector is a class selector (for example, ".bigMargins" or ".myStyle"),
* you must be sure to start the
* <code>selector</code> property with a period (.).</p>
*
* <p>If the specified selector is a type selector (for example, "Button"), do not start the
* <code>selector</code> property with a period.</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 to clear.
* @param update Set to <code>true</code> to force an immediate update of the styles.
* Set to <code>false</code> to avoid an immediate update of the styles in the application.
* The styles will be updated the next time this method or the <code>setStyleDeclaration()</code> method is
* called with the <code>update</code> property set to <code>true</code>.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function clearStyleDeclaration(selector:String,
update:Boolean):void
{
var styleDeclaration:CSSStyleDeclaration =
getStyleDeclaration(selector);
if (styleDeclaration && styleDeclaration.selectorRefCount > 0)
styleDeclaration.selectorRefCount--;
// Clear out legacy selectors map
delete _selectors[selector];
// Clear out matching decls from our selectors stored by subject
var decls:Array;
var i:int;
var decl:CSSStyleDeclaration;
if (styleDeclaration && styleDeclaration.subject)
{
decls = _subjects[styleDeclaration.subject] as Array;
if (decls)
{
// Work from the back of the array so we can remove elements
// as we go.
for (i = decls.length - 1; i >= 0; i--)
{
decl = decls[i];
if (decl && decl.selectorString == selector)
{
if (decls.length == 1)
delete _subjects[styleDeclaration.subject];
else
decls.splice(i, 1);
}
}
}
}
else
{
// Without a subject, we start searching all declarations for this
// selector, clear out matching selectors if found and then assume
// this we can limit our search to this subject and stop looking.
var matchingSubject:Boolean = false;
for each (decls in _subjects)
{
if (decls)
{
// Work from the back of the array so we can remove elements
// as we go.
for (i = decls.length - 1; i >= 0; i--)
{
decl = decls[i];
if (decl && decl.selectorString == selector)
{
matchingSubject = true;
if (decls.length == 1)
delete _subjects[decl.subject];
else
decls.splice(i, 1);
}
}
if (matchingSubject)
break;
}
}
}
if (update)
styleDeclarationsChanged();
}
/**
* @private
* After an entire selector is added, replaced, or removed,
* this method updates all the DisplayList trees.
*/
public function styleDeclarationsChanged():void
{
var sms:Array /* of SystemManager */ =
SystemManagerGlobals.topLevelSystemManagers;
var n:int = sms.length;
for (var i:int = 0; i < n; i++)
{
// Type as Object to avoid dependency on SystemManager or WindowedSystemManager
var sm:ISystemManager = sms[i];
var cm:Object = sm.getImplementation("mx.managers::ISystemManagerChildManager");
Object(cm).regenerateStyleCache(true);
Object(cm).notifyStyleChangeInChildren(null, true);
}
}
/**
* Adds to the list of styles that can inherit values
* from their parents.
*
* <p><b>Note:</b> Ensure that you avoid using duplicate style names, as name
* collisions can result in decreased performance if a style that is
* already used becomes inheriting.</p>
*
* @param styleName The name of the style that is added to the list of styles that can inherit values.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function registerInheritingStyle(styleName:String):void
{
if (_inheritingStyles[styleName] != true)
{
_inheritingStyles[styleName] = true;
mergedInheritingStylesCache = null;
if (hasEventListener(FlexChangeEvent.STYLE_MANAGER_CHANGE))
dispatchInheritingStylesChangeEvent();
}
}
/**
* Tests to see if a style is inheriting.
*
* @param styleName The name of the style that you test to see if it is inheriting.
*
* @return Returns <code>true</code> if the specified style is inheriting.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function isInheritingStyle(styleName:String):Boolean
{
if (mergedInheritingStylesCache)
return mergedInheritingStylesCache[styleName] == true;
if (_inheritingStyles[styleName] == true)
return true;
if (parent && parent.isInheritingStyle(styleName))
return true;
return false;
}
/**
* Test to see if a TextFormat style is inheriting.
*
* @param styleName The name of the style that you test to see if it is inheriting.
*
* @return Returns <code>true</code> if the specified TextFormat style
* is inheriting.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function isInheritingTextFormatStyle(styleName:String):Boolean
{
if (inheritingTextFormatStyles[styleName] == true)
return true;
if (parent && parent.isInheritingTextFormatStyle(styleName))
return true;
return false;
}
/**
* Adds to the list of styles which may affect the measured size
* of the component.
* When one of these styles is set with <code>setStyle()</code>,
* the <code>invalidateSize()</code> method is automatically called on the component
* to make its measured size get recalculated later.
*
* @param styleName The name of the style that you add to the list.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function registerSizeInvalidatingStyle(styleName:String):void
{
sizeInvalidatingStyles[styleName] = true;
}
/**
* Tests to see if a style changes the size of a component.
*
* <p>When one of these styles is set with the <code>setStyle()</code> method,
* the <code>invalidateSize()</code> method is automatically called on the component
* to make its measured size get recalculated later.</p>
*
* @param styleName The name of the style to test.
*
* @return Returns <code>true</code> if the specified style is one
* which may affect the measured size of the component.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function isSizeInvalidatingStyle(styleName:String):Boolean
{
if (sizeInvalidatingStyles[styleName] == true)
return true;
if (parent && parent.isSizeInvalidatingStyle(styleName))
return true;
return false;
}
/**
* Adds to the list of styles which may affect the measured size
* of the component's parent container.
* <p>When one of these styles is set with <code>setStyle()</code>,
* the <code>invalidateSize()</code> method is automatically called on the component's
* parent container to make its measured size get recalculated
* later.</p>
*
* @param styleName The name of the style to register.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function registerParentSizeInvalidatingStyle(styleName:String):void
{
parentSizeInvalidatingStyles[styleName] = true;
}
/**
* Tests to see if the style changes the size of the component's parent container.
*
* <p>When one of these styles is set with <code>setStyle()</code>,
* the <code>invalidateSize()</code> method is automatically called on the component's
* parent container to make its measured size get recalculated
* later.</p>
*
* @param styleName The name of the style to test.
*
* @return Returns <code>true</code> if the specified style is one
* which may affect the measured size of the component's
* parent container.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function isParentSizeInvalidatingStyle(styleName:String):Boolean
{
if (parentSizeInvalidatingStyles[styleName] == true)
return true;
if (parent && parent.isParentSizeInvalidatingStyle(styleName))
return true;
return false;
}
/**
* Adds to the list of styles which may affect the appearance
* or layout of the component's parent container.
* When one of these styles is set with <code>setStyle()</code>,
* the <code>invalidateDisplayList()</code> method is auomatically called on the component's
* parent container to make it redraw and/or relayout its children.
*
* @param styleName The name of the style to register.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function registerParentDisplayListInvalidatingStyle(
styleName:String):void
{
parentDisplayListInvalidatingStyles[styleName] = true;
}
/**
* Tests to see if this style affects the component's parent container in
* such a way as to require that the parent container redraws itself when this style changes.
*
* <p>When one of these styles is set with <code>setStyle()</code>,
* the <code>invalidateDisplayList()</code> method is auomatically called on the component's
* parent container to make it redraw and/or relayout its children.</p>
*
* @param styleName The name of the style to test.
*
* @return Returns <code>true</code> if the specified style is one
* which may affect the appearance or layout of the component's
* parent container.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function isParentDisplayListInvalidatingStyle(
styleName:String):Boolean
{
if (parentDisplayListInvalidatingStyles[styleName] == true)
return true;
if (parent && parent.isParentDisplayListInvalidatingStyle(styleName))
return true;
return false;
}
/**
* Adds a color name to the list of aliases for colors.
*
* @param colorName The name of the color to add to the list; for example, "blue".
* If you later access this color name, the value is not case-sensitive.
*
* @param colorValue Color value, for example, 0x0000FF.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function registerColorName(colorName:String, colorValue:uint):void
{
colorNames[colorName.toLowerCase()] = colorValue;
}
/**
* Tests to see if the given String is an alias for a color value. For example,
* by default, the String "blue" is an alias for 0x0000FF.
*
* @param colorName The color name to test. This parameter is not case-sensitive.
*
* @return Returns <code>true</code> if <code>colorName</code> is an alias
* for a color.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function isColorName(colorName:String):Boolean
{
if (colorNames[colorName.toLowerCase()] !== undefined)
return true;
if (parent && parent.isColorName(colorName))
return true;
return false;
}
/**
* Returns the numeric RGB color value that corresponds to the
* specified color string.
* The color string can be either a case-insensitive color name
* such as <code>"red"</code>, <code>"Blue"</code>, or
* <code>"haloGreen"</code>, a hexadecimal value such as 0xFF0000, or a #-hexadecimal String
* such as <code>"#FF0000"</code>.
*
* <p>This method returns a uint, such as 4521830, that represents a color. You can convert
* this uint to a hexadecimal value by passing the numeric base (in this case, 16), to
* the uint class's <code>toString()</code> method, as the following example shows:</p>
* <pre>
* import mx.styles.StyleManager;
* private function getNewColorName():void {
* StyleManager.registerColorName("soylentGreen",0x44FF66);
* trace(StyleManager.getColorName("soylentGreen").toString(16));
* }
* </pre>
*
* @param colorName The color name.
*
* @return Returns a uint that represents the color value or <code>NOT_A_COLOR</code>
* if the value of the <code>colorName</code> property is not an alias for a color.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function getColorName(colorName:Object):uint
{
var n:Number;
if (colorName is String)
{
if (colorName.charAt(0) == "#")
{
// Map "#77EE11" to 0x77EE11
n = Number("0x" + colorName.slice(1));
return isNaN(n) ? StyleManager.NOT_A_COLOR : uint(n);
}
if (colorName.charAt(1) == "x" && colorName.charAt(0) == '0')
{
// Map "#77EE11" to 0x77EE11
n = Number(colorName);
return isNaN(n) ? StyleManager.NOT_A_COLOR : uint(n);
}
// Map "red" or "Red" to 0xFF0000;
// Map "haloGreen" or "HaLoGrEeN" to 0x46FF00.
var c:* = colorNames[colorName.toLowerCase()];
if (c === undefined)
{
// If not found then try our parent
if (parent)
c = parent.getColorName(colorName);
}
if (c === undefined)
return StyleManager.NOT_A_COLOR;
return uint(c);
}
return uint(colorName);
}
/**
* Converts each element of the colors Array from a color name
* to a numeric RGB color value.
* Each color String can be either a case-insensitive color name
* such as <code>"red"</code>, <code>"Blue"</code>, or
* <code>"haloGreen"</code>, a hexadecimal value such as 0xFF0000, or a #-hexadecimal String
* such as <code>"#FF0000"</code>..
*
* @param colors An Array of color names.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function getColorNames(colors:Array /* of Number or String */):void
{
if (!colors)
return;
var n:int = colors.length;
for (var i:int = 0; i < n; i++)
{
if ((colors[i] != null) && isNaN(colors[i]))
{
var colorNumber:uint = getColorName(colors[i]);
if (colorNumber != StyleManager.NOT_A_COLOR)
colors[i] = colorNumber;
}
}
}
/**
* Determines if a specified parameter is a valid style property. For example:
*
* <pre>
* trace(StyleManager.isValidStyleValue(myButton.getStyle("color")).toString());
* </pre>
*
* <p>This can be useful because some styles can be set to values
* such as 0, <code>NaN</code>,
* the empty String (<code>""</code>), or <code>null</code>, which can
* cause an <code>if (value)</code> test to fail.</p>
*
* @param value The style property to test.
*
* @return If you pass the value returned by a <code>getStyle()</code> method call
* to this method, it returns <code>true</code> if the style
* was set and <code>false</code> if it was not set.
*
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function isValidStyleValue(value:*):Boolean
{
// By convention, we don't allow style values to be undefined,
// so we can check for this as the "not set" value.
if (value !== undefined)
return true;
if (parent)
return parent.isValidStyleValue(value);
return false;
}
/**
* @private
*/
public function loadStyleDeclarations(
url:String, update:Boolean = true,
trustContent:Boolean = false,
applicationDomain:ApplicationDomain = null,
securityDomain:SecurityDomain = null):
IEventDispatcher
{
return loadStyleDeclarations2(url, update, applicationDomain, securityDomain);
}
/**
* Loads a style SWF.
*
* @param url Location of the style SWF.
*
* @param update If true, all the DisplayList trees will be updated.
* The default is true.
*
* @return An IEventDispatcher implementation that supports
* StyleEvent.PROGRESS, StyleEvent.COMPLETE, and
* StyleEvent.ERROR.
*
* @see flash.system.SecurityDomain
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function loadStyleDeclarations2(
url:String, update:Boolean = true,
applicationDomain:ApplicationDomain = null,
securityDomain:SecurityDomain = null):
IEventDispatcher
{
var module:IModuleInfo = ModuleManager.getModule(url);
var thisStyleManager:IStyleManager2 = this;
var readyHandler:Function = function(moduleEvent:ModuleEvent):void
{
var styleModule:IStyleModule = IStyleModule(moduleEvent.module.factory.create());
// Register the style module to use this style manager.
moduleEvent.module.factory.registerImplementation("mx.styles::IStyleManager2", thisStyleManager);
styleModule.setStyleDeclarations(thisStyleManager);
styleModules[moduleEvent.module.url].styleModule = styleModule;
if (update)
styleDeclarationsChanged();
};
module.addEventListener(ModuleEvent.READY, readyHandler,
false, 0, true);
var styleEventDispatcher:StyleEventDispatcher =
new StyleEventDispatcher(module);
var errorHandler:Function = function(moduleEvent:ModuleEvent):void
{
var errorText:String = resourceManager.getString(
"styles", "unableToLoad", [ moduleEvent.errorText, url ]);
if (styleEventDispatcher.willTrigger(StyleEvent.ERROR))
{
var styleEvent:StyleEvent = new StyleEvent(
StyleEvent.ERROR, moduleEvent.bubbles, moduleEvent.cancelable);
styleEvent.bytesLoaded = 0;
styleEvent.bytesTotal = 0;
styleEvent.errorText = errorText;
styleEventDispatcher.dispatchEvent(styleEvent);
}
else
{
throw new Error(errorText);
}
};
module.addEventListener(ModuleEvent.ERROR, errorHandler,
false, 0, true);
styleModules[url] =
new StyleModuleInfo(module, readyHandler, errorHandler);
// This Timer gives the loadStyleDeclarations() caller a chance
// to add event listeners to the return value, before the module
// is loaded.
var timer:Timer = new Timer(0);
var timerHandler:Function = function(event:TimerEvent):void
{
timer.removeEventListener(TimerEvent.TIMER, timerHandler);
timer.stop();
module.load(applicationDomain, securityDomain, null, moduleFactory);
};
timer.addEventListener(TimerEvent.TIMER, timerHandler, false, 0, true);
timer.start();
return styleEventDispatcher;
}
/**
* Unloads a style SWF.
*
* @param url Location of the style SWF.
*
* @param update If true, all the DisplayList trees will be updated.
* The default is true.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function unloadStyleDeclarations(
url:String, update:Boolean = true):void
{
var styleModuleInfo:StyleModuleInfo = styleModules[url];
if (styleModuleInfo)
{
styleModuleInfo.styleModule.unload();
var module:IModuleInfo = styleModuleInfo.module;
module.unload();
module.removeEventListener(ModuleEvent.READY,
styleModuleInfo.readyHandler);
module.removeEventListener(ModuleEvent.ERROR,
styleModuleInfo.errorHandler);
styleModules[url] = null;
}
if (update)
styleDeclarationsChanged();
}
/**
* @private
*/
private function dispatchInheritingStylesChangeEvent():void
{
var event:Event = new FlexChangeEvent(FlexChangeEvent.STYLE_MANAGER_CHANGE,
false, false, {property: "inheritingStyles"});
dispatchEvent(event);
}
/**
* @private
*/
public function acceptMediaList(value:String):Boolean
{
if (!mqp)
{
mqp = MediaQueryParser.instance;
if (!mqp)
{
mqp = new MediaQueryParser(moduleFactory);
MediaQueryParser.instance = mqp;
}
}
return mqp.parse(value);
}
//--------------------------------------------------------------------------
//
// Event handlers
//
//--------------------------------------------------------------------------
private function styleManagerChangeHandler(event:FlexChangeEvent):void
{
if (!event.data)
return; // invalid message
var property:String = event.data["property"];
if (property == "inheritingStyles")
{
mergedInheritingStylesCache = null;
}
if (hasEventListener(FlexChangeEvent.STYLE_MANAGER_CHANGE))
dispatchEvent(event);
}
}
}
import flash.events.EventDispatcher;
import mx.events.ModuleEvent;
import mx.events.StyleEvent;
import mx.modules.IModuleInfo;
import mx.styles.IStyleModule;
////////////////////////////////////////////////////////////////////////////////
//
// Helper class: StyleEventDispatcher
//
////////////////////////////////////////////////////////////////////////////////
/**
* @private
*/
class StyleEventDispatcher extends EventDispatcher
{
//--------------------------------------------------------------------------
//
// Constructor
//
//--------------------------------------------------------------------------
/**
* Constructor
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function StyleEventDispatcher(moduleInfo:IModuleInfo)
{
super();
moduleInfo.addEventListener(
ModuleEvent.PROGRESS, moduleInfo_progressHandler, false, 0, true);
moduleInfo.addEventListener(
ModuleEvent.READY, moduleInfo_readyHandler, false, 0, true);
}
//--------------------------------------------------------------------------
//
// Event handlers
//
//--------------------------------------------------------------------------
/**
* @private
*/
private function moduleInfo_progressHandler(event:ModuleEvent):void
{
var styleEvent:StyleEvent = new StyleEvent(
StyleEvent.PROGRESS, event.bubbles, event.cancelable);
styleEvent.bytesLoaded = event.bytesLoaded;
styleEvent.bytesTotal = event.bytesTotal;
dispatchEvent(styleEvent);
}
/**
* @private
*/
private function moduleInfo_readyHandler(event:ModuleEvent):void
{
var styleEvent:StyleEvent = new StyleEvent(StyleEvent.COMPLETE);
styleEvent.bytesLoaded = event.bytesLoaded;
styleEvent.bytesTotal = event.bytesTotal;
dispatchEvent(styleEvent);
}
}
////////////////////////////////////////////////////////////////////////////////
//
// Helper class: StyleModuleInfo
//
////////////////////////////////////////////////////////////////////////////////
/**
* @private
*/
class StyleModuleInfo
{
//--------------------------------------------------------------------------
//
// Constructor
//
//--------------------------------------------------------------------------
/**
* Constructor
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function StyleModuleInfo(module:IModuleInfo,
readyHandler:Function,
errorHandler:Function)
{
super();
this.module = module;
this.readyHandler = readyHandler;
this.errorHandler = errorHandler;
}
//--------------------------------------------------------------------------
//
// Properties
//
//--------------------------------------------------------------------------
//----------------------------------
// errorHandler
//----------------------------------
/**
* @private
*/
public var errorHandler:Function;
//----------------------------------
// readyHandler
//----------------------------------
/**
* @private
*/
public var readyHandler:Function;
//----------------------------------
// styleModule
//----------------------------------
/**
* @private
*/
public var styleModule:IStyleModule;
//----------------------------------
// module
//----------------------------------
/**
* @private
*/
public var module:IModuleInfo
}
class CSSClass
{
public static const CSSSelector:int = 0;
public static const CSSCondition:int = 1;
public static const CSSStyleDeclaration:int = 2;
}
class CSSFactory
{
public static const DefaultFactory:int = 0;
public static const Factory:int = 1;
public static const Override:int = 2;
}
class CSSDataType
{
public static const Native:int = 0;
public static const Definition:int = 1;
}