Transferred from the Adobe Open Source Subversion Repository

Revision: 18639
Author:   egeorgie@adobe.com
Date:     2010-11-17T01:20:40.860178Z

Log Message:
-----------
SkinnablePopUpContainer P-ARB changes

- Rename PopUpCloseEvent -> PopUpEvent
- Remove "disabledAndClosed", "disabledAndClosedAndLandscape" states
- Renamed SkinnablePopUpContainer's property from opened -> isOpen

Additionally:
- turn off modalTransparency and modalBlur in the mobileTheme

QE notes: SkinnablePopUpContainer is now code complete
Doc notes:
Bugs:
Reviewer: Jason & Jason
Tests run: manual, checkintests
Is noteworthy for integration: No

Modified Paths:
--------------
<path kind="file" copyfrom-path="/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/events/PopUpCloseEvent.as" copyfrom-rev="18594" action="A">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/events/PopUpEvent.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/framework/src/mx/core/UIComponent.as</path>
<path kind="file" action="D">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/events/PopUpCloseEvent.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/defaults.css</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobilecomponents/src/spark/components/ViewMenu.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobilecomponents/src/spark/components/supportClasses/MobileApplicationBase.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/SkinnablePopUpContainer.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/framework/src/mx/events/FlexEvent.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/ViewMenuSkin.mxml</path>

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1280737 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/spark/src/spark/components/SkinnablePopUpContainer.as
+++ frameworks/projects/spark/src/spark/components/SkinnablePopUpContainer.as
@@ -17,7 +17,7 @@
 import mx.events.FlexEvent;
 import mx.managers.PopUpManager;

-import spark.events.PopUpCloseEvent;
+import spark.events.PopUpEvent;

 //--------------------------------------
 //  Events
@@ -29,14 +29,14 @@
  *  This event is dispatched when the container switches from "closed" to "normal"
  *  state and the transition to that state completes.
  *
- *  @eventType mx.events.FlexEvent.OPEN
+ *  @eventType spark.events.PopUpEvent.OPEN
  *
  *  @langversion 3.0
  *  @playerversion Flash 10
  *  @playerversion AIR 2.5
  *  @productversion Flex 4.5
  */
-[Event(name="open", type="mx.events.FlexEvent")]
+[Event(name="open", type="spark.events.PopUpEvent")]

 /**
  *  Dispatched by the container when it's closed.
@@ -53,14 +53,14 @@
  *  it will dispatch this event.  Then, in the listener, the developer can check
  *  the commit parameter and perform the appropriate action.

  *
- *  @eventType mx.events.PopUpCloseEvent.CLOSE
+ *  @eventType spark.events.PopUpEvent.CLOSE
  *
  *  @langversion 3.0
  *  @playerversion Flash 10
  *  @playerversion AIR 2.5
  *  @productversion Flex 4.5
  */
-[Event(name="close", type="spark.events.PopUpCloseEvent")]
+[Event(name="close", type="spark.events.PopUpEvent")]

 //--------------------------------------
 //  States
@@ -77,18 +77,23 @@
 [SkinState("closed")]

 /**
- *  Disabled and Closed State
- *
- *  @langversion 3.0
- *  @playerversion Flash 10
- *  @playerversion AIR 2.5
- *  @productversion Flex 4.5
- */
-[SkinState("disabledAndClosed")]
-
-// FIXME (egeorgie): ASDoc comment
-/**
- *
+ *  The SkinnablePopUpContainer class is a SkinnableContainer that also acts as a pop-up.
+ *
+ *  The SkinnablePopUpContainer is initially in its "closed" state and when it's opened
+ *  it will add itself as a pop-up to the PopUpManager and transition to its "normal" state.
+ *
+ *
When using SkinnablePopUpContainer the pop-up is defined in mxml as
+ *  a SkinnablePopUpContainer component.  To show the component create an instance and
+ *  call the open() method. The developers are responsible for the sizing and positioning
+ *  of the component.  To close the component call the close()
+ *  method.  If the pop-up needs to pass data back to a handler, you can add a listener for
+ *  the PopUp.CLOSE event and specify the data in the close() method.

+ *
+ *  To define open and close animations, use a custom skin with transitions between the "closed"
+ *  and "normal" states.
+ *
+ *  @see spark.skins.spark.SkinnablePopUpContainerSkin
+ *
  *  @langversion 3.0
  *  @playerversion Flash 10
  *  @playerversion AIR 2.5
@@ -127,7 +132,7 @@
      *
      *  @private
      */
-    private var closeEvent:PopUpCloseEvent;
+    private var closeEvent:PopUpEvent;

     /**
      *  Track whether the container is added to the PopUpManager.
@@ -135,7 +140,7 @@
      *  @private
      */
     private var addedToPopUpManager:Boolean = false;
-
+
     //--------------------------------------------------------------------------
     //
     //  Properties
@@ -143,32 +148,32 @@
     //--------------------------------------------------------------------------

     //----------------------------------
-    //  opened
+    //  isOpen
     //----------------------------------

     /**
-     *  Storage for the opened property.
+     *  Storage for the isOpen property.
      *
      *  @private
      */
-    private var _opened:Boolean = false;
+    private var _isOpen:Boolean = false;

     [Inspectable(category="General", defaultValue="false")]
-
-    /**
-     *  True when the container is currently showing as a pop-up.
-     *
+
+    /**
+     *  True when the container is open and is currently showing as a pop-up.
+     *
      *  @see #open
-     *  @see #close
+     *  @see #close
      *
      *  @langversion 3.0
      *  @playerversion Flash 10
      *  @playerversion AIR 2.5
      *  @productversion Flex 4.5
      */
