You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@royale.apache.org by ah...@apache.org on 2019/12/23 06:52:38 UTC

[royale-asjs] branch develop updated (f50c999 -> 045ae19)

This is an automated email from the ASF dual-hosted git repository.

aharui pushed a change to branch develop
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git.


    from f50c999  Cleaned up ElementWrapper and HTMLElementWrapper
     new 8047afb  FormItemSkin clean compilation.  But will it work?
     new a612f3c  more attempts to use Form Skins
     new 7d88501  something showed up
     new 317ed11  IMXMLObjects need to become IDocument
     new cf84133  try setting measuredWidth/Height to 0 if constrained by both left/right.  I think Flex would have skipped measuring.  This helped Spark Form/FormItem layout correctly
     new 8a5f51d  no default stroke
     new fff234a  need to force layouts down the tree from Form
     new 4136088  Merge branch 'SparkForm' into develop
     new 045ae19  Merge branch 'develop' of https://github.com/apache/royale-asjs into develop

The 9 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../org/apache/royale/html/beads/ContainerView.as  |   28 +-
 .../MXRoyale/src/main/resources/defaults.css       |    1 +
 .../MXRoyale/src/main/royale/MXRoyaleClasses.as    |    3 +
 .../errors/ConstraintError.as}                     |   12 +-
 .../containers/utilityClasses/ConstraintColumn.as  |   14 +-
 .../mx/containers/utilityClasses/ConstraintRow.as  |   12 +-
 .../MXRoyale/src/main/royale/mx/controls/Button.as |   11 -
 .../src/main/royale/mx/core/ILayoutElement.as      |    5 +-
 .../src/main/royale/mx/core/UIComponent.as         |  109 +-
 .../src/main/royale/mx/display/Graphics.as         |   54 +-
 .../SparkRoyale/src/main/resources/defaults.css    |   14 +-
 .../src/main/resources/spark-royale-manifest.xml   |    4 +
 .../src/main/royale/SparkRoyaleClasses.as          |    5 +
 .../src/main/royale/spark/components/Form.as       |    2 +
 .../src/main/royale/spark/components/FormItem.as   |    7 +
 .../src/main/royale/spark/components/Label.as      |   11 +-
 .../royale/spark/components/SkinnableContainer.as  |   23 +-
 .../royale/spark/components/beads/GroupView.as     |    3 +
 .../components/beads/SkinnableContainerView.as     |   51 +-
 .../beads/{GroupView.as => SparkContainerView.as}  |   36 +-
 .../components/beads/SparkSkinScrollingViewport.as |  174 ++
 .../spark/components/supportClasses/ButtonBase.as  |    9 -
 .../supportClasses/SkinnableComponent.as           |  118 +-
 .../supportClasses/SkinnableContainerBase.as       |    4 +-
 .../components/supportClasses/SkinnableTextBase.as |   16 +-
 .../spark/components/supportClasses/TextBase.as    |   13 +-
 .../main/royale/spark/layouts/ConstraintLayout.as  | 1987 ++++++++++++++++++++
 .../main/royale/spark/layouts/FormItemLayout.as    |   10 +-
 .../src/main/royale/spark/layouts/FormLayout.as    |   17 +-
 .../royale/spark/skins/spark/FormItemSkin.mxml     |  188 ++
 .../main/royale/spark/skins/spark/FormSkin.mxml    |   97 +
 31 files changed, 2885 insertions(+), 153 deletions(-)
 copy frameworks/projects/MXRoyale/src/main/royale/mx/{collections/errors/SortError.as => containers/errors/ConstraintError.as} (83%)
 copy frameworks/projects/SparkRoyale/src/main/royale/spark/components/beads/{GroupView.as => SparkContainerView.as} (74%)
 create mode 100644 frameworks/projects/SparkRoyale/src/main/royale/spark/components/beads/SparkSkinScrollingViewport.as
 create mode 100644 frameworks/projects/SparkRoyale/src/main/royale/spark/layouts/ConstraintLayout.as
 create mode 100644 frameworks/projects/SparkRoyale/src/main/royale/spark/skins/spark/FormItemSkin.mxml
 create mode 100644 frameworks/projects/SparkRoyale/src/main/royale/spark/skins/spark/FormSkin.mxml


[royale-asjs] 03/09: something showed up

Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

aharui pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git

commit 7d88501ef80f09915114bb7604d2671830b1955a
Author: Alex Harui <ah...@apache.org>
AuthorDate: Tue Dec 17 21:07:19 2019 -0800

    something showed up
---
 .../src/main/royale/mx/core/UIComponent.as         |  35 +++++++
 .../src/main/royale/spark/components/FormItem.as   |   5 +
 .../royale/spark/components/SkinnableContainer.as  |  19 +++-
 .../royale/spark/components/beads/GroupView.as     |   3 +
 .../components/beads/SkinnableContainerView.as     |  31 ++++++
 .../spark/components/beads/SparkContainerView.as   |  50 +++++++++-
 .../supportClasses/SkinnableComponent.as           | 109 ++++++++++++++++++---
 .../main/royale/spark/layouts/ConstraintLayout.as  |   4 +-
 8 files changed, 236 insertions(+), 20 deletions(-)

diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/core/UIComponent.as b/frameworks/projects/MXRoyale/src/main/royale/mx/core/UIComponent.as
index 12d7914..d5242bc 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/core/UIComponent.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/core/UIComponent.as
@@ -4350,6 +4350,41 @@ COMPILE::JS
         invalidateDisplayListFlag = false;
     }
 
+    override public function isWidthSizedToContent():Boolean
+    {
+        if (!isNaN(_explicitWidth))
+            return false;
+        if (!isNaN(percentWidth))
+            return false;
+        var left:* = ValuesManager.valuesImpl.getValue(this, "left");
+        var right:* = ValuesManager.valuesImpl.getValue(this, "right");
+        if (typeof(left) === "string" && String(left).indexOf(":") != -1)
+            left = undefined;
+        if (typeof(right) === "string" && String(right).indexOf(":") != -1)
+            right = undefined;        
+        if (left === undefined || right === undefined) return true;
+        if (parent is UIComponent)
+            return (parent as UIComponent).isWidthSizedToContent();
+        return false;
+    }
+
+    override public function isHeightSizedToContent():Boolean
+    {
+        if (!isNaN(_explicitHeight))
+            return false;
+        if (!isNaN(percentHeight))
+            return false;
+        var top:* = ValuesManager.valuesImpl.getValue(this, "top");
+        var bottom:* = ValuesManager.valuesImpl.getValue(this, "bottom");
+        if (typeof(top) === "string" && String(top).indexOf(":") != -1)
+            top = undefined;
+        if (typeof(bottom) === "string" && String(bottom).indexOf(":") != -1)
+            bottom = undefined;        
+        if (top === undefined || bottom === undefined) return true;
+        if (parent is UIComponent)
+            return (parent as UIComponent).isHeightSizedToContent();
+        return false;
+    }
     
     [Inspectable(category="General")]
 
diff --git a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/FormItem.as b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/FormItem.as
index f29c132..d8681e3 100644
--- a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/FormItem.as
+++ b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/FormItem.as
@@ -423,6 +423,11 @@ package spark.components
 			}
 		}
 		
+        override protected function get skinParts():Object
+        {
+            return { labelDisplay: true, sequenceLabelDisplay: true};
+        }
+        
 		/**
 		 *  @private
 		 */
diff --git a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/SkinnableContainer.as b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/SkinnableContainer.as
index f612a3a..4491791 100644
--- a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/SkinnableContainer.as
+++ b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/SkinnableContainer.as
@@ -55,6 +55,7 @@ import org.apache.royale.core.IParent;
 import org.apache.royale.core.ValuesManager;
 import org.apache.royale.events.ValueEvent;
 import org.apache.royale.events.Event;
+import org.apache.royale.events.IEventDispatcher;
 import org.apache.royale.utils.MXMLDataInterpreter;
 import org.apache.royale.utils.loadBeadFromValuesManager;
 
@@ -658,8 +659,8 @@ public class SkinnableContainer extends SkinnableContainerBase implements IConta
             ? contentGroup.layout 
             : contentGroupProperties.layout;
         */
-        if (!_layout)
-            _layout = new BasicLayout();
+        //if (!_layout)
+        //    _layout = new BasicLayout();
         return _layout;
     }
     
@@ -902,6 +903,11 @@ public class SkinnableContainer extends SkinnableContainerBase implements IConta
      */
     public function childrenAdded():void
     {
+        if (skin)
+        {
+            var skinDispatcher:IEventDispatcher = (view as SkinnableContainerView).contentView as IEventDispatcher;
+            skinDispatcher.dispatchEvent(new ValueEvent("childrenAdded"));
+        }
         dispatchEvent(new ValueEvent("childrenAdded"));
     }
     
@@ -998,10 +1004,11 @@ public class SkinnableContainer extends SkinnableContainerBase implements IConta
      *  @playerversion AIR 1.5
      *  @productversion Royale 0.9.4
      */
-     protected function partAdded(partName:String, instance:Object):void
-    { //override
-        /* super.partAdded(partName, instance);
+    override protected function partAdded(partName:String, instance:Object):void
+    { 
+        super.partAdded(partName, instance);
 
+        /* 
         if (instance == contentGroup)
         {
             if (_contentModified)
@@ -1264,6 +1271,8 @@ public class SkinnableContainer extends SkinnableContainerBase implements IConta
          if (c == contentView)
          {
              super.addElement(c); // ContainerView uses addElement to add inner contentView
+             if (c == skin)
+                 findSkinParts();
              return;
          }
          contentView.addElement(c, dispatchEvent);
diff --git a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/beads/GroupView.as b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/beads/GroupView.as
index 8e7e6b1..89f221e 100644
--- a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/beads/GroupView.as
+++ b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/beads/GroupView.as
@@ -68,6 +68,9 @@ public class GroupView extends org.apache.royale.html.beads.GroupView
     override public function beforeLayout():void
     {
         var host:GroupBase = _strand as GroupBase;
+        // some Groups have left/right but are still sized to content.
+        // the left/right create padding instead.  So isntead of
+        // isWidthSizedToContent, we only check explicit and percent
         if (host.isWidthSizedToContent() || host.isHeightSizedToContent())
         {
             host.layout.measure();
diff --git a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/beads/SkinnableContainerView.as b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/beads/SkinnableContainerView.as
index 7e4ece8..f9263a7 100644
--- a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/beads/SkinnableContainerView.as
+++ b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/beads/SkinnableContainerView.as
@@ -23,6 +23,8 @@ package spark.components.beads
 import spark.components.SkinnableContainer;
 import spark.components.supportClasses.GroupBase;
 import spark.components.supportClasses.SkinnableComponent;
+import spark.components.supportClasses.Skin;
+import spark.layouts.BasicLayout;
 
 import org.apache.royale.core.IBead;
 import org.apache.royale.core.IContainer;
@@ -55,6 +57,35 @@ public class SkinnableContainerView extends SparkContainerView
 		super();
 	}
 
+    /**
+     *  Adjusts the size of the host after the layout has been run if needed
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10.2
+     *  @playerversion AIR 2.6
+     *  @productversion Royale 0.0
+     *  @royaleignorecoercion org.apache.royale.core.UIBase
+     */
+    override public function beforeLayout():void
+    {
+        var host:SkinnableContainer = _strand as SkinnableContainer;
+        if (host.isWidthSizedToContent() || host.isHeightSizedToContent())
+        {
+            if (host.skin)
+            {
+                (host.skin as Skin).layout.measure();
+                host.measuredHeight = host.skin.measuredHeight;
+                host.measuredWidth = host.skin.measuredWidth;
+            }
+            else 
+            {
+                if (host.layout == null)
+                    host.layout = new BasicLayout();
+                host.layout.measure();
+            }
+        }
+    }
+    
     override protected function addViewport():void
     {
         var chost:IContainer = host as IContainer;
diff --git a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/beads/SparkContainerView.as b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/beads/SparkContainerView.as
index e27a832..0331ec3 100644
--- a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/beads/SparkContainerView.as
+++ b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/beads/SparkContainerView.as
@@ -22,6 +22,7 @@ package spark.components.beads
 
 import spark.components.SkinnableContainer;
 import spark.components.supportClasses.GroupBase;
+import spark.layouts.BasicLayout;
 
 import org.apache.royale.core.IBead;
 import org.apache.royale.core.IContainer;
@@ -29,6 +30,8 @@ import org.apache.royale.core.ILayoutChild;
 import org.apache.royale.core.IStrand;
 import org.apache.royale.core.UIBase;
 import org.apache.royale.html.beads.ContainerView;
+import org.apache.royale.events.Event;
+import org.apache.royale.events.IEventDispatcher;
 
 /**
  *  @private
@@ -62,7 +65,10 @@ public class SparkContainerView extends ContainerView
         super.strand = value;
         var host:SkinnableContainer = _strand as SkinnableContainer;
         var g:GroupBase = (contentView as GroupBase);
-        g.layout = host.layout;
+        if (host.layout != null)
+            g.layout = host.layout;
+        if (g.layout == null)
+            g.layout = new BasicLayout();
         
         if (!host.isWidthSizedToContent())
             g.percentWidth = 100;
@@ -70,6 +76,48 @@ public class SparkContainerView extends ContainerView
             g.percentHeight = 100;
 
     }
+    
+    /**
+     *  Adjusts the size of the host after the layout has been run if needed
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10.2
+     *  @playerversion AIR 2.6
+     *  @productversion Royale 0.0
+     *  @royaleignorecoercion org.apache.royale.core.UIBase
+     */
+    override public function beforeLayout():void
+    {
+        var host:SkinnableContainer = _strand as SkinnableContainer;
+        if (host.isWidthSizedToContent() || host.isHeightSizedToContent())
+        {
+            host.layout.measure();
+        }
+    }
+    
+    /**
+     *  Adjusts the size of the host after the layout has been run if needed
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10.2
+     *  @playerversion AIR 2.6
+     *  @productversion Royale 0.0
+     *  @royaleignorecoercion org.apache.royale.core.UIBase
+     */
+    override public function afterLayout():void
+    {
+        var host:SkinnableContainer = _strand as SkinnableContainer;
+        if (host.isWidthSizedToContent() || host.isHeightSizedToContent())
+        {
+            // request re-run layout on the parent.  In theory, we should only
+            // end up in afterLayout if the content size changed.
+            if (host.parent)
+            {
+                (host.parent as IEventDispatcher).dispatchEvent(new Event("layoutNeeded"));   
+            }
+        }
+    }
+
 
 }
 
diff --git a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/SkinnableComponent.as b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/SkinnableComponent.as
index e96269f..e0c4153 100644
--- a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/SkinnableComponent.as
+++ b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/SkinnableComponent.as
@@ -26,25 +26,17 @@ COMPILE::JS
 
 /*
 import flash.display.DisplayObject;*/
-import org.apache.royale.events.Event;
-/*import flash.geom.Point;
-import flash.utils.*;
-import mx.core.FlexVersion;
-import mx.core.ILayoutElement;
-import mx.core.IVisualElement;
-import mx.events.PropertyChangeEvent;
-
-import spark.events.SkinPartEvent;
-import spark.utils.FTETextUtil;
-
-*/
+import mx.collections.IList;
 import mx.core.IFactory;
 import mx.core.mx_internal;
-import mx.collections.IList;
+
+import org.apache.royale.events.Event;
 use namespace mx_internal;
 
 import mx.core.UIComponent;
 import spark.components.DataGroup;
+//import spark.events.SkinPartEvent;
+
 //--------------------------------------
 //  Styles
 //--------------------------------------
@@ -288,8 +280,99 @@ public class SkinnableComponent extends UIComponent
            return;
         
         _skin = value;
+        findSkinParts();
         dispatchEvent(new Event("skinChanged"));
     }
