Transferred from the Adobe Open Source Subversion Repository

Revision: 5215
Author:   rfrishbe@adobe.com
Date:     2009-03-10T01:39:37.388950Z

Log Message:
-----------
Initial checkin for FxVideoDisplay.  FxVideoDisplay is the new skinnable video component in Gumbo.  VideoElement is the new chromeless video component in Gumbo.

As part of this checkin, a new swc was added to the libs directory, videoPlayer.swc, which holds the underlying FLVPlackback VideoPlayer we are using today in VideoElement.

Multi-bit rate support hasn't been added yet, the skin could use a lot of work, and work needs to be done on state/skinstate support.  Otherwise, most things should be working.

QE Notes: You can start testing :-)
Doc Notes: -
Bugs: -
Reviewer: Deepa
tests: checkintests

Modified Paths:
--------------
<path kind="file" action="A">/flex/sdk/trunk/frameworks/projects/flex4/src/spark/events/VideoEvent.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/flex4/src/Flex4Classes.as</path>
<path kind="file" action="A">/flex/sdk/trunk/frameworks/libs/videoPlayer.swc</path>
<path kind="file" action="A">/flex/sdk/trunk/frameworks/projects/flex4/src/mx/components/FxVideoDisplay.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/mxml-2009-manifest.xml</path>
<path kind="file" action="A">/flex/sdk/trunk/frameworks/projects/flex4/src/mx/graphics/VideoElement.as</path>
<path kind="file" action="A">/flex/sdk/trunk/frameworks/projects/flex4/src/mx/skins/spark/FxVideoDisplayPlayPauseButtonSkin.mxml</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/flex4/build.xml</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/flex4/defaults.css</path>
<path kind="file" action="A">/flex/sdk/trunk/frameworks/projects/flex4/src/spark/events/MetadataEvent.as</path>
<path kind="file" action="M">/flex/sdk/trunk/build.xml</path>
<path kind="file" action="A">/flex/sdk/trunk/frameworks/projects/flex4/src/mx/skins/spark/FxVideoDisplayMuteButtonSkin.mxml</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/flex4/manifest.xml</path>
<path kind="dir" action="A">/flex/sdk/trunk/frameworks/projects/flex4/src/spark</path>
<path kind="dir" action="A">/flex/sdk/trunk/frameworks/projects/flex4/src/spark/events</path>
<path kind="file" action="A">/flex/sdk/trunk/frameworks/projects/flex4/src/mx/skins/spark/FxVideoDisplaySkin.mxml</path>

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