-    public function get opened():Boolean
-    {
-        return _opened;
+    public function get isOpen():Boolean
+    {
+        return _isOpen;
     }

     //--------------------------------------------------------------------------
@@ -182,6 +187,7 @@
      *  waits till any state transitions are finished playing and dispatches FlexEvent.OPEN event.
      *
      *  @param owner The owner of the container.
+     *
      *  @param modal Whether the container should be modal.
      *
      *  @see #close
@@ -191,9 +197,9 @@
      *  @playerversion AIR 2.5
      *  @productversion Flex 4.5
      */
-    public function open(owner:DisplayObjectContainer, modal:Boolean = true):void
-    {
-        if (_opened)
+    public function open(owner:DisplayObjectContainer, modal:Boolean = false):void
+    {
+        if (isOpen)
             return;

         closeEvent = null; // Clear any pending close event
@@ -214,19 +220,19 @@

         // Change state *after* we pop up, as the skin needs to go be in the initial "closed"
         // state while being created above in order for transitions to detect state change and play.
-        _opened = true;
+        _isOpen = true;
         invalidateSkinState();
         if (skin)
-            skin.addEventListener(FlexEvent.STATE_TRANSITION_COMPLETE, stateTransitionComplete_handler);
+            skin.addEventListener(FlexEvent.STATE_CHANGE_COMPLETE, stateChangeComplete_handler);
         else
-            stateTransitionComplete_handler(null); // Call directly
+            stateChangeComplete_handler(null); // Call directly
     }

     /**
      *  Changes the current state to "closed", waits till any state transitions are finished playing,
-     *  dispatches a PopUpClose.CLOSE event and removes the container from the PopUpManager.
-     *
-     *
The PopUpCloseEvent provides a mechanism to pass commit information from the container to
+     *  dispatches a PopUpEvent.CLOSE event and removes the container from the PopUpManager.
+     *
+     *
The PopUpEvent provides a mechanism to pass commit information from the container to
      *  a listener.  One typical usage scenario is building a multiple-choice dialog with a
      *  cancel button.  When a valid option is selected, the developer closes the dialog
      *  with a call to the SkinnablePopUpContainer.close() method, passing
@@ -235,8 +241,8 @@
      *  it will dispatch this event.  Then, in the listener, the developer can check
      *  the commit parameter and perform the appropriate actions.

      *
-     *  @param commit The value for the commit property of the PopUpClose event.
-     *  @param data The value for the data property for the PopUpClose event.
+     *  @param commit The value for the commit property of the PopUpEvent event.
+     *  @param data The value for the data property for the PopUpEvent event.
      *
      *  @see #open
      *
@@ -247,20 +253,20 @@
      */
     public function close(commit:Boolean = false, data:* = undefined):void
     {
-        if (!_opened)
+        if (!isOpen)
             return;

         // We will dispatch the event later, when the close transition is complete.
-        closeEvent = new PopUpCloseEvent(commit, data);
+        closeEvent = new PopUpEvent(PopUpEvent.CLOSE, false, false, commit, data);

         // Change state
-        _opened = false;
+        _isOpen = false;
         invalidateSkinState();

         if (skin)
-            skin.addEventListener(FlexEvent.STATE_TRANSITION_COMPLETE, stateTransitionComplete_handler);
+            skin.addEventListener(FlexEvent.STATE_CHANGE_COMPLETE, stateChangeComplete_handler);
         else
-            stateTransitionComplete_handler(null); // Call directly
+            stateChangeComplete_handler(null); // Call directly
     }

     //--------------------------------------------------------------------------
@@ -268,7 +274,7 @@
     //  Overridden Methods
     //
     //--------------------------------------------------------------------------
-
+
     /**
      *  @private
      */
@@ -278,14 +284,13 @@
         // "normal"
         // "disabled"
         // "closed"
-        // "disabledAndClosed"

         var state:String = super.getCurrentSkinState();
-        if (!opened)
-            return state == "normal" ? "closed" : state + "AndClosed";
+        if (!isOpen)
+            return state == "normal" ? "closed" : state;
         return state;
     }
-
+
     //--------------------------------------------------------------------------
     //
     //  Event handlers
@@ -297,15 +302,15 @@
      *
      *  Called when we have completed transitioning to opened/closed state.
      */
-    private function stateTransitionComplete_handler(event:Event):void
+    private function stateChangeComplete_handler(event:Event):void
     {
         // We get called directly with null if there's no skin to listen to.
         if (event)
-            event.target.removeEventListener(FlexEvent.STATE_TRANSITION_COMPLETE, stateTransitionComplete_handler);
+            event.target.removeEventListener(FlexEvent.STATE_CHANGE_COMPLETE, stateChangeComplete_handler);

-        if (opened)
+        if (isOpen)
         {
-            dispatchEvent(new FlexEvent(FlexEvent.OPEN));
+            dispatchEvent(new PopUpEvent(PopUpEvent.OPEN, false, false));
         }
         else
         {


link crypt with death duck

link crypt with death duck

--- src/com/merlinds/miracle_tool/models/vo/ElementVO.as
+++ src/com/merlinds/miracle_tool/models/vo/ElementVO.as
@@ -64,6 +64,7 @@
 				source = this.bitmapData.clone();
 			}
 			matrix.scale(scale, scale);
+			if(this.width < 1)this.width = 1;
 			this.bitmapData = new BitmapData(this.width, this.height, true, 0x0);
 			bitmapData.draw(source, matrix, null, null, null, true);
 			var selector:Bitmap = new Bitmap(new BitmapData(this.width, this.height, true, 0x3300FF00));


Transferred from the Adobe Open Source Subversion Repository

Revision: 12850
Author:   jimurphy@adobe.com
Date:     2009-12-11T14:57:14.623098Z

Log Message:
-----------
add 6 new DMV projects to the SDK:
automation
automation_air
automation_dmv
automation_flashflexkit
automation_spark
datavisualization

These projects are setup to build in an ant main call.  There are currently several warnings in the datavisualization project that will be cleaned up.  No checkintests exist for these projects as of yet.

I also modified the exisitng projects build files for easier management of the localization targets, bundle and fat-swc. If the projects that I updated:airframework,airspark,framework,playerglobal,rpc,and spark.  All the new projects have been implemented this same way.

QE notes: DMV folks should run through their tests
Doc notes: probably
Bugs: nope
Reviewer:
Tests run: ran the following targets: compile,checkintests,other.locales and doc
Is noteworthy for integration: no

Modified Paths:
--------------
1404 paths were modified

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1251446 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/automation/src/mx/automation/delegates/controls/MenuItemRendererAutomationImpl.as
+++ frameworks/projects/automation/src/mx/automation/delegates/controls/MenuItemRendererAutomationImpl.as
@@ -0,0 +1,121 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  ADOBE SYSTEMS INCORPORATED
+//  Copyright 2009 Adobe Systems Incorporated
+//  All Rights Reserved.
+//
+//  NOTICE: Adobe permits you to use, modify, and distribute this file
+//  in accordance with the terms of the license agreement accompanying it.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package mx.automation.delegates.controls
+{
+	import flash.display.DisplayObject;
+
+	import mx.automation.Automation;
+	import mx.automation.delegates.core.UIComponentAutomationImpl;
+	import mx.controls.menuClasses.MenuItemRenderer;
+	import mx.core.mx_internal;
+
+	use namespace mx_internal;
+
+	[Mixin]
+	/**
+	 *
+	 *  Defines methods and properties required to perform instrumentation for the
+	 *  MenuItemRenderer class.
+	 *
+	 *  @see mx.controls.menuClasses.MenuItemRenderer
+	 *
+	 *
+	 *  @langversion 3.0
+	 *  @playerversion Flash 9
+	 *  @playerversion AIR 1.1
+	 *  @productversion Flex 3
+	 */
+	public class MenuItemRendererAutomationImpl extends UIComponentAutomationImpl
+	{
+		include "../../../core/Version.as";
+
+		//--------------------------------------------------------------------------
+		//
+		//  Class methods
+		//
+		//--------------------------------------------------------------------------
+
+		/**
+		 *  Registers the delegate class for a component class with automation manager.
+		 *
+		 *  @param root The SystemManger of the application.
+		 *
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public static function init(root:DisplayObject):void
+		{
+			Automation.registerDelegateClass(MenuItemRenderer, MenuItemRendererAutomationImpl);
+		}
+
+		//--------------------------------------------------------------------------
+		//
+		//  Constructor
+		//
+		//--------------------------------------------------------------------------
+
+		/**
+		 *  Constructor.
+		 * @param obj MenuItemRenderer object to be automated.
+		 *
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function MenuItemRendererAutomationImpl(obj:MenuItemRenderer)
+		{
+			super(obj);
+		}
+
+		//----------------------------------
+		//  menuItemRenderer
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  storage for the owner component
+		 */
+		protected function get menuItemRenderer():MenuItemRenderer
+		{
+			return uiComponent as MenuItemRenderer;
+		}
+
+		//----------------------------------
+		//  automationName
+		//----------------------------------
+
+		/**
+		 *  @private
+		 */
+		override public function get automationName():String
+		{
+			return menuItemRenderer.getLabel().text || super.automationName;
+		}
+
+		//----------------------------------
+		//  automationValue
+		//----------------------------------
+
+		/**
+		 *  @private
+		 */
+		override public function get automationValue():Array
+		{
+			return [menuItemRenderer.getLabel().text];
+		}
+
+	}
+
+}


Now using callLater again for requesting columns.

--- WeaveData/src/weave/data/DataSources/AbstractDataSource.as
+++ WeaveData/src/weave/data/DataSources/AbstractDataSource.as
@@ -182,7 +182,6 @@
 		}

 		/**
-		 * requestHierarchyFromSource
 		 * This function must be implemented by classes by extend AbstractDataSource.
 		 * This function should make a request to the source to fill in the hierarchy at the given subtree.
 		 * This function will only be called once per subtreeNode.
@@ -191,7 +190,6 @@
 		/* abstract */ protected function requestHierarchyFromSource(subtreeNode:XML = null):void { }

 		/**
-		 * requestHierarchyFromSource
 		 * This function must be implemented by classes that extend AbstractDataSource.
 		 * This function should make a request to the source to fill in the proxy column.
 		 * @param columnReference An object that contains all the information required to request the column from this IDataSource.
@@ -200,7 +198,6 @@
 		/* abstract */ protected function requestColumnFromSource(columnReference:IColumnReference, proxyColumn:ProxyColumn):void { }

 		/**
-		 * url
 		 * The url of the data source.
 		 * This is included here because most IDataSource implementations will have a URL.
 		 * It is a special case to have an IDataSource without one.
@@ -209,7 +206,6 @@
 		public const url:LinkableString = newLinkableChild(this, LinkableString);

 		/**
-		 * getAttributeHierarchy
 		 * @return An AttributeHierarchy object that will be updated when new pieces of the hierarchy are filled in.
 		 */
 		public function get attributeHierarchy():IAttributeHierarchy
@@ -226,14 +222,12 @@
 		private var _pendingColumnRequests:Array = [];

 		/**
-		 * _requestedHierarchySubtreeStringMap
 		 * This maps a requested hierarchy subtree xml string to a value of true.
 		 * If a subtree node has not been requested yet, it will not appear in this Object.
 		 */
 		private var _requestedHierarchySubtreeStringMap:Object = new Object();

 		/**
-		 * initializeHierarchySubtree
 		 * If the hierarchy subtree pointed to subtreeNode
 		 * @param subtreeNode A pointer to a node in the hierarchy representing the root of the subtree to request from the source.
 		 */
@@ -303,7 +297,6 @@
 		}

 		/**
-		 * handlePendingColumnRequest
 		 * This function will call requestColumnFromSource() if the hierarchyPointer in the column is now valid.
 		 * Otherwise, it will call delayColumnRequest() again.
 		 * This function may be overridden by classes that extend AbstractDataSource.
@@ -319,8 +312,8 @@
 			{
 				debug('requestColumnFromSource', request.columnReference.getHashCode());

-				//StageUtils.callLater(this, requestColumnFromSource, [request.columnReference, request.proxyColumn]);
-				requestColumnFromSource(request.columnReference, request.proxyColumn);
+				WeaveAPI.StageUtils.callLater(this, requestColumnFromSource, [request.columnReference, request.proxyColumn]);
+				//requestColumnFromSource(request.columnReference, request.proxyColumn);
 			}
 			else
 			{
@@ -329,7 +322,6 @@
 		}

 		/**
-		 * delayColumnRequest
 		 * This will put an initialized proxy column into the list of pending requests.
 		 * It will also call initializeHierarchySubtree() for a subtree of the hierarchy, if a subtree is missing.
 		 * This function can be overridden to have different behavior, but this definition is recommended.
@@ -343,7 +335,6 @@
 		}

 		/**
-		 * handleAllPendingColumnRequests
 		 * This function will call handlePendingColumnRequest() on each pending column request.
 		 */
 		private function handleAllPendingColumnRequests():void
@@ -375,7 +366,6 @@
 		private const _proxyColumnToReferenceMap:Dictionary = new Dictionary(false);

 		/**
-		 * dispose
 		 * This function should be called when the IDataSource is no longer in use.
 		 * All existing pointers to objects should be set to null so they can be garbage collected.
 		 */


Improved the debug-mode logging a bit.

Improved the debug-mode logging a bit.

git-svn-id: a1a4b28b82a3276cc491891159dd9963a0a72fae@4384 542714f4-19e9-0310-aa3c-eee0fc999fb1

--- src/as/com/threerings/io/ObjectInputStream.as
+++ src/as/com/threerings/io/ObjectInputStream.as
@@ -66,13 +66,13 @@
                     "Created mapping: (" + code + "): " + cname);

             } else {
-                if (DEBUG) log.debug(
-                    DEBUG_ID + "Read known code: (" + code + ")");
                 cmap = (_classMap[code] as ClassMapping);
                 if (null == cmap) {
                     throw new IOError("Read object for which we have no " +
-                        "registered class metadata.");
+                        "registered class metadata [code=" + code + "].");
                 }
+                if (DEBUG) log.debug(DEBUG_ID + "Read known code: (" +
+                    code + ": " + cmap.classname + ")");
             }

 //            log.debug("Creating object sleeve...");


Transferred from the Adobe Open Source Subversion Repository

Revision: 17943
Author:   jszeto@adobe.com
Date:     2010-09-29T22:22:15.975011Z

Log Message:
-----------
ViewMenu initial checkin

Implemented ViewMenu, ViewMenuItem, ViewMenuLayout and all relevant skins.
Integrated into MobileApplicationBase and MobileApplication
Includes PARB review changes
Appearance will change once the visual design has been completed

QE notes: Ready to test!
Doc notes: Needs an ASDoc pass
Bugs: none
Reviewer: Glenn
Tests run: checkintests
Is noteworthy for integration: no