+    
+    /**
+     * @private 
+     * 
+     * Contains a flat list of all the skin parts. This includes
+     * inherited skin parts. It is best to use a for...in to loop
+     * through the skin parts. The property name will be the name of the 
+     * skin part and it's value will be a boolean specifying if it is required
+     * or not.
+     * 
+     * The actual return value of this method will be generated by the
+     * compiler and may not be null.
+     * 
+     */
+    protected function get skinParts():Object
+    {
+        return null;
+    }
+
+    /**
+     *  Find the skin parts in the skin class and assign them to the properties of the component.
+     *  You do not call this method directly. 
+     *  Flex calls it automatically when it calls the <code>attachSkin()</code> method.
+     *  Typically, a subclass of SkinnableComponent does not override this method.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    protected function findSkinParts():void
+    {
+        if (skinParts)
+        {
+            for (var id:String in skinParts)
+            {
+                if (skinParts[id] == true)
+                {
+                    if (!(id in skin))
+                        throw(new Error(resourceManager.getString("components", "requiredSkinPartNotFound", [id])));
+                }
+                
+                if (id in skin)
+                {
+                    this[id] = skin[id];
+                    
+                    // If the assigned part has already been instantiated, call partAdded() here,
+                    // but only for static parts.
+                    if (this[id] != null && !(this[id] is IFactory))
+                        partAdded(id, this[id]);
+                }
+            }
+        }
+    }
+
+    /**
+     *  Called when a skin part is added. 
+     *  You do not call this method directly. 
+     *  For static parts, Flex calls it automatically when it calls the <code>attachSkin()</code> method. 
+     *  For dynamic parts, Flex calls it automatically when it calls 
+     *  the <code>createDynamicPartInstance()</code> method. 
+     *
+     *  <p>Override this function to attach behavior to the part. 
+     *  If you want to override behavior on a skin part that is inherited from a base class, 
+     *  do not call the <code>super.partAdded()</code> method. 
+     *  Otherwise, you should always call the <code>super.partAdded()</code> method.</p>
+     *
+     *  @param partname The name of the part.
+     *
+     *  @param instance The instance of the part.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    protected function partAdded(partName:String, instance:Object):void
+    {
+        /*
+        // Dispatch a partAdded event.
+        // This event is an internal implementation detail subject to change.
+        // The accessibility implementation classes listen for this to know
+        // when to add their event listeners to skin parts being added.
+        var event:SkinPartEvent = new SkinPartEvent(SkinPartEvent.PART_ADDED);
+        event.partName = partName;
+        event.instance = instance;
+        dispatchEvent(event);
+        */
+    }
+
 	//dataGroup copied from SkinnableDataContainer
 	/**
      *  An optional skin part that defines the DataGroup in the skin class 
diff --git a/frameworks/projects/SparkRoyale/src/main/royale/spark/layouts/ConstraintLayout.as b/frameworks/projects/SparkRoyale/src/main/royale/spark/layouts/ConstraintLayout.as
index 07c6fbd..d949fb1 100644
--- a/frameworks/projects/SparkRoyale/src/main/royale/spark/layouts/ConstraintLayout.as
+++ b/frameworks/projects/SparkRoyale/src/main/royale/spark/layouts/ConstraintLayout.as
@@ -679,7 +679,7 @@ public class ConstraintLayout extends LayoutBase
         COMPILE::JS
         {                
         if (layoutElement['constraintElementId'] == null)
-            layoutElement['constraintElementId'] = constraintElementId.toString();
+            layoutElement['constraintElementId'] = (constraintElementId++).toString();
         var elementInfo:ElementConstraintInfo = constraintCache[layoutElement['constraintElementId']];
         }
         COMPILE::SWF
@@ -1733,6 +1733,8 @@ public class ConstraintLayout extends LayoutBase
         }
         COMPILE::JS
         {
+            if (layoutElement['constraintElementId'] == null)
+                layoutElement['constraintElementId'] = (constraintElementId++).toString();
             constraintCache[layoutElement['constraintElementId']] = elementInfo;                
             
         }


[royale-asjs] 01/09: FormItemSkin clean compilation. But will it work?

Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

aharui pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git

commit 8047afb888a484e5d71dc4663536ba0a1611d9eb
Author: Alex Harui <ah...@apache.org>
AuthorDate: Tue Dec 10 11:43:59 2019 -0800

    FormItemSkin clean compilation.  But will it work?
---
 .../org/apache/royale/html/beads/ContainerView.as  |   28 +-
 .../MXRoyale/src/main/resources/defaults.css       |    1 +
 .../MXRoyale/src/main/royale/MXRoyaleClasses.as    |    3 +
 .../royale/mx/containers/errors/ConstraintError.as |   58 +
 .../containers/utilityClasses/ConstraintColumn.as  |    6 +-
 .../mx/containers/utilityClasses/ConstraintRow.as  |    6 +-
 .../MXRoyale/src/main/royale/mx/controls/Button.as |   11 -
 .../src/main/royale/mx/core/ILayoutElement.as      |    5 +-
 .../src/main/royale/mx/core/UIComponent.as         |   70 +-
 .../SparkRoyale/src/main/resources/defaults.css    |   12 +-
 .../src/main/resources/spark-royale-manifest.xml   |    4 +
 .../src/main/royale/SparkRoyaleClasses.as          |    5 +
 .../src/main/royale/spark/components/Label.as      |   11 +-
 .../components/beads/SkinnableContainerView.as     |   26 +-
 ...nableContainerView.as => SparkContainerView.as} |    9 +-
 .../components/beads/SparkSkinScrollingViewport.as |  168 ++
 .../spark/components/supportClasses/ButtonBase.as  |    9 -
 .../supportClasses/SkinnableComponent.as           |    6 +-
 .../components/supportClasses/SkinnableTextBase.as |   16 +-
 .../spark/components/supportClasses/TextBase.as    |   13 +-
 .../main/royale/spark/layouts/ConstraintLayout.as  | 1984 ++++++++++++++++++++
 .../main/royale/spark/layouts/FormItemLayout.as    |   10 +-
 .../src/main/royale/spark/layouts/FormLayout.as    |    6 +-
 .../royale/spark/skins/spark/FormItemSkin.mxml     |  188 ++
 .../main/royale/spark/skins/spark/FormSkin.mxml    |   97 +
 25 files changed, 2651 insertions(+), 101 deletions(-)

diff --git a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/ContainerView.as b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/ContainerView.as
index fae6a90..0d242a6 100644
--- a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/ContainerView.as
+++ b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/ContainerView.as
@@ -136,12 +136,17 @@ package org.apache.royale.html.beads
 
             createViewport();
 
-			var chost:IContainer = host as IContainer;
-			chost.strandChildren.addElement(viewport.contentView);
+            addViewport();
 
 			super.strand = value;
 		}
 
+        protected function addViewport():void
+        {
+            var chost:IContainer = host as IContainer;
+            chost.strandChildren.addElement(viewport.contentView);            
+        }
+        
 		/**
 		 * Called when the host is ready to complete its setup (usually after its size has been
 		 * determined).
@@ -368,14 +373,19 @@ package org.apache.royale.html.beads
 				_viewport = loadBeadFromValuesManager(IViewport, "iViewport", _strand) as IViewport;
 			
 			if (_viewport) {
-				var chost:IContainer = host as IContainer;
-				// add the viewport's contentView to this host ONLY if
-				// the contentView is not the host itself, which is likely
-				// most situations.
-				if (chost != null && chost != _viewport.contentView) {
-					chost.addElement(_viewport.contentView);
-				}
+                addViewport();
 			}
 		}
+        
+        protected function addViewport():void
+        {
+            var chost:IContainer = host as IContainer;
+            // add the viewport's contentView to this host ONLY if
+            // the contentView is not the host itself, which is likely
+            // most situations.
+            if (chost != null && chost != _viewport.contentView) {
+                chost.addElement(_viewport.contentView);
+            }            
+        }
 	}
 }
diff --git a/frameworks/projects/MXRoyale/src/main/resources/defaults.css b/frameworks/projects/MXRoyale/src/main/resources/defaults.css
index a1dea0c..be9e88f 100644
--- a/frameworks/projects/MXRoyale/src/main/resources/defaults.css
+++ b/frameworks/projects/MXRoyale/src/main/resources/defaults.css
@@ -124,6 +124,7 @@ Alert
 Button
 {
     IBeadModel: ClassReference("org.apache.royale.html.beads.models.ImageAndTextModel");
+	font-weight: bold;
 }
 
 Canvas
diff --git a/frameworks/projects/MXRoyale/src/main/royale/MXRoyaleClasses.as b/frameworks/projects/MXRoyale/src/main/royale/MXRoyaleClasses.as
index c001742..77e4881 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/MXRoyaleClasses.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/MXRoyaleClasses.as
@@ -57,6 +57,9 @@ internal class MXRoyaleClasses
 	import mx.containers.beads.CanvasLayout; CanvasLayout;
     import mx.containers.beads.layouts.BasicLayout; BasicLayout;
 	import mx.controls.beads.AlertView; AlertView;
+    import mx.containers.errors.ConstraintError; ConstraintError;
+    import mx.containers.utilityClasses.ConstraintColumn; ConstraintColumn;
+    import mx.containers.utilityClasses.ConstraintRow; ConstraintRow;
 	import mx.containers.gridClasses.GridColumnInfo; GridColumnInfo;
 	import mx.containers.gridClasses.GridRowInfo; GridRowInfo;
 	import mx.events.CloseEvent; CloseEvent;
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/containers/errors/ConstraintError.as b/frameworks/projects/MXRoyale/src/main/royale/mx/containers/errors/ConstraintError.as
new file mode 100644
index 0000000..da029e5
--- /dev/null
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/containers/errors/ConstraintError.as
@@ -0,0 +1,58 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.containers.errors
+{
+
+/**
+ *  This error is thrown when a constraint expression is not configured properly;
+ *  for example, if the GridColumn reference is invalid.
+ *  
+ *  @langversion 3.0
+ *  @playerversion Flash 9
+ *  @playerversion AIR 1.1
+ *  @productversion Flex 3
+ */
+public class ConstraintError extends Error
+{
+//    include "../../core/Version.as";
+
+    //--------------------------------------------------------------------------
+    //
+    //  Constructor
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  Constructor.
+	 *
+	 *  @param message A message providing information about the error cause.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function ConstraintError(message:String)
+    {
+        super(message);
+    }
+}
+
+}
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/containers/utilityClasses/ConstraintColumn.as b/frameworks/projects/MXRoyale/src/main/royale/mx/containers/utilityClasses/ConstraintColumn.as
index 4e8de23..527b0af 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/containers/utilityClasses/ConstraintColumn.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/containers/utilityClasses/ConstraintColumn.as
@@ -27,13 +27,13 @@ import flash.events.Event;
 import flash.events.IEventDispatcher;
 */
 import mx.core.IInvalidating;
-/*
 import mx.core.mx_internal;
+/*
 import mx.core.IMXMLObject;
 import flash.events.EventDispatcher;
 
-use namespace mx_internal;
 */
+use namespace mx_internal;
 
 /**
  *  The ConstraintColumn class partitions an absolutely
@@ -76,7 +76,7 @@ public class ConstraintColumn extends EventDispatcher //implements IMXMLObject
 	//  Variables
 	//
 	//--------------------------------------------------------------------------
-	protected var contentSize:Boolean = false;
+	mx_internal var contentSize:Boolean = false;
 	
 	//--------------------------------------------------------------------------
 	//
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/containers/utilityClasses/ConstraintRow.as b/frameworks/projects/MXRoyale/src/main/royale/mx/containers/utilityClasses/ConstraintRow.as
index 706a69e..92ef5a3 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/containers/utilityClasses/ConstraintRow.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/containers/utilityClasses/ConstraintRow.as
@@ -27,12 +27,12 @@ import flash.events.Event;
 import flash.events.IEventDispatcher;
 */
 import mx.core.IInvalidating;
-/*
 import mx.core.mx_internal;
+use namespace mx_internal;
+/*
 import mx.core.IMXMLObject;
 import flash.events.EventDispatcher;
 
-use namespace mx_internal;
 */
 	
 /**
@@ -75,7 +75,7 @@ public class ConstraintRow extends EventDispatcher //implements IMXMLObject
 	//  Variables
 	//
 	//--------------------------------------------------------------------------
-	protected var contentSize:Boolean = false;
+	mx_internal var contentSize:Boolean = false;
 	
 	
 	//--------------------------------------------------------------------------
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/controls/Button.as b/frameworks/projects/MXRoyale/src/main/royale/mx/controls/Button.as
index 75baacb..e97663f 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/controls/Button.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/controls/Button.as
@@ -277,17 +277,6 @@ public class Button extends UIComponent implements IDataRenderer
 	}
 	
 	// ------------------------------------------------
-	//  fontStyle
-	// ------------------------------------------------
-	
-	public function get fontStyle():String
-	{
-		return "BOLD";
-	}
-	public function set fontStyle(value:String):void
-	{
-	}
-	// ------------------------------------------------
 	//  icon
 	// ------------------------------------------------
 	
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/core/ILayoutElement.as b/frameworks/projects/MXRoyale/src/main/royale/mx/core/ILayoutElement.as
index 786b73b..ecb8ec3 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/core/ILayoutElement.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/core/ILayoutElement.as
@@ -224,13 +224,14 @@ public interface ILayoutElement extends IEventDispatcher
      *  @playerversion Flash 10
      *  @playerversion AIR 1.5
      *  @productversion Flex 4
-    function get baseline():Object;
      */
+    function get baseline():Object;
+     
     
     /**
      *  @private
-    function set baseline(value:Object):void;
      */
+    function set baseline(value:Object):void;
 
     /**
      *  The y-coordinate of the baseline
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/core/UIComponent.as b/frameworks/projects/MXRoyale/src/main/royale/mx/core/UIComponent.as
index 8494e90..12d7914 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/core/UIComponent.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/core/UIComponent.as
@@ -3112,7 +3112,12 @@ COMPILE::JS
         addEventListener("stateChangeComplete", stateChangeCompleteHandler);
         dispatchEvent(event);
     }
-
+    
+    public function setCurrentState(stateName:String, playTransition:Boolean=true):void
+    {
+        currentState = stateName;
+    }
+    
     private function stateChangeCompleteHandler(event:Event):void
     {
         callLater(dispatchUpdateComplete); 
@@ -4679,6 +4684,52 @@ COMPILE::JS
     {
         this._uid = uid;
     }
+    
+    /*	  
+    *  @langversion 3.0
+    *  @playerversion Flash 9
+    *  @playerversion AIR 1.1
+    *  @productversion Flex 3
+    */
+    public function get showErrorSkin():Object
+    {
+        return ValuesManager.valuesImpl.getValue(this, "showErrorSkin");
+    }
+    public function set showErrorSkin(value:Object):void
+    {
+        setStyle("showErrorSkin", value);
+    }
+
+    /*	  
+    *  @langversion 3.0
+    *  @playerversion Flash 9
+    *  @playerversion AIR 1.1
+    *  @productversion Flex 3
+    */
+    public function get showErrorTip():Object
+    {
+        return ValuesManager.valuesImpl.getValue(this, "showErrorTip");
+    }
+    public function set showErrorTip(value:Object):void
+    {
+        setStyle("showErrorTip", value);
+    }
+    
+    /*	  
+    *  @langversion 3.0
+    *  @playerversion Flash 9
+    *  @playerversion AIR 1.1
+    *  @productversion Flex 3
+    */
+    public function get baseline():Object
+    {
+        return ValuesManager.valuesImpl.getValue(this, "baseline");
+    }
+    public function set baseline(value:Object):void
+    {
+        setStyle("baseline", value);
+    }
+    
 	[Inspectable(category="General")]
 	
 	/*	  
@@ -4695,6 +4746,23 @@ COMPILE::JS
     {
         setStyle("fontSize", value);
     }
+    [Inspectable(category="General")]
+    
+    /*	  
+    *  @langversion 3.0
+    *  @playerversion Flash 9
+    *  @playerversion AIR 1.1
+    *  @productversion Flex 3
+    */
+    public function get fontStyle():Object
+    {
+        return ValuesManager.valuesImpl.getValue(this, "fontStyle");
+    }
+    public function set fontStyle(value:Object):void
+    {
+        setStyle("fontStyle", value);
+    }
+    
 	[Inspectable(category="General")]
 	
 	/*	  
diff --git a/frameworks/projects/SparkRoyale/src/main/resources/defaults.css b/frameworks/projects/SparkRoyale/src/main/resources/defaults.css
index b28ab14..48705da 100644
--- a/frameworks/projects/SparkRoyale/src/main/resources/defaults.css
+++ b/frameworks/projects/SparkRoyale/src/main/resources/defaults.css
@@ -117,9 +117,19 @@ DropDownList
 	border: 1px solid #333333
 }
 
+Form
+{
+	skinClass: ClassReference("spark.skins.spark.FormSkin");
+}
+
+FormItem
+{
+	skinClass: ClassReference("spark.skins.spark.FormItemSkin");
+}
+
 List
 {
-	IBeadView: ClassReference("spark.components.beads.SkinnableContainerView");
+	IBeadView: ClassReference("spark.components.beads.SparkContainerView");
 	IBeadLayout: ClassReference("spark.layouts.supportClasses.SparkLayoutBead");
 	IViewport: ClassReference("org.apache.royale.html.supportClasses.ScrollingViewport");
 	IViewportModel: ClassReference("org.apache.royale.html.beads.models.ViewportModel");
diff --git a/frameworks/projects/SparkRoyale/src/main/resources/spark-royale-manifest.xml b/frameworks/projects/SparkRoyale/src/main/resources/spark-royale-manifest.xml
index 265edde..6918347 100644
--- a/frameworks/projects/SparkRoyale/src/main/resources/spark-royale-manifest.xml
+++ b/frameworks/projects/SparkRoyale/src/main/resources/spark-royale-manifest.xml
@@ -75,6 +75,9 @@
 	<component id="HorizontalLayout" class="spark.layouts.HorizontalLayout"/>
 	<component id="TileLayout" class="spark.layouts.TileLayout"/>
     <component id="Module" class="spark.modules.Module" />
+    <component id="FormItemLayout" class="spark.layouts.FormItemLayout"/>
+    <component id="ConstraintColumn" class="mx.containers.utilityClasses.ConstraintColumn" lookupOnly="true"/>
+    <component id="ConstraintRow" class="mx.containers.utilityClasses.ConstraintRow" lookupOnly="true"/>
 
     <component id="ArrayCollection" class="mx.collections.ArrayCollection" lookupOnly="true"/>
 
@@ -115,6 +118,7 @@
     <component id="TabBarView" class="spark.components.beads.TabBarView"/>
     <component id="MXAdvancedDataGridItemRenderer" class="spark.controls.advancedDataGridClasses.MXAdvancedDataGridItemRenderer"/>
     <component id="SparkTextButtonItemRenderer" class="spark.components.supportClasses.SparkTextButtonItemRenderer"/>
+    <component id="Skin" class="spark.components.supportClasses.Skin"/>
 
 	
 </componentPackage>
diff --git a/frameworks/projects/SparkRoyale/src/main/royale/SparkRoyaleClasses.as b/frameworks/projects/SparkRoyale/src/main/royale/SparkRoyaleClasses.as
index 82ec840..bea2c7f 100644
--- a/frameworks/projects/SparkRoyale/src/main/royale/SparkRoyaleClasses.as
+++ b/frameworks/projects/SparkRoyale/src/main/royale/SparkRoyaleClasses.as
@@ -36,8 +36,12 @@ internal class SparkRoyaleClasses
     import spark.skins.spark.TitleWindowCloseButtonSkin; TitleWindowCloseButtonSkin; 
 	import spark.skins.spark.ComboBoxButtonSkin; ComboBoxButtonSkin; 
 	import spark.skins.spark.ComboBoxTextInputSkin; ComboBoxTextInputSkin; 
+    import spark.skins.spark.FormSkin; FormSkin; 
+    import spark.skins.spark.FormItemSkin; FormItemSkin; 
 	
 	import spark.layouts.supportClasses.SparkLayoutBead; SparkLayoutBead;
+    import spark.layouts.FormLayout; FormLayout;
+    import spark.layouts.FormItemLayout; FormItemLayout;
 	
 	import spark.components.supportClasses.RegExPatterns; RegExPatterns;
 	
@@ -77,6 +81,7 @@ internal class SparkRoyaleClasses
     import spark.components.beads.PanelView; PanelView;
     import spark.components.beads.GroupView; GroupView;
     import spark.components.beads.SkinnableContainerView; SkinnableContainerView;
+    import spark.components.beads.SparkSkinScrollingViewport; SparkSkinScrollingViewport;
     import spark.components.beads.DropDownListView; DropDownListView;
     import spark.components.beads.TitleWindowView; TitleWindowView;
     import spark.components.beads.controllers.DropDownListController; DropDownListController;
diff --git a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/Label.as b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/Label.as
index cf07f26..f1faad0 100644
--- a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/Label.as
+++ b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/Label.as
@@ -419,16 +419,7 @@ public class Label extends TextBase
     {
         
     }
-	
-	public function get fontStyle():String
-    {
-        return "";
-    }
-    public function set fontStyle(value:String):void
-    {
-        
-    }
-    
+	    
     public function get textDecoration():String
     {
         return "";
diff --git a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/beads/SkinnableContainerView.as b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/beads/SkinnableContainerView.as
index f02ae43..ca63c80 100644
--- a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/beads/SkinnableContainerView.as
+++ b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/beads/SkinnableContainerView.as
@@ -22,18 +22,19 @@ package spark.components.beads
 
 import spark.components.SkinnableContainer;
 import spark.components.supportClasses.GroupBase;
+import spark.components.supportClasses.SkinnableComponent;
 
 import org.apache.royale.core.IBead;
+import org.apache.royale.core.IContainer;
 import org.apache.royale.core.ILayoutChild;
 import org.apache.royale.core.IStrand;
 import org.apache.royale.core.UIBase;
-import org.apache.royale.html.beads.ContainerView;
 
 /**
  *  @private
  *  The SkinnableContainerView for emulation.
  */
-public class SkinnableContainerView extends ContainerView
+public class SkinnableContainerView extends SparkContainerView
 {
 	//--------------------------------------------------------------------------
 	//
@@ -54,22 +55,15 @@ public class SkinnableContainerView extends ContainerView
 		super();
 	}
 
-    /**
-     */
-    override public function set strand(value:IStrand):void
+    override protected function addViewport():void
     {
-        super.strand = value;
-        var host:SkinnableContainer = _strand as SkinnableContainer;
-        var g:GroupBase = (contentView as GroupBase);
-        g.layout = host.layout;
-        
-        if (!host.isWidthSizedToContent())
-            g.percentWidth = 100;
-        if (!host.isHeightSizedToContent())
-            g.percentHeight = 100;
-
+        var chost:IContainer = host as IContainer;
+        var skinhost:SkinnableComponent = host as SkinnableComponent;
+        if (chost != null && chost != viewport.contentView) {
+            chost.addElement(skinhost.skin);
+        }            
     }
-    
+
 }
 
 }
