//////////////////////////////////////////////////////////////////////////////// // // 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.events.EventDispatcher; import flash.utils.Dictionary; import mx.core.Singleton; import mx.core.mx_internal; import mx.events.FlexChangeEvent; import mx.managers.ISystemManager; import mx.managers.SystemManagerGlobals; import mx.utils.ObjectUtil; import flash.events.Event; use namespace mx_internal; [ExcludeClass] /** * The CSSStyleDeclaration class represents a set of CSS style rules. * The MXML compiler automatically generates one CSSStyleDeclaration object * for each selector in the CSS files associated with a Flex application. * *

A CSS rule such as *

 *      Button { color: #FF0000 }
 *  
* affects every instance of the Button class; * a selector like Button is called a type selector * and must not start with a dot.

* *

A CSS rule such as *

 *      .redButton { color: #FF0000 }
 *  
* affects only components whose styleName property * is set to "redButton"; * a selector like .redButton is called a class selector * and must start with a dot.

* *

You can access the autogenerated CSSStyleDeclaration objects * using the StyleManager.getStyleDeclaration() method, * passing it either a type selector *

 *  var buttonDeclaration:CSSStyleDeclaration =
 *      StyleManager.getStyleDeclaration("Button");
 *  
* or a class selector *
 *  var redButtonStyleDeclaration:CSSStyleDeclaration =
 *      StyleManager.getStyleDeclaration(".redButton");
 *  
*

* *

You can use the getStyle(), setStyle(), * and clearStyle() methods to get, set, and clear * style properties on a CSSStyleDeclaration.

* *

You can also create and install a CSSStyleDeclaration at run time * using the StyleManager.setStyleDeclaration() method: *

 *  var newStyleDeclaration:CSSStyleDeclaration = new CSSStyleDeclaration(".bigMargins");
 *  newStyleDeclaration.defaultFactory = function():void
 *  {
 *      leftMargin = 50;
 *      rightMargin = 50;
 *  }
 *  StyleManager.setStyleDeclaration(".bigMargins", newStyleDeclaration, true);
 *  
*

* * @see mx.core.UIComponent * @see mx.styles.StyleManager * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public class CSSMergedStyleDeclaration extends CSSStyleDeclaration { include "../core/Version.as"; //-------------------------------------------------------------------------- // // Constructor // //-------------------------------------------------------------------------- /** * @private * * A CSSStyleDeclaration that is a merger between two styles. The styles are for the same * selector. One style is from the local style manager and the other style is from the style manager's * parent. * * @param style - A style from the local style manager. May be null. * * @param parentStyle - The style in the parent style manager for the same selector. May be null. * * @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 setSelector - 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 * by calling styleManager.setStyleDeclaration(styleDeclaration.selectorString, styleDeclaration, false); * * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 4 * */ public function CSSMergedStyleDeclaration(style:CSSStyleDeclaration, parentStyle:CSSStyleDeclaration, selector:Object=null, styleManager:IStyleManager2=null, setSelector:Boolean = false) { super(selector, styleManager, setSelector); this.style = style; this.parentStyle = parentStyle; var i:uint; var n:uint; var effectsArray:Array; // combine effects child and parent effects array if (style && style.effects) { effects = []; effectsArray = style.effects; n = effectsArray.length; for (i = 0; i < n; i++) effects[i] = effectsArray[i]; } if (parentStyle && parentStyle.effects) { if (!effects) effects = []; effectsArray = parentStyle.effects; n = effectsArray.length; for (i = 0; i < n; i++) { effects[i] = effectsArray[i]; if (effects.indexOf(effectsArray[i]) == -1) effects[i] = effectsArray[i]; } } updateOverrides = true; } //-------------------------------------------------------------------------- // // Variables // //-------------------------------------------------------------------------- /** * @private * * Local storage for the style in the local style manager. */ private var style:CSSStyleDeclaration; /** * @private * * Local storage for the style in the parent style manager. */ private var parentStyle:CSSStyleDeclaration; /** * @private * * If true then update the overrides array from the style and * parentStyle. */ private var updateOverrides:Boolean; //-------------------------------------------------------------------------- // // Properties // //-------------------------------------------------------------------------- //---------------------------------- // defaultFactory //---------------------------------- /** * @private */ private var _defaultFactory:Function; [Inspectable(environment="none")] /** * @private */ override public function get defaultFactory():Function { if (_defaultFactory != null) return _defaultFactory; if ((style != null && style.defaultFactory != null) || (parentStyle != null && parentStyle.defaultFactory != null)) { _defaultFactory = function():void { if (parentStyle && parentStyle.defaultFactory != null) parentStyle.defaultFactory.apply(this); if (style && style.defaultFactory != null) style.defaultFactory.apply(this); }; } return _defaultFactory; } /** * @private */ override public function set defaultFactory(f:Function):void { // not supported } //---------------------------------- // factory //---------------------------------- /** * @private */ private var _factory:Function; [Inspectable(environment="none")] /** * @private */ override public function get factory():Function { if (_factory != null) return _factory; if ((style != null && style.factory != null) || (parentStyle != null && parentStyle.factory != null)) { _factory = function():void { if (parentStyle && parentStyle.factory != null) parentStyle.factory.apply(this); if (style && style.factory != null) style.factory.apply(this); }; } return _factory; } /** * @private */ override public function set factory(f:Function):void { // not supported } /** * @private */ override public function get overrides():Object { if (!updateOverrides) return super.overrides; var obj:Object; var mergedOverrides:Object = null; if (style && style.overrides) { mergedOverrides = []; var childOverrides:Object = style.overrides; for (obj in childOverrides) mergedOverrides[obj] = childOverrides[obj]; } if (parentStyle && parentStyle.overrides) { if (!mergedOverrides) mergedOverrides = []; var parentOverrides:Object = parentStyle.overrides; for (obj in parentOverrides) { if (mergedOverrides[obj] === undefined) mergedOverrides[obj] = parentOverrides[obj]; } } super.overrides = mergedOverrides; updateOverrides = false; return mergedOverrides; } /** * @private */ override public function set overrides(o:Object):void { // not supported } /** * @private */ override public function setStyle(styleProp:String, newValue:*):void { // not supported } /** * @private */ override mx_internal function addStyleToProtoChain(chain:Object, target:DisplayObject, filterMap:Object = null):Object { // If we have a local style, then add only it to the chain. It will // take are of adding its parent to the chain. // If then is no style, but a parentStyle, then add the parent Style // to the chain. if (style) return style.addStyleToProtoChain(chain, target, filterMap); else if (parentStyle) return parentStyle.addStyleToProtoChain(chain, target, filterMap); else return chain; } } }