Modified Paths:
--------------
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobilecomponents/manifest.xml</path>
<path kind="file" action="A">/private/flex/sdk/branches/hero_private/frameworks/projects/mobilecomponents/src/spark/layouts/ViewMenuLayout.as</path>
<path kind="dir" action="A">/private/flex/sdk/branches/hero_private/frameworks/projects/mobilecomponents/src/spark/layouts</path>
<path kind="file" action="A">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/ViewMenuItemSkin.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobilecomponents/src/spark/components/View.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobilecomponents/src/spark/components/MobileApplication.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/defaults.css</path>
<path kind="file" action="A">/private/flex/sdk/branches/hero_private/frameworks/projects/mobilecomponents/src/spark/components/ViewMenuItem.as</path>
<path kind="file" action="A">/private/flex/sdk/branches/hero_private/frameworks/projects/mobilecomponents/src/spark/components/ViewMenu.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobilecomponents/src/spark/components/supportClasses/MobileApplicationBase.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/MobileThemeClasses.as</path>
<path kind="file" action="A">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/ViewMenuSkin.mxml</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/MobileApplicationSkin.as</path>

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1264215 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/mobilecomponents/src/spark/components/ViewMenuItem.as
+++ frameworks/projects/mobilecomponents/src/spark/components/ViewMenuItem.as
@@ -0,0 +1,92 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  ADOBE SYSTEMS INCORPORATED
+//  Copyright 2010 Adobe Systems Incorporated
+//  All Rights Reserved.
+//
+//  NOTICE: Adobe permits you to use, modify, and distribute this file
+//  in accordance with the terms of the license agreement accompanying it.
+//
+////////////////////////////////////////////////////////////////////////////////
+package spark.components
+{
+
+import flash.events.Event;
+import flash.events.MouseEvent;
+
+import spark.components.supportClasses.ButtonBase;
+
+/**
+ *  Caret State of the Button
+ */
+[SkinState("showsCaret")]
+
+/**
+ *  Displays a label and icon inside of an ViewMenu. Typically, you should
+ *  listen for the itemClick event to perform some operation based on clicking
+ *  this item.
+ */
+public class ViewMenuItem extends ButtonBase
+{
+    //--------------------------------------------------------------------------
+    //
+    //  Constructor
+    //
+    //--------------------------------------------------------------------------
+    /**
+     *  Constructor
+     */
+    public function ViewMenuItem()
+    {
+        super();
+    }
+
+    //----------------------------------
+    //  showsCaret
+    //----------------------------------
+
+    /**
+     *  @private
+     *  Storage for the showsCaret property
+     */
+    private var _showsCaret:Boolean = false;
+
+    /**
+     *  True if the ViewMenuItem is in the caret state.
+     *
+     *  @default false
+     */
+    public function get showsCaret():Boolean
+    {
+        return _showsCaret;
+    }
+
+    /**
+     *  @private
+     */
+    public function set showsCaret(value:Boolean):void
+    {
+        if (value == _showsCaret)
+            return;
+
+        _showsCaret = value;
+        invalidateSkinState();
+        invalidateDisplayList();
+    }
+
+    /**
+     *  @private
+     */
+    override protected function getCurrentSkinState():String
+    {
+        var skinState:String = super.getCurrentSkinState();
+
+        // showsCaret has lower priority than disabled and down states
+        if (showsCaret && enabled && skinState != "down")
+            return "showsCaret";
+
+        return skinState;
+    }
+
+}
+}


Transferred from the Adobe Open Source Subversion Repository

Revision: 23017
Author:   jasonsj@adobe.com
Date:     2011-10-15T00:41:19.242956Z

Log Message:
-----------
Restore start values on pop-up after soft keyboard is deactivated due to pop-up closing or orientation change. Fix logic for capturing start values before blocking external changes to start values. Simplify soft keyboard effect state tracking.

QE notes: None
Doc notes: None
Bugs:
SDK-31842 SPUC SK Effects [iOS] [Android] : SPUC does not resize on landscape
Reviewer: tkraikit
Tests run: checkintests, cyclone SK effects w/ Lavayna
Is noteworthy for integration: No

Modified Paths:
--------------
<path kind="file" action="M">/private/flex/sdk/branches/4.y/frameworks/projects/spark/src/spark/components/SkinnablePopUpContainer.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/4.y/frameworks/projects/mobilecomponents/src/spark/components/Callout.as</path>

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1280755 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/spark/src/spark/components/SkinnablePopUpContainer.as
+++ frameworks/projects/spark/src/spark/components/SkinnablePopUpContainer.as
@@ -20,7 +20,6 @@
 import flash.events.SoftKeyboardTrigger;
 import flash.events.TimerEvent;
 import flash.geom.Rectangle;
-import flash.system.Capabilities;
 import flash.utils.Timer;

 import mx.core.EventPriority;
@@ -31,6 +30,7 @@
 import mx.effects.Parallel;
 import mx.events.EffectEvent;
 import mx.events.FlexEvent;
+import mx.events.ResizeEvent;
 import mx.events.SandboxMouseEvent;
 import mx.managers.PopUpManager;
 import mx.managers.SystemManager;
@@ -51,16 +51,16 @@

 /**
  *  Dispatched by the container when it's opened and ready for user interaction.
- *
- *
This event is dispatched when the container switches from the
- *  closed to normal skin state and the transition
+ *
+ *
This event is dispatched when the container switches from the
+ *  closed to normal skin state and the transition
  *  to that state completes.

  *
  *
Note: As of Flex 4.6, SkinnablePopUp container inherits its styles
  *  from the stage and not its owner.

- *
+ *
  *  @eventType spark.events.PopUpEvent.OPEN
- *
+ *
  *  @langversion 3.0
  *  @playerversion Flash 10
  *  @playerversion AIR 2.5
@@ -70,26 +70,26 @@

 /**
  *  Dispatched by the container when it's closed.
- *
- *
This event is dispatched when the container switches from the
- *  normal to closed skin state and
+ *
+ *
This event is dispatched when the container switches from the
+ *  normal to closed skin state and
  *  the transition to that state completes.

- *
- *
The event provides a mechanism to pass commit information from
- *  the container to an event listener.
- *  One typical usage scenario is building a multiple-choice dialog with a
- *  cancel button.
- *  When a valid option is selected, you close the pop up
+ *
+ *
The event provides a mechanism to pass commit information from
+ *  the container to an event listener.
+ *  One typical usage scenario is building a multiple-choice dialog with a
+ *  cancel button.
+ *  When a valid option is selected, you close the pop up
  *  with a call to the close() method, passing
  *  true to the commit parameter and optionally passing in
- *  any relevant data.
+ *  any relevant data.
  *  When the SkinnablePopUpContainer has completed closing,
- *  it dispatches this event.
- *  Then, in the event listener, you can check the commit
+ *  it dispatches this event.
+ *  Then, in the event listener, you can check the commit
  *  property and perform the appropriate action.

  *
  *  @eventType spark.events.PopUpEvent.CLOSE
- *
+ *
  *  @langversion 3.0
  *  @playerversion Flash 10
  *  @playerversion AIR 2.5
@@ -103,14 +103,14 @@

 /**
  *  Duration of the soft keyboard move and resize effect in milliseconds.
- *
+ *
  *  @default 150
- *
+ *
  *  @langversion 3.0
  *  @playerversion Flash 11
  *  @playerversion AIR 3.1
  *  @productversion Flex 4.6
- */
+ */
 [Style(name="softKeyboardEffectDuration", type="Number", format="Time", inherit="no", minValue="0.0")]

 //--------------------------------------
@@ -119,7 +119,7 @@

 /**
  *  The closed state.
- *
+ *
  *  @langversion 3.0
  *  @playerversion Flash 10
  *  @playerversion AIR 2.5
@@ -129,30 +129,30 @@

 /**
  *  The SkinnablePopUpContainer class is a SkinnableContainer that functions as a pop-up.
- *  One typical use for a SkinnablePopUpContainer container is to open a simple window
+ *  One typical use for a SkinnablePopUpContainer container is to open a simple window
  *  in an application, such as an alert window, to indicate that the user must perform some action.
  *
- *
You do not create a SkinnablePopUpContainer container as part of the normal layout
- *  of its parent container.
- *  Instead, it appears as a pop-up window on top of its parent.
+ *
You do not create a SkinnablePopUpContainer container as part of the normal layout
+ *  of its parent container.
+ *  Instead, it appears as a pop-up window on top of its parent.
  *  Therefore, you do not create it directly in the MXML code of your application.

  *
- *
Instead, you create is as an MXML component, often in a separate MXML file.
+ *
Instead, you create is as an MXML component, often in a separate MXML file.
  *  To show the component create an instance of the MXML component, and
- *  then call the open() method.
- *  You can also set the size and position of the component when you open it.

- *
- *
To close the component, call the close() method.
- *  If the pop-up needs to return data to a handler, you can add an event listener for
- *  the PopUp.CLOSE event, and specify the returned data in
+ *  then call the open() method.
+ *  You can also set the size and position of the component when you open it.

+ *
+ *
To close the component, call the close() method.
+ *  If the pop-up needs to return data to a handler, you can add an event listener for
+ *  the PopUp.CLOSE event, and specify the returned data in
  *  the close() method.

  *
- *
The SkinnablePopUpContainer is initially in its closed skin state.
- *  When it opens, it adds itself as a pop-up to the PopUpManager,
+ *
The SkinnablePopUpContainer is initially in its closed skin state.
+ *  When it opens, it adds itself as a pop-up to the PopUpManager,
  *  and transition to the normal skin state.
- *  To define open and close animations, use a custom skin with transitions between
+ *  To define open and close animations, use a custom skin with transitions between
  *  the closed and normal skin states.

- *
+ *
  *
The SkinnablePopUpContainer container has the following default characteristics:

  *

  *
Characteristic	Description

@@ -162,11 +162,11 @@
  *
Default skin class	spark.skins.spark.SkinnablePopUpContainerSkin

  *

  *
- *  @mxml
The <s:SkinnablePopUpContainer> tag inherits all of the tag
+ *  @mxml
The <s:SkinnablePopUpContainer> tag inherits all of the tag
  *  attributes of its superclass and adds the following tag attributes:

  *
  *

- *  <s:SkinnablePopUpContainer
+ *  <s:SkinnablePopUpContainer
  *    Events
  *    close="No default"
  *    open="No default"
@@ -187,10 +187,10 @@
     //  Constructor
     //
     //--------------------------------------------------------------------------
-
-    /**
-     *  Constructor.
-     *
+
+    /**
+     *  Constructor.
+     *
      *  @langversion 3.0
      *  @playerversion Flash 10
      *  @playerversion AIR 2.5
@@ -200,7 +200,7 @@
     {
         super();
     }
-
+
     //--------------------------------------------------------------------------
     //
     //  Variables
@@ -208,122 +208,114 @@
     //--------------------------------------------------------------------------

     /**
-     *  Storage for the close event while waiting for the close transition to
+     *  Storage for the close event while waiting for the close transition to
      *  complete before dispatching it.
-     *
-     *  @private
-     */
+     *
+     *  @private
+     */
     private var closeEvent:PopUpEvent;
-
+
     /**
      *  Track whether the container is added to the PopUpManager.
-     *
-     *  @private
-     */
+     *
+     *  @private
+     */
     private var addedToPopUpManager:Boolean = false;

-    /**
-     *  @private
-     *  Soft keyboard effect.
-     */
-    private var effect:IEffect;
-
-    /**
-     *  @private
-     *  Track keyboard height to avoid unnecessary transitions.
-     */
-    private var cachedKeyboardHeight:Number;
-
+    //--------------------------------------------------------------------------
+    //
+    //  Soft Keyboard Effect Variables
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     *  The current soft keyboard effect instance. This field is only set in
+     *  cases where the position and size are not snapped during (a) initial
+     *  activation and (b) deactivation.
+     */
+    private var softKeyboardEffect:IEffect;
+
     /**
      *  @private
      *  Original pop-up y-position.
      */