diff --git a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/beads/SkinnableContainerView.as b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/beads/SparkContainerView.as
similarity index 92%
copy from frameworks/projects/SparkRoyale/src/main/royale/spark/components/beads/SkinnableContainerView.as
copy to frameworks/projects/SparkRoyale/src/main/royale/spark/components/beads/SparkContainerView.as
index f02ae43..e27a832 100644
--- a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/beads/SkinnableContainerView.as
+++ b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/beads/SparkContainerView.as
@@ -24,6 +24,7 @@ import spark.components.SkinnableContainer;
 import spark.components.supportClasses.GroupBase;
 
 import org.apache.royale.core.IBead;
+import org.apache.royale.core.IContainer;
 import org.apache.royale.core.ILayoutChild;
 import org.apache.royale.core.IStrand;
 import org.apache.royale.core.UIBase;
@@ -31,9 +32,9 @@ import org.apache.royale.html.beads.ContainerView;
 
 /**
  *  @private
- *  The SkinnableContainerView for emulation.
+ *  The SparkContainerView for emulation.
  */
-public class SkinnableContainerView extends ContainerView
+public class SparkContainerView extends ContainerView
 {
 	//--------------------------------------------------------------------------
 	//
@@ -49,7 +50,7 @@ public class SkinnableContainerView extends ContainerView
 	 *  @playerversion AIR 1.1
 	 *  @productversion Flex 3
 	 */
-	public function SkinnableContainerView()
+	public function SparkContainerView()
 	{
 		super();
 	}
@@ -69,7 +70,7 @@ public class SkinnableContainerView extends ContainerView
             g.percentHeight = 100;
 
     }
-    
+
 }
 
 }
diff --git a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/beads/SparkSkinScrollingViewport.as b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/beads/SparkSkinScrollingViewport.as
new file mode 100644
index 0000000..d2fa6cf
--- /dev/null
+++ b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/beads/SparkSkinScrollingViewport.as
@@ -0,0 +1,168 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 spark.components.beads
+{
+
+import mx.core.mx_internal;
+use namespace mx_internal;
+
+import spark.components.supportClasses.GroupBase;
+import spark.components.supportClasses.SkinnableComponent;
+
+import org.apache.royale.core.IBead;
+import org.apache.royale.core.IContentView;
+import org.apache.royale.core.IStrand;
+import org.apache.royale.core.IUIBase;
+import org.apache.royale.core.IViewport;
+import org.apache.royale.core.UIBase;
+import org.apache.royale.core.ValuesManager;
+import org.apache.royale.geom.Size;
+
+COMPILE::SWF
+{
+    import flash.geom.Rectangle;
+}
+
+/**
+ *  @private
+ *  The viewport that loads a Spark Skin.
+ */
+public class SparkSkinScrollingViewport implements IViewport
+{
+	//--------------------------------------------------------------------------
+	//
+	//  Constructor
+	//
+	//--------------------------------------------------------------------------
+
+	/**
+	 *  Constructor.
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 9
+	 *  @playerversion AIR 1.1
+	 *  @productversion Flex 3
+	 */
+	public function SparkSkinScrollingViewport()
+	{
+		super();
+	}
+
+    protected var contentArea:UIBase;
+    
+    /**
+     * Get the actual parent of the container's content.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10.2
+     *  @playerversion AIR 2.6
+     *  @productversion Royale 0.0
+     */
+    public function get contentView():IUIBase
+    {
+        return contentArea;
+    }
+    
+    protected var host:SkinnableComponent;
+    
+    /**
+     */
+    public function set strand(value:IStrand):void
+    {
+        host = value as SkinnableComponent;
+        
+        var c:Class = ValuesManager.valuesImpl.getValue(value, "skinClass") as Class;
+        host.setSkin(new c());
+        
+        contentArea = host.skin["contentGroup"];
+        
+        COMPILE::JS
+        {
+            setScrollStyle();
+        }
+        
+    }
+    
+    /**
+     * Subclasses override this method to change scrolling behavior
+     */
+    COMPILE::JS
+    protected function setScrollStyle():void
+    {
+        contentArea.element.style.overflow = "auto";
+    }
+    
+    /**
+     * @copy org.apache.royale.core.IViewport#setPosition()
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10.2
+     *  @playerversion AIR 2.6
+     *  @productversion Royale 0.0
+     */
+    public function setPosition(x:Number, y:Number):void
+    {
+        COMPILE::SWF {
+            contentArea.x = x;
+            contentArea.y = y;
+        }
+    }
+    
+    /**
+     * @copy org.apache.royale.core.IViewport#layoutViewportBeforeContentLayout()
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10.2
+     *  @playerversion AIR 2.6
+     *  @productversion Royale 0.0
+     */
+    public function layoutViewportBeforeContentLayout(width:Number, height:Number):void
+    {
+        COMPILE::SWF {
+            if (!isNaN(width))
+                contentArea.width = width;
+            if (!isNaN(height))
+                contentArea.height = height;
+        }
+    }
+    
+    /**
+     * @copy org.apache.royale.core.IViewport#layoutViewportAfterContentLayout()
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10.2
+     *  @playerversion AIR 2.6
+     *  @productversion Royale 0.0
+     */
+    public function layoutViewportAfterContentLayout(contentSize:Size):void
+    {
+        COMPILE::SWF {
+            var hostWidth:Number = UIBase(host).width;
+            var hostHeight:Number = UIBase(host).height;
+            
+            var rect:flash.geom.Rectangle = new flash.geom.Rectangle(0, 0, hostWidth, hostHeight);
+            contentArea.scrollRect = rect;
+            
+            return;
+        }
+    }
+}
+
+}
diff --git a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/ButtonBase.as b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/ButtonBase.as
index 7338e2f..9393500 100644
--- a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/ButtonBase.as
+++ b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/ButtonBase.as
@@ -451,15 +451,6 @@ public class ButtonBase extends SkinnableComponent implements IFocusManagerCompo
         return element;
     }
 
