| //////////////////////////////////////////////////////////////////////////////// |
| // |
| // 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 flashx.textLayout.property |
| { |
| import flashx.textLayout.debug.assert; |
| import flashx.textLayout.formats.FormatValue; |
| import flashx.textLayout.tlf_internal; |
| |
| use namespace tlf_internal; |
| |
| [ExcludeClass] |
| /** A property description with an Array value.@private */ |
| public class ArrayProperty extends Property |
| { |
| private var _memberType:Class; |
| |
| public function ArrayProperty(nameValue:String, defaultValue:Array, inherited:Boolean, categories:Vector.<String>, mType:Class) |
| { |
| super(nameValue, defaultValue, inherited, categories); |
| _memberType = mType; |
| CONFIG::debug { assert(_memberType.description != null,"Array member class must have description"); } |
| // can defaultValue be INHERIT? |
| CONFIG::debug { assert(checkArrayTypes(defaultValue),"Array has bad defaultValue"); } |
| } |
| |
| /** The type the members of the array are required to be. */ |
| public function get memberType():Class |
| { return _memberType; } |
| |
| protected function checkArrayTypes(val:Object):Boolean |
| { |
| if (val == null) |
| return true; |
| if (!(val is Array)) |
| return false; |
| if (_memberType == null) |
| return true; |
| for each (var obj:Object in (val as Array)) |
| { |
| if (!(obj is _memberType)) |
| return false |
| } |
| return true; |
| } |
| |
| /** @private */ |
| public override function get defaultValue():* |
| { return super.defaultValue == null ? null : (super.defaultValue as Array).slice(); } |
| |
| /** @private */ |
| public override function setHelper(currVal:*,newVal:*):* |
| { |
| if (newVal === null) |
| newVal = undefined; |
| |
| if (newVal == undefined || newVal == FormatValue.INHERIT) |
| return newVal; |
| |
| if (newVal is String) |
| newVal = this.valueFromString(String(newVal)); |
| |
| if (!checkArrayTypes(newVal)) |
| { |
| Property.errorHandler(this,newVal); |
| return currVal; |
| } |
| return (newVal as Array).slice(); |
| } |
| |
| /** @private */ |
| public override function concatInheritOnlyHelper(currVal:*,concatVal:*):* |
| { |
| return (inherited && currVal === undefined) || currVal == FormatValue.INHERIT ? ((concatVal is Array) ? (concatVal as Array).slice() : concatVal) : currVal; |
| |
| } |
| /** @private */ |
| public override function concatHelper(currVal:*,concatVal:*):* |
| { |
| if (inherited) |
| return currVal === undefined || currVal == FormatValue.INHERIT ? ((concatVal is Array) ? (concatVal as Array).slice() : concatVal) : currVal; |
| if (currVal === undefined) |
| return defaultValue; |
| return currVal == FormatValue.INHERIT ? ((concatVal is Array) ? (concatVal as Array).slice() : concatVal) : currVal; |
| |
| } |
| /** @private */ |
| public override function equalHelper(v1:*,v2:*):Boolean |
| { |
| if (_memberType != null) |
| { |
| var v1Array:Array = v1 as Array; |
| var v2Array:Array = v2 as Array; |
| |
| if (v1Array && v2Array) |
| { |
| if (v1Array.length == v2Array.length) |
| { |
| var desc:Object = _memberType.description; |
| for (var i:int=0; i < v1Array.length; ++i) |
| { |
| if (!Property.equalAllHelper(desc, v1[i], v2[i])) |
| return false; |
| } |
| return true; |
| } |
| } |
| } |
| return v1 == v2; |
| } |
| |
| /** @private */ |
| public override function toXMLString(val:Object):String |
| { |
| if (val == FormatValue.INHERIT) |
| return String(val); |
| // TODO-7/7/2008-The XML format for array properties (as implemented below) |
| // is appropriate for what it is currently used, but can be ambiguous. |
| // For example, what if XML representations of contained elements contain the delimiters used here? |
| |
| // TODO: Check for description? |
| var desc:Object = _memberType.description; |
| var rslt:String = ""; |
| var addSemi:Boolean = false; |
| for each (var member:Object in val) |
| { |
| if (addSemi) |
| rslt += "; " |
| // export each element ',' separated |
| var addComma:Boolean = false; |
| for each (var prop:Property in desc) |
| { |
| var val:Object = member[prop.name]; |
| if (val != null) |
| { |
| if (addComma) |
| rslt += ", "; |
| rslt += prop.name + ":" + prop.toXMLString(val); |
| addComma = true; |
| } |
| } |
| addSemi = true; |
| } |
| return rslt; |
| } |
| |
| /** @private */ |
| private function valueFromString(str:String):* |
| { |
| // TODO-7/7/2008-The XML format for array properties can be ambiguous. |
| // See comment in toXMLString. |
| if ((str == null) || (str == "")) |
| return null; |
| if (str == FormatValue.INHERIT) |
| return str; |
| var result:Array = new Array(); |
| var desc:Object = _memberType.description; |
| |
| var attrsAll:Array = str.split('; '); |
| for each (var attrs:String in attrsAll) |
| { |
| var obj:Object = new _memberType(); // NO PMD |
| |
| var attrsOne:Array = attrs.split(', '); |
| for each (var attr:String in attrsOne) |
| { |
| var nameValArr:Array = attr.split(':'); |
| var propName:String = nameValArr[0]; |
| var propVal:String = nameValArr[1]; |
| |
| for each (var prop:Property in desc) |
| { |
| if (prop.name == propName) |
| { |
| obj[propName] = prop.setHelper(propVal,obj[propName]); |
| break; |
| } |
| } |
| } |
| result.push(obj); |
| } |
| |
| return result; |
| } |
| } |
| } |