| //////////////////////////////////////////////////////////////////////////////// |
| // |
| // 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 |
| { |
| import flash.utils.Dictionary; |
| |
| import flashx.textLayout.elements.FlowElement; |
| import flashx.textLayout.elements.FlowGroupElement; |
| import flashx.textLayout.elements.IFormatResolver; |
| import flashx.textLayout.elements.TextFlow; |
| import flashx.textLayout.formats.ITextLayoutFormat; |
| import flashx.textLayout.formats.TextLayoutFormat; |
| import flashx.textLayout.formats.TextLayoutFormat; |
| import flashx.textLayout.property.Property; |
| import flashx.textLayout.tlf_internal; |
| use namespace tlf_internal; |
| |
| import mx.styles.CSSStyleDeclaration; |
| import mx.styles.StyleManager; |
| import mx.styles.IStyleManager2; |
| |
| /** This version hands back a style on demand from the dictinoary. |
| * Another way to do it would be to "redo" the cascade top down. |
| */ |
| public class FlexStyleResolver implements IFormatResolver |
| { |
| private var _formatCache:Dictionary; |
| private var _styleManager:IStyleManager2; |
| |
| static public var classToNameDictionary:Object = { "SpanElement":"flashx.textLayout.elements.span", "ParagraphElement":"flashx.textLayout.elements.p", "TextFlow":"flashx.textLayout.elements.TextFlow", "DivElement":"flashx.textLayout.elements.div" } |
| |
| /** Create a flex style resolver. |
| * @param ignoreGlobal - don't use global settings. |
| */ |
| public function FlexStyleResolver(styleManager:IStyleManager2):void |
| { |
| // cache results |
| _formatCache = new Dictionary(true); |
| _styleManager = styleManager; |
| } |
| |
| private function addStyleAttributes(attr:TextLayoutFormat, styleSelector:String):TextLayoutFormat |
| { |
| var foundStyle:CSSStyleDeclaration = _styleManager.getStyleDeclaration(styleSelector); |
| if (foundStyle) |
| { |
| for each (var prop:Property in TextLayoutFormat.description) |
| { |
| var propStyle:Object = foundStyle.getStyle(prop.name); |
| if (propStyle) |
| { |
| if (attr == null) |
| attr = new TextLayoutFormat(); |
| attr[prop.name] = propStyle; |
| } |
| } |
| } |
| return attr; |
| } |
| |
| public function resolveFormat(elem:Object):ITextLayoutFormat |
| { |
| // trace("flowStyleResolver"); |
| // lookup in the cache |
| var attr:TextLayoutFormat = _formatCache[elem]; |
| if (attr !== null) |
| return attr; |
| |
| // global on TextFlow only |
| if (elem is FlowElement) |
| { |
| // maps ParagraphElement to p, SpanElement to span etc. |
| var elemClassName:String = flash.utils.getQualifiedClassName(elem); |
| elemClassName = elemClassName.substr(elemClassName.lastIndexOf(":")+1) |
| var dictionaryName:String = FlexStyleResolver.classToNameDictionary[elemClassName] ; |
| attr = addStyleAttributes(attr, dictionaryName ? dictionaryName : elemClassName); |
| |
| if (elem.styleName != null) |
| attr = addStyleAttributes(attr, "." + elem.styleName); |
| |
| if (elem.id != null) |
| attr = addStyleAttributes(attr, "#" + elem.id); |
| |
| _formatCache[elem] = attr; |
| } |
| // else if elem is ContainerController inherit via the container? |
| return attr; |
| } |
| |
| public function resolveUserFormat(elem:Object,userStyle:String):* |
| { |
| var flowElem:FlowElement = elem as FlowElement; |
| var cssStyle:CSSStyleDeclaration; |
| var propStyle:*; |
| |
| // support non-tlf styles |
| if (flowElem) |
| { |
| if (flowElem.id) |
| { |
| cssStyle = _styleManager.getStyleDeclaration("#"+flowElem.id); |
| if (cssStyle) |
| { |
| propStyle = cssStyle.getStyle(userStyle); |
| if (propStyle !== undefined) |
| return propStyle; |
| } |
| } |
| if (flowElem.styleName) |
| { |
| cssStyle = _styleManager.getStyleDeclaration("."+flowElem.styleName); |
| if (cssStyle) |
| { |
| propStyle = cssStyle.getStyle(userStyle); |
| if (propStyle !== undefined) |
| return propStyle; |
| } |
| } |
| |
| var elemClassName:String = flash.utils.getQualifiedClassName(flowElem); |
| elemClassName = elemClassName.substr(elemClassName.lastIndexOf(":")+1) |
| var dictionaryName:String = classToNameDictionary[elemClassName]; |
| cssStyle = _styleManager.getStyleDeclaration(dictionaryName == null ? elemClassName : dictionaryName); |
| if (cssStyle) |
| { |
| propStyle = cssStyle.getStyle(userStyle); |
| if (propStyle !== undefined) |
| return propStyle; |
| } |
| } |
| return undefined; |
| } |
| |
| public function invalidateAll(tf:TextFlow):void |
| { |
| _formatCache = new Dictionary(true); // clears the cache |
| } |
| |
| // id and styleName don't need to descend now do they - this could conditionally descend on the change type. |
| public function invalidate(target:Object):void |
| { |
| delete _formatCache[target]; |
| var blockElem:FlowGroupElement = target as FlowGroupElement; |
| if (blockElem) |
| { |
| for (var idx:int = 0; idx < blockElem.numChildren; idx++) |
| invalidate(blockElem.getChildAt(idx)); |
| } |
| } |
| |
| // these are sharable between TextFlows |
| public function getResolverForNewFlow(oldFlow:TextFlow,newFlow:TextFlow):IFormatResolver |
| { return this; } |
| } |
| } |