-	public function set fontStyle(value:String):void
-    {
-       
-    }
-	public function get fontStyle():String          
-    {
-        return "NORMAL";
-    }
-    
     public function get lineThrough():Boolean
     {
 	return true;
diff --git a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/SkinnableComponent.as b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/SkinnableComponent.as
index e6fb4ba..e96269f 100644
--- a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/SkinnableComponent.as
+++ b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/SkinnableComponent.as
@@ -32,16 +32,16 @@ import flash.utils.*;
 import mx.core.FlexVersion;
 import mx.core.ILayoutElement;
 import mx.core.IVisualElement;
-import mx.core.mx_internal;
 import mx.events.PropertyChangeEvent;
 
 import spark.events.SkinPartEvent;
 import spark.utils.FTETextUtil;
 
-use namespace mx_internal;
 */
 import mx.core.IFactory;
+import mx.core.mx_internal;
 import mx.collections.IList;
+use namespace mx_internal;
 
 import mx.core.UIComponent;
 import spark.components.DataGroup;
@@ -282,7 +282,7 @@ public class SkinnableComponent extends UIComponent
      *  Setter for the skin instance.  This is so the bindable event
      *  is dispatched
      */ 
-    private function setSkin(value:UIComponent):void
+    mx_internal function setSkin(value:UIComponent):void
     {
         if (value === _skin)
            return;
diff --git a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/SkinnableTextBase.as b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/SkinnableTextBase.as
index 8f6f098..521a5d2 100644
--- a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/SkinnableTextBase.as
+++ b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/SkinnableTextBase.as
@@ -940,21 +940,7 @@ public class SkinnableTextBase extends SkinnableComponent
         
         invalidateProperties();
     } */
-    
-    //----------------------------------
-    //  fontStyle
-    //----------------------------------
-	
-	public function get fontStyle():String
-    {
-        return "";
-    } 
-  
-     public function set fontStyle(value:String):void
-    {
-    
-    }
-    
+        
     //----------------------------------
     //  typicalText
     //----------------------------------
diff --git a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/TextBase.as b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/TextBase.as
index 9274153..aaed390 100644
--- a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/TextBase.as
+++ b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/TextBase.as
@@ -32,7 +32,6 @@ import mx.core.IFlexModuleFactory;
 import mx.resources.IResourceManager;
 import mx.resources.ResourceManager;
 
-import spark.core.IDisplayText;
 import spark.utils.TextUtil;
 
 */
@@ -58,6 +57,8 @@ import org.apache.royale.core.ITextModel;
 
 use namespace mx_internal;
 
+import spark.core.IDisplayText;
+
 //--------------------------------------
 //  Styles
 //--------------------------------------
@@ -113,9 +114,9 @@ use namespace mx_internal;
  *  @royalesuppresspublicvarwarning
 */
 
-public class TextBase extends UIComponent 
-{ //implements IDisplayText
+public class TextBase extends UIComponent implements IDisplayText
 
+{ 
   //  include "../../core/Version.as";
 
     //--------------------------------------------------------------------------
@@ -343,7 +344,7 @@ public class TextBase extends UIComponent
      *  @private
 	 *  Storage for the isTruncated property.
      */
-    //private var _isTruncated:Boolean = false;
+    private var _isTruncated:Boolean = false;
         
     /**
 	 *  A read-only property reporting whether the text has been truncated.
@@ -377,12 +378,12 @@ public class TextBase extends UIComponent
      *  @playerversion AIR 1.5
      *  @productversion Royale 0.9.4
      */
-	/* public function get isTruncated():Boolean
+	public function get isTruncated():Boolean
     {
 		// For some reason, the compiler needs an explicit cast to Boolean
 		// to avoid a warning even though at runtime "is Boolean" is true.
 		return Boolean(_isTruncated);
-    } */
+    }
     
     /**
      *  @private
diff --git a/frameworks/projects/SparkRoyale/src/main/royale/spark/layouts/ConstraintLayout.as b/frameworks/projects/SparkRoyale/src/main/royale/spark/layouts/ConstraintLayout.as
new file mode 100644
index 0000000..069c55f
--- /dev/null
+++ b/frameworks/projects/SparkRoyale/src/main/royale/spark/layouts/ConstraintLayout.as
@@ -0,0 +1,1984 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 spark.layouts
+{
+COMPILE::SWF
+{
+    import flash.utils.Dictionary;
+}
+
+import mx.containers.errors.ConstraintError;
+import mx.containers.utilityClasses.ConstraintColumn;
+import mx.containers.utilityClasses.ConstraintRow;
+import mx.containers.utilityClasses.Flex;
+import mx.core.ILayoutElement;
+import mx.core.mx_internal;
+import mx.resources.ResourceManager;
+
+import spark.components.supportClasses.GroupBase;
+import spark.layouts.supportClasses.LayoutBase;
+import spark.layouts.supportClasses.LayoutElementHelper;
+
+import org.apache.royale.geom.Point;
+
+use namespace mx_internal;
+
+//[ResourceBundle("layout")]
+
+/**
+ *  The ConstraintLayout class arranges the layout elements based on their individual
+ *  settings and a set of constraint regions defined by constraint columns and
+ *  constraint rows. Although you can use all of the properties and constraints from
+ *  BasicLayout to position and size elements, ConstraintLayout gives you the ability
+ *  to create sibling-relative layouts by constraining elements to the specified
+ *  columns and rows. 
+ *
+ *  <p><b>Note: </b>The Spark list-based controls (the Spark List control and its subclasses
+ *  such as ButtonBar, ComboBox, DropDownList, and TabBar) do not support the ConstraintLayout class. 
+ *  Do not use ConstraintLayout with the Spark list-based controls.</p>
+ *
+ *  <p>Per-element supported constraints are <code>left</code>, <code>right</code>, 
+ *  <code>top</code>, <code>bottom</code>, <code>baseline</code>,
+ *  <code>percentWidth</code>, and <code>percentHeight</code>.
+ *  Element's minimum and maximum sizes will always be respected.</p>
+ * 
+ *  <p>Columns and rows may have an explicit size or content size (no explicit size). 
+ *  Explicit size regions will be fixed at their specified size, while content size
+ *  regions will stretch to fit only the elements constrained to them. If multiple
+ *  content size regions are spanned by an element, the space will be divided
+ *  equally among the content size regions.</p>
+ *
+ *  <p>The measured size of the container is calculated from the elements, their
+ *  constraints, their preferred sizes, and the sizes of the rows and columns.
+ *  The size of each row and column is just big enough to hold all of the elements
+ *  constrained to it at their preferred sizes with constraints satisfied. The measured
+ *  size of the container is big enough to hold all of the columns and rows as well as
+ *  any other elements left at their preferred sizes with constraints satisfied. </p>
+ *
+ *  <p>During a call to the <code>updateDisplayList()</code> method, 
+ *  the element's size is determined according to
+ *  the rules in the following order of precedence (the element's minimum and
+ *  maximum sizes are always respected):</p>
+ *  <ul>
+ *    <li>If the element has <code>percentWidth</code> or <code>percentHeight</code> set, 
+ *    then its size is calculated as a percentage of the available size, where the available
+ *    size is the region or container size minus any <code>left</code>, <code>right</code>,
+ *    <code>top</code>, or <code>bottom</code> constraints.</li>
+ *
+ *    <li>If the element has both left and right constraints, it's width is
+ *    set to be the region's or container's width minus the <code>left</code> 
+ *    and <code>right</code> constraints.</li>
+ * 
+ *    <li>If the element has both <code>top</code> and <code>bottom</code> constraints, 
+ *    it's height is set to be the container's height minus the <code>top</code>
+ *    and <code>bottom</code> constraints.</li>
+ *
+ *    <li>The element is set to its preferred width and/or height.</li>
+ *  </ul>
+ * 
+ *  <p>The element's position is determined according to the rules in the following
+ *  order of precedence:</p>
+ *  <ul>
+ *    <li>If element's baseline is specified, then the element is positioned in
+ *    the vertical direction such that its <code>baselinePosition</code> (usually the base line
+ *    of its first line of text) is aligned with <code>baseline</code> constraint.</li>
+ *
+ *    <li>If element's <code>top</code> or <code>left</code> constraints
+ *    are specified, then the element is
+ *    positioned such that the top-left corner of the element's layout bounds is
+ *    offset from the top-left corner of the container by the specified values.</li>
+ *
+ *    <li>If element's <code>bottom</code> or <code>right</code> constraints are specified,
+ *    then the element is positioned such that the bottom-right corner 
+ *    of the element's layout bounds is
+ *    offset from the bottom-right corner of the container by the specified values.</li>
+ * 
+ *    <li>When no constraints determine the position in the horizontal or vertical
+ *    direction, the element is positioned according to its x and y coordinates.</li>
+ *  </ul>
+ *
+ *  <p>The content size of the container is calculated as the maximum of the
+ *  coordinates of the bottom-right corner of all the layout elements and 
+ *  constraint regions.</p>
+ *  
+ *  @langversion 3.0
+ *  @playerversion Flash 10
+ *  @playerversion AIR 1.5
+ *  @productversion Flex 4.5
+ */
+public class ConstraintLayout extends LayoutBase
+{
+
+    //See FLEX-33311 for more details on why this is used
+    private var constraintCacheNeeded:int = 0;
+
+    //--------------------------------------------------------------------------
+    //
+    //  Class methods
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     * 
+     *  @return true if the constraints determine the element's width;
+     */
+    private static function constraintsDetermineWidth(elementInfo:ElementConstraintInfo):Boolean
+    {
+        return !isNaN(elementInfo.left) && !isNaN(elementInfo.right);
+    }
+    
+    /**
+     *  @private
+     * 
+     *  @return true if the constraints determine the element's height;
+     */
+    private static function constraintsDetermineHeight(elementInfo:ElementConstraintInfo):Boolean
+    {
+        return !isNaN(elementInfo.top) && !isNaN(elementInfo.bottom);
+    }
+    
+    /**
+     *  @private
+     *  @return Returns the maximum value for an element's dimension so that the component doesn't
+     *  spill out of the container size. Calculations are based on the layout rules.
+     *  Pass in unscaledWidth, left, right, childX to get a maxWidth value.
+     *  Pass in unscaledHeight, top, bottom, childY to get a maxHeight value.
+     */
+    private static function maxSizeToFitIn(totalSize:Number,
+                                           lowConstraint:Number,
+                                           highConstraint:Number,
+                                           position:Number):Number
+    {
+        if (!isNaN(lowConstraint))
+        {
+            // childWidth + left <= totalSize
+            return totalSize - lowConstraint;
+        }
+        else if (!isNaN(highConstraint))
+        {
+            // childWidth + right <= totalSize
+            return totalSize - highConstraint;
+        }
+        else
+        {
+            // childWidth + childX <= totalSize
+            return totalSize - position;
+        }
+    }
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Constructor
+    //
+    //--------------------------------------------------------------------------
+    
+    /**
+     *  Constructor.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4.5
+     */
+    public function ConstraintLayout()
+    {
+        super();
+    }
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Variables
+    //
+    //--------------------------------------------------------------------------
+    
+    /**
+     *  @private
+     *  Vectors that keep track of children spanning
+     *  content size columns or rows or whether the 
+     *  elements don't use columns or rows at all.
+     */
+    private var colSpanElements:Vector.<ElementConstraintInfo> = null;
+    private var rowSpanElements:Vector.<ElementConstraintInfo> = null;
+    private var otherElements:Vector.<ElementConstraintInfo> = null;
+    
+    /**
+     *  @private
+     *  Vectors to store the baseline property of the rows, and
+     *  the maximum ascent of the elements in each row.
+     *  
+     *  In rowBaselines, the value is stored as
+     *  [value, maxAscent] if the baseline is maxAscent:value, 
+     *  and [value, null] if the baseline is just a value.
+     */
+    private var rowBaselines:Vector.<Array> = null;
+    private var rowMaxAscents:Vector.<Number> = null;
+    
+    /**
+     *  @private
+     *  Hashtable that maps elements to their constraint
+     *  information. The mapping has type:
+     *  ILayoutElement -> ElementConstraintInfo
+     * 
+     *  This cache is always discarded after measure() or
+     *  updateDisplayList() because the constraints may have changed.
+     */
+    COMPILE::JS
+    private var constraintCache:Object = null;
+    COMPILE::SWF
+    private var constraintCache:Dictionary = null;
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Properties
+    //
+    //--------------------------------------------------------------------------
+    
+    //----------------------------------
+    //  constraintColumns
+    //----------------------------------
+    
+    private var _constraintColumns:Vector.<ConstraintColumn> = new Vector.<ConstraintColumn>(0, true);
+    // An associative array of column id --> column index
+    private var columnsObject:Object = {};
+    
+    /**
+     *  A Vector of ConstraintColumn instances that partition the target container.
+     *  The ConstraintColumn instance at index 0 is the left-most column;
+     *  indices increase from left to right. 
+     * 
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4.5
+     */
+    public function get constraintColumns():Vector.<ConstraintColumn>
+    {
+        // make defensive copy
+        return _constraintColumns.slice();
+    }
+    
+    /**
+     *  @private
+     */
+    public function set constraintColumns(value:Vector.<ConstraintColumn>):void
+    {   
+        // clear constraintColumns
+        if (value == null)
+        {
+            _constraintColumns = new Vector.<ConstraintColumn>(0, true);
+            columnsObject = {};
+            return;
+        }
+        
+        var n:int = value.length;
+        var col:ConstraintColumn;
+        var temp:Vector.<ConstraintColumn> = value.slice();
+        var obj:Object = {};
+        
+        for (var i:int = 0; i < n; i++)
+        {
+            col = temp[i];
+            col.container = this.target;
+            obj[col.id] = i;
+        }
+        
+        _constraintColumns = temp;
+        columnsObject = obj;
+        
+        if (target)
+        {
+            target.invalidateSize();
+            target.invalidateDisplayList();
+        }
+    }
+    
+    //----------------------------------
+    //  constraintRows
+    //----------------------------------
+    
+    private var _constraintRows:Vector.<ConstraintRow> = new Vector.<ConstraintRow>(0, true);
+    // An associative array of row id --> row index
+    private var rowsObject:Object = {};
+    
+    /**
+     *  A Vector of ConstraintRow instances that partition the target container.
+     *  The ConstraintRow instance at index 0 is the top-most column;
+     *  indices increase from top to bottom. 
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4.5
+     */
+    public function get constraintRows():Vector.<ConstraintRow> 
+    {
+        return _constraintRows.slice();
+    }
+    
+    /**
+     *  @private
+     */
+    public function set constraintRows(value:Vector.<ConstraintRow>):void
+    {
+        // clear constraintRows
+        if (value == null)
+        {
+            _constraintRows = new Vector.<ConstraintRow>(0, true);
+            rowsObject = {};
+            return;
+        }
+        
+        var n:int = value.length;
+        var row:ConstraintRow;
+        var temp:Vector.<ConstraintRow> = value.slice();
+        var obj:Object = {};
+        rowBaselines = new Vector.<Array>();
+        
+        for (var i:int = 0; i < n; i++)
+        {
+            row = temp[i];
+            row.container = this.target;
+            obj[row.id] = i;
+            rowBaselines[i] = LayoutElementHelper.parseConstraintExp(row.baseline);
+            
+            var maxAscentStr:String = rowBaselines[i][1];
+            if (maxAscentStr && maxAscentStr != "maxAscent")
+                throw new Error(ResourceManager.getInstance().getString("layout", "invalidBaselineOnRow",
+                                                                        [ row.id, row.baseline ]));
+        }
+        
+        _constraintRows = temp;
+        rowsObject = obj;
+        
+        if (target)
+        {
+            target.invalidateSize();
+            target.invalidateDisplayList();
+        }
+    }
+    
+    /**
+     *  @private
+     *  Resets the target on the constraintColumns and constraintRows.
+     */
+    override public function set target(value:GroupBase):void
+    {
+        super.target = value;
+        
+        // setting a new target means we need to reset the targets of
+        // our columns and rows
+        var i:int;
+        var n:int = _constraintColumns.length;
+
+        for (i = 0; i < n; i++)
+        {
+            _constraintColumns[i].container = value;
+        }
+        
+        n = _constraintRows.length;
+        for (i = 0; i < n; i++)
+        {
+            _constraintRows[i].container = value;
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //  Overridden Methods: LayoutBase
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     * 
+     *  1) Parse each element constraint and populate the constraintCache
+     *  2) Measure the columns and rows based on only the elements that use them
+     *     and get the sum of the column widths and row heights.
+     *  3) Measure the size of this container based on elements that don't use
+     *     either columns or rows or both.
+     *  4) Take the max of 2 and 3 to find the measuredWidth.
+     */
+    override public function measure():void
+    {
+        checkUseVirtualLayout();
+        super.measure();
+        
+        var layoutTarget:GroupBase = target;
+        if (!layoutTarget)
+            return;
+
+        var width:Number = 0;
+        var height:Number = 0;
+        var minWidth:Number = 0;
+        var minHeight:Number = 0;
+        
+        parseConstraints();
+        
+        // Find preferred column widths and row heights.
+        var colWidths:Vector.<Number> = measureColumns();
+        var rowHeights:Vector.<Number> = measureRows();
+        var n:Number;
+        
+        for each (n in colWidths)
+        {
+            width += n;
+        }
+
+        for each (n in rowHeights)
+        {
+            height += n;
+        }
+        
+        // Find minimum measured width/height by passing in 0 for the constrained size.
+        // This means that percent size regions will be set to their min size.
+        constrainPercentRegionSizes(colWidths, 0, true);
+        for each (n in colWidths)
+        {
+            minWidth += n;
+        }
+        
+        constrainPercentRegionSizes(rowHeights, 0, false);
+        for each (n in rowHeights)
+        {
+            minHeight += n;
+        }
+        
+        if (otherElements)
+        {
+            var vec:Vector.<Number> = measureOtherContent();
+            
+            width = Math.max(width, vec[0]);
+            height = Math.max(height, vec[1]);
+            minWidth = Math.max(minWidth, vec[2]);
+            minHeight = Math.max(minHeight, vec[3]);
+        }
+
+        layoutTarget.measuredWidth = Math.ceil(width);
+        layoutTarget.measuredHeight = Math.ceil(height);
+        layoutTarget.measuredMinWidth = Math.ceil(minWidth);
+        layoutTarget.measuredMinHeight = Math.ceil(minHeight);
+        
+        // clear out cache
+        clearConstraintCache();
+    }
+    
+    /**
+     *  @private
+     * 
+     *  1) Re-parse element constraints because they may have changed.
+     *  2) Resize and reposition the columns and rows based on new constraints.
+     *  3) Size and position the elements in the available space.
+     */
+    override public function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
+    {
+        checkUseVirtualLayout();
+        super.updateDisplayList(unscaledWidth, unscaledHeight);
+        
+        var layoutTarget:GroupBase = target;
+        if (!layoutTarget)
+            return;
+        
+        // Need to measure in case of explicit width and height on target.
+        // Also need to reparse constraints in case of something changing.
+        measureAndPositionColumnsAndRows(unscaledWidth, unscaledHeight);
+        
+        layoutContent(unscaledWidth, unscaledHeight);
+    }
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Methods: Used by FormItemLayout
+    //
+    //--------------------------------------------------------------------------
+    
+    /**
+     *  Lays out the elements of the layout target using the current
+     *  widths and heights of the columns and rows. Used by FormItemLayout
+     *  after setting new column widths to lay elements using those new widths.
+     *
+     *  @param unscaledWidth Specifies the width of the component, in pixels,
+     *  in the component's coordinates, regardless of the value of the
+     *  <code>scaleX</code> property of the component.
+     *
+     *  @param unscaledHeight Specifies the height of the component, in pixels,
+     *  in the component's coordinates, regardless of the value of the
+     *  <code>scaleY</code> property of the component.
+     * 
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4.5
+     */ 
+    protected function layoutContent(unscaledWidth:Number, unscaledHeight:Number):void
+    {
+        var layoutTarget:GroupBase = target;
+        if (!layoutTarget)
+            return;
+        
+        var count:int = layoutTarget.numElements;
+        var layoutElement:ILayoutElement;
+        
+        var maxX:Number = 0;
+        var maxY:Number = 0;
+        
+        // update children
+        for (var i:int = 0; i < count; i++)
+        {
+            layoutElement = layoutTarget.getElementAt(i) as ILayoutElement;
+            if (!layoutElement || !layoutElement.includeInLayout)
+                continue;
+            
+            applyConstraintsToElement(unscaledWidth, unscaledHeight, layoutElement);
+            
+            // update content limits
+            maxX = Math.max(maxX, layoutElement.getLayoutBoundsX() +
+                            layoutElement.getLayoutBoundsWidth());
+            maxY = Math.max(maxY, layoutElement.getLayoutBoundsY() +
+                            layoutElement.getLayoutBoundsHeight());
+        }
+        
+        // Make sure that if the content spans partially over a pixel to the right/bottom,
+        // the content size includes the whole pixel.
+        layoutTarget.setContentSize(Math.ceil(maxX), Math.ceil(maxY));
+        
+        // clear out cache
+        clearConstraintCache();
+    }
+    
+    /**
+     *  Used by FormItemLayout to measure and set new column widths
+     *  and row heights before laying out the elements.
+     *  
+     *  @param constrainedWidth The total width available for columns to stretch
+     *  or shrink their percent width columns. If NaN, percent width columns
+     *  are unconstrained and fit to their content.
+     *  @param constrainedHeight The total height available for rows to stretch
+     *  or shrink their percent height rows. If NaN, percent height rows
+     *  are unconstrained and fit to their content.
+     * 
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4.5
+     */
+    protected function measureAndPositionColumnsAndRows(constrainedWidth:Number = NaN, constrainedHeight:Number = NaN):void
+    {
+        parseConstraints();
+        setColumnWidths(measureColumns(constrainedWidth));
+        setRowHeights(measureRows(constrainedHeight));
+    }
+    
+    /**
+     *  @private
+     *  This function is mx_internal so that FormItemLayout can use it
+     *  in its updateDisplayList.
+     */
+    mx_internal function checkUseVirtualLayout():void
+    {
+        if (useVirtualLayout)
+            throw new Error(ResourceManager.getInstance().getString("layout", "constraintLayoutNotVirtualized"));
+    }
+    
+    /**
+     *  @private
+     */
+    override mx_internal function get virtualLayoutSupported():Boolean
+    {
+        return false;
+    }
+    
+    /**
+     *  @private
+     *  Used to set new column widths before laying out the elements.
+     *  Used by FormItemLayout to set column widths provided by the
+     *  Form.
+     */ 
+    mx_internal function setColumnWidths(value:Vector.<Number>):void
+    {
+        if (value == null)
+            return;
+        
+        var constraintColumns:Vector.<ConstraintColumn> = this._constraintColumns;
+        var numCols:int = constraintColumns.length;
+        var totalWidth:Number = 0;
+        
+        for (var i:int = 0; i < numCols; i++)
+        {
+            constraintColumns[i].setActualWidth(value[i]);
+            constraintColumns[i].x = totalWidth;
+            totalWidth += value[i];
+        }
+    }
+    
+    /**
+     *  @private
+     *  Used to set new row heights before laying out the elements.
+     */ 
+    mx_internal function setRowHeights(value:Vector.<Number>):void
+    {
+        if (value == null)
+            return;
+        
+        var constraintRows:Vector.<ConstraintRow> = this._constraintRows;
+        var numRows:int = constraintRows.length;
+        var totalHeight:Number = 0;
+        
+        for (var i:int = 0; i < numRows; i++)
+        {
+            constraintRows[i].setActualHeight(value[i]);
+            constraintRows[i].y = totalHeight;
+            totalHeight += value[i];
+        }
+    }
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Methods
+    //
+    //--------------------------------------------------------------------------
+
+    private var constraintElementId:int = 0;
+    
+    /**
+     *  @private
+     *  Sizes and positions the element based on the given size of the container
+     *  and the element's constraints.
+     * 
+     *  1) Retrieves element constraints from the constraint cache.
+     *  2) Determines the x and y boundaries of each side.
+     *  3) Sizes the element based on constraints and its preferred
+     *     size. The precedence for sizing is as follows: percent, 
+     *     top and bottom constraints, preferred size.
+     *  4) Positions the element based on its constraints. The precedence
+     *     for positioning is as follows: baseline, left and top, right and bottom,
+     *     x and y.  
+     */
+    private function applyConstraintsToElement(unscaledWidth:Number,
+                                               unscaledHeight:Number,
+                                               layoutElement:ILayoutElement):void
+    {
+        COMPILE::JS
+        {                
+        if (layoutElement['constraintElementId'] == null)
+            layoutElement['constraintElementId'] = constraintElementId.toString();
+        var elementInfo:ElementConstraintInfo = constraintCache[layoutElement['constraintElementId']];
+        }
+        COMPILE::SWF
+        {
+        var elementInfo:ElementConstraintInfo = constraintCache[layoutElement];
+        }
+        
+        var left:Number = elementInfo.left;
+        var right:Number = elementInfo.right;
+        var top:Number = elementInfo.top;
+        var bottom:Number = elementInfo.bottom;
+        var baseline:Number = elementInfo.baseline;
+        
+        var leftBoundary:String = elementInfo.leftBoundary;
+        var rightBoundary:String = elementInfo.rightBoundary;
+        var topBoundary:String = elementInfo.topBoundary;
+        var bottomBoundary:String = elementInfo.bottomBoundary;
+        var baselineBoundary:String = elementInfo.baselineBoundary;
+        
+        var percentWidth:Number = layoutElement.percentWidth;
+        var percentHeight:Number = layoutElement.percentHeight;
+        
+        var availableWidth:Number;
+        var availableHeight:Number;
+        
+        var elementWidth:Number = NaN;
+        var elementHeight:Number = NaN;
+        var elementMaxWidth:Number = NaN;
+        var elementMaxHeight:Number = NaN;
+        var elementX:Number = 0;
+        var elementY:Number = 0;
+        
+        var leftHolder:Number = 0;
+        var rightHolder:Number = unscaledWidth;
+        var topHolder:Number = 0;
+        var bottomHolder:Number = unscaledHeight;
+        var baselineHolder:Number = 0;
+        
+        var i:Number;
+        
+        var col:ConstraintColumn;
+        var row:ConstraintRow;
+        
+        if (leftBoundary)
+        {
+            col = _constraintColumns[elementInfo.colSpanLeftIndex];
+            leftHolder = col.x;
+        }
+        
+        if (rightBoundary)
+        {
+            col = _constraintColumns[elementInfo.colSpanRightIndex];
+            rightHolder = col.x + col.width;
+        }
+        
+        if (topBoundary)
+        {
+            row = _constraintRows[elementInfo.rowSpanTopIndex];
+            topHolder = row.y;
+        }
+        
+        if (bottomBoundary)
+        {
+            row = _constraintRows[elementInfo.rowSpanBottomIndex];
+            bottomHolder = row.y + row.height;
+        }
+        
+        if (baselineBoundary)
+        {
+            var baselineIndex:Number = elementInfo.baselineIndex;
+            var rowBaseline:Array = rowBaselines[baselineIndex];
+            row = _constraintRows[baselineIndex];
+            
+            // add baseline offset from row.
+            baselineHolder = row.y + Number(rowBaseline[0]);
+            
+            // add maxAscent. maxAscent defaults to 0 if not specified.
+            if (rowMaxAscents)
+                baselineHolder += rowMaxAscents[baselineIndex];
+            
+            // If bottom doesn't exist, then the bottom should be restricted to the
+            // baseline row.
+            if (isNaN(bottom))
+                bottomHolder = row.y + row.height;
+        }
+        
+        // available width
+        availableWidth = Math.round(rightHolder - leftHolder);
+        
+        // cases are baseline with top and bottom, 
+        // baseline with top, baseline with bottom, no baseline
+        if (!isNaN(baseline) && (isNaN(top) || isNaN(bottom)))
+            availableHeight = Math.round(bottomHolder - baselineHolder);
+        else
+            availableHeight = Math.round(bottomHolder - topHolder);
+        
+        // set width
+        if (!isNaN(percentWidth))
+        {
+            if (!isNaN(left))
+                availableWidth -= left;
+            if (!isNaN(right))
+                availableWidth -= right;
+            
+            elementWidth = Math.round(availableWidth * Math.min(percentWidth * 0.01, 1));
+            elementMaxWidth = Math.min(layoutElement.getMaxBoundsWidth(),
+                maxSizeToFitIn(unscaledWidth, left, right, layoutElement.getLayoutBoundsX()));
+        }
+        else if (!isNaN(left) && !isNaN(right))
+        {
+            elementWidth = availableWidth - left - right;
+        }
+        
+        // set height
+        if (!isNaN(percentHeight))
+        {
+            if (!isNaN(top))
+                availableHeight -= top;
+            if (!isNaN(bottom))
+                availableHeight -= bottom;    
+            
+            elementHeight = Math.round(availableHeight * Math.min(percentHeight * 0.01, 1));
+            elementMaxHeight = Math.min(layoutElement.getMaxBoundsHeight(),
+                maxSizeToFitIn(unscaledHeight, top, bottom, layoutElement.getLayoutBoundsY()));
+        }
+        else if (!isNaN(top) && !isNaN(bottom))
+        {
+            elementHeight = availableHeight - top - bottom;
+        }
+        
+        // Apply min and max constraints, make sure min is applied last. In the cases
+        // where elementWidth and elementHeight are NaN, setLayoutBoundsSize will use preferredSize
+        // which is already constrained between min and max.
+        if (!isNaN(elementWidth))
+        {
+            if (isNaN(elementMaxWidth))
+                elementMaxWidth = layoutElement.getMaxBoundsWidth();
+            elementWidth = Math.max(layoutElement.getMinBoundsWidth(), Math.min(elementMaxWidth, elementWidth));
+        }
+        
+        if (!isNaN(elementHeight))
+        {
+            if (isNaN(elementMaxHeight))
+                elementMaxHeight = layoutElement.getMaxBoundsHeight();
+            elementHeight = Math.max(layoutElement.getMinBoundsHeight(), Math.min(elementMaxHeight, elementHeight));
+        }
+        
+        layoutElement.setLayoutBoundsSize(elementWidth, elementHeight);
+        // update temp variables
+        elementWidth = layoutElement.getLayoutBoundsWidth();
+        elementHeight = layoutElement.getLayoutBoundsHeight();
+        
+        // Horizontal Position
+        if (!isNaN(left))
+            elementX = leftHolder + left;
+        else if (!isNaN(right))
+            elementX = rightHolder - right - elementWidth;
+        else
+            elementX = layoutElement.getLayoutBoundsX();
+        
+        // Vertical Position
+        if (!isNaN(baseline))
+            elementY = baselineHolder + baseline - layoutElement.baselinePosition;
+        else if (!isNaN(top))
+            elementY = topHolder + top;
+        else if (!isNaN(bottom))
+            elementY = bottomHolder - bottom - elementHeight;
+        else
+            elementY = layoutElement.getLayoutBoundsY();
+        
+        layoutElement.setLayoutBoundsPosition(elementX, elementY);
+    }
+    
+    /**
+     *  @private
+     *  Updates the widths of content size and percent size columns that are spanned
+     *  by the specified element. This method updates the provided column widths 
+     *  vector in place. The algorithm is as follows:
+     * 
+     *  1) Determine the space needed by the element to satisfy its constraints
+     *     and be at its preferred size.
+     * 
+     *  2) Calculate the number of columns the element will span.
+     * 
+     *  3) If the element causes a column to expand, update the column width to match.
+     *     a) For the single spanning case, we only need to check if this element's 
+     *        required width is larger than the column's current width.
+     *     b) For the multiple spanning case, we distribute the remaining width after 
+     *        subtracting the fixed size columns across the content/percent size columns.
+     *        Then, we only update a column's width if the new divided width would cause
+     *        the column's width to expand.
+     * 
+     *  @param elementInfo The constraint information of the element.
+     *  @param colWidths The vector of column widths to update.
+     */
+    private function updateColumnWidthsForElement(colWidths:Vector.<Number>, elementInfo:ElementConstraintInfo):void
+    {
+        var layoutElement:ILayoutElement = elementInfo.layoutElement;
+        var numCols:int = _constraintColumns.length;
+        var col:ConstraintColumn;
+        
+        var leftIndex:int = -1;
+        var rightIndex:int = -1;
+        var span:int;
+        
+        var extX:Number = 0;
+        var preferredWidth:Number = layoutElement.getPreferredBoundsWidth();
+        var maxExtent:Number;
+        var remainingWidth:Number;
+        
+        var j:int;
+        var colWidth:Number = 0;
+        
+        // 1) Determine how much space the element needs to satisfy its
+        //    constraints and be at its preferred width.
+        if (!isNaN(elementInfo.left))
+        {
+            extX += elementInfo.left;
+            if (elementInfo.leftBoundary)
+                leftIndex = elementInfo.colSpanLeftIndex;
+            else
+                leftIndex = 0; // constrained to parent
+        }
+        
+        if (!isNaN(elementInfo.right))
+        {
+            extX += elementInfo.right;
+            if (elementInfo.rightBoundary)
+                rightIndex = elementInfo.colSpanRightIndex;
+            else
+                rightIndex = numCols - 1; // constrained to parent
+        }
+        
+        maxExtent = extX + preferredWidth;
+        remainingWidth = maxExtent;
+        
+        // 2) If either the left or the right constraint doesn't exist,
+        //    we must find the span of the element. We do this by
+        //    determining the index of the last column that the element
+        //    occupies in the unconstrained direction.
+        if (leftIndex < 0 || rightIndex < 0)
+        {
+            var isLeft:Boolean = leftIndex < 0;
+            var startIndex:int = isLeft ? rightIndex : leftIndex;
+            var endIndex:int = isLeft ? -1 : numCols;
+            var increment:int = isLeft ? -1 : 1;
+            
+            if (isLeft) // defaults to 0
+                leftIndex = 0;
+            else // defaults to numCols - 1
+                rightIndex = numCols - 1;
+            
+            for (j = startIndex; j != endIndex ; j += increment)
+            {
+                col = _constraintColumns[j];
+                
+                // subtract fixed columns
+                if (!isNaN(col.explicitWidth))
+                    remainingWidth -= col.explicitWidth;
+                
+                if ((col.contentSize || !isNaN(col.percentWidth)) || remainingWidth < 0)
+                {
+                    if (isLeft)
+                        leftIndex = j;
+                    else
+                        rightIndex = j;
+                    break;
+                }
+            }
+        }
+        // always 1 or positive.
+        span = rightIndex - leftIndex + 1;
+        
+        // 3) If the element causes a column to expand, update the column width to match.
+        if (span == 1)
+        {
+            // a) For the single spanning case, we only need to check if this element's 
+            //    required width is larger than the column's current width.
+            col = _constraintColumns[leftIndex];
+            
+            if (col.contentSize || !isNaN(col.percentWidth))
+            {   
+                colWidth = Math.max(colWidths[leftIndex], extX + preferredWidth);
+                
+                if (constraintsDetermineWidth(elementInfo))
+                    colWidth = Math.max(colWidth, extX + layoutElement.getMinBoundsWidth());
+                
+                // bound with max width of column
+                if (!isNaN(col.maxWidth))
+                    colWidth = Math.min(colWidth, col.maxWidth);
+                
+                colWidths[leftIndex] = Math.ceil(colWidth);
+            }
+        }
+        else
+        {
+            // b) multiple spanning case when span >= 2.
+            //    1) start from leftIndex and subtract fixed columns.
+            //    2) divide space evenly into content/percent size columns.
+            var contentCols:Vector.<ConstraintColumn> = new Vector.<ConstraintColumn>();
+            var contentColsIndices:Vector.<int> = new Vector.<int>();
+            
+            remainingWidth = maxExtent;
+            for (j = leftIndex; j <= rightIndex; j++)
+            {
+                col = _constraintColumns[j];
+                
+                if (!isNaN(col.explicitWidth))
+                {
+                    if (remainingWidth < col.width)
+                        break;
+                    
+                    remainingWidth -= col.width;
+                }
+                else if (col.contentSize || !isNaN(col.percentWidth))
+                {
+                    contentCols.push(col);
+                    contentColsIndices.push(j);
+                }
+            }
+            
+            var numContentCols:Number = contentCols.length;
+            if (numContentCols > 0)
+            {
+                var splitWidth:Number = remainingWidth / numContentCols;
+                
+                for (j = 0; j < numContentCols; j++)
+                {
+                    col = contentCols[j];
+                    
+                    colWidth = Math.max(colWidths[contentColsIndices[j]], splitWidth);
+                    if (!isNaN(col.maxWidth))
+                        colWidth = Math.min(colWidth, col.maxWidth);
+                    
+                    colWidths[contentColsIndices[j]] = Math.ceil(colWidth);
+                }
+            }
+        }
+    }
+    
+    /**
+     *  Adjusts the sizes of percent size columns or rows to fill the constrainedSize.
+     *  This method updates the provided column widths or row heights vector in place.
+     *  
+     *  The term, "region", refers to a column or row.
+     *  The percent size region sizes are first reset to their minimum size. 
+     *  If the given region sizes from the content and fixed size regions already
+     *  fill the available space, then the percent size region sizes stay at their
+     *  minimum size. Otherwise, the remaining space is distributed to the percent 
+     *  size regions based on the ratio of its percent size to the sum of all the 
+     *  percent sizes.
+     */
+    private function constrainPercentRegionSizes(sizes:Vector.<Number>, constrainedSize:Number, isColumns:Boolean):void
+    {
+        var col:ConstraintColumn;
+        var row:ConstraintRow;
+        var numSizes:int = isColumns ? _constraintColumns.length : _constraintRows.length;
+        
+        var childInfoArray:Array /* of ConstraintRegionFlexChildInfo */ = [];
+        var childInfo:ConstraintRegionFlexChildInfo;
+        var remainingSpace:Number = constrainedSize;
+        var percentMinSizes:Number = 0;
+        var totalPercent:Number = 0;
+        
+        // Set percent size regions back to minSize and
+        // find the remaining space.
+        for (var i:int = 0; i < numSizes; i++)
+        {
+            var percentSize:Number;
+            var minSize:Number;
+            var maxSize:Number;
+            
+            if (isColumns)
+            {
+                col = _constraintColumns[i];
+                percentSize = col.percentWidth;
+                minSize = col.minWidth;
+                maxSize = col.maxWidth;
+            }
+            else
+            {
+                row = _constraintRows[i];
+                percentSize = row.percentHeight;
+                minSize = row.minHeight;
+                maxSize = row.maxHeight;
+            }
+
+            if (!isNaN(percentSize))
+            {
+                sizes[i] = (!isNaN(minSize)) ? Math.ceil(Math.max(minSize, 0)) : 0;
+                percentMinSizes += sizes[i];
+                totalPercent += percentSize;
+                
+                // Fill childInfoArray for distributing the width.
+                childInfo = new ConstraintRegionFlexChildInfo();
+                childInfo.index = i;
+                childInfo.percent = percentSize;
+                childInfo.min = minSize;
+                childInfo.max = maxSize;
+                childInfoArray.push(childInfo);
+            }
+            else
+            {
+                remainingSpace -= sizes[i];
+            }
+        }
+        
+        // If there's space remaining, distribute the width to the percent size
+        // columns based on their ratio of percentWidth to sum of all the percentWidths.
+        if (remainingSpace > percentMinSizes)
+        {            
+            Flex.flexChildrenProportionally(constrainedSize, 
+                                            remainingSpace,
+                                            totalPercent,
+                                            childInfoArray);
+            
+            var roundOff:Number = 0;
+            for each (childInfo in childInfoArray)
+            {
+                // Make sure the calculated widths are rounded to pixel boundaries
+                var size:Number = Math.round(childInfo.size + roundOff);
+                roundOff += childInfo.size - size;
+                
+                sizes[childInfo.index] = size;
+                
+                // remainingSpace -= size;
+            }
+            // TODO (klin): What do we do if there's remainingSpace after all this?
+        }
+    }
+    
+    /** 
+     *  @private
+     *  This function measures the ConstraintColumns partitioning
+     *  the target and returns their new widths. The calculations
+     *  are based on the current constraintCache and other derived
+     *  data structures. To update the constraintCache, one needs to
+     *  call the parseConstraints() method.
+     *  
+     *  The widths are measured with the following requirements:
+     *  1. Fixed size columns honor their pixel values.
+     *  
+     *  2. Content size columns whose children only span that column
+     *     assumes the width of the widest child.
+     *  
+     *  3. Content size columns whose children span more than one column
+     *     assumes the widest width possible when the child's size is divided
+     *     among the spanned columns.
+     *     a. Each child divides its preferred width among the content size
+     *        columns that it spans. A child also always honors fixed size
+     *        columns that it spans.
+     *     b. The column takes the widest width given by its children.
+     *  
+     *  4. Percent size columns measure exactly like content size columns
+     *     at first, but after measurement, if availableWidth is provided,
+     *     the percent size columns are remeasured to allow the columns to
+     *     fit exactly in the remaining width in accordance with their given
+     *     percentage.
+     *     a. The percentages given are treated as ratios for how the width
+     *        should be divided among the percent size columns.
+     *     b. If no remaining space is available or the measured size of all
+     *        the content and fixed size columns are greater than the 
+     *        constrainedWidth, percent size columns are set to their minimum.
+     *  
+     *  5. Columns always honor their max and min widths.
+     *  
+     *  6. If constrainedWidth is not specified, sum the column widths to find
+     *     the total measured width of the target.
+     * 
+     *  @param constrainedWidth The constraining width to be used when measuring
+     *  percent size columns. The default is NaN.
+     *  
+     *  @return A vector of the new column widths.
+     */
+    mx_internal function measureColumns(constrainedWidth:Number = NaN):Vector.<Number>
+    {
+        // TODO (klin): Parameterize this to work for both columns and rows.
+        // This may mean we need to add some mx_internal properties to 
+        // the columns for "major size", etc... Question is, what about
+        // 1-D properties like baseline? What parts can we parameterize and
+        // what parts aren't possible.
+        
+        // Parse constraints if it hasn't been done yet, make sure to clear 
+        // the cache afterwards.
+        var clearCache:Boolean = false;
+        if (!constraintCache)
+        {
+            parseConstraints();
+            clearCache = true;
+        }
+        
+        if (_constraintColumns.length <= 0)
+            return new Vector.<Number>();
+        
+        var measuredWidth:Number = 0;
+        var i:Number;
+        var numCols:Number = _constraintColumns.length;
+        var col:ConstraintColumn;
+        var hasContentSize:Boolean = false;
+        var hasPercentSize:Boolean = false;
+        var colWidths:Vector.<Number> = new Vector.<Number>(numCols);
+        
+        // Start column widths at the minWidth of each column or
+        // its explicit width.
+        for (i = 0; i < numCols; i++)
+        {
+            col = _constraintColumns[i];
+            
+            if (col.contentSize || !isNaN(col.percentWidth))
+            {
+                hasContentSize ||= col.contentSize;
+                hasPercentSize ||= !isNaN(col.percentWidth);
+                
+                if (!isNaN(col.minWidth))
+                    colWidths[i] = Math.ceil(Math.max(col.minWidth, 0));
+                else
+                    colWidths[i] = 0;
+            }
+            else if (!isNaN(col.explicitWidth))
+            {
+                var w:Number = col.explicitWidth;
+                
+                if (!isNaN(col.minWidth))
+                    w = Math.max(w, col.minWidth);
+                
+                if (!isNaN(col.maxWidth))
+                    w = Math.min(w, col.maxWidth);
+                
+                colWidths[i] = Math.ceil(w);
+            }
+        }
+        
+        // Assumption: elements in colSpanElements have one or more constraints touching a column.
+        // This is enforced in parseElementConstraints().
+        if (colSpanElements && (hasContentSize || hasPercentSize))
+        {
+            // Measure content/percent size columns.
+            for each (var elementInfo:ElementConstraintInfo in colSpanElements)
+            {
+                updateColumnWidthsForElement(colWidths, elementInfo);
+            }
+        }
+        
+        // Adjust percent size columns to account for constraining width.
+        if (!isNaN(constrainedWidth) && hasPercentSize)
+        {
+            constrainPercentRegionSizes(colWidths, constrainedWidth, true);
+        }
+        
+        // Clear the cache only if we created it just for this method call.
+        if (clearCache)
+            clearConstraintCache();
+        
+        return colWidths;
+    }
+    
+    /**
+     *  @private
+     *  Updates the heights of content size and percent size rows that are spanned
+     *  by the specified element. This method updates the provided row heights 
+     *  vector in place. The algorithm is as follows:
+     * 
+     *  1) Determine the space needed by the element to satisfy its constraints
+     *     and be at its preferred size.
+     * 
+     *  2) Calculate the number of rows the element will span.
+     * 
+     *  3) If the element causes a row to expand, update the row height to match.
+     *     a) For the single spanning case, we only need to check if this element's 
+     *        required height is larger than the row's current height.
+     *     b) For the multiple spanning case, we distribute the remaining height after 
+     *        subtracting the fixed size rows across the content/percent size rows.
+     *        Then, we only update a row's height if the new divided height would cause
+     *        the row's height to expand.
+     * 
+     *  @param elementInfo The constraint information of the element.
+     *  @param colWidths The vector of column widths to update.
+     */
+    private function updateRowHeightsForElement(rowHeights:Vector.<Number>, elementInfo:ElementConstraintInfo):void
+    {
+        var layoutElement:ILayoutElement = elementInfo.layoutElement;
+        var numRows:int = _constraintRows.length;
+        var row:ConstraintRow;
+        
+        var topIndex:int = -1;
+        var bottomIndex:int = -1;
+        var span:int;
+        
+        var extY:Number = 0;
+        var preferredHeight:Number = layoutElement.getPreferredBoundsHeight();
+        var maxExtent:Number;
+        var remainingHeight:Number;
+        
+        var j:int;
+        var rowHeight:Number = 0;
+        
+        // 1) Determine how much space the element needs to satisfy its
+        //    constraints and be at its preferred height.
+        if (!isNaN(elementInfo.top))
+        {
+            extY += elementInfo.top;
+            if (elementInfo.topBoundary)
+                topIndex = elementInfo.rowSpanTopIndex;
+            else
+                topIndex = 0; // constrained to parent
+        }
+        
+        if (!isNaN(elementInfo.bottom))
+        {
+            extY += elementInfo.bottom;
+            if (elementInfo.bottomBoundary)
+                bottomIndex = elementInfo.rowSpanBottomIndex;
+            else
+                bottomIndex = numRows - 1; // constrained to parent
+        }
+        
+        // Only include baseline if at least one of top or bottom don't
+        // exist.
+        if (!isNaN(elementInfo.baseline) && (topIndex < 0 || bottomIndex < 0))
+        {
+            extY += elementInfo.baseline - layoutElement.baselinePosition;
+            
+            if (!isNaN(elementInfo.top))
+                extY -= elementInfo.top;
+            
+            if (elementInfo.baselineBoundary)
+            {
+                topIndex = elementInfo.baselineIndex;
+                
+                // add baseline offset.
+                extY += Number(rowBaselines[topIndex][0]); 
+                
+                // add maxAscent. maxAscent is 0 if not specified on the row.
+                if (rowMaxAscents)
+                    extY += rowMaxAscents[topIndex];
+            }
+            else
+            {
+                topIndex = 0;
+            }
+        }
+        
+        maxExtent = extY + preferredHeight;
+        remainingHeight = maxExtent;
+            
+        // 2) If either the top or the bottom constraint doesn't exist,
+        //    we must find the span of the element. We do this by
+        //    determining the index of the last row that the element
+        //    occupies in the unconstrained direction.
+        if (topIndex < 0 || bottomIndex < 0)
+        {
+            var isTop:Boolean = topIndex < 0;
+            var startIndex:int = isTop ? bottomIndex : topIndex;
+            var endIndex:int = isTop ? -1 : numRows;
+            var increment:int = isTop ? -1 : 1;
+            
+            if (isTop) // defaults to 0
+                topIndex = 0;
+            else // defaults to numRows - 1
+                bottomIndex = numRows - 1;
+            
+            for (j = startIndex; j != endIndex ; j += increment)
+            {
+                row = _constraintRows[j];
+                
+                // subtract fixed rows
+                if (!isNaN(row.explicitHeight))
+                    remainingHeight -= row.explicitHeight;
+                
+                if ((row.contentSize || !isNaN(row.percentHeight)) || remainingHeight < 0)
+                {
+                    if (isTop)
+                        topIndex = j;
+                    else
+                        bottomIndex = j;
+                    break;
+                }
+            }
+        }
+        // always 1 or positive.
+        span = bottomIndex - topIndex + 1;
+        
+        // 3) If the element causes a row to expand, update the row height to match.
+        if (span == 1)
+        {
+            // a) For the single spanning case, we only need to check if this element's 
+            //    required height is larger than the row's current height.
+            row = _constraintRows[topIndex];
+            
+            if (row.contentSize || !isNaN(row.percentHeight))
+            {   
+                rowHeight = Math.max(rowHeights[topIndex], extY + preferredHeight);
+                
+                if (constraintsDetermineHeight(elementInfo))
+                    rowHeight = Math.max(rowHeight, extY + layoutElement.getMinBoundsHeight());
+                
+                // bound with max height of row
+                if (!isNaN(row.maxHeight))
+                    rowHeight = Math.min(rowHeight, row.maxHeight);
+                
+                rowHeights[topIndex] = Math.ceil(rowHeight);
+            }
+        }
+        else
+        {
+            // b) multiple spanning case. span >= 2.
+            //    1) start from topIndex and subtract fixed rows
+            //    2) divide space evenly into content/percent size rows.
+            var contentRows:Vector.<ConstraintRow> = new Vector.<ConstraintRow>();
+            var contentRowsIndices:Vector.<int> = new Vector.<int>();
+            
+            remainingHeight = maxExtent;
+            for (j = topIndex; j <= bottomIndex; j++)
+            {
+                row = _constraintRows[j];
+                
+                if (!isNaN(row.explicitHeight))
+                {
+                    if (remainingHeight < row.height)
+                        break;
+                    
+                    remainingHeight -= row.height;
+                }
+                else if (row.contentSize || !isNaN(row.percentHeight))
+                {
+                    contentRows.push(row);
+                    contentRowsIndices.push(j);
+                }
+            }
+            
+            var numContentRows:Number = contentRows.length;
+            if (numContentRows > 0)
+            {
+                var splitHeight:Number = remainingHeight / numContentRows;
+                
+                for (j = 0; j < numContentRows; j++)
+                {
+                    row = contentRows[j];
+                    
+                    rowHeight = Math.max(rowHeights[contentRowsIndices[j]], splitHeight);
+                    if (!isNaN(row.maxHeight))
+                        rowHeight = Math.min(rowHeight, row.maxHeight);
+                    
+                    rowHeights[contentRowsIndices[j]] = Math.ceil(rowHeight);
+                }
+            }
+        }
+    }
+    
+    /**
+     *  @private
+     *  Synonymous to measureColumns(), but with added baseline constraint.
+     *  Baseline is only included in the measurement if at least one of the element's
+     *  top or bottom constraint doesn't exist. The calculations are based on the
+     *  current constraintCache. To update the constraintCache, one needs to call
+     *  the parseConstraints() method.
+     */
+    private function measureRows(constrainedHeight:Number = NaN):Vector.<Number>
+    {
+        if (_constraintRows.length <= 0)
+            return new Vector.<Number>();
+        
+        var measuredHeight:Number = 0;
+        var i:Number;
+        var numRows:Number = _constraintRows.length;
+        var row:ConstraintRow;
+        var hasContentSize:Boolean = false;
+        var hasPercentSize:Boolean = false;
+        var rowHeights:Vector.<Number> = new Vector.<Number>(numRows);
+        
+        // Start row heights at the minHeight of each row or
+        // its explicit height.
+        for (i = 0; i < numRows; i++)
+        {
+            row = _constraintRows[i];
+            
+            if (row.contentSize || !isNaN(row.percentHeight))
+            {
+                hasContentSize ||= row.contentSize;
+                hasPercentSize ||= !isNaN(row.percentHeight);
+                
+                if (!isNaN(row.minHeight))
+                    rowHeights[i] = Math.ceil(Math.max(row.minHeight, 0));
+                else
+                    rowHeights[i] = 0;
+            }
+            else if (!isNaN(row.explicitHeight))
+            {
+                var h:Number = row.explicitHeight;
+                
+                if (!isNaN(row.minHeight))
+                    h = Math.max(h, row.minHeight);
+                
+                if (!isNaN(row.maxHeight))
+                    h = Math.min(h, row.maxHeight);
+                
+                rowHeights[i] = Math.ceil(h);
+            }
+        }
+        
+        // Assumption: elements in rowSpanElements have one or more constraints touching a row.
+        // This is enforced in parseElementConstraints().
+        if (rowSpanElements && (hasContentSize || hasPercentSize))
+        {
+            // Measure content/percent size columns.
+            for each (var elementInfo:ElementConstraintInfo in rowSpanElements)
+            {
+                updateRowHeightsForElement(rowHeights, elementInfo);
+            }
+        }
+        
+        // Adjust percent size rows to account for constraining height.
+        if (!isNaN(constrainedHeight) && hasPercentSize)
+        {
+            constrainPercentRegionSizes(rowHeights, constrainedHeight, false);
+        }
+        
+        return rowHeights;
+    }
+    
+    /**
+     *  @private
+     *  Measures the size of target based on content not included in the columns and rows.
+     *  Basically, applies BasicLayout to other content to determine measured size.
+     *  Returns a vector with the measured [width, height, minWidth, minHeight].
+     */
+    private function measureOtherContent():Vector.<Number>
+    {
+        var width:Number = 0;
+        var height:Number = 0;
+        var minWidth:Number = 0;
+        var minHeight:Number = 0;
+        var count:int = otherElements.length;
+        
+        for (var i:int = 0; i < count; i++)
+        {
+            var elementInfo:ElementConstraintInfo = otherElements[i];
+            var layoutElement:ILayoutElement = elementInfo.layoutElement;
+            
+            // Only measure width if not constrained to columns.
+            if (!elementInfo.leftBoundary && !elementInfo.rightBoundary)
+            {
+                var left:Number = elementInfo.left;
+                var right:Number = elementInfo.right;
+                var extX:Number;
+                
+                if (!isNaN(left) && !isNaN(right))
+                {
+                    // If both left & right are set, then the extents is always
+                    // left + right so that the element is resized to its preferred
+                    // size (if it's the one that pushes out the default size of the container).
+                    extX = left + right;                
+                }
+                else if (!isNaN(left) || !isNaN(right))
+                {
+                    extX = isNaN(left) ? 0 : left;
+                    extX += isNaN(right) ? 0 : right;
+                }
+                else
+                {
+                    extX = layoutElement.getBoundsXAtSize(NaN, NaN);
+                }
+                
+                var preferredWidth:Number = layoutElement.getPreferredBoundsWidth();
+                width = Math.max(width, extX + preferredWidth);
+                
+                // Find the minimum default extents, we take the minimum height only
+                // when the element size is determined by the parent size
+                var elementMinWidth:Number =
+                    constraintsDetermineWidth(elementInfo) ? layoutElement.getMinBoundsWidth() :
+                    preferredWidth;
+                
+                minWidth = Math.max(minWidth, extX + elementMinWidth);
+            }
+            
+            // only measure height if not constrained to rows.
+            var noVerticalBoundaries:Boolean = !elementInfo.topBoundary && !elementInfo.bottomBoundary;
+            var noBaselineBoundary:Boolean = !elementInfo.baselineBoundary;
+            
+            if (noVerticalBoundaries || noBaselineBoundary)
+            {
+                var top:Number;
+                var bottom:Number;
+                var baseline:Number;
+                var extY:Number;
+                
+                if (noVerticalBoundaries)
+                {
+                    top = elementInfo.top;
+                    bottom = elementInfo.bottom;
+                }
+                
+                if (noBaselineBoundary)
+                    baseline = elementInfo.baseline;
+                
+                if (!isNaN(top) && !isNaN(bottom))
+                {
+                    // If both top & bottom are set, then the extents is always
+                    // top + bottom so that the element is resized to its preferred
+                    // size (if it's the one that pushes out the default size of the container).
+                    extY = top + bottom;                
+                }
+                else if (!isNaN(baseline))
+                {
+                    extY = Math.round(baseline - layoutElement.baselinePosition);
+                }
+                else if (!isNaN(top) || !isNaN(bottom))
+                {
+                    extY = isNaN(top) ? 0 : top;
+                    extY += isNaN(bottom) ? 0 : bottom;
+                }
+                else
+                {
+                    extY = layoutElement.getBoundsYAtSize(NaN, NaN);
+                }
+                
+                var preferredHeight:Number = layoutElement.getPreferredBoundsHeight();
+                height = Math.max(height, extY + preferredHeight);
+                
+                // Find the minimum default extents, we take the minimum height only
+                // when the element size is determined by the parent size
+                var elementMinHeight:Number =
+                    constraintsDetermineHeight(elementInfo) ? layoutElement.getMinBoundsHeight() : 
+                    preferredHeight;
+                
+                minHeight = Math.max(minHeight, extY + elementMinHeight);
+            }
+        }
+        
+        var vec:Vector.<Number> = new Vector.<Number>(4, true);
+        vec[0] = Math.max(width, minWidth);
+        vec[1] = Math.max(height, minHeight);
+        vec[2] = minWidth;
+        vec[3] = minHeight;
+        
+        return vec;
+    }
+    
+    /**
+     *  @private
+     *  Iterates over elements and calls parseElementConstraints on each.
+     */
+    private function parseConstraints():void
+    {
+        var layoutTarget:GroupBase = target;
+        if (!layoutTarget)
+            return;
+
+        constraintCacheNeeded++;
+
+        var count:Number = layoutTarget.numElements;
+        var layoutElement:ILayoutElement;
+        
+        COMPILE::SWF
+        {
+            var cache:Dictionary = new Dictionary(true);
+        }
+        COMPILE::JS
+        {
+            var cache:Object = {};
+        }
+        var i:int;
+        
+        // Populate rowBaselines with baseline information from rows.
+        var n:int = _constraintRows.length;
+        var row:ConstraintRow;
+
+        if (rowBaselines == null)
+            rowBaselines = new Vector.<Array>();
+        else
+            rowBaselines.length = 0;
+        
+        for (i = 0; i < n; i++)
+        {
+            row = _constraintRows[i];
+            rowBaselines[i] = LayoutElementHelper.parseConstraintExp(row.baseline);
+            
+            var maxAscentStr:String = rowBaselines[i][1];
+            if (maxAscentStr && maxAscentStr != "maxAscent")
+                throw new Error(ResourceManager.getInstance().getString("layout", "invalidBaselineOnRow",
+                    [ row.id, row.baseline ]));
+        }
+        
+        for (i = 0; i < count; i++)
+        {
+            layoutElement = layoutTarget.getElementAt(i) as ILayoutElement;
+            if (!layoutElement || !layoutElement.includeInLayout)
+                continue;
+            
+            parseElementConstraints(layoutElement, cache);
+        }
+        
+        this.constraintCache = cache;
+        constraintCacheNeeded--;
+    }
+    
+    /**
+     *  @private
+     *  This function parses the constraints of a single element, creates an
+     *  ElementConstraintInfo object for the element, and throws errors if the
+     *  columns or rows are not found for each constraint.
+     */
+    private function parseElementConstraints(layoutElement:ILayoutElement, constraintCache:Object /*Dictionary*/):void
+    {
+        // Variables to track the offsets
+        var left:Number;
+        var right:Number;
+        var top:Number;
+        var bottom:Number;
+        var baseline:Number;
+        
+        // Variables to track the boundaries from which
+        // the offsets are calculated from. If null, the 
+        // boundary is the parent container edge.
+        var leftBoundary:String;
+        var rightBoundary:String;
+        var topBoundary:String;
+        var bottomBoundary:String;
+        var baselineBoundary:String;
+        
+        var message:String;
+        
+        var temp:Array = LayoutElementHelper.parseConstraintExp(layoutElement.left);
+        left = temp[0];
+        leftBoundary = temp[1];
+        
+        temp = LayoutElementHelper.parseConstraintExp(layoutElement.right, temp);
+        right = temp[0];
+        rightBoundary = temp[1];
+        
+        temp = LayoutElementHelper.parseConstraintExp(layoutElement.top, temp);
+        top = temp[0];
+        topBoundary = temp[1];
+        
+        temp = LayoutElementHelper.parseConstraintExp(layoutElement.bottom, temp);
+        bottom = temp[0];
+        bottomBoundary = temp[1];
+        
+        temp = LayoutElementHelper.parseConstraintExp(layoutElement.baseline, temp);
+        baseline = temp[0];
+        baselineBoundary = temp[1];
+        
+        // save values into a Dictionary based on element name.
+        var elementInfo:ElementConstraintInfo = new ElementConstraintInfo(layoutElement,
+            left, right, top, bottom, baseline,
+            leftBoundary, rightBoundary,
+            topBoundary, bottomBoundary, baselineBoundary);
+        COMPILE::SWF
+        {
+            constraintCache[layoutElement] = elementInfo;                
+        }
+        COMPILE::JS
+        {
+            constraintCache[layoutElement['constraintElementId']] = elementInfo;                
+            
+        }
+        
+        
+        // If some pair of boundaries don't exist, we will need to measure
+        // the container size based on the element's other properties like
+        // x, y, width, height.
+        var i:Number;
+        if ((!leftBoundary && !rightBoundary) ||
+            (!topBoundary && !bottomBoundary) ||
+            !baselineBoundary)
+        {
+            if (!otherElements)
+                otherElements = new Vector.<ElementConstraintInfo>();
+            
+            otherElements.push(elementInfo);
+        }
+        
+        // match columns
+        if (leftBoundary || rightBoundary)
+        {
+            var numColumns:Number = _constraintColumns.length;
+            var colIndex:Object;
+
+            if (!colSpanElements)
+                colSpanElements = new Vector.<ElementConstraintInfo>();
+            
+            colSpanElements.push(elementInfo);
+            
+            if (leftBoundary)
+            {
+                colIndex = columnsObject[leftBoundary];
+                
+                if (colIndex != null)
+                    elementInfo.colSpanLeftIndex = int(colIndex);
+                
+                // throw error if no match.
+                if (elementInfo.colSpanLeftIndex < 0)
+                {
+                    message = ResourceManager.getInstance().getString(
+                        "layout", "columnNotFound", [ leftBoundary ]);
+                    throw new ConstraintError(message);
+                }
+            }
+            
+            // can we assume rightIndex >= leftIndex?
+            if (rightBoundary)
+            {
+                colIndex = columnsObject[rightBoundary];
+                
+                if (colIndex != null)
+                    elementInfo.colSpanRightIndex = int(colIndex);
+                
+                // throw error if no match.
+                if (elementInfo.colSpanRightIndex < 0)
+                {
+                    message = ResourceManager.getInstance().getString(
+                        "layout", "columnNotFound", [ rightBoundary ]);
+                    throw new ConstraintError(message);
+                }
+            }
+        }
+        
+        // match rows.
+        if (topBoundary || bottomBoundary || baselineBoundary)
+        {
+            var rowIndex:Object;
+            
+            if (!rowSpanElements)
+                rowSpanElements = new Vector.<ElementConstraintInfo>();
+            
+            rowSpanElements.push(elementInfo);
+            
+            if (topBoundary)
+            {
+                rowIndex = rowsObject[topBoundary];
+                
+                if (rowIndex != null)
+                    elementInfo.rowSpanTopIndex = int(rowIndex);
+                
+                // throw error if no match.
+                if (elementInfo.rowSpanTopIndex < 0)
+                {
+                    message = ResourceManager.getInstance().getString(
+                        "layout", "rowNotFound", [ topBoundary ]);
+                    throw new ConstraintError(message);
+                }
+            }
+            
+            if (bottomBoundary)
+            {
+                rowIndex = rowsObject[bottomBoundary];
+                
+                if (rowIndex != null)
+                    elementInfo.rowSpanBottomIndex = int(rowIndex);
+                
+                // throw error if no match.
+                if (elementInfo.rowSpanBottomIndex < 0)
+                {
+                    message = ResourceManager.getInstance().getString(
+                        "layout", "rowNotFound", [ bottomBoundary ]);
+                    throw new ConstraintError(message);
+                }
+            }
+            
+            if (baselineBoundary)
+            {
+                rowIndex = rowsObject[baselineBoundary];
+                
+                if (rowIndex != null)
+                    elementInfo.baselineIndex = int(rowIndex);
+                
+                // throw error if no match.
+                if (elementInfo.baselineIndex < 0)
+                {
+                    message = ResourceManager.getInstance().getString(
+                        "layout", "rowNotFound", [ baselineBoundary ]);
+                    throw new ConstraintError(message);
+                }
+                
+                // when using maxAscent, calculate maximum baselinePosition for this row.
+                var bIndex:int = elementInfo.baselineIndex;
+                var numRows:Number = _constraintRows.length;
+                
+                if (rowBaselines[bIndex][1])
+                {
+                    // maxAscents will all default to 0.
+                    if (!rowMaxAscents)
+                        rowMaxAscents = new Vector.<Number>(numRows, true);
+
+                    rowMaxAscents[bIndex] = Math.max(rowMaxAscents[bIndex], layoutElement.baselinePosition);
+                }
+            }
+        }
+    }
+    
+    /**
+     *  @private
+     */
+    private function clearConstraintCache():void
+    {
+        if(!constraintCacheNeeded)
+        {
+            colSpanElements = null;
+            rowSpanElements = null;
+            otherElements = null;
+            rowBaselines = null;
+            rowMaxAscents = null;
+            constraintCache = null;
+        }
+    }
+}
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Helper class: ElementConstraintInfo
+//
+////////////////////////////////////////////////////////////////////////////////
+
+import mx.core.ILayoutElement;
+
+class ElementConstraintInfo
+{
+    //--------------------------------------------------------------------------
+    //
+    //  Constructor
+    //
+    //--------------------------------------------------------------------------
+    
+    /**
+     *  @private
+     */
+    public function ElementConstraintInfo(
+        layoutElement:ILayoutElement,
+        left:Number, right:Number,
+        top:Number, bottom:Number,
+        baseline:Number, leftBoundary:String = null,
+        rightBoundary:String = null,
+        topBoundary:String = null, bottomBoundary:String = null,
+        baselineBoundary:String = null,
+        colSpanLeftIndex:int = -1, colSpanRightIndex:int = -1,
+        rowSpanTopIndex:int = -1, rowSpanBottomIndex:int = -1,
+        baselineIndex:int = -1):void
+    {
+        super();
+        
+        // pointer to element
+        this.layoutElement = layoutElement;
+        
+        // offsets
+        this.left = left;
+        this.right = right;
+        this.top = top;
+        this.bottom = bottom;
+        this.baseline = baseline;
+        
+        // boundaries (ie: parent, column or row edge)
+        this.leftBoundary = leftBoundary;
+        this.rightBoundary = rightBoundary;
+        this.topBoundary = topBoundary;
+        this.bottomBoundary = bottomBoundary;
+        this.baselineBoundary = baselineBoundary;
+        
+        this.colSpanLeftIndex = colSpanLeftIndex;
+        this.colSpanRightIndex = colSpanRightIndex;
+        this.rowSpanTopIndex = rowSpanTopIndex;
+        this.rowSpanBottomIndex = rowSpanBottomIndex;
+        this.baselineIndex = baselineIndex;
+    }
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Properties
+    //
+    //--------------------------------------------------------------------------
+    
+    public var layoutElement:ILayoutElement;
+    
+    public var left:Number;
+    public var right:Number;
+    public var top:Number;
+    public var bottom:Number;
+    public var baseline:Number;
+    public var leftBoundary:String;
+    public var rightBoundary:String;
+    public var topBoundary:String;
+    public var bottomBoundary:String;
+    public var baselineBoundary:String;
+    
+    public var colSpanLeftIndex:int;
+    public var colSpanRightIndex:int;
+    public var rowSpanTopIndex:int;
+    public var rowSpanBottomIndex:int;
+    public var baselineIndex:int;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Helper class: ConstraintRegionFlexChildInfo
+//
+////////////////////////////////////////////////////////////////////////////////
+
+import mx.containers.utilityClasses.FlexChildInfo;
+
+class ConstraintRegionFlexChildInfo extends FlexChildInfo
+{
+    public var index:int
+}
diff --git a/frameworks/projects/SparkRoyale/src/main/royale/spark/layouts/FormItemLayout.as b/frameworks/projects/SparkRoyale/src/main/royale/spark/layouts/FormItemLayout.as
index 58778ac..b2586d1 100644
--- a/frameworks/projects/SparkRoyale/src/main/royale/spark/layouts/FormItemLayout.as
+++ b/frameworks/projects/SparkRoyale/src/main/royale/spark/layouts/FormItemLayout.as
@@ -35,7 +35,7 @@ package spark.layouts
 	 *  @playerversion AIR 2.5
 	 *  @productversion Flex 4.5
 	 */ 
-	public class FormItemLayout //extends ConstraintLayout
+	public class FormItemLayout extends ConstraintLayout
 	{
 		//--------------------------------------------------------------------------
 		//
@@ -62,7 +62,7 @@ package spark.layouts
 		 *  @private
 		 *  Only resize columns and rows if setLayoutColumnWidths hasn't been called.
 		 */
-		/*override public function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
+		override public function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
 		{
 			checkUseVirtualLayout();
 			
@@ -77,7 +77,7 @@ package spark.layouts
 				setColumnWidths(layoutColumnWidths);
 			
 			layoutContent(unscaledWidth, unscaledHeight);
-		}*/
+		}
 		
 		/**
 		 *  @private
@@ -85,7 +85,7 @@ package spark.layouts
 		 */
 		public function getMeasuredColumnWidths():Vector.<Number>
 		{
-			return null; //measureColumns();
+			return measureColumns();
 		}
 		
 		/**
@@ -98,7 +98,7 @@ package spark.layouts
 			// apply new measurements and position the columns again.
 			layoutColumnWidths = value;
 			
-			// setColumnWidths(layoutColumnWidths);
+			setColumnWidths(layoutColumnWidths);
 			
 			// target.invalidateDisplayList();
 		}
diff --git a/frameworks/projects/SparkRoyale/src/main/royale/spark/layouts/FormLayout.as b/frameworks/projects/SparkRoyale/src/main/royale/spark/layouts/FormLayout.as
index 5de74d7..5d6a474 100644
--- a/frameworks/projects/SparkRoyale/src/main/royale/spark/layouts/FormLayout.as
+++ b/frameworks/projects/SparkRoyale/src/main/royale/spark/layouts/FormLayout.as
@@ -369,7 +369,7 @@ package spark.layouts
 		 *  percent widths.
 		 */
 		private function constrainPercentColumnWidths(colWidths:Vector.<Number>, constrainedWidth:Number, formItems:Vector.<ILayoutElement>):void
-		{/*
+		{
 			if (formItems.length == 0)
 				return;
 			
@@ -378,7 +378,7 @@ package spark.layouts
 			const constraintColumns:Vector.<ConstraintColumn> = fiLayout.constraintColumns;
 			const numCols:int = constraintColumns.length;
 			var col:ConstraintColumn;
-			var childInfoArray:Array*/ /* of ColumnFlexChildInfo *//* = [];
+			var childInfoArray:Array /* of ColumnFlexChildInfo */ = [];
 			var childInfo:ColumnFlexChildInfo;
 			var remainingWidth:Number = constrainedWidth;
 			var percentMinWidths:Number = 0;
@@ -430,7 +430,7 @@ package spark.layouts
 					remainingWidth -= colWidth;
 				}
 				// TODO (klin): What do we do if there's remainingWidth after all this?
-			}*/
+			}
 		}
 	}
 }