-    private var cachedYPosition:Number;
-
-    /**
-     *  @private
-     *  Indicates the soft keyboard deactivate event was received but the
-     *  deactivate effect is delayed.
-     */
-    private var deactivateEffectIsPending:Boolean = false;
-
+    private var softKeyboardEffectCachedYPosition:Number;
+
+    /**
+     *  @private
+     *  Indicates a soft keyboard event was received but the effect is delayed
+     *  while waiting for a mouseDown and mouseUp event sequence.
+     */
+    private var softKeyboardEffectPendingEventType:String = null;
+
     /**
      *  @private
      *  Number of milliseconds to wait for a mouseDown and mouseUp event
      *  sequence before playing the deactivate effect.
      */
-    mx_internal var deactivateEffectDelay:Number = 100;
-
-    /**
-     *  @private
-     */
-    private var deactivateTimer:Timer;
-
-    /**
-     *  @private
-     */
-    private var orientationChanging:Boolean = false;
-
-    /**
-     *  @private
-     *  Flag for iOS specific handling of orientation change.
-     */
-    private var isIOS:Boolean = false;
-
+    mx_internal var softKeyboardEffectPendingEffectDelay:Number = 100;
+
+    /**
+     *  @private
+     *  Timer used for awaiting a mouseDown event after a pending soft keyboard
+     *  effect.
+     */
+    private var softKeyboardEffectPendingEventTimer:Timer;
+
+    /**
+     *  @private
+     *  Flag when orientationChanging is dispatched and orientationChange has
+     *  not been received.
+     */
+    private var softKeyboardEffectOrientationChanging:Boolean = false;
+
     /**
      *  @private
      *  Flag when orientation change handlers are installed to suppress
      *  excess soft keyboard effects during orientation change on iOS.
      */
-    private var orientationHandlerAdded:Boolean = false;
-
-    /**
-     *  @private
-     *  Flag when mouse listeners are installed to delay the soft keyboard
-     *  deactivate effect.
-     */
-    private var deactiveTriggersAdded:Boolean = false;
-
-    /**
-     *  @private
-     *  Flag when explicitHeight is set when the soft keyboard effect is
-     *  active. When true, we prevent the original cached height from being
-     *  modified.
-     */
-    private var softKeyboardEffectCachedHeightExplicit:Boolean = false;
-
-    /**
-     *  @private
-     *  Flag when explicitHeightChanged listeners are installed after
+    private var softKeyboardEffectOrientationHandlerAdded:Boolean = false;
+
+    /**
+     *  @private
+     *  Flag when mouse and orientation listeners are installed before
      *  the soft keyboard activate effect is played.
      */
-    private var activeListenersInstalled:Boolean;
+    private var softKeyboardStateChangeListenersInstalled:Boolean;
+
+    /**
+     *  @private
+     *  Flag when resize listers are installed after ACTIVATE and uninstalled
+     *  just before DEACTIVATE.
+     */
+    private var resizeListenerInstalled:Boolean = false;

     //--------------------------------------------------------------------------
     //
     //  Properties
     //
     //--------------------------------------------------------------------------
-
+
     //----------------------------------
     //  isOpen
     //----------------------------------
-
+
     /**
      *  Storage for the isOpen property.
      *
      *  @private
      */
     private var _isOpen:Boolean = false;
-
+
     [Inspectable(category="General", defaultValue="false")]

     /**
-     *  Contains true when the container is open and is currently showing as a pop-up.
+     *  Contains true when the container is open and is currently showing as a pop-up.
      *
      *  @see #open
-     *  @see #close
-     *
+     *  @see #close
+     *
      *  @langversion 3.0
      *  @playerversion Flash 10
      *  @playerversion AIR 2.5
@@ -333,12 +325,12 @@
     {
         return _isOpen;
     }
-
+
     /**
      *  Updates the isOpen flag to be reflected in the skin state
      *  without actually popping up the container through the PopUpManager.
-     *
-     *  @private
+     *
+     *  @private
      */
     mx_internal function setIsOpen(value:Boolean):void
     {
@@ -346,19 +338,19 @@
         _isOpen = value;
         invalidateSkinState();
     }
-
+
     //----------------------------------
     //  resizeForSoftKeyboard
     //----------------------------------
-
+
     private var _resizeForSoftKeyboard:Boolean = true;
-
-    /**
-     *  Enables resizing the pop-up when the soft keyboard
-     *  on a mobile device is active.
-     *
+
+    /**
+     *  Enables resizing the pop-up when the soft keyboard
+     *  on a mobile device is active.
+     *
      *  @default true
-     *
+     *
      *  @langversion 3.0
      *  @playerversion AIR 3
      *  @productversion Flex 4.6
@@ -367,7 +359,7 @@
     {
         return _resizeForSoftKeyboard;
     }
-
+
     /**
      *  @private
      */
@@ -375,22 +367,22 @@
     {
         if (_resizeForSoftKeyboard == value)
             return;
-
+
         _resizeForSoftKeyboard = value;
     }
-
+
     //----------------------------------
     //  moveForSoftKeyboard
     //----------------------------------
-
+
     private var _moveForSoftKeyboard:Boolean = true;
-
-    /**
-     *  Enables moving the pop-up when the soft keyboard
-     *  on a mobile device is active.
-     *
+
+    /**
+     *  Enables moving the pop-up when the soft keyboard
+     *  on a mobile device is active.
+     *
      *  @default true
-     *
+     *
      *  @langversion 3.0
      *  @playerversion AIR 3
      *  @productversion Flex 4.6
@@ -399,7 +391,7 @@
     {
         return _moveForSoftKeyboard;
     }
-
+
     /**
      *  @private
      */
@@ -407,7 +399,7 @@
     {
         if (_moveForSoftKeyboard == value)
             return;
-
+
         _moveForSoftKeyboard = value;
     }

@@ -416,14 +408,14 @@
     //  Methods
     //
     //--------------------------------------------------------------------------
-
-    /**
-     *  Opens the container as a pop-up, and switches the skin state from
+
+    /**
+     *  Opens the container as a pop-up, and switches the skin state from
      *  closed to normal.
-     *  After and transitions finish playing, it dispatches  the
+     *  After and transitions finish playing, it dispatches  the
      *  FlexEvent.OPEN event.
      *
-     *  @param owner The owner of the container.
+     *  @param owner The owner of the container.
      *  The popup appears over this component. The owner must not be descendant
      *  of this container.
      *
@@ -431,8 +423,8 @@
      *  A modal container takes all keyboard and mouse input until it is closed.
      *  A nonmodal container allows other components to accept input while the pop-up window is open.
      *
-     *  @see #close
-     *
+     *  @see #close
+     *
      *  @langversion 3.0
      *  @playerversion Flash 10
      *  @playerversion AIR 2.5
@@ -441,11 +433,11 @@
     public function open(owner:DisplayObjectContainer, modal:Boolean = false):void
     {
         if (isOpen)
-            return;
-
+            return;
+
         closeEvent = null; // Clear any pending close event
         this.owner = owner;
-
+
         // We track whether we've been added to the PopUpManager to handle the
         // scenario of state transition interrupton. For example we may be playing
         // a close transition and be interrupted with a call to open() in which
@@ -457,12 +449,12 @@

             // This will create the skin and attach it
             PopUpManager.addPopUp(this, owner, modal);
-
+
             updatePopUpPosition();
         }
-
+
         // Change state *after* we pop up, as the skin needs to go be in the initial "closed"
-        // state while being created above in order for transitions to detect state change and play.
+        // state while being created above in order for transitions to detect state change and play.
         _isOpen = true;
         invalidateSkinState();
         if (skin)
@@ -470,17 +462,17 @@
         else
             stateChangeComplete_handler(null); // Call directly
     }
-
+
     /**
      *  Positions the pop-up after the pop-up is added to PopUpManager but
      *  before any state transitions occur. The base implementation of open()
      *  calls updatePopUpPosition() immediately after the pop-up is added.
-     *
+     *
      *  This method may also be called at any time to update the pop-up's
      *  position. Pop-ups that are positioned relative to their owner should
      *  call this method after position or size changes occur on the owner or
      *  it's ancestors.
-     *
+     *
      *  @langversion 3.0
      *  @playerversion AIR 3
      *  @productversion Flex 4.6
@@ -490,34 +482,34 @@
         // subclasses will implement custom positioning
         // e.g. PopUpManager.centerPopUp()
     }
-
-    /**
-     *  Changes the current skin state to closed, waits until any state transitions
-     *  finish playing, dispatches a PopUpEvent.CLOSE event,
+
+    /**
+     *  Changes the current skin state to closed, waits until any state transitions
+     *  finish playing, dispatches a PopUpEvent.CLOSE event,
      *  and then removes the container from the PopUpManager.
      *
-     *
Use the close() method of the SkinnablePopUpContainer container
-     *  to pass data back to the main application from the pop up.
-     *  One typical usage scenario is building a dialog with a cancel button.
+     *
Use the close() method of the SkinnablePopUpContainer container
+     *  to pass data back to the main application from the pop up.
+     *  One typical usage scenario is building a dialog with a cancel button.
      *  When a valid option is selected in the dialog box, you close the dialog
      *  with a call to the close() method, passing
-     *  true to the commit parameter and optionally passing
-     *  any relevant data.
+     *  true to the commit parameter and optionally passing
+     *  any relevant data.
      *  When the SkinnablePopUpContainer has completed closing,
-     *  it dispatch the close event.
+     *  it dispatch the close event.
      *  In the event listener for the close event, you can check
      *  the commit parameter and perform the appropriate actions.

      *
-     *  @param commit Specifies if the return data should be committed by the application.
-     *  The value of this argument is written to the commit property of
+     *  @param commit Specifies if the return data should be committed by the application.
+     *  The value of this argument is written to the commit property of
      *  the PopUpEvent event object.
-     *
-     *  @param data Specifies any data returned to the application.
-     *  The value of this argument is written to the data property of
+     *
+     *  @param data Specifies any data returned to the application.
+     *  The value of this argument is written to the data property of
      *  the PopUpEvent event object.
      *
      *  @see #open
-     *
+     *
      *  @langversion 3.0
      *  @playerversion Flash 10
      *  @playerversion AIR 2.5
@@ -527,7 +519,7 @@
     {
         if (!isOpen)
             return;
-
+
         // We will dispatch the event later, when the close transition is complete.
         closeEvent = new PopUpEvent(PopUpEvent.CLOSE, false, false, commit, data);

@@ -540,22 +532,22 @@
         else
             stateChangeComplete_handler(null); // Call directly
     }
-
-    /**
-     *  Called by the soft keyboard activate and deactive event handlers,
+
+    /**
+     *  Called by the soft keyboard activate and deactive event handlers,
      *  this method is responsible for creating the Spark effect played on the pop-up.
-     *
+     *
      *  This method may be overridden by subclasses. By default, it
      *  creates a parellel move and resize effect on the pop-up.
      *
      *  @param yTo The new y-coordinate of the pop-up.
      *
      *  @param height The new height of the pop-up.
-     *
+     *
      *  @return An IEffect instance serving as the move and/or resize transition
      *  for the pop-up. This effect is played after the soft keyboard is
      *  activated or deactivated.
-     *
+     *
      *  @langversion 3.0
      *  @playerversion AIR 3
      *  @productversion Flex 4.6
@@ -565,7 +557,7 @@
         var move:Move;
         var resize:Resize;
         var easer:IEaser = new Power(0, 5);
-
+
         if (yTo != this.y)
         {
             move = new Move();
@@ -574,7 +566,7 @@
             move.disableLayout = true;
             move.easer = easer;
         }
-
+
         if (heightTo != this.height)
         {
             resize = new Resize();
@@ -583,56 +575,107 @@
             resize.disableLayout = true;
             resize.easer = easer;
         }
-
+
         if (move && resize)
         {
             var parallel:Parallel = new Parallel();
             parallel.addChild(move);
             parallel.addChild(resize);
-
+
             return parallel;
         }
         else if (move || resize)
         {
             return (move) ? move : resize;
         }
-
+
         return null;
     }
-
+
     //--------------------------------------------------------------------------
     //
     //  mx_internal properties
     //
     //--------------------------------------------------------------------------

+    //----------------------------------------
+    //  softKeyboardEffectCachedExplicitHeight
+    //----------------------------------------
+
+    /**
+     *  @private
+     */
+    private var _softKeyboardEffectExplicitHeightFlag:Boolean = false;
+
+    /**
+     *  @private
+     *  Flag when explicitHeight is set when the soft keyboard effect is
+     *  active. Use this to distinguish explicitHeight changes due to the
+     *  resizeForSoftKeyboard setting. When true, we prevent the original
+     *  cached height from being modified.
+     */
+    mx_internal function get softKeyboardEffectExplicitHeightFlag():Boolean
+    {
+        return _softKeyboardEffectExplicitHeightFlag;
+    }
+
+    private function setSoftKeyboardEffectExplicitHeightFlag(value:Boolean):void
+    {
+        _softKeyboardEffectExplicitHeightFlag = value;
+    }
+
+    //----------------------------------------
+    //  softKeyboardEffectCachedExplicitWidth
+    //----------------------------------------
+
+    /**
+     *  @private
+     */
+    private var _softKeyboardEffectExplicitWidthFlag:Boolean = false;
+
+    /**
+     *  @private
+     *  Flag when explicitWidth is set when the soft keyboard effect is
+     *  active. Use this to distinguish explicitWidth changes due to the
+     *  resizeForSoftKeyboard setting.
+     */
+    mx_internal function get softKeyboardEffectExplicitWidthFlag():Boolean
+    {
+        return _softKeyboardEffectExplicitWidthFlag;
+    }
+
+    private function setSoftKeyboardEffectExplicitWidthFlag(value:Boolean):void
+    {
+        _softKeyboardEffectExplicitWidthFlag = value;
+    }
+
     //----------------------------------
     //  softKeyboardEffectCachedHeight
     //----------------------------------