--- frameworks/projects/spark/src/spark/components/VideoPlayer.as
+++ frameworks/projects/spark/src/spark/components/VideoPlayer.as
@@ -0,0 +1,1381 @@
+package mx.components
+{
+import fl.video.VideoEvent;
+import fl.video.VideoState;
+
+import flash.display.StageDisplayState;
+import flash.events.Event;
+import flash.events.FullScreenEvent;
+import flash.events.MouseEvent;
+import flash.events.ProgressEvent;
+import flash.geom.Rectangle;
+
+import mx.components.baseClasses.FxComponent;
+import mx.components.baseClasses.FxRange;
+import mx.core.mx_internal;
+import mx.events.FlexEvent;
+import mx.events.SandboxMouseEvent;
+import mx.graphics.VideoElement;
+import mx.graphics.baseClasses.TextGraphicElement;
+import mx.utils.BitFlagUtil;
+
+import spark.events.MetadataEvent;
+import spark.events.VideoEvent;
+
+//--------------------------------------
+//  Events
+//--------------------------------------
+
+/**
+ *  Dispatched when the NetConnection is closed,
+ *  whether by being timed out, by calling the close() method,
+ *  or by loading a new video stream.  This event is only dispatched
+ *  with RTMP streams, never HTTP.
+ *
+ *  @eventType spark.events.VideoEvent.CLOSE
+ *
+ *  @langversion 3.0
+ *  @playerversion Flash 10
+ *  @playerversion AIR 1.5
+ *  @productversion Flex 4
+ */
+[Event(name="close", type="spark.events.VideoEvent")]
+
+/**
+ * Dispatched when playing completes because the player reached the end of the FLV file.
+ * The component does not dispatch the event if you call the stop() or
+ * pause() methods
+ * or click the corresponding controls.
+ *
+ *  @eventType spark.events.VideoEvent.COMPLETE
+ *
+ *  @langversion 3.0
+ *  @playerversion Flash 10
+ *  @playerversion AIR 1.5
+ *  @productversion Flex 4
+ */
+[Event(name="complete", type="spark.events.VideoEvent")]
+
+/**
+ *  Dispatched the first time the FLV file's metadata is reached.
+ *  The event object has an info property that contains the
+ *  info object received by the NetStream.onMetaData event callback.
+ *
+ *  @eventType spark.events.MetadataEvent.METADATA_RECEIVED
+ *
+ *  @langversion 3.0
+ *  @playerversion Flash 10
+ *  @playerversion AIR 1.5
+ *  @productversion Flex 4
+ */
+[Event(name="metadataReceived", type="spark.events.MetadataEvent")]
+
+/**
+ *  Dispatched every 0.25 seconds, or how often the underlying video
+ *  player's playheadUpdateInterval is set to, while the
+ *  video is playing.  This event is not dispatched when it is paused
+ *  or stopped, unless a seek occurs.
+ *
+ *  @eventType spark.events.VideoEvent.PLAYHEAD_UPDATE
+ *
+ *  @langversion 3.0
+ *  @playerversion Flash 10
+ *  @playerversion AIR 1.5
+ *  @productversion Flex 4
+ */
+[Event(name="playheadUpdate", type="spark.events.VideoEvent")]
+
+/**
+ *  Indicates progress made in number of bytes downloaded. Dispatched at the frequency
+ *  specified by the underlying video player's progressInterval property, starting
+ *  when the load begins and ending when all bytes are loaded or there is a network error.
+ *  The default is every 0.25 seconds starting when load is called and ending
+ *  when all bytes are loaded or if there is a network error. Use this event to check
+ *  bytes loaded or number of bytes in the buffer.
+ *
+ *
Dispatched only for a progressive HTTP download. Indicates progress in number of
+ *  downloaded bytes. The event object has the bytesLoaded and bytesTotal
+ *  properties

+ *
+ *  @eventType flash.events.ProgressEvent.PROGRESS
+ *
+ *  @langversion 3.0
+ *  @playerversion Flash 10
+ *  @playerversion AIR 1.5
+ *  @productversion Flex 4
+ */
+[Event(name="progress", type="flash.events.ProgressEvent")]
+
+/**
+ *  Dispatched when the video is loaded and ready to display.
+ *
+ *
This event is dispatched the first time the VideoPlayer
+ *  enters a responsive state after a new FLV is loaded
+ *  with the play() or load() method.
+ *  It is dispatched once for each FLV loaded.

+ *
+ *  @eventType spark.events.VideoEvent.READY
+ *
+ *  @langversion 3.0
+ *  @playerversion Flash 10
+ *  @playerversion AIR 1.5
+ *  @productversion Flex 4
+ */
+[Event(name="ready", type="spark.events.VideoEvent")]
+
+//--------------------------------------
+//  SkinStates
+//--------------------------------------
+
+/**
+ *  Buffering State of the VideoDisplay
+ *
+ *  @langversion 3.0
+ *  @playerversion Flash 10
+ *  @playerversion AIR 1.5
+ *  @productversion Flex 4
+ */
+[SkinState("buffering")]
+
+/**
+ *  Connection Error State of the VideoDisplay
+ *
+ *  @langversion 3.0
+ *  @playerversion Flash 10
+ *  @playerversion AIR 1.5
+ *  @productversion Flex 4
+ */
+[SkinState("connectionError")]
+
+/**
+ *  Disabled State of the VideoDisplay
+ *
+ *  @langversion 3.0
+ *  @playerversion Flash 10
+ *  @playerversion AIR 1.5
+ *  @productversion Flex 4
+ */
+[SkinState("disabled")]
+
+/**
+ *  Disconnected State of the VideoDisplay
+ *
+ *  @langversion 3.0
+ *  @playerversion Flash 10
+ *  @playerversion AIR 1.5
+ *  @productversion Flex 4
+ */
+[SkinState("disconnected")]
+
+/**
+ *  FullScreen State of the VideoDisplay
+ *
+ *  @langversion 3.0
+ *  @playerversion Flash 10
+ *  @playerversion AIR 1.5
+ *  @productversion Flex 4
+ */
+[SkinState("fullScreen")]
+
+/**
+ *  Loading State of the VideoDisplay
+ *
+ *  @langversion 3.0
+ *  @playerversion Flash 10
+ *  @playerversion AIR 1.5
+ *  @productversion Flex 4
+ */
+[SkinState("loading")]
+
+/**
+ *  Pause State of the VideoDisplay
+ *
+ *  @langversion 3.0
+ *  @playerversion Flash 10
+ *  @playerversion AIR 1.5
+ *  @productversion Flex 4
+ */
+[SkinState("paused")]
+
+/**
+ *  Playing State of the VideoDisplay
+ *
+ *  @langversion 3.0
+ *  @playerversion Flash 10
+ *  @playerversion AIR 1.5
+ *  @productversion Flex 4
+ */
+[SkinState("playing")]
+
+/**
+ *  Seeking State of the VideoDisplay
+ *
+ *  @langversion 3.0
+ *  @playerversion Flash 10
+ *  @playerversion AIR 1.5
+ *  @productversion Flex 4
+ */
+[SkinState("seeking")]
+
+/**
+ *  Stopped State of the VideoDisplay
+ *
+ *  @langversion 3.0
+ *  @playerversion Flash 10
+ *  @playerversion AIR 1.5
+ *  @productversion Flex 4
+ */
+[SkinState("stopped")]
+
+//--------------------------------------
+//  Other metadata
+//--------------------------------------
+
+[DefaultProperty("source")]
+
+//[IconFile("VideoDisplay.png")]
+
+/**
+ *  The FxVideoDisplay class is skinnable video player that supports
+ *  progressive download, multi-bitrate, and streaming video.
+ *
+ *
VideoElement is the chromeless version.

+ *
+ *  @see mx.graphics.VideoElement
+ *
+ *  @langversion 3.0
+ *  @playerversion Flash 10
+ *  @playerversion AIR 1.5
+ *  @productversion Flex 4
+ */
+public class FxVideoDisplay extends FxComponent
+{
+    //--------------------------------------------------------------------------
+    //
+    //  Class constants
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     */
+    private static const AUTO_PLAY_PROPERTY_FLAG:uint = 1 << 0;
+
+    /**
+     *  @private
+     */
+    private static const AUTO_REWIND_PROPERTY_FLAG:uint = 1 << 1;
+
+    /**
+     *  @private
+     */
+    private static const IS_LIVE_PROPERTY_FLAG:uint = 1 << 2;
+
+    /**
+     *  @private
+     */
+    private static const MAINTAIN_ASPECT_RATIO_PROPERTY_FLAG:uint = 1 << 3;
+
+    /**
+     *  @private
+     */
+    private static const SOURCE_PROPERTY_FLAG:uint = 1 << 4;
+
+    /**
+     *  @private
+     */
+    private static const VOLUME_PROPERTY_FLAG:uint = 1 << 5;
+
+    //--------------------------------------------------------------------------
+    //
+    //  Constructor
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  Constructor.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function FxVideoDisplay()
+    {
+        super();
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //  Skin Parts
+    //
+    //--------------------------------------------------------------------------
+
+    [SkinPart(required="true")]
+
+    /**
+     *  A required skin part that defines the VideoElement.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    public var videoElement:VideoElement;
+
+    [SkinPart(required="false")]
+
+    /**
+     *  An optional skin part to display the current playheadTime.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    public var playheadTimeLabel:TextGraphicElement;
+
+    [SkinPart(required="false")]
+
+    /**
+     *  An optional skin part for a fullScreen button.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    public var fullScreenButton:FxButton;
+
+    [SkinPart(required="false")]
+
+    /**
+     *  An optional skin part for the mute button.  When the
+     *  video is muted, the selected property will be set to
+     *  true.  When the video is not muted,
+     *  the selected property will be set to false.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    public var muteButton:FxToggleButton;
+
+    [SkinPart(required="false")]
+
+    /**
+     *  An optional skin part for the pause button
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    public var pauseButton:FxButton;
+
+    [SkinPart(required="false")]
+
+    /**
+     *  An optional skin part for the play button
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    public var playButton:FxButton;
+
+    [SkinPart(required="false")]
+
+    /**
+     *  An optional skin part for a play/pause button.  When the
+     *  video is playing, the selected property will be set to
+     *  true.  When the video is paused or stopped,
+     *  the selected property will be set to false.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    public var playPauseButton:FxToggleButton;
+
+    [SkinPart(required="false")]
+
+    /**
+     *  An optional skin part for the scrub bar (the
+     *  timeline).
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    public var scrubBar:FxRange;
+
+    [SkinPart(required="false")]
+
+    /**
+     *  An optional skin part for the stop button
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    public var stopButton:FxButton;
+
+    [SkinPart(required="false")]
+
+    /**
+     *  An optional skin part to display the totalTime.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    public var totalTimeLabel:TextGraphicElement;
+
+    [SkinPart(required="false")]
+
+    /**
+     *  An optional skin part for the volume control.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    public var volumeBar:FxRange;
+
+    //--------------------------------------------------------------------------
+    //
+    //  Variables
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     *  Several properties are proxied to videoElement.  However, when videoElement
+     *  is not around, we need to store values set on VideoDisplay.  This object
+     *  stores those values.  If videoElement is around, the values are stored
+     *  on the videoElement directly.  However, we need to know what values
+     *  have been set by the developer on the VideoDisplay (versus set on
+     *  the videoElement or defaults of the videoElement) as those are values
+     *  we want to carry around if the videoElement changes (via a new skin).
+     *  In order to store this info effeciently, videoElementProperties becomes
+     *  a uint to store a series of BitFlags.  These bits represent whether a
+     *  property has been explicitely set on this VideoDisplay.  When the
+     *  contentGroup is not around, videoElementProperties is a typeless
+     *  object to store these proxied properties.  When videoElement is around,
+     *  videoElementProperties stores booleans as to whether these properties
+     *  have been explicitely set or not.
+     */
+    private var videoElementProperties:Object = {};
+
+    //--------------------------------------------------------------------------
+    //
+    //  Overridden properties
+    //
+    //--------------------------------------------------------------------------
+
+    //----------------------------------
+    //  enabled
+    //----------------------------------
+
+    private var wasPlayingBeforeDisabled:Boolean;
+
+    /**
+     *  @private
+     */
+    override public function set enabled(value:Boolean):void
+    {
+        // TODO (rfrishbe): what about autoPlay and manual calls to play()?
+        super.enabled = value;
+
+        if (!value && videoElement)
+        {
+            if (isPlaying || wasPlayingBeforeDisabled)
+                wasPlayingBeforeDisabled = true;
+            else
+                wasPlayingBeforeDisabled = false;
+            videoElement.pause();
+        }
+        else if (wasPlayingBeforeDisabled)
+        {
+            wasPlayingBeforeDisabled = false;
+            videoElement.play();
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //  Properties
+    //
+    //--------------------------------------------------------------------------
+
+    //----------------------------------
+    //  autoPlay
+    //----------------------------------
+
+    [Inspectable(category="General", defaultValue="true")]
+
+    /**
+     *  @copy spark.primitives.VideoElement#autoPlay
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    public function get autoPlay():Boolean
+    {
+        return (videoElement) ? videoElement.autoPlay : videoElementProperties.autoPlay;
+    }
+
+    /**
+     * @private
+     */
+    public function set autoPlay(value:Boolean):void
+    {
+        if (videoElement)
+        {
+            videoElement.autoPlay = value;
+            videoElementProperties = BitFlagUtil.update(videoElementProperties as uint,
+                                                        AUTO_PLAY_PROPERTY_FLAG, true);
+        }
+        else
+            videoElementProperties.autoPlay = value;
+    }
+
+    //----------------------------------
+    //  autoRewind
+    //----------------------------------
+
+    [Inspectable(category="General", defaultValue="true")]
+
+    /**
+     *  @copy spark.primitives.VideoElement#autoRewind
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    public function get autoRewind():Boolean
+    {
+        return (videoElement) ? videoElement.autoRewind : videoElementProperties.autoRewind;
+    }
+
+    /**
+     * @private
+     */
+    public function set autoRewind(value:Boolean):void
+    {
+        if (videoElement)
+        {
+            videoElement.autoRewind = value;
+            videoElementProperties = BitFlagUtil.update(videoElementProperties as uint,
+                                                        AUTO_REWIND_PROPERTY_FLAG, true);
+        }
+        else
+            videoElementProperties.autoRewind = value;
+    }
+
+    //----------------------------------
+    //  isLive
+    //----------------------------------
+
+    [Inspectable(category="General", defaultValue="false")]
+
+    /**
+     *  @copy spark.primitives.VideoElement#isLive
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    public function get isLive():Boolean
+    {
+        return (videoElement) ? videoElement.isLive : videoElementProperties.isLive;
+    }
+
+    /**
+     *  @private
+     */
+    public function set isLive(value:Boolean):void
+    {
+        if (videoElement)
+        {
+            videoElement.isLive = value;
+            videoElementProperties = BitFlagUtil.update(videoElementProperties as uint,
+                                                        IS_LIVE_PROPERTY_FLAG, true);
+        }
+        else
+            videoElementProperties.isLive = value;
+    }
+
+    //----------------------------------
+    //  isMuted
+    //----------------------------------
+
+    [Inspectable(category="General", defaultValue="false")]
+
+    /**
+     *  @copy spark.primitives.VideoElement#isMuted
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    public function get isMuted():Boolean
+    {
+        if (videoElement)
+            return videoElement.isMuted;
+        else
+            return false;
+    }
+
+    //----------------------------------
+    //  isPlaying
+    //----------------------------------
+
+    [Inspectable(category="General")]
+
+    /**
+     *  @copy spark.primitives.VideoElement#isPlaying
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    public function get isPlaying():Boolean
+    {
+        if (videoElement)
+            return videoElement.isPlaying;
+        else
+            return false;
+    }
+
+    //----------------------------------
+    //  maintainAspectRatio
+    //----------------------------------
+
+    [Inspectable(Category="General", defaultValue="true")]
+
+    /**
+     *  @copy spark.primitives.VideoElement#maintainAspectRatio
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    public function get maintainAspectRatio():Boolean
+    {
+        return (videoElement) ? videoElement.maintainAspectRatio : videoElementProperties.maintainAspectRatio;
+    }
+
+    /**
+     *  @private
+     */
+    public function set maintainAspectRatio(value:Boolean):void
+    {
+        if (videoElement)
+        {
+            videoElement.maintainAspectRatio = value;
+            videoElementProperties = BitFlagUtil.update(videoElementProperties as uint,
+                                                        MAINTAIN_ASPECT_RATIO_PROPERTY_FLAG, true);
+        }
+        else
+            videoElementProperties.maintainAspectRatio = value;
+    }
+
+    //----------------------------------
+    //  playheadTime
+    //----------------------------------
+
+    [Bindable("playheadUpdate")]
+    [Inspectable(Category="General", defaultValue="0")]
+
+    /**
+     *  @copy spark.primitives.VideoElement#playheadTime
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    public function get playheadTime():Number
+    {
+        if (videoElement)
+            return videoElement.playheadTime;
+        else
+            return 0;
+    }
+
+    //----------------------------------
+    //  source
+    //----------------------------------
+
+    [Bindable("sourceChanged")]
+    [Inspectable(category="General", defaultValue="null")]
+
+    /**
+     *  @copy spark.primitives.VideoElement#source
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    public function get source():Object
+    {
+        return (videoElement) ? videoElement.source : videoElementProperties.source;
+    }
+
+    /**
+     * @private
+     */
+    public function set source(value:Object):void
+    {
+        if (videoElement)
+        {
+            videoElement.source = value;
+            videoElementProperties = BitFlagUtil.update(videoElementProperties as uint,
+                                                        SOURCE_PROPERTY_FLAG, true);
+        }
+        else
+            videoElementProperties.source = value;
+    }
+
+    //----------------------------------
+    //  totalTime
+    //----------------------------------
+
+    [Bindable("complete")]
+    [Bindable("metadataReceived")]
+    [Inspectable(Category="General", defaultValue="0")]
+
+    /**
+     *  @copy spark.primitives.VideoElement#totalTime
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    public function get totalTime():Number
+    {
+        if (videoElement)
+            return videoElement.totalTime;
+        else
+            return 0;
+    }
+
+    //----------------------------------
+    //  volume
+    //----------------------------------
+
+    [Bindable("volumeChanged")]
+    [Inspectable(category="General", defaultValue="1.0")]
+
+    /**
+     *  @copy spark.primitives.VideoElement#volume
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    public function get volume():Number
+    {
+        return (videoElement) ? videoElement.volume : videoElement.volume;
+    }
+
+    /**
+     * @private
+     */
+    public function set volume(value:Number):void
+    {
+        if (videoElement)
+        {
+            videoElement.volume = value;
+            videoElementProperties = BitFlagUtil.update(videoElementProperties as uint,
+                                                 VOLUME_PROPERTY_FLAG, true);
+        }
+        else
+            videoElementProperties.volume = value;
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //  Overridden methods
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     *  Keep track of what the previous state was.  This is because when we're
+     *  figuring out our currentState, we look at 1) whether we're disabled
+     *  2) what our videoPlayer state is 3) what our previous state was
+     */
+    private var previousState:String = VideoState.DISCONNECTED;
+
+    /**
+     *  @private
+     */
+    override protected function getCurrentSkinState():String
+    {
+        if (!enabled)
+            return "disabled";
+
+        var currentState:String;
+
+        if (videoElement)
+            currentState = videoElement.mx_internal::videoPlayer.state;
+
+        // only push certain video player states to our skins.
+        // Resizing, rewinding, and execQueuedCmd are ignored,
+        // and that's why we keep track of the previousState, which
+        // is the last state we care about and want to push to our skin
+        switch (currentState)
+        {
+            case VideoState.BUFFERING:
+            case VideoState.CONNECTION_ERROR:
+            case VideoState.DISCONNECTED:
+            case VideoState.LOADING:
+            case VideoState.PAUSED:
+            case VideoState.PLAYING:
+            case VideoState.SEEKING:
+            case VideoState.STOPPED:
+            {
+                previousState = currentState;
+                break;
+            }
+        }
+
+        return previousState;
+    }
+
+    /**
+     *  @private
+     */
+    override protected function partAdded(partName:String, instance:Object):void
+    {
+        if (instance == videoElement)
+        {
+            // copy proxied values from videoProperties (if set) to video
+
+            var newVideoProperties:uint = 0;
+
+            if (videoElementProperties.source !== undefined)
+            {
+                videoElement.source = videoElementProperties.source;
+                newVideoProperties = BitFlagUtil.update(newVideoProperties as uint,
+                                                        SOURCE_PROPERTY_FLAG, true);
+            }
+
+            if (videoElementProperties.autoPlay !== undefined)
+            {
+                videoElement.autoPlay = videoElementProperties.autoPlay;
+                newVideoProperties = BitFlagUtil.update(newVideoProperties as uint,
+                                                        AUTO_PLAY_PROPERTY_FLAG, true);
+            }
+
+            if (videoElementProperties.volume !== undefined)
+            {
+                videoElement.volume = videoElementProperties.volume;
+                newVideoProperties = BitFlagUtil.update(newVideoProperties as uint,
+                                                        VOLUME_PROPERTY_FLAG, true);
+            }
+
+            if (videoElementProperties.autoRewind !== undefined)
+            {
+                videoElement.autoRewind = videoElementProperties.autoRewind;
+                newVideoProperties = BitFlagUtil.update(newVideoProperties as uint,
+                                                        AUTO_REWIND_PROPERTY_FLAG, true);
+            }
+
+            if (videoElementProperties.isLive !== undefined)
+            {
+                videoElement.isLive = videoElementProperties.isLive;
+                newVideoProperties = BitFlagUtil.update(newVideoProperties as uint,
+                                                        IS_LIVE_PROPERTY_FLAG, true);
+            }
+
+            if (videoElementProperties.maintainAspectRatio !== undefined)
+            {
+                videoElement.maintainAspectRatio = videoElementProperties.maintainAspectRatio;
+                newVideoProperties = BitFlagUtil.update(newVideoProperties as uint,
+                                                        MAINTAIN_ASPECT_RATIO_PROPERTY_FLAG, true);
+            }
+
+            videoElementProperties = newVideoProperties;
+
+            videoElement.addEventListener(spark.events.VideoEvent.CLOSE, dispatchEvent);
+            videoElement.addEventListener(spark.events.VideoEvent.COMPLETE, dispatchEvent);
+            videoElement.addEventListener(MetadataEvent.METADATA_RECEIVED, videoElement_metaDataReceivedHandler);
+            videoElement.addEventListener(spark.events.VideoEvent.PLAYHEAD_UPDATE, videoElement_playHeadUpdateHandler);
+            videoElement.addEventListener(ProgressEvent.PROGRESS, dispatchEvent);
+            videoElement.addEventListener(fl.video.VideoEvent.STATE_CHANGE, videoElement_stateChangeHandler);
+
+            // just strictly for binding purposes
+            videoElement.addEventListener("sourceChanged", dispatchEvent);
+            videoElement.addEventListener("volumeChanged", dispatchEvent);
+
+            if (volumeBar)
+                volumeBar.value = volume;
+
+            if (scrubBar)
+            {
+                scrubBar.minimum = 0;
+                scrubBar.maximum = videoElement.totalTime;
+                scrubBar.value = videoElement.playheadTime;
+            }
+
+            if (playheadTimeLabel)
+                playheadTimeLabel.text = videoElement.playheadTime.toString();
+
+            if (totalTimeLabel)
+                totalTimeLabel.text = videoElement.totalTime.toString();
+        }
+        else if (instance == playButton)
+        {
+            playButton.addEventListener(MouseEvent.CLICK, playButton_clickHandler);
+        }
+        else if (instance == pauseButton)
+        {
+            pauseButton.addEventListener(MouseEvent.CLICK, pauseButton_clickHandler);
+        }
+        else if (instance == playPauseButton)
+        {
+            playPauseButton.addEventListener(MouseEvent.CLICK, playPauseButton_clickHandler);
+        }
+        else if (instance == stopButton)
+        {
+            stopButton.addEventListener(MouseEvent.CLICK, stopButton_clickHandler);
+        }
+        else if (instance == muteButton)
+        {
+            muteButton.addEventListener(MouseEvent.CLICK, muteButton_clickHandler);
+        }
+        else if (instance == volumeBar)
+        {
+            volumeBar.addEventListener(Event.CHANGE, volumeBar_changeHandler);
+            volumeBar.minimum = 0;
+            volumeBar.maximum = 1;
+            if (videoElement)
+                volumeBar.value = volume;
+        }
+        else if (instance == scrubBar)
+        {
+            if (videoElement)
+            {
+                scrubBar.minimum = 0;
+                scrubBar.maximum = videoElement.totalTime;
+                scrubBar.value = videoElement.playheadTime;
+            }
+            scrubBar.addEventListener(MouseEvent.MOUSE_DOWN, scrubBar_mouseEventHandler);
+            scrubBar.addEventListener(FlexEvent.VALUE_COMMIT, scrubBar_valueCommitHandler);
+            scrubBar.addEventListener(Event.CHANGE, scrubBar_changeHandler);
+        }
+        else if (instance == fullScreenButton)
+        {
+            fullScreenButton.addEventListener(MouseEvent.CLICK, fullScreenButton_clickHandler);
+        }
+        else if (instance == playheadTimeLabel)
+        {
+            if (videoElement)
+                playheadTimeLabel.text = videoElement.playheadTime.toString();
+        }
+        else if (instance == totalTimeLabel)
+        {
+            if (totalTimeLabel)
+                totalTimeLabel.text = videoElement.totalTime.toString();
+        }
+    }
+
+    /**
+     *  @private
+     */
+    override protected function partRemoved(partName:String, instance:Object):void
+    {
+        if (instance == videoElement)
+        {
+            // copy proxied values from video (if explicitely set) to videoProperties
+
+            var newVideoProperties:Object = {};
+
+            if (BitFlagUtil.isSet(videoElementProperties as uint, SOURCE_PROPERTY_FLAG))
+                newVideoProperties.source = videoElement.source;
+
+            if (BitFlagUtil.isSet(videoElementProperties as uint, AUTO_PLAY_PROPERTY_FLAG))
+                newVideoProperties.autoPlay = videoElement.autoPlay;
+
+            if (BitFlagUtil.isSet(videoElementProperties as uint, VOLUME_PROPERTY_FLAG))
+                newVideoProperties.volume = videoElement.volume;
+
+            if (BitFlagUtil.isSet(videoElementProperties as uint, AUTO_REWIND_PROPERTY_FLAG))
+                newVideoProperties.autoRewind = videoElement.autoRewind;
+
+            if (BitFlagUtil.isSet(videoElementProperties as uint, IS_LIVE_PROPERTY_FLAG))
+                newVideoProperties.isLive = videoElement.isLive;
+
+            if (BitFlagUtil.isSet(videoElementProperties as uint, MAINTAIN_ASPECT_RATIO_PROPERTY_FLAG))
+                newVideoProperties.maintainAspectRatio = videoElement.maintainAspectRatio;
+
+            videoElementProperties = newVideoProperties;
+
+            videoElement.removeEventListener(spark.events.VideoEvent.CLOSE, dispatchEvent);
+            videoElement.removeEventListener(spark.events.VideoEvent.COMPLETE, videoElement_completeHandler);
+            videoElement.removeEventListener(MetadataEvent.METADATA_RECEIVED, videoElement_metaDataReceivedHandler);
+            videoElement.removeEventListener(spark.events.VideoEvent.PLAYHEAD_UPDATE, videoElement_playHeadUpdateHandler);
+            videoElement.removeEventListener(ProgressEvent.PROGRESS, dispatchEvent);
+            videoElement.removeEventListener(fl.video.VideoEvent.STATE_CHANGE, videoElement_stateChangeHandler);
+
+            // just strictly for binding purposes
+            videoElement.removeEventListener("sourceChanged", dispatchEvent);
+            videoElement.removeEventListener("volumeChanged", dispatchEvent);
+        }
+        else if (instance == playButton)
+        {
+            playButton.removeEventListener(MouseEvent.CLICK, playButton_clickHandler);
+        }
+        else if (instance == pauseButton)
+        {
+            pauseButton.removeEventListener(MouseEvent.CLICK, pauseButton_clickHandler);
+        }
+        else if (instance == playPauseButton)
+        {
+            playPauseButton.removeEventListener(MouseEvent.CLICK, playPauseButton_clickHandler);
+        }
+        else if (instance == stopButton)
+        {
+            stopButton.removeEventListener(MouseEvent.CLICK, stopButton_clickHandler);
+        }
+        else if (instance == muteButton)
+        {
+            playButton.removeEventListener(MouseEvent.CLICK, muteButton_clickHandler);
+        }
+        else if (instance == volumeBar)
+        {
+            volumeBar.removeEventListener(Event.CHANGE, volumeBar_changeHandler);
+        }
+        else if (instance == scrubBar)
+        {
+            scrubBar.removeEventListener(MouseEvent.MOUSE_DOWN, scrubBar_mouseEventHandler);
+            scrubBar.removeEventListener(FlexEvent.VALUE_COMMIT, scrubBar_valueCommitHandler);
+            scrubBar.removeEventListener(Event.CHANGE, scrubBar_changeHandler);
+        }
+        else if (instance == fullScreenButton)
+        {
+            fullScreenButton.removeEventListener(MouseEvent.CLICK, fullScreenButton_clickHandler);
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //  Methods
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @copy spark.primitives.VideoElement#mute()
+     *
+     *  @throws TypeError if the skin hasn't been loaded up yet
+     *                    and there's no videoElement.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    public function mute():void
+    {
+        videoElement.mute();
+
+        if (muteButton)
+            muteButton.selected = true;
+    }
+
+    /**
+     *  @copy spark.primitives.VideoElement#pause()
+     *
+     *  @throws TypeError if the skin hasn't been loaded up yet
+     *                    and there's no videoElement.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    public function pause():void
+    {
+        videoElement.pause();
+    }
+
+    /**
+     *  @copy spark.primitives.VideoElement#play()
+     *
+     *  @throws TypeError if the skin hasn't been loaded up yet
+     *                    and there's no videoElement.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    public function play(startTime:Number=-1, duration:Number=-1):void
+    {
+        videoElement.play(startTime, duration);
+    }
+
+    /**
+     *  @copy spark.primitives.VideoElement#seek()
+     *
+     *  @throws TypeError if the skin hasn't been loaded up yet
+     *                    and there's no videoElement.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    public function seek(time:Number):void
+    {
+        videoElement.seek(time);
+    }
+
+    /**
+     *  @copy spark.primitives.VideoElement#stop()
+     *
+     *  @throws TypeError if the skin hasn't been loaded up yet
+     *                    and there's no videoElement.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    public function stop():void
+    {
+        videoElement.stop();
+    }
+
+    /**
+     *  @copy spark.primitives.VideoElement#unmute()
+     *
+     *  @throws TypeError if the skin hasn't been loaded up yet
+     *                    and there's no videoElement.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    public function unmute():void
+    {
+        videoElement.unmute();
+
+        if (muteButton)
+            muteButton.selected = false;
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //  Event handlers
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     */
+    private function videoElement_completeHandler(event:MetadataEvent):void
+    {
+        if (totalTimeLabel)
+            totalTimeLabel.text = videoElement.totalTime.toString();
+
+        dispatchEvent(event);
+    }
+
+    /**
+     *  @private
+     */
+    private function videoElement_metaDataReceivedHandler(event:MetadataEvent):void
+    {
+        if (scrubBar)
+        {
+            scrubBar.minimum = 0;
+            scrubBar.maximum = videoElement.totalTime;
+            scrubBar.value = videoElement.playheadTime;
+        }
+
+        if (totalTimeLabel)
+            totalTimeLabel.text = videoElement.totalTime.toString();
+    }
+
+    /**
+     *  @private
+     */
+    private function videoElement_playHeadUpdateHandler(event:spark.events.VideoEvent):void
+    {
+        if (scrubBar && !scrubBarMouseCaptured)
+        {
+            scrubBar.minimum = 0;
+            scrubBar.maximum = videoElement.totalTime;
+            scrubBar.value = videoElement.playheadTime;
+        }
+
+        if (playheadTimeLabel)
+            playheadTimeLabel.text = videoElement.playheadTime.toString();
+    }
+
+    /**
+     *  @private
+     */
+    private function videoElement_stateChangeHandler(event:fl.video.VideoEvent):void
+    {
+        if (playPauseButton)
+            playPauseButton.selected = isPlaying;
+        invalidateSkinState();
+    }
+
+    /**
+     *  @private
+     */
+    private function fullScreenButton_clickHandler(event:MouseEvent):void
+    {
+        // TODO (rfrishbe): What should we do on full screen?
+        includeInLayout = false;
+        setLayoutBoundsSize(stage.fullScreenWidth, stage.fullScreenHeight);
+        videoElement.mx_internal::videoPlayer.smoothing = false;
+        videoElement.mx_internal::videoPlayer.deblocking = 0;
+        validateNow();
+        stage.fullScreenSourceRect = new Rectangle(0, 0, width, height);
+        stage.displayState = StageDisplayState.FULL_SCREEN;
+        stage.addEventListener(FullScreenEvent.FULL_SCREEN, fullScreenEventHandler);
+    }
+
+    private function fullScreenEventHandler(event:FullScreenEvent):void
+    {
+        if (event.fullScreen)
+            return;
+
+        stage.removeEventListener(FullScreenEvent.FULL_SCREEN, fullScreenEventHandler);
+        setLayoutBoundsSize(NaN, NaN);
+        includeInLayout = true;
+        invalidateSize();
+        invalidateDisplayList();
+    }
+
+    /**
+     *  @private
+     */
+    private function playButton_clickHandler(event:MouseEvent):void
+    {
+        if (!isPlaying)
+            play();
+    }
+
+    /**
+     *  @private
+     */
+    private function pauseButton_clickHandler(event:MouseEvent):void
+    {
+        pause();
+    }
+
+    /**
+     *  @private
+     */
+    private function stopButton_clickHandler(event:MouseEvent):void
+    {
+        stop();
+    }
+
+    /**
+     *  @private
+     */
+    private function playPauseButton_clickHandler(event:MouseEvent):void
+    {
+        if (isPlaying)
+            pause();
+        else
+            play();
+    }
+
+    /**
+     *  @private
+     */
+    private function muteButton_clickHandler(event:MouseEvent):void
+    {
+        if (isMuted)
+            unmute();
+        else
+            mute();
+    }
+
+    /**
+     *  @private
+     */
+    private function volumeBar_changeHandler(event:Event):void
+    {
+        volume = volumeBar.value;
+    }
+
+    /**
+     *  @private
+     *  When someone is holding the scrubBar, we don't want to update the
+     *  range's value--for this time period, we'll let the user completely
+     *  control the range.
+     */
+    private var scrubBarMouseCaptured:Boolean;
+
+    /**
+     *  @private
+     */
+    private function scrubBar_mouseEventHandler(event:MouseEvent):void
+    {
+        switch (event.type)
+        {
+            case MouseEvent.MOUSE_DOWN:
+            {
+                scrubBarMouseCaptured = true;
+                systemManager.getSandboxRoot().addEventListener(MouseEvent.MOUSE_UP, scrubBar_mouseEventHandler, true /*useCapture*/);
+                systemManager.getSandboxRoot().addEventListener(SandboxMouseEvent.MOUSE_UP_SOMEWHERE, scrubBar_mouseEventHandler);
+                break;
+            }
+            case MouseEvent.MOUSE_UP:
+            case SandboxMouseEvent.MOUSE_UP_SOMEWHERE:
+            {
+                scrubBarMouseCaptured = false;
+                break;
+            }
+
+        }
+    }
+
+    /**
+     *  @private
+     */
+    private function scrubBar_changeHandler(event:Event):void
+    {
+        seek(scrubBar.value);
+    }
+
+    /**
+     *  @private
+     */
+    private function scrubBar_valueCommitHandler(event:Event):void
+    {
+        //seek(scrubBar.value);
+        //play();
+    }
+}
+}


Transferred from the Adobe Open Source Subversion Repository

Revision: 12025
Author:   rfrishbe@adobe.com
Date:     2009-11-20T01:48:04.689786Z

Log Message:
-----------
Switching out the old video component for the new video component that uses OSMF.  Also fixing RSL issue with OSMF because a change in flex-config.xml accidentally got overwritten.  Also fixing a bug caught during the last code review where you would set the volume on the VideoPlayer, but the volumeBar wouldn't be made aware of that change.

Switching out the video component results in *many* API changes.  The changes are highlighted below:

Class name changes:

 - spark.primitives.VideoElement is being renamed to spark.components.VideoDisplay
 - spark.components.mediaClasses.StreamingVideoSource is renamed to park.components.mediaClasses.DynamicStreamingVideoSource
 - spark.components.mediaClasses.StreamItem is renamed to park.components.mediaClasses.DynamicStreamingVideoItem

VideoDisplay/VideoPlayer event changes:

The new video component's events are:
 - bytesLoadedChange : org.osmf.events.LoadEvent
 - currentTimeChange : org.osmf.events.TimeEvent
 - durationChange : org.osmf.events.TimeEvent
 - mediaPlayerStateChange : org.osmf.events.MediaPlayerStateChangeEvent

The old video component's events were:
 - close : spark.events.VideoEvent (removed)
 - complete : spark.events.VideoEvent (replaced with mediaPlayerStateChange)
 - metaDataReceived : spark.events.VideoEvent (replaced with mediaPlayerStateChange)
 - playheadUpdate : spark.events.VideoEvent (replaced with currentTimeChange)
 - progress : flash.events.ProgressEvent (replaced with bytesLoadedChange)
 - ready : spark.events.VideoEvent (replaced with mediaPlayerStateChange)

VideoDisplay/VideoPlayer property changes:

Renames:

 - maintainAspectRatio:Boolean has been renamed to scaleMode:String and rather than true/false, it now access 4 values: none, zoom, letterbox, and stretch.  See the enum class org.osmf.display.ScaleMode.
 - playheadTime:Number has been renamed to currentTime:Number
 - playWhenHidden has been renamed to pauseWhenHidden, and it's "tense" has been reversed.  So playWhenHidden = true correlates to pauseWhenHidden = false.  Also, before we would only pause when the video component was explcitly set to visible=false, but now we detect if the video components or any of it's ancestors have been hidden.
 - totalTime:Number has been renamed to duration:Number

New properties:

 - bytesLoaded:Number This is a new property not available on the old video component
 - bytesTotal:Number This is a new property not available on the old video component
 - loop: Boolean this was a property added a while ago on the old video component but not in the original video player spec
 - mediaPlayerState: this is a new property that details the state of the video component.  See org.osmf.media.MediaPlayerState for all the possible values.
 - seekToFirstFrame:Boolean (pending PARB approval) - This is a new property available on VideoDisplay/VideoPlayer.  When autoPlay = false, if seekToFirstFrame is set to true, then we will connect to the server to start downloading the video, figure out the size of the video and resize appropriately, and show the first frame of the video.  If seekToFirstFrame is false, then no connection to the server is made, there's no implicit size for this video, and the first frame will not be show automatically.  By default the value of this property is true.  In the old video component, when autoPlay = false, we always has the same behavior as seekToFirstFrame = true.  Now it is controllable through this property.  Eventually, (not for Flex 4.0), we will most-likely have support for a thumbnail source or a splash screen so the video's preview will show up without making an unneeded connection to the server.  The property name may change depending on PARB.

Other changes:

 - autoRewind: The default of autoRewind is now true instead of false
 - enabled: before we paused the video when the video component was explicitly set to enabled = false.  Now we pause the video when the video component or any of it's ancestors have been disabled.

VideoPlayer-only changes:

 - videoObject:flash.media.Video property is now a new property on VideoPlayer.  It was previously only on VideoDisplay.
 - The skin states for the old VideoPlayer were: connectionError, disabled, disconnected, loading, playing, stopped, connectionErrorAndFullScreen, disabledAndFullScreen, disconnectedAndFullScreen, loadingAndFullScreen, playingAndFullScreen, stoppedAndFullScreen.  The new skin states are: uninitialized, loading, ready, playing, paused, buffering, playbackError, disabled, uninitializedAndFullScreen, loadingAndFullScreen, readyAndFullScreen, playingAndFullScreen, pausedAndFullScreen, bufferingAndFullScreen, playbackErrorAndFullScreen, disabledAndFullScreen

DynamicStreamingVideoItem property changes:

 - bitRate:Number renamed to bitrate:Number

DynamicStreamingVideoSource property changes:

 - initialIndex has been added to DynamicSteramingVideoSource
 - live:Boolean has changed to streamType:String which accepts values: live, recorded, any.  See the enum class org.osmf.net.StreamType for more info.
 - serverURI:String renamed to host:Object
 - streamItems:Array has changed types to streamItems:Vector.<DynamicStreamingVideoItem>

ScrubBar property changes (THESE CHANGES ARE NOT DONE YET, BUT SHOULD BE DONE SOON)

 - bufferedStart will be removed
 - bufferedEnd will be renamed to loadedRangeEnd.  This property name still may change depending on PARB.
 - bufferedArea skin part needs to be renamed.  Probably will be renamed to loadedArea.  PARB still deciding.

QE notes: -
Doc notes: -
Bugs: -
Reviewer: Kevin
Tests run: checkintests
Is noteworthy for integration: Yes

Modified Paths:
--------------
<path kind="file" action="D">/flex/sdk/trunk/frameworks/projects/spark/src/spark/components/mediaClasses/StreamItem.as</path>
<path kind="file" action="D">/flex/sdk/trunk/frameworks/projects/spark/src/spark/primitives/VideoElement.png</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/flex-config.xml</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/spark/src/SparkClasses.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/spark-manifest.xml</path>
<path kind="file" action="D">/flex/sdk/trunk/frameworks/projects/spark/src/spark/components/mediaClasses/StreamingVideoSource.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/spark/defaults.css</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/wireframe/build.xml</path>
<path kind="file" copyfrom-path="/flex/sdk/trunk/frameworks/projects/spark/src/spark/components/VideoPlayer2.as" copyfrom-rev="12005" action="R">/flex/sdk/trunk/frameworks/projects/spark/src/spark/components/VideoPlayer.as</path>
<path kind="file" copyfrom-path="/flex/sdk/trunk/frameworks/projects/spark/src/spark/skins/spark/VideoPlayerSkin2.mxml" copyfrom-rev="12005" action="R">/flex/sdk/trunk/frameworks/projects/spark/src/spark/skins/spark/VideoPlayerSkin.mxml</path>
<path kind="file" action="D">/flex/sdk/trunk/frameworks/projects/spark/src/spark/components/VideoPlayer2.as</path>
<path kind="file" action="D">/flex/sdk/trunk/frameworks/projects/spark/src/spark/primitives/VideoElement.as</path>
<path kind="file" action="D">/flex/sdk/trunk/frameworks/projects/spark/src/spark/skins/spark/VideoPlayerSkin2.mxml</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/wireframe/src/spark/skins/wireframe/VideoPlayerSkin.mxml</path>

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

--- frameworks/projects/spark/src/spark/components/VideoPlayer.as
+++ frameworks/projects/spark/src/spark/components/VideoPlayer.as
@@ -412,7 +412,7 @@
  *  @playerversion AIR 1.5
  *  @productversion Flex 4
  */
-public class VideoPlayer2 extends SkinnableComponent
+public class VideoPlayer extends SkinnableComponent
 {
     include "../core/Version.as";

@@ -486,7 +486,7 @@
      *  @playerversion AIR 1.5
      *  @productversion Flex 4
      */
-    public function VideoPlayer2()
+    public function VideoPlayer()
     {
         super();
     }
@@ -1319,6 +1319,9 @@
         {
             videoDisplayProperties.volume = value;
         }
+
+        if (volumeBar)
+            volumeBar.value = value;
     }

     //--------------------------------------------------------------------------


Transferred from the Adobe Open Source Subversion Repository

Revision: 12127
Author:   hmuller@adobe.com
Date:     2009-11-23T23:58:00.001192Z

Log Message:
-----------
Additional min/max Inspectable metadata, mostly for the filter classes.

QE notes:
Doc notes:
Bugs: sdk-24365
Reviewer: Chet, Jason, Ryan
Tests run:
Is noteworthy for integration: no

Modified Paths:
--------------
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/spark/src/spark/filters/ConvolutionFilter.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/filters/BaseDimensionFilter.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/spark/src/spark/components/VideoDisplay.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/spark/src/spark/components/supportClasses/ScrollBar.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/spark/src/spark/filters/BlurFilter.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/spark/src/spark/filters/DisplacementMapFilter.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/spark/src/spark/filters/GlowFilter.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/spark/src/spark/components/VideoPlayer.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/spark/src/spark/filters/DropShadowFilter.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/spark/src/spark/filters/BevelFilter.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/spark/src/spark/filters/GradientFilter.as</path>

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

--- frameworks/projects/spark/src/spark/filters/GradientFilter.as
+++ frameworks/projects/spark/src/spark/filters/GradientFilter.as
@@ -130,6 +130,8 @@

     private var _angle:Number = 45;

+    [Inspectable(minValue="0.0", maxValue="360.0")]
+
     /**
      *  The angle, in degrees. Valid values are 0 to 360.
      *  The angle value represents the angle of the theoretical light source


Remove duplicated call of UpdateViewParameters.[ci skip]

--- Bin/Data/Scripts/Editor.as
+++ Bin/Data/Scripts/Editor.as
@@ -140,7 +140,6 @@
         if (cameraElem.HasAttribute("limitrotation")) limitRotation = cameraElem.GetBool("limitrotation");
         if (cameraElem.HasAttribute("mousewheelcameraposition")) mouseWheelCameraPosition = cameraElem.GetBool("mousewheelcameraposition");
         if (cameraElem.HasAttribute("viewportmode")) viewportMode = cameraElem.GetUInt("viewportmode");
-        UpdateViewParameters();
         if (cameraElem.HasAttribute("mouseorbitmode")) mouseOrbitMode = cameraElem.GetInt("mouseorbitmode");
         UpdateViewParameters();
     }


Transferred from the Adobe Open Source Subversion Repository

Revision: 10951
Author:   klin@adobe.com
Date:     2009-10-09T17:15:44.211985Z

Log Message:
-----------
TitleWindow initial checkin. This is the spark equivalent of the mx:TitleWindow. One major difference is that we support a new skinstate called active. In this state, the titlebar of the window that is in focus or if one of that window's children is in focus.

-Added TitleWindow component to spark framework.
-Added new TitleWindowBoundsEvent to define events when you drag a TitleWindow.
-Added TitleWindow default skin and wireframe skin.
-Included TitleWindow to manifests and stylesheets.
-Added TitleWindow checkin test.
-Modified Panel's controlBarGroupProperties and related constants to be mx_internal in order for titlewindow to have the correct state when the controlBar is present and visible.
-Added ASDoc example for TW.
-Added icon for FB integration.
-Changed mx:TitleWindow's Alternative metadata to point to the spark TitleWindow.

SDK-23648 - small cosmetic fix on TitleWindow skin for titleDisplay overlapping with the closeButton

QE notes: TitleWindow ready for testing.
Doc notes: Yes
Bugs: SDK-23648
Reviewer: Ryan
Tests run: checkintests
Is noteworthy for integration: Yes

Modified Paths:
--------------
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/spark/src/SparkClasses.as</path>
<path kind="file" action="A">/flex/sdk/trunk/frameworks/projects/spark/src/spark/components/TitleWindow.png</path>
<path kind="file" action="A">/flex/sdk/trunk/frameworks/projects/spark/src/spark/skins/spark/TitleWindowSkin.mxml</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/wireframe/src/WireframeClasses.as</path>
<path kind="file" action="A">/flex/sdk/trunk/frameworks/projects/wireframe/src/spark/skins/wireframe/TitleWindowSkin.mxml</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/spark/defaults-3.0.0.css</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/spark/src/spark/components/Panel.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/spark/defaults.css</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/wireframe/defaults.css</path>
<path kind="file" action="A">/flex/sdk/trunk/frameworks/projects/spark/asdoc/en_US/spark/components/examples/SimpleTitleWindowExample.mxml</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/tests/basicTests/BasicTests-config.xml</path>
<path kind="file" action="A">/flex/sdk/trunk/frameworks/projects/spark/src/spark/events/TitleWindowBoundsEvent.as</path>
<path kind="file" action="A">/flex/sdk/trunk/frameworks/projects/spark/src/spark/components/TitleWindow.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/containers/TitleWindow.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/spark-manifest.xml</path>
<path kind="file" action="A">/flex/sdk/trunk/frameworks/projects/spark/src/spark/skins/spark/TitleWindowCloseButtonSkin.mxml</path>
<path kind="file" action="A">/flex/sdk/trunk/frameworks/projects/spark/asdoc/en_US/spark/components/examples/TitleWindowApp.mxml</path>
<path kind="file" action="A">/flex/sdk/trunk/frameworks/projects/wireframe/src/spark/skins/wireframe/TitleWindowCloseButtonSkin.mxml</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/tests/basicTests/BasicTests.mxml</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/spark/src/spark/skins/spark/PanelSkin.mxml</path>
<path kind="file" action="A">/flex/sdk/trunk/frameworks/tests/basicTests/spark/scripts/TitleWindowTestScript.mxml</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/wireframe/src/spark/skins/wireframe/PanelSkin.mxml</path>
<path kind="file" action="A">/flex/sdk/trunk/frameworks/tests/basicTests/spark/views/TitleWindowTests.mxml</path>

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

--- frameworks/projects/mx/src/mx/containers/TitleWindow.as
+++ frameworks/projects/mx/src/mx/containers/TitleWindow.as
@@ -119,7 +119,7 @@

 [IconFile("TitleWindow.png")]

-[Alternative(replacement="spark.components.Panel", since="4.0")]
+[Alternative(replacement="spark.components.TitleWindow", since="4.0")]

 /**
  *  A TitleWindow layout container contains a title bar, a caption,


Transferred from the Adobe Open Source Subversion Repository

Revision: 5119
Author:   smgilson@adobe.com
Date:     2009-03-01T15:19:39.936226Z

Log Message:
-----------
Clean up some ASDoc tags from the addition of the @productversion/@playerversion tags

QE Notes: None
Doc Notes: None
Bugs: -

Modified Paths:
--------------
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/skins/halo/HaloBorder.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/controls/ToolTip.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/rpc/src/mx/rpc/events/ResultEvent.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/rpc/src/mx/rpc/remoting/Operation.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/airframework/src/mx/controls/HTML.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/rpc/src/mx/messaging/config/ServerConfig.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/effects/EffectManager.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/rpc/src/mx/messaging/channels/HTTPChannel.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/rpc/src/mx/messaging/messages/HTTPRequestMessage.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/controls/CalendarLayout.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/core/Container.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/core/UITextField.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/controls/Button.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/halo/src/mx/skins/halo/HaloBorder.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/controls/videoClasses/NCManager.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/rpc/src/mx/messaging/AbstractConsumer.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/utils/Base64Encoder.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/validators/StringValidator.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/rpc/src/mx/rpc/xml/SchemaMarshaller.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework_textLayout/src/mx/core/UITLFTextField.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/core/IInteractiveObjectInterface.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/core/UIComponent.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/flex4/src/mx/components/TextView.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/core/ContainerRawChildrenList.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/rpc/src/mx/messaging/channels/AMFChannel.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/core/Application.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/rpc/src/mx/rpc/events/FaultEvent.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/rpc/src/mx/rpc/wsdl/WSDL.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/rpc/src/mx/rpc/AbstractOperation.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/flex4/src/mx/skins/spark/SparkSkin.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/effects/Tween.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/flex4/src/mx/effects/effectClasses/FxResizeInstance.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/containers/Accordion.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/controls/videoClasses/VideoPlayer.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/managers/HistoryManagerImpl.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/rpc/src/mx/rpc/xml/Schema.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/rpc/src/mx/utils/HexEncoder.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/managers/SystemManager.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/rpc/src/mx/rpc/soap/Operation.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/core/IDisplayObjectInterface.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/rpc/src/mx/rpc/http/AbstractOperation.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/core/IDisplayObjectContainerInterface.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/controls/Label.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/effects/effectClasses/SoundEffectInstance.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/flex4/src/mx/components/FxList.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/controls/dataGridClasses/DataGridItemRenderer.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/effects/effectClasses/SequenceInstance.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/controls/Text.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/core/ISpriteInterface.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/haloclassic/src/haloclassic/HaloRectBorder.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/rpc/src/mx/rpc/soap/mxml/Operation.as</path>

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

--- frameworks/projects/rpc/src/mx/rpc/AbstractOperation.as
+++ frameworks/projects/rpc/src/mx/rpc/AbstractOperation.as
@@ -238,11 +238,6 @@
     * event bubbling; dispatch the event if there's someone listening on us,
     * otherwise have the RemoteObject dispatch it in case there's a default
     * handler.
-    *
-    *  @langversion 3.0
-    *  @playerversion Flash 9
-    *  @playerversion AIR 1.1
-    *  @productversion Flex 3
     */
     override mx_internal function dispatchRpcEvent(event:AbstractEvent):void
     {


366 Removed Array type from ArrayUtil parameters to make them accept Vectors as well

--- raw/src/org/yellcorp/lib/core/ArrayUtil.as
+++ raw/src/org/yellcorp/lib/core/ArrayUtil.as
@@ -29,7 +29,7 @@
         // TODO: this is not quite how Python works, Python returns
         // values with equal indices as tuples

-        var result:Array = new Array();
+        var result:Array = [ ];
         var currentArray:Array;
         var len:int = 0;
         var i:int;
@@ -94,7 +94,7 @@
      *                          reductionFunction(array[0], array[1])
      * </listing>
      */
-    public static function reduce(array:Array, reductionFunction:Function, initialValue:* = null):*
+    public static function reduce(array:*, reductionFunction:Function, initialValue:* = null):*
     {
         var i:int;
         var acc:*;
@@ -157,7 +157,7 @@
      * @return              An array with the specified index/property
      *                      values from the Array/Object
      */
-    public static function pick(arrayOrObject:*, indices:Array):Array
+    public static function pick(arrayOrObject:*, indices:*):Array
     {
         var i:int;
         var picked:Array = [ ];
@@ -188,9 +188,9 @@
      * @return         A new Array of each object's property
      *                 value.
      */
-    public static function mapToProperty(array:Array, property:*):Array
-    {
-        var mapper:Function = function (m:*, i:int, a:Array):*
+    public static function mapToProperty(array:*, property:*):Array
+    {
+        var mapper:Function = function (m:*, i:int, a:*):*
         {
             return m[property];
         };
@@ -217,9 +217,9 @@
      * @return           A new Array of the results of each
      *                   method call.
      */
-    public static function mapToMethod(array:Array, methodName:String, methodArgs:Array = null):Array
-    {
-        var mapper:Function = function (m:*, i:int, a:Array):*
+    public static function mapToMethod(array:*, methodName:String, methodArgs:* = null):Array
+    {
+        var mapper:Function = function (m:*, i:int, a:*):*
         {
             return m[methodName].apply(m, methodArgs);
         };
@@ -248,7 +248,7 @@
      *                     that cast to Boolean as true.
      * @return The number of calls to boolFunction that returned true
      */
-    public static function count(array:Array, boolFunction:Function = null):int
+    public static function count(array:*, boolFunction:Function = null):int
     {
         var i:int;
         var result:int;
@@ -296,7 +296,7 @@
      *                     assumes 0.
      * @return The index of the first member to return true, or -1 if none did.
      */
-    public static function indexOf(array:Array, boolFunction:Function = null, startIndex:int = 0):int
+    public static function indexOf(array:*, boolFunction:Function = null, startIndex:int = 0):int
     {
         var i:int;
         if (!array) return -1;
@@ -343,7 +343,7 @@
      *                     assumes the end of the array.
      * @return The index of the last member to return true, or -1 if none did.
      */
-    public static function lastIndexOf(array:Array, boolFunction:Function = null, startIndex:int = -1):int
+    public static function lastIndexOf(array:*, boolFunction:Function = null, startIndex:int = -1):int
     {
         var i:int;
         if (!array) return -1;
@@ -389,7 +389,7 @@
      *                     assumes 0.
      * @return The first member to return true, or null if none did.
      */
-    public static function getFirst(array:Array, boolFunction:Function, startIndex:int = 0):*
+    public static function getFirst(array:*, boolFunction:Function, startIndex:int = 0):*
     {
         var index:int = indexOf(array, boolFunction, startIndex);
         return index >= 0 ? array[index] : null;
@@ -421,7 +421,7 @@
      *                     assumes the end of the array.
      * @return The last member to return true, or null if none did.
      */
-    public static function getLast(array:Array, boolFunction:Function, startIndex:int = -1):*
+    public static function getLast(array:*, boolFunction:Function, startIndex:int = -1):*
     {
         var index:int = lastIndexOf(array, boolFunction, startIndex);
         return index >= 0 ? array[index] : null;
@@ -431,7 +431,7 @@
      * Returns a copy of an array with equal items removed.  Equality
      * checking is strict ===.
      */
-    public static function unique(array:Array):Array
+    public static function unique(array:*):Array
     {
         var result:Array = [ ];
         var member:*;
@@ -467,7 +467,7 @@
      */
     public static function simpleCallback(closure:Function):Function
     {
-        function callback(item:*, index:int, array:Array):*
+        function callback(item:*, index:int, array:*):*
         {
             return closure(item);
         }


FragmentLoader : on loading/parsing error, try to level switch down before skipping fragments

also treat ERR_INCOMPLETE_CHUNKED_ENCODING as parsing error (not IO error)

--- src/org/mangui/hls/loader/FragmentLoader.as
+++ src/org/mangui/hls/loader/FragmentLoader.as
@@ -411,17 +411,21 @@
         }

         /* in case of parsing error,
-            first, try to switch to redundant stream if any
+            first, try to flush any tags that might have been injected in the NetStream
+            then switch to redundant stream if any
+            OR level switch down and cap level if in auto mode
             OR skip fragment if allowed to
             if not allowed to, report PARSING error
         */
         private function _fragHandleParsingError(message : String) : void {
             var hlsError : HLSError = new HLSError(HLSError.FRAGMENT_PARSING_ERROR, _fragCurrent.url, "Parsing Error :" + message);
+            var level : Level = _levels[_fragCurrent.level];
             CONFIG::LOGGING {
                 Log.warn(hlsError.msg);
             }
+            // flush any tags that might have been injected for this fragment
+            _streamBuffer.flushLastFragment(_fragCurrent.level,_fragCurrent.seqnum);
             _hls.dispatchEvent(new HLSEvent(HLSEvent.WARNING, hlsError));
-            var level : Level = _levels[_fragCurrent.level];
             // if we have redundant streams left for that level, switch to it
             if(level.redundantStreamId < level.redundantStreamsNb) {
                 CONFIG::LOGGING {
@@ -433,6 +437,16 @@
                 _loadingState = LOADING_IDLE;
                 // dispatch event to force redundant level loading
                 _hls.dispatchEvent(new HLSEvent(HLSEvent.LEVEL_SWITCH, _fragCurrent.level));
+            } else if(_hls.autoLevel && _fragCurrent.level) {
+                // auto level and not on level 0, try to switch down for next fragment, and cap level to avoid coming back on this one
+                _levelNext = _fragCurrent.level-1;
+                if(_hls.autoLevelCapping == -1) {
+                    _hls.autoLevelCapping = _levelNext;
+                } else {
+                    _hls.autoLevelCapping = Math.min(_levelNext,_hls.autoLevelCapping);
+                }
+                // switch back to IDLE state to request new fragment at lowest level
+                _loadingState = LOADING_IDLE;
             } else if(HLSSettings.fragmentLoadSkipAfterMaxRetry == true) {
                 CONFIG::LOGGING {
                     Log.warn("error parsing fragment, skip it and load next one");
@@ -453,16 +467,14 @@
             }
         }

+        /* in case of IO error,
+            retry loading fragment several times if allowed to
+            then switch to redundant stream if any
+            OR level switch down and cap level if in auto mode
+            OR skip fragment if allowed to
+            if not allowed to, report LOADING error
+        */
         private function _fraghandleIOError(message : String) : void {
-            /* usually, errors happen in two situations :
-            - bad networks  : in that case, the second or third reload of URL should fix the issue
-                               if loading retry still fails after HLSSettings.fragmentLoadMaxRetry, and
-                               if (a) redundant stream(s) is/are available for that level, then try to switch
-                               to that redundant stream instead.
-            - live playlist : when we are trying to load an out of bound fragments : for example,
-            the playlist on webserver is from SN [51-61]
-            the one in memory is from SN [50-60], and we are trying to load SN50.
-             */
             var hlsError : HLSError = new HLSError(HLSError.FRAGMENT_LOADING_ERROR, _fragCurrent.url, "I/O Error while loading fragment:" + message);
             _hls.dispatchEvent(new HLSEvent(HLSEvent.WARNING, hlsError));
             CONFIG::LOGGING {
@@ -490,6 +502,16 @@
                     _loadingState = LOADING_IDLE;
                     // dispatch event to force redundant level loading
                     _hls.dispatchEvent(new HLSEvent(HLSEvent.LEVEL_SWITCH, _fragCurrent.level));
+                } else if(_hls.autoLevel && _fragCurrent.level) {
+                    // auto level and not on level 0, try to switch down for next fragment, and cap level to avoid coming back on this one
+                    _levelNext = _fragCurrent.level-1;
+                    if(_hls.autoLevelCapping == -1) {
+                        _hls.autoLevelCapping = _levelNext;
+                    } else {
+                        _hls.autoLevelCapping = Math.min(_levelNext,_hls.autoLevelCapping);
+                    }
+                    // switch back to IDLE state to request new fragment at lowest level
+                    _loadingState = LOADING_IDLE;
                 } else if(HLSSettings.fragmentLoadSkipAfterMaxRetry == true) {
                     /* check if loaded fragment is not the last one of a live playlist.
                         if it is the case, don't skip to next, as there is no next fragment :-)
@@ -722,7 +744,11 @@
                 var hlsError : HLSError = new HLSError(HLSError.FRAGMENT_LOADING_CROSSDOMAIN_ERROR, _fragCurrent.url, txt);
                 _hls.dispatchEvent(new HLSEvent(HLSEvent.ERROR, hlsError));
             } else {
-                _fraghandleIOError("HTTP status:" + _fragLoadStatus + ",msg:" + event.text);
+                if(_fragLoadStatus == 200) {
+                    _fragHandleParsingError("HTTP 2OO but IO error, treat as parsing error");
+                } else {
+                    _fraghandleIOError("HTTP status:" + _fragLoadStatus + ",msg:" + event.text);
+                }
             }
         };

@@ -913,8 +939,6 @@
         private function _fragParsingErrorHandler(error : String) : void {
             // abort any load in progress
             _stop_load();
-            // flush any tags that might have been injected for this fragment
-            _streamBuffer.flushLastFragment(_fragCurrent.level,_fragCurrent.seqnum);
             // then try to overcome parsing error
             _fragHandleParsingError(error);
         }


Issue #119: Ensure mouse cursor is visible when OAuth sign-in page is displayed.

--- src/com/esri/builder/controllers/ApplicationCompleteController.as
+++ src/com/esri/builder/controllers/ApplicationCompleteController.as
@@ -41,6 +41,7 @@

 import mx.core.FlexGlobals;
 import mx.logging.ILogger;
+import mx.managers.CursorManager;
 import mx.managers.ToolTipManager;
 import mx.resources.ResourceManager;
 import mx.rpc.AsyncResponder;
@@ -310,20 +311,20 @@

         if (PortalModel.getInstance().isAGO(portalURL))
         {
-            idManager.addEventListener(IdentityManagerEvent.SHOW_OAUTH_WEB_VIEW, showOAuthWebViewHandler);
+            idManager.addEventListener(IdentityManagerEvent.SHOW_OAUTH_WEB_VIEW, startup_showOAuthWebViewHandler);
             PortalModel.getInstance().registerOAuthPortal(portalURL, Model.instance.cultureCode);
             idManager.getCredential(portalURL, false, new Responder(getCredentialOutcomeHandler,
                                                                     getCredentialOutcomeHandler));

             function getCredentialOutcomeHandler(outcome:Object):void
             {
-                idManager.removeEventListener(IdentityManagerEvent.SHOW_OAUTH_WEB_VIEW, showOAuthWebViewHandler);
+                idManager.removeEventListener(IdentityManagerEvent.SHOW_OAUTH_WEB_VIEW, startup_showOAuthWebViewHandler);
                 validateSettings();
             }

-            function showOAuthWebViewHandler(event:IdentityManagerEvent):void
-            {
-                idManager.removeEventListener(IdentityManagerEvent.SHOW_OAUTH_WEB_VIEW, showOAuthWebViewHandler);
+            function startup_showOAuthWebViewHandler(event:IdentityManagerEvent):void
+            {
+                idManager.removeEventListener(IdentityManagerEvent.SHOW_OAUTH_WEB_VIEW, startup_showOAuthWebViewHandler);
                 event.preventDefault();
                 idManager.setCredentialForCurrentSignIn(null);
                 validateSettings();
@@ -333,11 +334,18 @@
         {
             validateSettings();
         }
+
+        idManager.addEventListener(IdentityManagerEvent.SHOW_OAUTH_WEB_VIEW, showOAuthWebViewHandler);
     }

     private function validateSettings():void
     {
         AppEvent.dispatch(AppEvent.SAVE_SETTINGS, Model.instance.exportSettings());
+    }
+
+    private function showOAuthWebViewHandler(event:IdentityManagerEvent):void
+    {
+        CursorManager.removeAllCursors();   // ensure cursor is visible
     }
 }
 }


Allow to be constructed in, and flipped between, storing
preferences or just providing a runtime place for them to live.

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

--- src/as/com/threerings/util/Config.as
+++ src/as/com/threerings/util/Config.as
@@ -42,7 +42,18 @@
      */
     public function Config (path :String)
     {
-        _so = SharedObject.getLocal("config_" + path, "/");
+        setPath(path);
+    }
+
+    public function setPath (path :String) :void
+    {
+        _so = (path == null) ? null : SharedObject.getLocal("config_" + path, "/");
+        _data = (_so == null) ? {} : _so.data;
+
+        // dispatch events for all settings
+        for (var n :String in _data) {
+            dispatchEvent(new ConfigValueSetEvent(n, _data[n]));
+        }
     }

     /**
@@ -50,7 +61,7 @@
      */
     public function getValue (name :String, defValue :Object) :Object
     {
-        var val :* = _so.data[name];
+        var val :* = _data[name];
         return (val === undefined) ? defValue : val;
     }

@@ -59,8 +70,10 @@
      */
     public function setValue (name :String, value :Object) :void
     {
-        _so.data[name] = value;
-        _so.flush(); // flushing is not strictly necessary
+        _data[name] = value;
+        if (_so != null) {
+            _so.flush(); // flushing is not strictly necessary
+        }

         // dispatch an event corresponding
         dispatchEvent(new ConfigValueSetEvent(name, value));
@@ -68,11 +81,15 @@

     /**
      * Remove any set value for the specified preference.
+     * This does not dispatch an event because this would only be done to remove an
+     * obsolete preference.
      */
     public function remove (name :String) :void
     {
-        delete _so.data[name];
-        _so.flush(); // flushing is not strictly necessary
+        delete _data[name];
+        if (_so != null) {
+            _so.flush(); // flushing is not strictly necessary
+        }
     }

     /**
@@ -86,6 +103,13 @@
      */
     public function ensureCapacity (kilobytes :int, rl :ResultListener) :void
     {
+        if (_so == null) {
+            if (rl != null) {
+                rl.requestCompleted(this);
+            }
+            return;
+        }
+
         // flush with the size, see if we're cool
         var result :String = _so.flush(1024 * kilobytes);
         if (rl == null) {
@@ -119,5 +143,8 @@

     /** The shared object that contains our preferences. */
     protected var _so :SharedObject;
+
+    /** The object in which we store things, usually _so.data. */
+    protected var _data :Object;
 }
 }


Flash, Image: Check for resize necessity before resizing, not after. Wtf?..

--- src/flash/src/com/Image.as
+++ src/flash/src/com/Image.as
@@ -207,6 +207,11 @@
 						var matrix:Matrix, imgWidth:Number, imgHeight:Number;

 						scale = selector(tmpWidth / output.width, tmpHeight / output.height);
+						if (scale > 1) {
+							dispatchEvent(new ImageEvent(ImageEvent.RESIZE, { width: output.width, height: output.height }));
+							return;
+						}
+
 						matrix = new Matrix;
 						matrix.scale(scale, scale);

@@ -224,10 +229,7 @@
 						output.dispose();
 						output = bd;

-						if (scale > 1) {
-							dispatchEvent(new ImageEvent(ImageEvent.RESIZE, { width: output.width, height: output.height }));
-							return;
-						} else if (output.width / 2 > width && output.height / 2 > height) {
+						if (output.width / 2 > width && output.height / 2 > height) {
 							downScale(output.width / 2, output.height / 2);
 						} else if (width < output.width || height < output.height) {
 							downScale(width, height);


fixed bug watching paths with integer indexes instead of Strings

--- WeaveCore/src/weave/core/LinkableWatcher.as
+++ WeaveCore/src/weave/core/LinkableWatcher.as
@@ -15,15 +15,15 @@

 package weave.core
 {
-	import flash.utils.Dictionary;
-
 	import weave.api.core.ICallbackCollection;
 	import weave.api.core.IDisposableObject;
+	import weave.api.core.ILinkableCompositeObject;
 	import weave.api.core.ILinkableDynamicObject;
 	import weave.api.core.ILinkableHashMap;
 	import weave.api.core.ILinkableObject;
 	import weave.api.core.ISessionManager;
 	import weave.compiler.StandardLib;
+	import weave.primitives.Dictionary2D;

 	/**
 	 * This is used to dynamically attach a set of callbacks to different targets.
@@ -57,7 +57,7 @@
 		private var _target:ILinkableObject; // the current target or ancestor of the to-be-target
 		private var _foundTarget:Boolean = true; // false when _target is not the desired target
 		protected var _targetPath:Array; // the path that is being watched
-		private var _pathDependencies:Dictionary = new Dictionary(true); // Maps an ILinkableDynamicObject to its previous internalObject.
+		private var _pathDependencies:Dictionary2D = new Dictionary2D(true, false); // (ILinkableCompositeObject, String) -> child object

 		/**
 		 * This is the linkable object currently being watched.
@@ -189,8 +189,8 @@
 			var subPath:Array = [];
 			for each (var name:* in _targetPath)
 			{
-				if (node is ILinkableDynamicObject)
-					addPathDependency(node as ILinkableDynamicObject);
+				if (node is ILinkableCompositeObject)
+					addPathDependency(node as ILinkableCompositeObject, name);

 				subPath[0] = name;
 				var child:ILinkableObject = sm.getObject(node, subPath);
@@ -232,38 +232,59 @@
 			internalSetTarget(node);
 		}

-		private function addPathDependency(ldo:ILinkableDynamicObject):void
+		private function addPathDependency(parent:ILinkableCompositeObject, pathElement:Object):void
+		{
+			// if parent is an ILinkableHashMap and pathElement is a String, we don't need to add the dependency
+			var lhm:ILinkableHashMap = parent as ILinkableHashMap;
+			if (lhm && pathElement is String)
+				return;
+
+			var ldo:ILinkableDynamicObject = parent as ILinkableDynamicObject;
+			if (ldo)
+				pathElement = null;
+
+			if (!_pathDependencies.get(parent, pathElement))
+			{
+				var child:ILinkableObject = WeaveAPI.SessionManager.getObject(parent, [pathElement]);
+				_pathDependencies.set(parent, pathElement, child);
+				var dependencyCallbacks:ICallbackCollection = getDependencyCallbacks(parent);
+				dependencyCallbacks.addImmediateCallback(this, handlePathDependencies);
+				dependencyCallbacks.addDisposeCallback(this, handlePathDependencies);
+			}
+		}
+
+		private function getDependencyCallbacks(parent:ILinkableObject):ICallbackCollection
+		{
+			var lhm:ILinkableHashMap = parent as ILinkableHashMap;
+			if (lhm)
+				return lhm.childListCallbacks;
+			return WeaveAPI.SessionManager.getCallbackCollection(parent);
+		}
+
+		private function handlePathDependencies():void
 		{
 			var sm:ISessionManager = WeaveAPI.SessionManager;
-			if (!_pathDependencies[ldo])
-			{
-				_pathDependencies[ldo] = ldo.internalObject;
-				sm.getCallbackCollection(ldo).addImmediateCallback(this, handlePathDependencies);
-				sm.getCallbackCollection(ldo).addDisposeCallback(this, handlePathDependencies);
-			}
-		}
-
-		private function handlePathDependencies():void
-		{
-			var sm:ISessionManager = WeaveAPI.SessionManager;
-			for (var key:Object in _pathDependencies)
-			{
-				var ldo:ILinkableDynamicObject = key as ILinkableDynamicObject;
-				if (sm.objectWasDisposed(ldo) || ldo.internalObject != _pathDependencies[ldo])
+			for (var parent:Object in _pathDependencies.dictionary)
+			{
+				for (var pathElement:Object in _pathDependencies.dictionary[parent])
 				{
-					resetPathDependencies();
-					handlePath();
-					return;
+					var oldChild:ILinkableObject = _pathDependencies.get(parent, pathElement);
+					var newChild:ILinkableObject = sm.getObject(parent as ILinkableObject, [pathElement]);
+					if (sm.objectWasDisposed(parent) || oldChild != newChild)
+					{
+						resetPathDependencies();
+						handlePath();
+						return;
+					}
 				}
 			}
 		}

 		private function resetPathDependencies():void
 		{
-			var sm:ISessionManager = WeaveAPI.SessionManager;
-			for (var key:Object in _pathDependencies)
-				sm.getCallbackCollection(key as ILinkableDynamicObject).removeCallback(handlePathDependencies);
-			_pathDependencies = new Dictionary(true);
+			for (var parent:Object in _pathDependencies.dictionary)
+				getDependencyCallbacks(parent as ILinkableObject).removeCallback(handlePathDependencies);
+			_pathDependencies = new Dictionary2D(true, false);
 		}

 		/**


modify the frame data of animation interface

--- src/model/CopyDataProxy.as
+++ src/model/CopyDataProxy.as
@@ -291,7 +291,7 @@

 		public function executeBehaviorCopy():void
 		{
-			var copiedDestinationBehaviors:XMLList = copyBehaviors(selectedSourceBehaviorList, selectedDestinaionBehaviorList, _sharedBoneNames, _destinationBoneNames);
+			var copiedDestinationBehaviors:XMLList = copyBehaviors(selectedSourceBehaviorList, selectedDestinaionBehaviorList, _sharedBoneNames, selectedSourceBoneList.copy(),selectedDestinaionBonelist.copy());
 			var destinationName:String = selectedDestinationArmature.@[ConstValues.A_NAME];

@@ -394,7 +394,7 @@

 						//check behaviors

-						var copiedDestinationBehaviors:XMLList = copyBehaviors(selectedSourceBehaviorList, selectedDestinaionBehaviorList, _sharedBoneNames, _destinationBoneNames);
+						var copiedDestinationBehaviors:XMLList = copyBehaviors(selectedSourceBehaviorList, selectedDestinaionBehaviorList, _sharedBoneNames, selectedSourceBoneList.copy(),selectedDestinaionBonelist.copy());
 						if (selectedDestinaionBehaviorList == copiedDestinationBehaviors)
 						{
 							trace("Behavior is the same after copied!");
@@ -505,27 +505,35 @@

-		private function copyBehaviors(sourceBehaviors:XMLList, destinationBehaviors:XMLList, sharedBoneNames:Vector.<String>, destinationBoneNames:XMLList):XMLList
+		private function copyBehaviors(sourceBehaviors:XMLList, destinationBehaviors:XMLList, sharedBoneNames:Vector.<String>, sourceBoneList:XMLList,destinaionBonelist:XMLList):XMLList
 		{
 			var copyContainer:XML = <container/>
+			//save the existing behaviors
 			copyContainer.appendChild(destinationBehaviors.copy());
+
+
+			//
+			//calculate the relative coordinates of sourceBoneList and destinaionBonelist
+			//
+
+
 			for each (var sourceBehavior:XML in sourceBehaviors)
 			{
 				var sourceBehaviorName:String = sourceBehavior.@[ConstValues.A_NAME];
 				if (destinationBehaviors.(@[ConstValues.A_NAME] == sourceBehaviorName).length() == 0)
 				{
-					copyContainer.appendChild(copyBehavior(sourceBehaviorName, sourceBehavior, sharedBoneNames, destinationBoneNames));
+					copyContainer.appendChild(copyBehavior(sourceBehaviorName, sourceBehavior, sharedBoneNames, sourceBoneList,destinaionBonelist));
 				}
 				else
 				{
-					//todo: how to do in this case?
+					//todo: Duplication of name, how to do in this case?
 				}
 			}

 			return copyContainer.children();
 		}

-		private function copyBehavior(behaviorName:String, sourceBehavior:XML, sharedBoneNames:Vector.<String>, destinationBoneNames:XMLList):XML
+		private function copyBehavior(behaviorName:String, sourceBehavior:XML, sharedBoneNames:Vector.<String>, sourceBoneList:XMLList,destinaionBonelist:XMLList):XML
 		{
 			var copiedBehavior:XML = sourceBehavior.copy();
 			copiedBehavior.@[ConstValues.A_NAME] = behaviorName;
@@ -533,15 +541,11 @@
 			//remove all children
 			copiedBehavior.setChildren(new XMLList());

-			for each (var boneName:String in destinationBoneNames)
-			{
-				if (sharedBoneNames.indexOf(boneName) != -1)
-					copiedBehavior.appendChild(sourceBehavior[ConstValues.BONE].(@[ConstValues.A_NAME] == boneName));
-				else
-				{
-					//todo: how to do in this case?
-				}
-			}
+			for each(var boneName:String in sharedBoneNames)
+			{
+				//todo: calculate the final frame data of this behavior
+			}
+
 			return copiedBehavior;
 		}


volume + ember + wrapper

volume + ember + wrapper

--- src/org/openvv/OVVAsset.as
+++ src/org/openvv/OVVAsset.as
@@ -296,6 +296,7 @@
         }
 	}

+
 	/**
 	 * Add a JavaScript resource upon reciveing a given vpaidEvent
 	 * @param	vpaidEvent The name of the VPAID event to add the JavaScript resource upon recived


Adding RegExpUtilTestSuite to RunAll

Adding RegExpUtilTestSuite to RunAll

--- raw/src/test/yellcorp/RunAll.as
+++ raw/src/test/yellcorp/RunAll.as
@@ -5,6 +5,7 @@

 import test.yellcorp.lib.binary.NumberInfoTest;
 import test.yellcorp.lib.color.ColorUtilTest;
+import test.yellcorp.lib.core.RegExpUtil.RegExpUtilTestSuite;
 import test.yellcorp.lib.core.SetTest;
 import test.yellcorp.lib.format.DateFormatFlexTest;
 import test.yellcorp.lib.format.NumberFormatUtilTest;
@@ -26,6 +27,7 @@
         super();
         tests = new TestSuite();
         tests.addTest(new NumberInfoTest());
+        tests.addTest(new RegExpUtilTestSuite());
         tests.addTest(new ColorUtilTest());
         tests.addTest(new GeoFormatTest());
         tests.addTest(new PrintfSuite());


fixed asdoc comment

fixed asdoc comment

--- FlexUnit4/src/org/flexunit/async/Async.as
+++ FlexUnit4/src/org/flexunit/async/Async.as
@@ -218,7 +218,7 @@
 		/**
 		 * Calls a method after a given delay.
 		 * @param testCase The current asynchronous test case.
-		 * @param callback The function that will be executed if the delay</delay> has been reached.
+		 * @param callback The function that will be executed if the delay has been reached.
 		 * @param delay The length of time, in milliseconds, before calling the callback.
 		 */
 		public static function delayCall(testCase:Object, callback:Function, delay:Number):void


fix broken import of AnimationController

--- src/aerys/minko/type/clone/CloneOptions.as
+++ src/aerys/minko/type/clone/CloneOptions.as
@@ -1,7 +1,7 @@
 package aerys.minko.type.clone
 {
 	import aerys.minko.scene.controller.AbstractController;
-	import aerys.minko.scene.controller.AnimationController;
+	import aerys.minko.scene.controller.animation.AnimationController;
 	import aerys.minko.scene.controller.TransformController;
 	import aerys.minko.scene.controller.camera.CameraController;
 	import aerys.minko.scene.controller.light.DirectionalLightController;


Fleshing out test case and reworking it to base it on EventResultHandler.

--- test/src/org/postgresql/pegasus/functional/SimpleQueryTest.as
+++ test/src/org/postgresql/pegasus/functional/SimpleQueryTest.as
@@ -1,11 +1,12 @@
 package org.postgresql.pegasus.functional {
-    import flash.events.Event;
-    import flash.events.EventDispatcher;
-    import flash.events.IEventDispatcher;
+
+    import org.postgresql.db.IColumn;
+    import org.postgresql.db.event.QueryCompletionEvent;
+    import org.postgresql.db.event.QueryResultEvent;
+    import org.postgresql.db.EventResultHandler;
     import org.flexunit.async.Async;
     import org.flexunit.asserts.assertEquals;
     import org.flexunit.asserts.assertNotNull;
-    import org.postgresql.db.SimpleResultHandler;
     import org.postgresql.db.QueryToken;

     /**
@@ -14,20 +15,29 @@
     public class SimpleQueryTest extends ConnectedTestBase {

         [Test(async,timeout=1000)]
-        public function testSelectText() : void {
-            var dummyDispatcher : IEventDispatcher = new EventDispatcher();
-            Async.proceedOnEvent(this, dummyDispatcher, 'success', 1000);
-            var handler:SimpleResultHandler = new SimpleResultHandler(
-                function(command : String, rowCount : int) : void {
+        public function testSelectText():void {
+            var handler:EventResultHandler = new EventResultHandler();
+            Async.proceedOnEvent(this, handler, QueryCompletionEvent.COMPLETE, 1000);
+
+			handler.addEventListener(QueryResultEvent.RESULT, function(e:QueryResultEvent) : void {
                     // Note that rowCount for a SELECT does *not* reflect the number of affected rows
-                    assertEquals(0, rowCount);
-                    assertEquals('SELECT', command);
-                    assertEquals(2, handler.columns.length);
-                    assertEquals(1, handler.data.length);
-                    dummyDispatcher.dispatchEvent(new Event('success'));
-                }
-            );
-            var sql:String = "select ''::text as empty, 'hello world'::text as txt";
+                    assertEquals(3, e.columns.length);
+                    assertEquals('empty', IColumn(e.columns[0]).name);
+                    assertEquals('one_char', IColumn(e.columns[1]).name);
+					assertEquals('text', IColumn(e.columns[2]).name);
+
+                    assertEquals(1, e.data.length);
+                    assertEquals('', e.data[0]['empty']);
+                    assertEquals('?', e.data[0]['one_char']);
+                    assertEquals('hello world', e.data[0]['text']);
+                });
+            // N.B.: this listener is executing with higher priority that the 'proceed' above
+            handler.addEventListener(QueryCompletionEvent.COMPLETE, function(e:QueryCompletionEvent):void {
+                    assertEquals(0, e.rows);
+                    assertEquals('SELECT', e.tag);
+            });
+
+            var sql:String = "select ''::text as empty, '?'::text as one_char, 'hello world'::text as text";
             var qt:QueryToken = connection.execute(sql, handler);
             assertNotNull(qt);
             assertEquals(qt.sql, sql);


Change 20071031-Philip-4 by Philip@Philip-DC on 2007-10-31 14:32:52 EDT
    in /cygdrive/f/laszlo/svn/src/svn/openlaszlo/trunk
    for http://svn.openlaszlo.org/openlaszlo/trunk

Summary: Fix reference to DEFAULT_SIZE in LzTextSprite.as

New Features:

Bugs Fixed: LPP-4952

Technical Reviewer: max
QA Reviewer: (pending)
Doc Reviewer: (pending)

Documentation:

Release Notes:

Details:
The reference for DEFAULT_SIZE should be this.DEFAULT_SIZE and not LzText.DEFAULT_SIZE.

Tests:
See test below. The message is NaN for an unpatched system. A valid number is displayed once patched.

<canvas>
  <font name="Helvetica" src="helmetr.ttf" />
  <simplelayout axis="y" spacing="10"/>
  <text name="message"/>

  <text font="Helvetica" multiline="true">
    Text using Helvetica
    <handler name="oninit">
      message.format("textheight = %g", this.sprite.lineheight);
    </handler>
  </text>
</canvas>

Files:
M      WEB-INF/lps/lfc/kernel/swf/LzTextSprite.as

Changeset: http://svn.openlaszlo.org/openlaszlo/patches/20071031-Philip-4.tar

git-svn-id: d62bde4b5aa582fdf07c8d403e53e0399a7ed285@7093 fa20e4f9-1d0a-0410-b5f3-dc9c16b8b17c

--- WEB-INF/lps/lfc/kernel/swf/LzTextSprite.as
+++ WEB-INF/lps/lfc/kernel/swf/LzTextSprite.as
@@ -583,7 +583,7 @@

     if (this.font != null) {
         this.lineheight = this.font.leading + ( this.font.height *
-                                                this.fontsize/ LzText.DEFAULT_SIZE );
+                                                this.fontsize/ this.DEFAULT_SIZE );
     }
 }


clearKeys() now reports that keys were removed

--- WeaveData/src/weave/data/KeySets/KeySet.as
+++ WeaveData/src/weave/data/KeySets/KeySet.as
@@ -219,8 +219,10 @@
 			// stop if there are no keys to remove
 			if (_keys.length == 0)
 				return false; // set did not change
-
-			// clear key-to-index mapping
+
+			keyCallbacks.keysRemoved = keyCallbacks.keysRemoved.concat(_keys);
+
+			// clear key-to-index mapping
 			_keyIndex = new Dictionary();
 			_keys = [];