diff --git a/frameworks/projects/SparkRoyale/src/main/royale/spark/skins/spark/FormItemSkin.mxml b/frameworks/projects/SparkRoyale/src/main/royale/spark/skins/spark/FormItemSkin.mxml
new file mode 100644
index 0000000..f562d6a
--- /dev/null
+++ b/frameworks/projects/SparkRoyale/src/main/royale/spark/skins/spark/FormItemSkin.mxml
@@ -0,0 +1,188 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+  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.
+
+-->
+
+<!--- The default skin class for the Spark FormItem component.  
+
+@see spark.components.FormItem
+
+@langversion 3.0
+@playerversion Flash 10
+@playerversion AIR 1.5
+@productversion Flex 4.5
+-->
+<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" 
+        xmlns:s="library://ns.apache.org/royale/spark" 
+        alpha.disabledStates=".5" creationComplete="init()">  
+    
+    <!-- host component -->
+    <fx:Metadata>
+        <![CDATA[ 
+        /** 
+        * @copy spark.skins.spark.ApplicationSkin#hostComponent
+        */
+        [HostComponent("spark.components.FormItem")]
+        ]]>
+    </fx:Metadata>
+    
+    <fx:Script>
+        <![CDATA[			
+			public function init():void {
+				requiredToolTip = resourceManager.getString("components","formItemRequired");
+			}
+			
+			private var _requiredToolTip:String;
+			/**
+			 *  The tooltip of the label showing when the component is required but nothing has been entered.
+			 *  Subclasses can set or override this property to customize the selected label.
+			 *  
+			 *  @langversion 3.0
+			 *  @playerversion AIR 3
+			 *  @productversion Flex 4.11
+			 */
+			[Bindable]
+			protected function get requiredToolTip():String 
+			{
+				return _requiredToolTip;
+			}
+			
+			protected function set requiredToolTip(value:String):void
+			{
+				_requiredToolTip = value;
+			}
+			
+            /**
+             *  @private
+             */
+            override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number) : void
+            {
+                // Push backgroundColor and backgroundAlpha directly.
+                // Handle undefined backgroundColor by hiding the background object.
+                if (isNaN(getStyle("backgroundColor")))
+                {
+                    background.visible = false;
+                }
+                else
+                {
+                    background.visible = true;
+                    bgFill.color = getStyle("backgroundColor");
+                    bgFill.alpha = getStyle("backgroundAlpha");
+                }
+                
+                var indicatorSource:Object;
+                if (currentState == "error" || currentState == "requiredAndError")
+                    indicatorSource = getStyle("errorIndicatorSource");
+                else if (currentState == "required" || "requiredAndDisabled")
+                    indicatorSource = getStyle("requiredIndicatorSource");
+                
+                if (indicatorSource && indicatorDisplay)
+                {
+                    indicatorDisplay.source = indicatorSource;
+                }
+                
+                super.updateDisplayList(unscaledWidth, unscaledHeight);
+            }
+            
+            /**
+             *  @private
+             */
+            override public function setCurrentState(stateName:String, playTransition:Boolean=true):void
+            {
+                super.setCurrentState(stateName, playTransition);
+                invalidateDisplayList();
+            }
+        ]]>        
+    </fx:Script>
+    
+    <s:states>
+        <s:State name="normal" />
+        <s:State name="disabled" stateGroups="disabledStates"/> 
+        <s:State name="error" stateGroups="errorStates"/>   
+        <s:State name="required" stateGroups="requiredStates"/> 
+        <s:State name="requiredAndDisabled" stateGroups="requiredStates, disabledStates"/>
+        <s:State name="requiredAndError" stateGroups="requiredStates, errorStates"/>    
+    </s:states>
+    
+    <s:layout>
+        <s:FormItemLayout>
+            <s:constraintColumns>
+                <!--- The column containing the sequence label. -->
+                <s:ConstraintColumn id="sequenceCol" />
+                <!--- The column containing the FormItem's label. -->
+                <s:ConstraintColumn id="labelCol" />
+                <!--- The column containing the FormItem's content. -->
+                <s:ConstraintColumn id="contentCol" width="100%"/>
+                <!--- The column containing the FormItem's help content. -->
+                <s:ConstraintColumn id="helpCol" maxWidth="200"/>
+            </s:constraintColumns>         
+            <s:constraintRows>
+                <!--- @private -->
+                <s:ConstraintRow id="row1" baseline="maxAscent:10" height="100%"/>
+            </s:constraintRows>  
+        </s:FormItemLayout>
+    </s:layout>
+            
+    <!--- Defines the appearance of the FormItem's background. -->
+    <s:Rect id="background" left="0" right="0" top="0" bottom="0">
+        <s:fill>
+            <!--- @private -->
+            <s:SolidColor id="bgFill" color="#FFFFFF"/>
+        </s:fill>
+    </s:Rect>
+    
+    <!--- @copy spark.components.FormItem#sequenceLabelDisplay -->
+    <s:Label id="sequenceLabelDisplay" 
+             fontWeight="bold"
+             left="sequenceCol:10" right="sequenceCol:5"
+             bottom="row1:10" baseline="row1:0"/>
+    <!--- @copy spark.components.FormItem#labelDisplay -->
+    <s:Label id="labelDisplay"
+             fontWeight="bold"
+             left="labelCol:0" right="labelCol:5" 
+             bottom="row1:10" baseline="row1:0"/>  
+    <!--- @copy spark.components.SkinnableContainer#contentGroup -->
+    <!-- Don't show the error tip on the content elements -->
+    <s:Group id="contentGroup" showErrorTip="false" showErrorSkin="true"
+             left="contentCol:0" right="contentCol:1" 
+             baseline="row1:0" bottom="row1:10">
+        <s:layout>
+            <s:VerticalLayout/>
+        </s:layout>
+    </s:Group>
+    <!-- Don't include the indicator in layout since we position it ourselves -->
+    <s:Group x="{contentGroup.x + contentGroup.contentWidth + 4}" y="{contentGroup.y}"
+             height="{Math.max(indicatorDisplay.height, contentGroup.contentHeight)}" includeInLayout="false">
+        <!--- @private -->
+        <s:Image id="indicatorDisplay" verticalCenter="0"
+                       toolTip="{requiredToolTip}" toolTip.errorStates=""
+                       includeIn="requiredStates,errorStates"/>
+    </s:Group>
+        
+    <!--- @copy spark.components.FormItem#helpContentGroup -->
+    <s:Group id="helpContentGroup" excludeFrom="errorStates"
+             fontStyle="italic" fontWeight="normal" color="0x666666"
+             left="helpCol:27" right="helpCol:10"
+             bottom="row1:10" baseline="row1:0"/>
+    <!--- @copy spark.components.FormItem#errorTextDisplay -->
+    <s:RichText id="errorTextDisplay" includeIn="errorStates"
+                fontStyle="italic" fontWeight="normal" color="0xFE0000"
+                left="helpCol:27" right="helpCol:10"
+                bottom="row1:10" baseline="row1:0" 
+                maxDisplayedLines="-1"/>    
+ </s:Skin>
\ No newline at end of file
diff --git a/frameworks/projects/SparkRoyale/src/main/royale/spark/skins/spark/FormSkin.mxml b/frameworks/projects/SparkRoyale/src/main/royale/spark/skins/spark/FormSkin.mxml
new file mode 100644
index 0000000..e5da8cb
--- /dev/null
+++ b/frameworks/projects/SparkRoyale/src/main/royale/spark/skins/spark/FormSkin.mxml
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+  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.
+
+-->
+
+<!--- The default skin class for a Spark Form container.  
+
+This skin defines a contentGroup for the Form container with a 
+FormLayout as its layout object. The FormLayout is a VerticalLayout
+that has additional logic to align the columns of FormItems.
+
+@see spark.components.Form
+@see spark.layouts.FormLayout
+
+@langversion 3.0
+@playerversion Flash 10
+@playerversion AIR 1.5
+@productversion Flex 4.5
+-->
+<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" 
+        xmlns:s="library://ns.apache.org/royale/spark" 
+        alpha.disabled="0.5">
+    
+    <fx:Metadata>
+        <![CDATA[ 
+        /** 
+        * @copy spark.skins.spark.ApplicationSkin#hostComponent
+        */
+        [HostComponent("spark.components.Form")]
+        ]]>
+    </fx:Metadata> 
+    <fx:Script >
+    
+        <![CDATA[         
+            /**
+             *  @private
+             */
+            override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number) : void
+            {
+                // Push backgroundColor and backgroundAlpha directly.
+                // Handle undefined backgroundColor by hiding the background object.
+                if (isNaN(getStyle("backgroundColor")))
+                {
+                    background.visible = false;
+                }
+                else
+                {
+                    background.visible = true;
+                    bgFill.color = getStyle("backgroundColor");
+                    bgFill.alpha = getStyle("backgroundAlpha");
+                }
+                
+                super.updateDisplayList(unscaledWidth, unscaledHeight);
+            }
+        ]]>        
+    </fx:Script>
+    
+    <s:states>
+        <s:State name="normal" />
+        <s:State name="error" />
+        <s:State name="disabled" />
+    </s:states>
+    
+    <!--- Defines the appearance of the Form class's background. -->
+    <s:Rect id="background" left="0" right="0" top="0" bottom="0">
+        <s:fill>
+            <!--- @private -->
+            <s:SolidColor id="bgFill" color="#FFFFFF"/>
+        </s:fill>
+    </s:Rect>
+    <!--- @copy spark.components.SkinnableContainer#contentGroup -->
+    <!-- We set Form's showErrorTip and showErrorSkin to false, so we set them back 
+         to true for the Form's elements -->
+    <s:Group id="contentGroup" showErrorSkin="true" showErrorTip="true" 
+             left="10" right="10" top="10" bottom="10">
+        <s:layout>
+            <s:FormLayout gap="7"/>
+        </s:layout>
+    </s:Group>
+    
+    
+</s:Skin>