-
+
     private var _softKeyboardEffectCachedHeight:Number;
-
-    /**
-     *  @private
-     *  The original pop-up height to restore to when the soft keyboard is
+
+    /**
+     *  @private
+     *  The original pop-up height to restore to when the soft keyboard is
      *  deactivated. If an explicitHeight was defined at activation, use it.
      *  If not, then use explicitMaxHeight or measuredHeight.
      */
     mx_internal function get softKeyboardEffectCachedHeight():Number
     {
         var heightTo:Number = _softKeyboardEffectCachedHeight;
-
-        if (!softKeyboardEffectCachedHeightExplicit)
+
+        if (!softKeyboardEffectExplicitHeightFlag)
         {
             if (!isNaN(explicitMaxHeight) && (measuredHeight > explicitMaxHeight))
                 heightTo = explicitMaxHeight;
             else
                 heightTo = measuredHeight;
         }
-
+
         return heightTo;
     }
-
+
     /**
      *  @private
      */
@@ -640,16 +683,16 @@
     {
         // Only allow changes to the cached height if it was not set explicitly
         // prior to and/or during the soft keyboard effect.
-        if (!softKeyboardEffectCachedHeightExplicit)
+        if (!softKeyboardEffectExplicitHeightFlag)
             _softKeyboardEffectCachedHeight = value;
     }
-
+
     //----------------------------------
     //  isSoftKeyboardEffectActive
     //----------------------------------
-
+
     private var _isSoftKeyboardEffectActive:Boolean;
-
+
     /**
      *  @private
      *  Returns true if the soft keyboard is active and the pop-up is moved
@@ -659,23 +702,23 @@
     {
         return _isSoftKeyboardEffectActive;
     }
-
+
     //----------------------------------
     //  marginTop
     //----------------------------------
-
+
     private var _marginTop:Number = 0;
-
-    /**
-     *  @private
-     *  Defines a margin at the top of the screen where the pop-up cannot be
+
+    /**
+     *  @private
+     *  Defines a margin at the top of the screen where the pop-up cannot be
      *  resized or moved to.
      */
     mx_internal function get softKeyboardEffectMarginTop():Number
     {
         return _marginTop;
     }
-
+
     /**
      *  @private
      */
@@ -683,23 +726,23 @@
     {
         _marginTop = value;
     }
-
+
     //----------------------------------
     //  marginBottom
     //----------------------------------
-
+
     private var _marginBottom:Number = 0;
-
-    /**
-     *  @private
-     *  Defines a margin at the bottom of the screen where the pop-up cannot be
+
+    /**
+     *  @private
+     *  Defines a margin at the bottom of the screen where the pop-up cannot be
      *  resized or moved to.
      */
     mx_internal function get softKeyboardEffectMarginBottom():Number
     {
         return _marginBottom;
     }
-
+
     /**
      *  @private
      */
@@ -707,13 +750,13 @@
     {
         _marginBottom = value;
     }
-
+
     //----------------------------------
     //  isMouseDown
     //----------------------------------
-
+
     private var _isMouseDown:Boolean = false;
-
+
     /**
      *  @private
      */
@@ -721,19 +764,18 @@
     {
         return _isMouseDown;
     }
-
+
     /**
      *  @private
      */
     private function set isMouseDown(value:Boolean):void
     {
         _isMouseDown = value;
-
-        // Play the deactivate effect on the first mouseUp after a deactivate
-        if (deactivateEffectIsPending)
-            playDeactivateEffect(true);
-    }
-
+
+        // Attempt to play a pending effect
+        playPendingEffect(true);
+    }
+
     //--------------------------------------------------------------------------
     //
     //  Overridden Methods
@@ -746,15 +788,15 @@
      */
     override mx_internal function initProtoChain():void
     {
-        // Maintain backwards compatibility of popup style inheritance
+        // Maintain backwards compatibility of popup style inheritance
         if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_6)
             super.initProtoChain();
         else
             StyleProtoChain.initProtoChain(this, false);
     }
-
-    /**
-     *  @private
+
+    /**
+     *  @private
      */
     override protected function getCurrentSkinState():String
     {
@@ -768,49 +810,42 @@
             return state == "normal" ? "closed" : state;
         return state;
     }
-
-    /**
-     *  @private
-     */
-    override public function initialize():void
-    {
-        super.initialize();
+
+    //--------------------------------------------------------------------------
+    //
+    //  Event handlers
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     *  Play the soft keyboard effect.
+     */
+    private function startEffect(event:Event):void
+    {
+        removeEventListener(Event.ENTER_FRAME, startEffect);
+
+        // Abort the effect if the pop-up is closed or closing. The state
+        // transition handler will restore the original size of the pop-up.
+        if (!isOpen || !softKeyboardEffect)
+            return;
+
+        // Clear the cached positions when the deactivate effect is complete.
+        softKeyboardEffect.addEventListener(EffectEvent.EFFECT_END, softKeyboardEffectCleanup);
+        softKeyboardEffect.addEventListener(EffectEvent.EFFECT_STOP, softKeyboardEffectCleanup);

-        // Determine if we are running on an iOS device
-        isIOS = Capabilities.version.indexOf("IOS") == 0;
-    }
-
-    //--------------------------------------------------------------------------
-    //
-    //  Event handlers
-    //
-    //--------------------------------------------------------------------------
-
-    /**
-     *  @private
-     *  Play the soft keyboard effect.
-     */
-    private function startEffect(event:Event):void
-    {
-        removeEventListener(Event.ENTER_FRAME, startEffect);
-
-        // Abort the deactivate effect if the pop-up is closed or closing.
-        // The close transition state change handler will restore the original
-        // size of the pop-up.
-        if (!isOpen || !effect)
-            return;
-
-        // Clear the cached positions when the deactivate effect is complete.
-        effect.addEventListener(EffectEvent.EFFECT_END, effectCleanup);
-        effect.addEventListener(EffectEvent.EFFECT_STOP, effectCleanup);
-
+        // Install mouse delay and orientation change listeners now.
+        // explicitHeight listener is installed after the effect completes.
+        if (isSoftKeyboardEffectActive)
+            installSoftKeyboardStateChangeListeners();
+
         // Force the master clock of the animation engine to update its
-        // current time so that the overhead of creating the effect is not
+        // current time so that the overhead of creating the effect is not
         // included in our animation interpolation. See SDK-27793
         Animation.pulse();
-        effect.play();
-    }
-
+        softKeyboardEffect.play();
+    }
+
     /**
      *  @private
      *
@@ -821,32 +856,28 @@
         // We get called directly with null if there's no skin to listen to.
         if (event)
             event.target.removeEventListener(FlexEvent.STATE_CHANGE_COMPLETE, stateChangeComplete_handler);
-
+
         // Check for soft keyboard support
         var topLevelApp:Application = FlexGlobals.topLevelApplication as Application;
         var softKeyboardEffectEnabled:Boolean = (topLevelApp && Application.softKeyboardBehavior == "none");
         var smStage:Stage = systemManager.stage;
-
+
         if (isOpen)
         {
             dispatchEvent(new PopUpEvent(PopUpEvent.OPEN, false, false));
-
+
             if (softKeyboardEffectEnabled)
             {
-                // Reset state
-                _isSoftKeyboardEffectActive = false;
-
                 if (smStage)
                 {
                     // Install soft keyboard event handling on the stage
-                    smStage.addEventListener(SoftKeyboardEvent.SOFT_KEYBOARD_ACTIVATE,
-                        softKeyboardActivateHandler, true, EventPriority.DEFAULT, true);
-                    smStage.addEventListener(SoftKeyboardEvent.SOFT_KEYBOARD_DEACTIVATE,
-                        softKeyboardDeactivateHandler, true, EventPriority.DEFAULT, true);
-
-                    // move and resize immediately if the soft keyboard is active
-                    if (smStage.softKeyboardRect.height > 0)
-                        softKeyboardActivateHandler();
+                    smStage.addEventListener(SoftKeyboardEvent.SOFT_KEYBOARD_ACTIVATE,
+                        stage_softKeyboardActivateHandler, true, EventPriority.DEFAULT, true);
+                    smStage.addEventListener(SoftKeyboardEvent.SOFT_KEYBOARD_DEACTIVATE,
+                        stage_softKeyboardDeactivateHandler, true, EventPriority.DEFAULT, true);
+                    systemManager.addEventListener(Event.RESIZE, systemManagerResizeHandler);
+
+                    updateSoftKeyboardEffect(true);
                 }
             }
         }
@@ -855,223 +886,105 @@
             // Dispatch the close event before removing from the PopUpManager.
             dispatchEvent(closeEvent);
             closeEvent = null;
-
+
             if (softKeyboardEffectEnabled && smStage)
             {
                 // Uninstall soft keyboard event handling
-                smStage.removeEventListener(SoftKeyboardEvent.SOFT_KEYBOARD_ACTIVATE,
-                    softKeyboardActivateHandler, true);
-                smStage.removeEventListener(SoftKeyboardEvent.SOFT_KEYBOARD_DEACTIVATE,
-                    softKeyboardDeactivateHandler, true);
+                smStage.removeEventListener(SoftKeyboardEvent.SOFT_KEYBOARD_ACTIVATE,
+                    stage_softKeyboardActivateHandler, true);
+                smStage.removeEventListener(SoftKeyboardEvent.SOFT_KEYBOARD_DEACTIVATE,
+                    stage_softKeyboardDeactivateHandler, true);
+                systemManager.removeEventListener(Event.RESIZE, systemManagerResizeHandler);
             }

             // We just finished closing, remove from the PopUpManager.
             PopUpManager.removePopUp(this);
             addedToPopUpManager = false;
             owner = null;
+
+            // Position and size may be invalid if the close transition
+            // completes before (a) deactivate is fired or (b) a pending
+            // soft keyboard change is still queued. Update immediately.
+            updateSoftKeyboardEffect(true);
+        }
+    }
+
+    /**
+     *  @private
+     */
+    private function stage_softKeyboardActivateHandler(event:SoftKeyboardEvent=null):void
+    {
+        var isFirstActivate:Boolean = false;
+
+        // Reset state
+        softKeyboardEffectPendingEventType = null;
+
+        // Save the original y-position and height if this is the first
+        // ACTIVATE event and an existing effect is not already in progress.
+        if (!isSoftKeyboardEffectActive && !softKeyboardEffect)
+            isFirstActivate = true;
+
+        if (isFirstActivate)
+        {
+            // Play the activate effect with animation
+            updateSoftKeyboardEffect(false);
+        }
+        else
+        {
+            // Keyboard height has changed. However, the effect can be delayed if
+            // a mouseUp within the pop-up is pending. An additional activate can
+            // occur while the keyboard is open to reflect size changes due to auto
+            // correction or orientation changes.

-            // Reset size and position if a deactivate effect was aborted while
-            // the close transition was playing. This allows the pop-up to open
-            // again later without any side effects from the aborted deactivate
-            // effect. See SDK-31534.
-            if (!isNaN(cachedYPosition))
-                this.y = cachedYPosition;
+            // As in the deactivate case, the move and resize effects should be
+            // delayed until the user can complete any mouse interaction. This
+            // allows the size and position of the pop-up to stay stable allowing
+            // events like a button press to complete normally.

-            // If explicit height wasn't used originally, then set height=NaN
-            // so that the next call to open() will re-measure.
-            if (softKeyboardEffectCachedHeightExplicit)
-                this.height = softKeyboardEffectCachedHeight;
+            if (isMouseDown)
+                setPendingSoftKeyboardEvent(event);
             else
-                this.height = NaN;
-
-            if (!isNaN(cachedYPosition) || softKeyboardEffectCachedHeightExplicit)
-                effectCleanup();
-        }
-    }
-
-    /**
-     *  @private
-     */
-    private function softKeyboardActivateHandler(event:SoftKeyboardEvent=null):void
-    {
-        var isFirstActivate:Boolean = false;
-
-        // Save the original y-position and height if this is the first
-        // ACTIVATE event and an existing deactivate effect is not already in
-        // progress.
-        if (!isSoftKeyboardEffectActive && !effect)
-        {
-            cachedYPosition = this.y;
-            setSoftKeyboardEffectCachedHeight(this.height);
-
-            // Initialize softKeyboardEffectCachedHeightExplicit
-            explicitHeightChangedHandler();
-
-            // reset cached keyboard height
-            cachedKeyboardHeight = 0;
-
-            isFirstActivate = true;
-        }
-
-        var smStage:Stage = systemManager.stage;
-        var softKeyboardRect:Rectangle = smStage.softKeyboardRect;
-
-        // Do not update if the keyboard has no height or if the height
-        // is unchanged
-        if ((softKeyboardRect.height == 0) ||
-            (cachedKeyboardHeight == softKeyboardRect.height))
-            return;
-
-        cachedKeyboardHeight = softKeyboardRect.height;
-
-        var sandboxRoot:DisplayObject = systemManager.getSandboxRoot();
-        var scaleFactor:Number = 1;
-
-        if (systemManager as SystemManager)
-            scaleFactor = SystemManager(systemManager).densityScale;
-
-        // All calculations are done in stage coordinates and converted back to
-        // application coordinates when playing effects. Also note that
-        // softKeyboardRect is also in stage coordinates.
-        var popUpY:Number = this.y * scaleFactor;
-        var popUpHeight:Number = softKeyboardEffectCachedHeight * scaleFactor;
-        var overlapGlobal:Number = (popUpY + popUpHeight) - softKeyboardRect.y;
-
-        var yToGlobal:Number = popUpY;
-        var heightToGlobal:Number = popUpHeight;
-
-        if (overlapGlobal > 0)
-        {
-            // shift y-position up to remove offset overlap
-            if (moveForSoftKeyboard)
-                yToGlobal = Math.max((softKeyboardEffectMarginTop * scaleFactor), (popUpY - overlapGlobal));
-
-            // adjust height based on new y-position
-            if (resizeForSoftKeyboard)
-            {
-                // compute new overlap
-                overlapGlobal = (yToGlobal + popUpHeight) - softKeyboardRect.y;
-
-                // adjust height if there is overlap
-                if (overlapGlobal > 0)
-                    heightToGlobal = popUpHeight - overlapGlobal - (softKeyboardEffectMarginBottom * scaleFactor);
-            }
-        }
-
-        // only play the effect if y-position or height changes
-        if ((yToGlobal != popUpY) ||
-            (heightToGlobal != popUpHeight))
-        {
-            // update state
-            _isSoftKeyboardEffectActive = true;
-
-            // convert to application coordinates, move to pixel boundaries
-            var yToLocal:Number = Math.floor(yToGlobal / scaleFactor);
-            var heightToLocal:Number = Math.floor(heightToGlobal / scaleFactor);
-
-            // preserve minimum height
-            heightToLocal = Math.max(heightToLocal, getMinBoundsHeight());
-
-            if (!deactiveTriggersAdded)
-            {
-                // Listen for mouseDown event on the pop-up and delay the soft
-                // keyboard deactivate effect. This allows button click events
-                // to complete normally before the button is re-positioned.
-                // See SDK-31534.
-                addEventListener(MouseEvent.MOUSE_DOWN, mouseHandler);
-
-                // Listen for mouseUp events anywhere to play the deactivate effect.
-                // See SDK-31534.
-                sandboxRoot.addEventListener(MouseEvent.MOUSE_UP,
-                    mouseHandler, true /* useCapture */);
-                sandboxRoot.addEventListener(SandboxMouseEvent.MOUSE_UP_SOMEWHERE,
-                    systemManager_mouseUpHandler);
-
-                deactiveTriggersAdded = true;
-            }
-
-            // Listen for orientationChanging and orientationChange to suspend
-            // soft keyboard effects until the change is complete. On iOS, an
-            // the keyboard is deactivated after orientationChanging, then
-            // immediately activated after orientationChange is complete.
-            if (isIOS && systemManager.isTopLevelRoot())
-            {
-                orientationHandlerAdded = true;
-                orientationChanging = false;
-
-                smStage.addEventListener("orientationChanging", stage_orientationHandler);
-                smStage.addEventListener("orientationChange", stage_orientationHandler);
-            }
-
-            // Disable the effect and instead snap the pop-up position when
-            // the keyboard size changes after the first activation. This
-            // allows the StageText instance to stay active instead of being
-            // hidden by a bitmap proxy. This solves an issue on Android
-            // where a keyboard size change causes a pop-up resize, then the
-            // resize effect and subsequent bitmap proxy cause the keyboard
-            // size to revert, effectively killing auto correction.
-            // See SDK-31834.
-            prepareEffect(yToLocal, heightToLocal, !isFirstActivate);
-        }
-    }
-
-    /**
-     *  @private
-     */
-    private function stage_orientationHandler(event:Event):void
-    {
-        orientationChanging = (event.type == "orientationChanging");
-    }
-    /**
-     *  @private
-     *  Listens for mouse events while the soft keyboard effect is active.
-     */
-    private function mouseHandler(event:MouseEvent):void
-    {
-        isMouseDown = (event.type == MouseEvent.MOUSE_DOWN);
-    }
-
-    private function systemManager_mouseUpHandler(event:Event):void
-    {
-        isMouseDown = false;
-    }
-
-    /**
-     *  @private
-     */
-    private function softKeyboardDeactivateHandler(event:SoftKeyboardEvent=null):void
-    {
-        // If the pop-up didn't move, do nothing. If we're in the middle of an
-        // orientation change, also do nothing.
-        if (!isSoftKeyboardEffectActive || orientationChanging)
+                updateSoftKeyboardEffect(true);
+        }
+    }
+
+    /**
+     *  @private
+     */
+    private function stage_softKeyboardDeactivateHandler(event:SoftKeyboardEvent=null):void
+    {
+        // If the effect is not active (no move or resize was needed), do
+        // nothing. If we're in the middle of an orientation change, also do
+        // nothing.
+        if (!isSoftKeyboardEffectActive || softKeyboardEffectOrientationChanging)
             return;

         // Reset state
-        deactivateEffectIsPending = false;
+        softKeyboardEffectPendingEventType = null;

         if (event.triggerType == SoftKeyboardTrigger.USER_TRIGGERED)
         {
             // userTriggered indicates they keyboard was closed explicitly (soft
             // button on soft keyboard) or on Android, pressing the back button.
             // Play the deactivate effect immediately.
-            playDeactivateEffect(false);
+            updateSoftKeyboardEffect(false);
         }
         else // if (event.triggerType == SoftKeyboardTrigger.CONTENT_TRIGGERED)
         {
             // contentTriggered indicates focus was lost by tapping away from
-            // StageText or a programmatic call. Unfortunately, this
+            // StageText or a programmatic call. Unfortunately, this
             // distinction isn't entirely intuitive. We only care about delaying
-            // the deactivate effect when due to a mouse event. Delaying the
+            // the deactivate effect when due to a mouse event. Delaying the
             // effect allows the pop-up position and size to stay static until
             // any mouse interaction is complete (e.g. button click).
-            // However, the softKeyboardDeactivate event is fired before
+            // However, the softKeyboardDeactivate event is fired before
             // the mouseDown event:
             //   deactivate -> mouseDown -> mouseUp

             // The approach here is to assume that a mouseDown was the trigger
             // for the softKeyboardDeactivate event. Continue to delay the
-            // deactivate effect until a mouseDown and mouseUp sequence is
-            // received. In the event that the deactivation was due to a
+            // deactivate effect until a mouseDown and mouseUp sequence is
+            // received. In the event that the deactivation was due to a
             // programmatic call, we'll stop this process after a specified
             // delay time.

@@ -1081,194 +994,375 @@
             // this approach will still work for the button click use case.
             // Sequence (b) would simply fire a normal button click and have
             // the consequence of a delayed deactivate effect only.
-            deactivateEffectIsPending = true;
-
-            // If mouseDown immediately precedes deactivate, don't create timer.
-            // Need to wait indefinitely for mouseUp instead of using a timer.
-            // Use the timer only when mouseDown has not occured yet
-            if (!isMouseDown)
-            {
-                deactivateTimer = new Timer(deactivateEffectDelay, 1);
-                deactivateTimer.addEventListener(TimerEvent.TIMER_COMPLETE, deactivateTimer_timerCompleteHandler);
-                deactivateTimer.start();
-            }
-        }
-    }
-
-    /**
-     *  @private
-     */
-    private function deactivateTimer_timerCompleteHandler(event:Event):void
-    {
-        // Timer completed and no mouseDown and mouseUp sequence was fired
-        playDeactivateEffect(false);
-    }
-
-    /**
-     *  @private
-     *  Plays the deactivate effect to restore the original y-position and
-     *  height. This is called directly by the deactivate handler when the
-     *  keyboard is dismissed by hardware or explicitly by a soft keyboard
-     *  dismiss button. Otherwise, this effect is either delayed by a timer
-     *  or is awaiting a mouseDown and mouseUp event sequence.
-     */
-    private function playDeactivateEffect(isMouseEvent:Boolean):void
-    {
-        var isTimerRunning:Boolean = deactivateTimer && deactivateTimer.running;
+            setPendingSoftKeyboardEvent(event);
+        }
+    }
+
+    /**
+     *  @private
+     *  Disable soft keyboard deactivate when orientation is changing.
+     */
+    private function stage_orientationChangingHandler(event:Event):void
+    {
+        softKeyboardEffectOrientationChanging = true;
+    }
+
+    /**
+     *  @private
+     *  Re-enable soft keyboard deactivate effect when orietation change
+     *  completes.
+     */
+    private function stage_orientationChangeHandler(event:Event):void
+    {
+        softKeyboardEffectOrientationChanging = false;

+        // Update now. We might not see an extra ACTIVATE or DEACTIVATE after
+        // orientation change.
+        updateSoftKeyboardEffect(true);
+    }
+
+    /**
+     *  @private
+     *  Listens for mouse events while the soft keyboard effect is active.
+     */
+    private function mouseHandler(event:MouseEvent):void
+    {
+        isMouseDown = (event.type == MouseEvent.MOUSE_DOWN);
+    }
+
+    private function systemManager_mouseUpHandler(event:Event):void
+    {
+        isMouseDown = false;
+    }
+
+    /**
+     *  @private
+     *  This function is only called when the pendingEffectTimer completed and no
+     *  mouseDown and mouseUp sequence was fired.
+     */
+    private function pendingEffectTimer_timerCompleteHandler(event:Event):void
+    {
+        playPendingEffect(false)
+    }
+
+    /**
+     *  @private
+     *  Play the effect when (a) not triggered by a mouse event or
+     *  (b) triggered by a mouseUp event
+     */
+    private function playPendingEffect(isMouseEvent:Boolean):void
+    {
+        var isTimerRunning:Boolean = softKeyboardEffectPendingEventTimer && softKeyboardEffectPendingEventTimer.running;
+
         // Received a mouseDown event while the timer is still running. Stop
         // the timer and wait for the next mouseUp.
-        var mouseDownDuringTimer:Boolean = isTimerRunning &&
+        var mouseDownDuringTimer:Boolean = isTimerRunning &&
             (isMouseEvent && isMouseDown);
+
+        // Cleanup the timer if we're (a) waiting for the next mouseUp or
+        // (b) this function was called for timerComplete
+        if (softKeyboardEffectPendingEventTimer && (mouseDownDuringTimer || !isMouseEvent))
+        {
+            softKeyboardEffectPendingEventTimer.removeEventListener(TimerEvent.TIMER_COMPLETE, pendingEffectTimer_timerCompleteHandler);
+            softKeyboardEffectPendingEventTimer.stop();
+            softKeyboardEffectPendingEventTimer = null;
+
+            return;
+        }
+
+        // Sanity check that a pendingEvent still exists and that the pop-up
+        // is currently open. If we timed out or if we got a mouseUp, then
+        // allow the pending effect to play.
+        var canPlayEffect:Boolean = softKeyboardEffectPendingEventType && isOpen &&
+            (!isMouseEvent || (isMouseEvent && !isMouseDown));
+
+        // Effect isn't played when still waiting for a mouseUp
+        if (canPlayEffect)
+        {
+            // Clear pending state
+            var isActivate:Boolean = softKeyboardEffectPendingEventType == SoftKeyboardEvent.SOFT_KEYBOARD_ACTIVATE;
+
+            // Snap the position only for pending activate events
+            updateSoftKeyboardEffect(isActivate);
+        }
+    }
+
+    /**
+     *  @private
+     */
+    private function softKeyboardEffectCleanup(event:EffectEvent):void
+    {
+        // Cleanup effect
+        softKeyboardEffect.removeEventListener(EffectEvent.EFFECT_END, softKeyboardEffectCleanup);
+        softKeyboardEffect.removeEventListener(EffectEvent.EFFECT_STOP, softKeyboardEffectCleanup);
+        softKeyboardEffect = null;

-        // Cleanup the timer if we're (a) waiting for the next mouseUp or if
-        // (b) this function was called for a non-mouse event
-        if (deactivateTimer && (mouseDownDuringTimer || !isMouseEvent))
-        {
-            deactivateTimer.removeEventListener(TimerEvent.TIMER_COMPLETE, deactivateTimer_timerCompleteHandler);
-            deactivateTimer.stop();
-            deactivateTimer = null;
-        }
+        if (isSoftKeyboardEffectActive)
+        {
+            installActiveResizeListener();
+        }
+        else
+        {
+            // If the deactivate effect is complete, uninstall listeners for
+            // mouse delay and orientation change listeners
+            uninstallSoftKeyboardStateChangeListeners();
+        }
+    }
+
+    /**
+     *  @private
+     *  Set flags when explicit size changes are detected.
+     */
+    private function resizeHandler(event:Event=null):void
+    {
+        setSoftKeyboardEffectExplicitWidthFlag(!isNaN(explicitWidth));
+        setSoftKeyboardEffectExplicitHeightFlag(!isNaN(explicitHeight));
+    }
+
+    /**
+     *  @private
+     *  Update effect immediately after orientation change is
+     *  followed by a system manager resize.
+     */
+    private function systemManagerResizeHandler(event:Event):void
+    {
+        // Guard against extraneous resizing during orientation changing.
+        // See SDK-31860.
+        if (!softKeyboardEffectOrientationChanging)
+            updateSoftKeyboardEffect(true);
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //  Private Methods
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     *  Update the position and height for this pop-up for various state changes
+     *  including: soft keyboard activation and deactivation, delayed soft
+     *  keyboard events due to mouse and keyboard event sequence, and
+     *  orientation change events.
+     */
+    private function updateSoftKeyboardEffect(snapPosition:Boolean):void
+    {
+        // Stop the current effect
+        if (softKeyboardEffect && softKeyboardEffect.isPlaying)
+            softKeyboardEffect.stop();

-        // Play the deactivate effect when (a) not triggered by a mouse event
-        // or (b) triggered by a mouseUp event
-        if (!isMouseEvent || (isMouseEvent && !isMouseDown))
-        {
-            // Uninstall mouse event handling and play the deactivate effect
-            _isSoftKeyboardEffectActive = false;
-            deactivateEffectIsPending = false;
-
-            if (deactiveTriggersAdded)
+        var softKeyboardRect:Rectangle = systemManager.stage.softKeyboardRect;
+        var isKeyboardOpen:Boolean = (softKeyboardRect.height > 0);
+
+        // Capture start values if not set
+        if (isNaN(softKeyboardEffectCachedYPosition))
+        {
+            if (isKeyboardOpen)
             {
-                removeEventListener(MouseEvent.MOUSE_DOWN, mouseHandler);
+                // Save original y-position and height
+                softKeyboardEffectCachedYPosition = this.y;
+                setSoftKeyboardEffectCachedHeight(this.height);

-                var sandboxRoot:DisplayObject = systemManager.getSandboxRoot();
-                sandboxRoot.removeEventListener(MouseEvent.MOUSE_UP, mouseHandler, true /* useCapture */);
-                sandboxRoot.removeEventListener(SandboxMouseEvent.MOUSE_UP_SOMEWHERE, systemManager_mouseUpHandler);
-
-                deactiveTriggersAdded = false;
+                // Initialize explicit size flags
+                resizeHandler();
+            }
+            else
+            {
+                // Keyboard is closed and we don't have any start values yet.
+                // Nothing to do.
+                return;
+            }
+        }
+
+        var sandboxRoot:DisplayObject = systemManager.getSandboxRoot();
+
+        var yToLocal:Number = softKeyboardEffectCachedYPosition;
+        var heightToLocal:Number = softKeyboardEffectCachedHeight;
+
+        // If the keyboard is active, check for overlap
+        if (isKeyboardOpen)
+        {
+            var scaleFactor:Number = 1;
+
+            if (systemManager as SystemManager)
+                scaleFactor = SystemManager(systemManager).densityScale;
+
+            // All calculations are done in stage coordinates and converted back to
+            // application coordinates when playing effects. Also note that
+            // softKeyboardRect is also in stage coordinates.
+            var popUpY:Number = yToLocal * scaleFactor;
+            var popUpHeight:Number = heightToLocal * scaleFactor;
+            var overlapGlobal:Number = (popUpY + popUpHeight) - softKeyboardRect.y;
+
+            var yToGlobal:Number = popUpY;
+            var heightToGlobal:Number = popUpHeight;
+
+            if (overlapGlobal > 0)
+            {
+                // shift y-position up to remove offset overlap
+                if (moveForSoftKeyboard)
+                    yToGlobal = Math.max((softKeyboardEffectMarginTop * scaleFactor), (popUpY - overlapGlobal));
+
+                // adjust height based on new y-position
+                if (resizeForSoftKeyboard)
+                {
+                    // compute new overlap
+                    overlapGlobal = (yToGlobal + popUpHeight) - softKeyboardRect.y;
+
+                    // adjust height if there is overlap
+                    if (overlapGlobal > 0)
+                        heightToGlobal = popUpHeight - overlapGlobal - (softKeyboardEffectMarginBottom * scaleFactor);
+                }
             }

-            // Uninstall orientation change handling
-            if (orientationHandlerAdded)
+            if ((yToGlobal != popUpY) ||
+                (heightToGlobal != popUpHeight))
             {
-                var smStage:Stage = systemManager.stage;
-                smStage.removeEventListener("orientationChange", stage_orientationHandler);
-                smStage.removeEventListener("orientationChanging", stage_orientationHandler);
-
-                orientationHandlerAdded = false;
+                // convert to application coordinates, move to pixel boundaries
+                yToLocal = Math.floor(yToGlobal / scaleFactor);
+                heightToLocal = Math.floor(heightToGlobal / scaleFactor);
+
+                // preserve minimum height
+                heightToLocal = Math.max(heightToLocal, getMinBoundsHeight());
             }
-
-            prepareEffect(cachedYPosition, softKeyboardEffectCachedHeight);
-        }
-    }
-
-    /**
-     *  @private
-     */
-    private function effectCleanup(event:EffectEvent=null):void
-    {
-        // Remove event listeners if we're listening to the deactivate effect
-        if (event)
-        {
-            event.target.removeEventListener(EffectEvent.EFFECT_END, effectCleanup);
-            event.target.removeEventListener(EffectEvent.EFFECT_STOP, effectCleanup);
-        }
-
-        // Cleanup effect
-        effect = null;
-
-        // Only clear the cached positions if the effect completed normally or
-        // if this was called directly from the close state transtion completion.
-        // The deactivate effect may stop preemtively if the keyboard is
-        // activated again while the deactivate effect is playing. In that case,
-        // we want to save the cached positions from the first activation.
-        var deactivateComplete:Boolean =
-            (!isSoftKeyboardEffectActive && (event && (event.type == EffectEvent.EFFECT_END)));
-
-        if (!event || deactivateComplete)
-        {
-            // Resize and move is complete, but the resize effect modifies
-            // explicitHeight. If the original height was not explicit, then
-            // restore it to NaN. This will cause
-            if (!softKeyboardEffectCachedHeightExplicit)
-                this.height = NaN;
-
-            cachedYPosition = NaN;
-            softKeyboardEffectCachedHeightExplicit = false;
-            setSoftKeyboardEffectCachedHeight(NaN);
-            cachedKeyboardHeight = 0;
-        }
-        else if (event && isSoftKeyboardEffectActive)
-        {
-            // Flag changes to explicitHeight after the open effect has completed.
-            // Stop listening for changes on deactivate before the effect starts.
-            // See prepareEffect().
-            installActiveListeners();
-        }
-    }
-
-    /**
-     *  @private
-     */
-    private function explicitHeightChangedHandler(event:Event=null):void
-    {
-        softKeyboardEffectCachedHeightExplicit = !isNaN(explicitHeight);
-    }
-
-    //--------------------------------------------------------------------------
-    //
-    //  Private Methods
-    //
-    //--------------------------------------------------------------------------
-
-    /**
-     *  @private
-     */
-    private function prepareEffect(yTo:Number, heightTo:Number, snapPosition:Boolean=false):void
-    {
-        // stop the current effect
-        if (effect && effect.isPlaying)
-            effect.stop();
-
+        }
+
+        // Update state
+        _isSoftKeyboardEffectActive = isKeyboardOpen;
+
         var duration:Number = getStyle("softKeyboardEffectDuration");

-        if ((duration > 0) && !snapPosition)
-            effect = createSoftKeyboardEffect(yTo, heightTo);
+        uninstallActiveResizeListener();

-        // Stop looking for explicitHeight changes. The Resize effect or
-        // or explicit resize will modify explicitHeight.
-        uninstallActiveListeners();
+        // Only create an effect when not snapping and the duration is
+        // non-negative. An effect will not be created by default if there is
+        // no change.
+        if (!snapPosition && (duration > 0))
+            softKeyboardEffect = createSoftKeyboardEffect(yToLocal, heightToLocal);

-        if (effect)
-        {
-            effect.duration = duration;
-
+        if (softKeyboardEffect)
+        {
+            softKeyboardEffect.duration = duration;
+
             // Wait a frame so that any queued work can be completed by the framework
             // and runtime before the effect starts.
             addEventListener(Event.ENTER_FRAME, startEffect);
         }
-        // Do not restore the callout size if the pop-up is closed or closing.
-        else if (isOpen)
-        {
-            // No effect, set size and position explicitly
-            this.y = yTo;
-            this.height = heightTo;
+        else
+        {
+            // No effect, snap. Set position and size explicitly.
+            this.y = yToLocal;
+
+            // If the pop-up is closed, remember to clear the explicit height
+            if (!isOpen && !softKeyboardEffectExplicitHeightFlag)
+                this.height = NaN;
+            else
+                this.height = heightToLocal;
+
+            if (isOpen)
+            {
+                // Validate so that other listeners like Scroller get the
+                // updated dimensions.
+                validateNow();
+
+                if (isSoftKeyboardEffectActive)
+                {
+                    installActiveResizeListener();
+                    installSoftKeyboardStateChangeListeners();
+                }
+            }
+            else // if (!isOpen)
+            {
+                // Uninstall mouse delay and orientation change listeners
+                uninstallSoftKeyboardStateChangeListeners();
+
+                // Clear start values
+                softKeyboardEffectCachedYPosition = NaN;
+                setSoftKeyboardEffectCachedHeight(NaN);
+            }
+        }
+    }
+
+    /**
+     *  @private
+     *  Start waiting for a (mouseDown, mouseUp) event sequence before effect
+     *  plays.
+     */
+    private function setPendingSoftKeyboardEvent(event:SoftKeyboardEvent):void
+    {
+        softKeyboardEffectPendingEventType = event.type;
+
+        // If the mouseDown event was already received, wait indefinitely
+        // for mouseUp. If the soft keyboard event fired before mouseDown,
+        // start a timer.
+        if (!isMouseDown)
+        {
+            softKeyboardEffectPendingEventTimer = new Timer(softKeyboardEffectPendingEffectDelay, 1);
+            softKeyboardEffectPendingEventTimer.addEventListener(TimerEvent.TIMER_COMPLETE, pendingEffectTimer_timerCompleteHandler);
+            softKeyboardEffectPendingEventTimer.start();
+        }
+    }
+
+    /**
+     *  @private
+     *  Listeners installed just before the soft keyboard effect makes changes
+     *  to the original position and height.
+     */
+    private function installSoftKeyboardStateChangeListeners():void
+    {
+        if (!softKeyboardStateChangeListenersInstalled)
+        {
+            // Listen for mouseDown event on the pop-up and delay the soft
+            // keyboard effect until mouseUp. This allows button click
+            // events to complete normally before the button is re-positioned.
+            // See SDK-31534.
+            var sandboxRoot:DisplayObject = systemManager.getSandboxRoot();
+            addEventListener(MouseEvent.MOUSE_DOWN, mouseHandler);
+
+            // Listen for mouseUp events anywhere to play the effect. See SDK-31534.
+            sandboxRoot.addEventListener(MouseEvent.MOUSE_UP,
+                mouseHandler, true /* useCapture */);
+            sandboxRoot.addEventListener(SandboxMouseEvent.MOUSE_UP_SOMEWHERE,
+                systemManager_mouseUpHandler);
+
+            // Listen for orientationChanging and orientationChange to suspend
+            // pop-up changes until the orientation change is complete.
+            // On iOS, the keyboard is deactivated after orientationChanging,
+            // then immediately activated after orientationChange is complete.
+            // On Android, the keyboard is deactivated after orientationChanging,
+            // but not reactivated after orienationChange.
+            // On QNX, the keyboard is not deactivated at all. The keyboard is
+            // simply activated again after orientationChange.
+            softKeyboardEffectOrientationChanging = false;

-            // Validate so that other listeners like Scroller get the updated dimensions
-            validateNow();
+            var smStage:Stage = systemManager.stage;
+            smStage.addEventListener("orientationChanging", stage_orientationChangingHandler);
+            smStage.addEventListener("orientationChange", stage_orientationChangeHandler);
+
+            softKeyboardStateChangeListenersInstalled = true;
+        }
+    }
+
+    /**
+     *  @private
+     */
+    private function uninstallSoftKeyboardStateChangeListeners():void
+    {
+        if (softKeyboardStateChangeListenersInstalled)
+        {
+            // Uninstall effect delay handling
+            removeEventListener(MouseEvent.MOUSE_DOWN, mouseHandler);

-            if (isSoftKeyboardEffectActive)
-            {
-                // Once the height is changed, begin looking for changes to
-                // explicitHeight that are not due to soft keyboard effects.
-                installActiveListeners();
-            }
-            else
-            {
-                // Cleanup cached size and position
-                effectCleanup();
-            }
+            var sandboxRoot:DisplayObject = systemManager.getSandboxRoot();
+            sandboxRoot.removeEventListener(MouseEvent.MOUSE_UP, mouseHandler, true /* useCapture */);
+            sandboxRoot.removeEventListener(SandboxMouseEvent.MOUSE_UP_SOMEWHERE, systemManager_mouseUpHandler);
+
+            // Uninstall orientation change handling
+            var smStage:Stage = systemManager.stage;
+            smStage.removeEventListener("orientationChange", stage_orientationChangeHandler);
+            smStage.removeEventListener("orientationChanging", stage_orientationChangeHandler);
+
+            softKeyboardStateChangeListenersInstalled = false;
         }
     }

@@ -1277,26 +1371,29 @@
      *  Listeners installed during the phase after the initial activate effect
      *  is complete and before the deactive effect starts.
      */
-    private function installActiveListeners():void
-    {
-        if (!activeListenersInstalled)
-        {
-            // Check for explicitHeight changes while the soft keyboard
-            // effect is active (but not playing)
-            addEventListener("explicitHeightChanged", explicitHeightChangedHandler);
-            activeListenersInstalled = true;
-        }
-    }
-
-    /**
-     *  @private
-     */
-    private function uninstallActiveListeners():void
-    {
-        if (activeListenersInstalled)
-        {
-            removeEventListener("explicitHeightChanged", explicitHeightChangedHandler);
-            activeListenersInstalled = false;
+    private function installActiveResizeListener():void
+    {
+        if (!resizeListenerInstalled)
+        {
+            // Flag size changes while the soft keyboard effect is active (but
+            // not playing)
+            addEventListener("explicitWidthChanged", resizeHandler);
+            addEventListener("explicitHeightChanged", resizeHandler);
+            resizeListenerInstalled = true;
+        }
+    }
+
+    /**
+     *  @private
+     */
+    private function uninstallActiveResizeListener():void
+    {
+        if (resizeListenerInstalled)
+        {
+            // Uninstall resize listener
+            removeEventListener("explicitWidthChanged", resizeHandler);
+            removeEventListener("explicitHeightChanged", resizeHandler);
+            resizeListenerInstalled = false;
         }
     }
 }