[royale-asjs] 09/09: Merge branch 'develop' of https://github.com/apache/royale-asjs into develop

Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

aharui pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git

commit 045ae19f8bcd663146672e7056782c95aa0afd4a
Merge: 4136088 f50c999
Author: Alex Harui <ah...@apache.org>
AuthorDate: Sun Dec 22 22:12:16 2019 -0800

    Merge branch 'develop' of https://github.com/apache/royale-asjs into develop

 .../beads/CrossBrowserFireListenerOverrideBead.as  |   4 +-
 .../DynamicAddItemRendererForArrayListData.as      |  29 ++-
 ...DynamicRemoveAllItemRendererForArrayListData.as |   6 +
 .../DynamicRemoveItemRendererForArrayListData.as   |  16 +-
 .../DynamicUpdateItemRendererForArrayListData.as   |   6 +-
 .../org/apache/royale/core/ElementWrapper.as       |  43 +++--
 .../org/apache/royale/core/HTMLElementWrapper.as   | 196 +--------------------
 .../org/apache/royale/events/KeyboardEvent.as      |  12 +-
 .../royale/org/apache/royale/events/MouseEvent.as  |  12 +-
 .../royale/events/utils/KeyboardEventConverter.as  |   5 +
 .../royale/events/utils/MouseEventConverter.as     |   5 +
 .../src/main/royale/mx/core/Application.as         |   8 +-
 .../mx/events/utils/KeyboardEventConverter.as      |   5 +
 .../royale/mx/events/utils/MouseEventConverter.as  |   5 +
 .../main/royale/spark/components/Application.as    |   4 +-
 15 files changed, 120 insertions(+), 236 deletions(-)


[royale-asjs] 04/09: IMXMLObjects need to become IDocument

Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

aharui pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git

commit 317ed115afddaac430af2801887e5b318c51527f
Author: Alex Harui <ah...@apache.org>
AuthorDate: Sun Dec 22 22:05:45 2019 -0800

    IMXMLObjects need to become IDocument
---
 .../main/royale/mx/containers/utilityClasses/ConstraintColumn.as  | 8 +++++++-
 .../src/main/royale/mx/containers/utilityClasses/ConstraintRow.as | 6 ++++++
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/containers/utilityClasses/ConstraintColumn.as b/frameworks/projects/MXRoyale/src/main/royale/mx/containers/utilityClasses/ConstraintColumn.as
index 527b0af..0426665 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/containers/utilityClasses/ConstraintColumn.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/containers/utilityClasses/ConstraintColumn.as
@@ -19,6 +19,7 @@
 
 package mx.containers.utilityClasses
 {
+import org.apache.royale.core.IDocument;
 import org.apache.royale.events.Event;
 import org.apache.royale.events.EventDispatcher;
 
@@ -50,7 +51,7 @@ use namespace mx_internal;
  *  @playerversion AIR 1.1
  *  @productversion Flex 3
  */
-public class ConstraintColumn extends EventDispatcher //implements IMXMLObject
+public class ConstraintColumn extends EventDispatcher implements IDocument//implements IMXMLObject
 {
 	//--------------------------------------------------------------------------
 	//
@@ -438,6 +439,11 @@ public class ConstraintColumn extends EventDispatcher //implements IMXMLObject
 			contentSize = true;
     }
     
+    public function setDocument(document:Object, id:String = null):void
+    {
+        initialized(document, id);
+    }
+    
 	/**
 	 *  Sizes the constraint column.
 	 *
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/containers/utilityClasses/ConstraintRow.as b/frameworks/projects/MXRoyale/src/main/royale/mx/containers/utilityClasses/ConstraintRow.as
index 92ef5a3..d5d1a35 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/containers/utilityClasses/ConstraintRow.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/containers/utilityClasses/ConstraintRow.as
@@ -19,6 +19,7 @@
 
 package mx.containers.utilityClasses
 {	
+import org.apache.royale.core.IDocument;
 import org.apache.royale.events.Event;
 import org.apache.royale.events.EventDispatcher;
 
@@ -488,6 +489,11 @@ public class ConstraintRow extends EventDispatcher //implements IMXMLObject
 			contentSize = true;
     }
     
+    public function setDocument(document:Object, id:String = null):void
+    {
+        initialized(document, id);
+    }
+    
     /**
      *  Sizes the ConstraintRow
      *


[royale-asjs] 06/09: no default stroke

Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

aharui pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git

commit 8a5f51d7c16858a17310bf6dabe23ddeb21175c4
Author: Alex Harui <ah...@apache.org>
AuthorDate: Sun Dec 22 22:08:05 2019 -0800

    no default stroke
---
 .../src/main/royale/mx/display/Graphics.as         | 54 +++++++++++++---------
 1 file changed, 33 insertions(+), 21 deletions(-)

diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/display/Graphics.as b/frameworks/projects/MXRoyale/src/main/royale/mx/display/Graphics.as
index 7caee4f..842564e 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/display/Graphics.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/display/Graphics.as
@@ -181,7 +181,7 @@ package mx.display
 		{
 		} 
 		
-        private var thickness:Number = 0.5;
+        private var thickness:Number = NaN;
         private var color:uint = 0;
         private var alpha:Number = 1.0;
         
@@ -254,11 +254,14 @@ package mx.display
             {
                 var path:SVGElement = document.createElementNS("http://www.w3.org/2000/svg", "ellipse") as SVGElement;
                 var colorString:String = "RGB(" + (color >> 16) + "," + ((color & 0xff00) >> 8) + "," + (color & 0xff) + ")";
-                path.setAttribute("stroke", colorString);
-                var widthString:String = thickness.toString();
-                path.setAttribute("stroke-width", widthString);
-                if (alpha != 1)
-                    path.setAttribute("stroke-opacity", alpha.toString());
+                if (!isNaN(thickness))
+                {
+                    path.setAttribute("stroke", colorString);
+                    var widthString:String = thickness.toString();
+                    path.setAttribute("stroke-width", widthString);
+                    if (alpha != 1)
+                        path.setAttribute("stroke-opacity", alpha.toString());
+                }
                 colorString = "RGB(" + (fillColor >> 16) + "," + ((fillColor & 0xff00) >> 8) + "," + (fillColor & 0xff) + ")";
                 path.setAttribute("fill", colorString);
                 if (fillAlpha != 1)
@@ -285,11 +288,14 @@ package mx.display
             {
                 var path:SVGElement = document.createElementNS("http://www.w3.org/2000/svg", "rect") as SVGElement;
                 var colorString:String = "RGB(" + (color >> 16) + "," + ((color & 0xff00) >> 8) + "," + (color & 0xff) + ")";
-                path.setAttribute("stroke", colorString);
-                var widthString:String = thickness.toString();
-                path.setAttribute("stroke-width", widthString);
-                if (alpha != 1)
-                    path.setAttribute("stroke-opacity", alpha.toString());
+                if (!isNaN(thickness))
+                {
+                    path.setAttribute("stroke", colorString);
+                    var widthString:String = thickness.toString();
+                    path.setAttribute("stroke-width", widthString);
+                    if (alpha != 1)
+                        path.setAttribute("stroke-opacity", alpha.toString());
+                }
                 colorString = "RGB(" + (fillColor >> 16) + "," + ((fillColor & 0xff00) >> 8) + "," + (fillColor & 0xff) + ")";
                 path.setAttribute("fill", colorString);
                 if (fillAlpha != 1)
@@ -321,11 +327,14 @@ package mx.display
             {
                 var path:SVGElement = document.createElementNS("http://www.w3.org/2000/svg", "rect") as SVGElement;
                 var colorString:String = "RGB(" + (color >> 16) + "," + ((color & 0xff00) >> 8) + "," + (color & 0xff) + ")";
-                path.setAttribute("stroke", colorString);
-                var widthString:String = thickness.toString();
-                path.setAttribute("stroke-width", widthString);
-                if (alpha != 1)
-                    path.setAttribute("stroke-opacity", alpha.toString());
+                if (!isNaN(thickness))
+                {
+                    path.setAttribute("stroke", colorString);
+                    var widthString:String = thickness.toString();
+                    path.setAttribute("stroke-width", widthString);
+                    if (alpha != 1)
+                        path.setAttribute("stroke-opacity", alpha.toString());
+                }
                 colorString = "RGB(" + (fillColor >> 16) + "," + ((fillColor & 0xff00) >> 8) + "," + (fillColor & 0xff) + ")";
                 path.setAttribute("fill", colorString);
                 if (fillAlpha != 1)
@@ -352,11 +361,14 @@ package mx.display
             {
                 var path:SVGElement = document.createElementNS("http://www.w3.org/2000/svg", "circle") as SVGElement;
                 var colorString:String = "RGB(" + (color >> 16) + "," + ((color & 0xff00) >> 8) + "," + (color & 0xff) + ")";
-                path.setAttribute("stroke", colorString);
-                var widthString:String = thickness.toString();
-                path.setAttribute("stroke-width", widthString);
-                if (alpha != 1)
-                    path.setAttribute("stroke-opacity", alpha.toString());
+                if (!isNaN(thickness))
+                {
+                    path.setAttribute("stroke", colorString);
+                    var widthString:String = thickness.toString();
+                    path.setAttribute("stroke-width", widthString);
+                    if (alpha != 1)
+                        path.setAttribute("stroke-opacity", alpha.toString());
+                }
                 colorString = "RGB(" + (fillColor >> 16) + "," + ((fillColor & 0xff00) >> 8) + "," + (fillColor & 0xff) + ")";
                 path.setAttribute("fill", colorString);
                 if (fillAlpha != 1)


[royale-asjs] 05/09: try setting measuredWidth/Height to 0 if constrained by both left/right. I think Flex would have skipped measuring. This helped Spark Form/FormItem layout correctly

Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

aharui pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git

commit cf84133cc507bdeae243770ee76614a8e86e2ab1
Author: Alex Harui <ah...@apache.org>
AuthorDate: Sun Dec 22 22:07:21 2019 -0800

    try setting measuredWidth/Height to 0 if constrained by both left/right.  I think Flex would have skipped measuring.  This helped Spark Form/FormItem layout correctly
---
 frameworks/projects/MXRoyale/src/main/royale/mx/core/UIComponent.as | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/core/UIComponent.as b/frameworks/projects/MXRoyale/src/main/royale/mx/core/UIComponent.as
index d5242bc..75c84dc 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/core/UIComponent.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/core/UIComponent.as
@@ -2201,7 +2201,7 @@ COMPILE::JS
                 if (oldWidth.length)
                     this.positioner.style.width = "";
                 if (oldLeft.length && oldRight.length) // if both are set, this also dictates width
-                    this.positioner.style.left = "";
+                    return 0; // this.positioner.style.left = "";
                 var mw:Number = this.positioner.offsetWidth;
                 if (mw == 0 && numChildren > 0)
                 {
@@ -2276,7 +2276,7 @@ COMPILE::JS
                 if (oldHeight.length)
                     this.positioner.style.height = "";
                 if (oldTop.length && oldBottom.length) // if both are set, this also dictates height
-                    this.positioner.style.top = "";
+                    return 0; //this.positioner.style.top = "";
                 var mh:Number = this.positioner.offsetHeight;
                 if (mh == 0 && numChildren > 0)
                 {


[royale-asjs] 08/09: Merge branch 'SparkForm' into develop

Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

aharui pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git

commit 4136088668ab1b7e859985fc3fd1f3438f8a72b5
Merge: 4236a95 fff234a
Author: Alex Harui <ah...@apache.org>
AuthorDate: Sun Dec 22 22:11:31 2019 -0800

    Merge branch 'SparkForm' into develop

 .../org/apache/royale/html/beads/ContainerView.as  |   28 +-
 .../MXRoyale/src/main/resources/defaults.css       |    1 +
 .../MXRoyale/src/main/royale/MXRoyaleClasses.as    |    3 +
 .../royale/mx/containers/errors/ConstraintError.as |   58 +
 .../containers/utilityClasses/ConstraintColumn.as  |   14 +-
 .../mx/containers/utilityClasses/ConstraintRow.as  |   12 +-
 .../MXRoyale/src/main/royale/mx/controls/Button.as |   11 -
 .../src/main/royale/mx/core/ILayoutElement.as      |    5 +-
 .../src/main/royale/mx/core/UIComponent.as         |  109 +-
 .../src/main/royale/mx/display/Graphics.as         |   54 +-
 .../SparkRoyale/src/main/resources/defaults.css    |   14 +-
 .../src/main/resources/spark-royale-manifest.xml   |    4 +
 .../src/main/royale/SparkRoyaleClasses.as          |    5 +
 .../src/main/royale/spark/components/Form.as       |    2 +
 .../src/main/royale/spark/components/FormItem.as   |    7 +
 .../src/main/royale/spark/components/Label.as      |   11 +-
 .../royale/spark/components/SkinnableContainer.as  |   23 +-
 .../royale/spark/components/beads/GroupView.as     |    3 +
 .../components/beads/SkinnableContainerView.as     |   51 +-
 .../beads/{GroupView.as => SparkContainerView.as}  |   36 +-
 .../components/beads/SparkSkinScrollingViewport.as |  174 ++
 .../spark/components/supportClasses/ButtonBase.as  |    9 -
 .../supportClasses/SkinnableComponent.as           |  118 +-
 .../supportClasses/SkinnableContainerBase.as       |    4 +-
 .../components/supportClasses/SkinnableTextBase.as |   16 +-
 .../spark/components/supportClasses/TextBase.as    |   13 +-
 .../main/royale/spark/layouts/ConstraintLayout.as  | 1987 ++++++++++++++++++++
 .../main/royale/spark/layouts/FormItemLayout.as    |   10 +-
 .../src/main/royale/spark/layouts/FormLayout.as    |   17 +-
 .../royale/spark/skins/spark/FormItemSkin.mxml     |  188 ++
 .../main/royale/spark/skins/spark/FormSkin.mxml    |   97 +
 31 files changed, 2937 insertions(+), 147 deletions(-)

diff --cc frameworks/projects/MXRoyale/src/main/royale/MXRoyaleClasses.as
index 26635dd,77e4881..25cca50
--- a/frameworks/projects/MXRoyale/src/main/royale/MXRoyaleClasses.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/MXRoyaleClasses.as
@@@ -57,7 -57,9 +57,10 @@@ internal class MXRoyaleClasse
  	import mx.containers.beads.CanvasLayout; CanvasLayout;
      import mx.containers.beads.layouts.BasicLayout; BasicLayout;
  	import mx.controls.beads.AlertView; AlertView;
 +    import mx.controls.beads.controllers.AlertMouseController; AlertMouseController;
+     import mx.containers.errors.ConstraintError; ConstraintError;
+     import mx.containers.utilityClasses.ConstraintColumn; ConstraintColumn;
+     import mx.containers.utilityClasses.ConstraintRow; ConstraintRow;
  	import mx.containers.gridClasses.GridColumnInfo; GridColumnInfo;
  	import mx.containers.gridClasses.GridRowInfo; GridRowInfo;
  	import mx.events.CloseEvent; CloseEvent;


[royale-asjs] 02/09: more attempts to use Form Skins

Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

aharui pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git

commit a612f3c57beb4a3564d31c1666c6e337978c592a
Author: Alex Harui <ah...@apache.org>
AuthorDate: Mon Dec 16 01:10:43 2019 -0800

    more attempts to use Form Skins
---
 .../SparkRoyale/src/main/resources/defaults.css    |  2 ++
 .../src/main/royale/spark/components/Form.as       |  2 ++
 .../src/main/royale/spark/components/FormItem.as   |  2 ++
 .../royale/spark/components/SkinnableContainer.as  |  4 ++--
 .../components/beads/SkinnableContainerView.as     |  6 ++++--
 .../components/beads/SparkSkinScrollingViewport.as |  8 ++++++-
 .../supportClasses/SkinnableContainerBase.as       |  4 ++--
 .../main/royale/spark/layouts/ConstraintLayout.as  | 25 +++++++++++-----------
 .../src/main/royale/spark/layouts/FormLayout.as    |  2 +-
 9 files changed, 35 insertions(+), 20 deletions(-)

diff --git a/frameworks/projects/SparkRoyale/src/main/resources/defaults.css b/frameworks/projects/SparkRoyale/src/main/resources/defaults.css
index 48705da..263f982 100644
--- a/frameworks/projects/SparkRoyale/src/main/resources/defaults.css
+++ b/frameworks/projects/SparkRoyale/src/main/resources/defaults.css
@@ -120,11 +120,13 @@ DropDownList
 Form
 {
 	skinClass: ClassReference("spark.skins.spark.FormSkin");
+	IViewport: ClassReference("spark.components.beads.SparkSkinScrollingViewport");
 }
 
 FormItem
 {
 	skinClass: ClassReference("spark.skins.spark.FormItemSkin");
+	IViewport: ClassReference("spark.components.beads.SparkSkinScrollingViewport");
 }
 
 List
diff --git a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/Form.as b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/Form.as
index 9ddf272..0bd6a30 100644
--- a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/Form.as
+++ b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/Form.as
@@ -125,6 +125,8 @@ package spark.components
 		public function Form()
 		{
 			super();
+            typeNames += " Form";
+            
 			// addEventListener(FlexEvent.VALID, validHandler, true);
 			// addEventListener(FlexEvent.INVALID, invalidHandler, true);
 			
diff --git a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/FormItem.as b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/FormItem.as
index d5aa302..f29c132 100644
--- a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/FormItem.as
+++ b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/FormItem.as
@@ -129,6 +129,8 @@ package spark.components
 		public function FormItem()
 		{
 			super();
+            typeNames += " FormItem";
+            
 			// Set these here instead of in the CSS type selector for Form
 			// We want to hide the fact that the Form itself doesn't show
 			// the error skin or error tip, but that its children do. 
diff --git a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/SkinnableContainer.as b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/SkinnableContainer.as
index a7c8cad..f612a3a 100644
--- a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/SkinnableContainer.as
+++ b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/SkinnableContainer.as
@@ -27,13 +27,13 @@ import mx.core.IVisualElementContainer;
 import mx.events.FlexEvent;
 import mx.utils.BitFlagUtil;
 
-import spark.components.supportClasses.SkinnableContainerBase;
 import spark.events.ElementExistenceEvent;
 */
 import mx.core.IUIComponent;
 import mx.core.IVisualElement;
 import mx.core.mx_internal;
 
+import spark.components.supportClasses.SkinnableContainerBase;
 import spark.components.supportClasses.SkinnableComponent;
 import spark.components.supportClasses.GroupBase;
 import spark.components.beads.SkinnableContainerView;
@@ -366,7 +366,7 @@ include "../styles/metadata/SelectionFormatTextStyles.as"
  *  @playerversion AIR 1.5
  *  @productversion Royale 0.9.4
  */
-public class SkinnableContainer extends SkinnableComponent implements IContainer, IContainerBaseStrandChildrenHost
+public class SkinnableContainer extends SkinnableContainerBase implements IContainer, IContainerBaseStrandChildrenHost
 {// SkinnableContainerBase 
  //    implements IDeferredContentOwner, IVisualElementContainer
    // include "../core/Version.as";
diff --git a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/beads/SkinnableContainerView.as b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/beads/SkinnableContainerView.as
index ca63c80..7e4ece8 100644
--- a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/beads/SkinnableContainerView.as
+++ b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/beads/SkinnableContainerView.as
@@ -59,9 +59,11 @@ public class SkinnableContainerView extends SparkContainerView
     {
         var chost:IContainer = host as IContainer;
         var skinhost:SkinnableComponent = host as SkinnableComponent;
-        if (chost != null && chost != viewport.contentView) {
+        if (chost != null && chost != viewport.contentView && skinhost.skin) {
             chost.addElement(skinhost.skin);
-        }            
+        }
+        else
+            super.addViewport();
     }
 
 }
diff --git a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/beads/SparkSkinScrollingViewport.as b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/beads/SparkSkinScrollingViewport.as
index d2fa6cf..0f4843e 100644
--- a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/beads/SparkSkinScrollingViewport.as
+++ b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/beads/SparkSkinScrollingViewport.as
@@ -33,6 +33,7 @@ import org.apache.royale.core.IUIBase;
 import org.apache.royale.core.IViewport;
 import org.apache.royale.core.UIBase;
 import org.apache.royale.core.ValuesManager;
+import org.apache.royale.events.Event;
 import org.apache.royale.geom.Size;
 
 COMPILE::SWF
@@ -90,9 +91,14 @@ public class SparkSkinScrollingViewport implements IViewport
         
         var c:Class = ValuesManager.valuesImpl.getValue(value, "skinClass") as Class;
         host.setSkin(new c());
+        host.skin.addEventListener("initComplete", initCompleteHandler);
+        contentArea = host.skin; // temporary assigment so that SkinnableContainer.addElement can add the skin
         
+    }
+    
+    private function initCompleteHandler(event:Event):void
+    {
         contentArea = host.skin["contentGroup"];
-        
         COMPILE::JS
         {
             setScrollStyle();
diff --git a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/SkinnableContainerBase.as b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/SkinnableContainerBase.as
index 5f3aa8f..dfef503 100644
--- a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/SkinnableContainerBase.as
+++ b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/SkinnableContainerBase.as
@@ -34,7 +34,7 @@ import mx.managers.IFocusManagerContainer;
  *  @playerversion AIR 1.5
  *  @productversion Flex 4
  */
-[SkinState("normal")]
+//[SkinState("normal")]
 
 /**
  *  Disabled State
@@ -44,7 +44,7 @@ import mx.managers.IFocusManagerContainer;
  *  @playerversion AIR 1.5
  *  @productversion Flex 4
  */
-[SkinState("disabled")]
+//[SkinState("disabled")]
 
 //--------------------------------------
 //  Excluded APIs
diff --git a/frameworks/projects/SparkRoyale/src/main/royale/spark/layouts/ConstraintLayout.as b/frameworks/projects/SparkRoyale/src/main/royale/spark/layouts/ConstraintLayout.as
index 069c55f..07c6fbd 100644
--- a/frameworks/projects/SparkRoyale/src/main/royale/spark/layouts/ConstraintLayout.as
+++ b/frameworks/projects/SparkRoyale/src/main/royale/spark/layouts/ConstraintLayout.as
@@ -255,7 +255,8 @@ public class ConstraintLayout extends LayoutBase
     //  constraintColumns
     //----------------------------------
     
-    private var _constraintColumns:Vector.<ConstraintColumn> = new Vector.<ConstraintColumn>(0, true);
+    // MXML assignment of vector not working right now
+    private var _constraintColumns:Array = []; //Vector.<ConstraintColumn> = new Vector.<ConstraintColumn>(0, true);
     // An associative array of column id --> column index
     private var columnsObject:Object = {};
     
@@ -269,7 +270,7 @@ public class ConstraintLayout extends LayoutBase
      *  @playerversion AIR 1.5
      *  @productversion Flex 4.5
      */
-    public function get constraintColumns():Vector.<ConstraintColumn>
+    public function get constraintColumns():Array //Vector.<ConstraintColumn>
     {
         // make defensive copy
         return _constraintColumns.slice();
@@ -278,19 +279,19 @@ public class ConstraintLayout extends LayoutBase
     /**
      *  @private
      */
-    public function set constraintColumns(value:Vector.<ConstraintColumn>):void
+    public function set constraintColumns(value:Array /*Vector.<ConstraintColumn>*/):void
     {   
         // clear constraintColumns
         if (value == null)
         {
-            _constraintColumns = new Vector.<ConstraintColumn>(0, true);
+            _constraintColumns = []; // new Vector.<ConstraintColumn>(0, true);
             columnsObject = {};
             return;
         }
         
         var n:int = value.length;
         var col:ConstraintColumn;
-        var temp:Vector.<ConstraintColumn> = value.slice();
+        var temp:Array /*Vector.<ConstraintColumn>*/ = value.slice();
         var obj:Object = {};
         
         for (var i:int = 0; i < n; i++)
@@ -314,7 +315,7 @@ public class ConstraintLayout extends LayoutBase
     //  constraintRows
     //----------------------------------
     
-    private var _constraintRows:Vector.<ConstraintRow> = new Vector.<ConstraintRow>(0, true);
+    private var _constraintRows:Array = [] // Vector.<ConstraintRow> = new Vector.<ConstraintRow>(0, true);
     // An associative array of row id --> row index
     private var rowsObject:Object = {};
     
@@ -328,7 +329,7 @@ public class ConstraintLayout extends LayoutBase
      *  @playerversion AIR 1.5
      *  @productversion Flex 4.5
      */
-    public function get constraintRows():Vector.<ConstraintRow> 
+    public function get constraintRows():Array //Vector.<ConstraintRow> 
     {
         return _constraintRows.slice();
     }
@@ -336,19 +337,19 @@ public class ConstraintLayout extends LayoutBase
     /**
      *  @private
      */
-    public function set constraintRows(value:Vector.<ConstraintRow>):void
+    public function set constraintRows(value:Array /*Vector.<ConstraintRow>*/):void
     {
         // clear constraintRows
         if (value == null)
         {
-            _constraintRows = new Vector.<ConstraintRow>(0, true);
+            _constraintRows = []; //new Vector.<ConstraintRow>(0, true);
             rowsObject = {};
             return;
         }
         
         var n:int = value.length;
         var row:ConstraintRow;
-        var temp:Vector.<ConstraintRow> = value.slice();
+        var temp:Array /*Vector.<ConstraintRow>*/ = value.slice();
         var obj:Object = {};
         rowBaselines = new Vector.<Array>();
         
@@ -616,7 +617,7 @@ public class ConstraintLayout extends LayoutBase
         if (value == null)
             return;
         
-        var constraintColumns:Vector.<ConstraintColumn> = this._constraintColumns;
+        var constraintColumns:Array /*Vector.<ConstraintColumn>*/ = this._constraintColumns;
         var numCols:int = constraintColumns.length;
         var totalWidth:Number = 0;
         
@@ -637,7 +638,7 @@ public class ConstraintLayout extends LayoutBase
         if (value == null)
             return;
         
-        var constraintRows:Vector.<ConstraintRow> = this._constraintRows;
+        var constraintRows:Array /*Vector.<ConstraintRow>*/ = this._constraintRows;
         var numRows:int = constraintRows.length;
         var totalHeight:Number = 0;
         
diff --git a/frameworks/projects/SparkRoyale/src/main/royale/spark/layouts/FormLayout.as b/frameworks/projects/SparkRoyale/src/main/royale/spark/layouts/FormLayout.as
index 5d6a474..d94d0c6 100644
--- a/frameworks/projects/SparkRoyale/src/main/royale/spark/layouts/FormLayout.as
+++ b/frameworks/projects/SparkRoyale/src/main/royale/spark/layouts/FormLayout.as
@@ -375,7 +375,7 @@ package spark.layouts
 			
 			// TODO (klin): What happens when the form items have different types of columns?
 			const fiLayout:FormItemLayout = getElementLayout(formItems[0]) as FormItemLayout;
-			const constraintColumns:Vector.<ConstraintColumn> = fiLayout.constraintColumns;
+			const constraintColumns:Array /*Vector.<ConstraintColumn>*/ = fiLayout.constraintColumns;
 			const numCols:int = constraintColumns.length;
 			var col:ConstraintColumn;
 			var childInfoArray:Array /* of ColumnFlexChildInfo */ = [];


[royale-asjs] 07/09: need to force layouts down the tree from Form

Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

aharui pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git

commit fff234a0704cce23680467564f95385ea0f129b1
Author: Alex Harui <ah...@apache.org>
AuthorDate: Sun Dec 22 22:08:48 2019 -0800

    need to force layouts down the tree from Form
---
 .../royale/spark/components/supportClasses/SkinnableComponent.as | 7 +++++++
 .../SparkRoyale/src/main/royale/spark/layouts/FormLayout.as      | 9 ++++++++-
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/SkinnableComponent.as b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/SkinnableComponent.as
index e0c4153..5875441 100644
--- a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/SkinnableComponent.as
+++ b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/SkinnableComponent.as
@@ -142,8 +142,15 @@ public class SkinnableComponent extends UIComponent
      */
     public function SkinnableComponent()
     {
+        addEventListener("layoutNeeded", layoutSkinNeeded);
     }
 	
+    private function layoutSkinNeeded(event:Event):void
+    {
+        if (skin)
+            skin.dispatchEvent(new Event("layoutNeeded"));
+    }
+    
     //--------------------------------------------------------------------------
     //  Properties
     //--------------------------------------------------------------------------
diff --git a/frameworks/projects/SparkRoyale/src/main/royale/spark/layouts/FormLayout.as b/frameworks/projects/SparkRoyale/src/main/royale/spark/layouts/FormLayout.as
index d94d0c6..c91a04d 100644
--- a/frameworks/projects/SparkRoyale/src/main/royale/spark/layouts/FormLayout.as
+++ b/frameworks/projects/SparkRoyale/src/main/royale/spark/layouts/FormLayout.as
@@ -27,7 +27,9 @@ package spark.layouts
 	import spark.components.supportClasses.GroupBase;
 	import spark.components.supportClasses.SkinnableComponent;
 	import spark.layouts.supportClasses.LayoutBase;
-	
+
+    import org.apache.royale.events.Event;
+    
 	use namespace mx_internal;
 	
 	/**
@@ -294,6 +296,11 @@ package spark.layouts
 				// Recalculate contentWidth; contentHeight already includes padding.
 				var contentWidth:Number = calculateColumnWidthsSum(columnMaxWidths);
 				layoutTarget.setContentSize(contentWidth + hPadding, layoutTarget.contentHeight);
+                
+                for each (formItem in formItems)
+                {
+                    formItem.dispatchEvent(new Event("layoutNeeded"));
+                }
 			}
 		}