//////////////////////////////////////////////////////////////////////////////// // // Licensed to the Apache Software Foundation (ASF) under one or more // contributor license agreements. See the NOTICE file distributed with // this work for additional information regarding copyright ownership. // The ASF licenses this file to You under the Apache License, Version 2.0 // (the "License"); you may not use this file except in compliance with // the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // //////////////////////////////////////////////////////////////////////////////// package mx.controls { import flash.display.Bitmap; import flash.display.DisplayObject; import flash.display.DisplayObjectContainer; import flash.display.Loader; import flash.display.LoaderInfo; import flash.display.Sprite; import flash.events.Event; import flash.events.EventDispatcher; import flash.events.HTTPStatusEvent; import flash.events.IEventDispatcher; import flash.events.IOErrorEvent; import flash.events.MouseEvent; import flash.events.ProgressEvent; import flash.events.SecurityErrorEvent; import flash.geom.Point; import flash.geom.Rectangle; import flash.net.URLRequest; import flash.system.ApplicationDomain; import flash.system.Capabilities; import flash.system.LoaderContext; import flash.system.SecurityDomain; import flash.utils.ByteArray; import mx.core.FlexGlobals; import mx.core.FlexLoader; import mx.core.FlexVersion; import mx.core.IFlexDisplayObject; import mx.core.IFlexModuleFactory; import mx.core.ILayoutDirectionElement; import mx.core.ISWFLoader; import mx.core.IUIComponent; import mx.core.LayoutDirection; import mx.core.UIComponent; import mx.core.mx_internal; import mx.events.FlexEvent; import mx.events.InterManagerRequest; import mx.events.InvalidateRequestData; import mx.events.Request; import mx.events.SWFBridgeEvent; import mx.events.SWFBridgeRequest; import mx.managers.CursorManager; import mx.managers.IMarshalSystemManager; import mx.managers.ISystemManager; import mx.managers.SystemManager; import mx.managers.SystemManagerGlobals; import mx.styles.ISimpleStyleClient; import mx.utils.LoaderUtil; use namespace mx_internal; //-------------------------------------- // Events //-------------------------------------- /** * Dispatched when content loading is complete. * *

This event is dispatched regardless of whether the load was triggered * by an autoload or an explicit call to the load() method.

* * @eventType flash.events.Event.COMPLETE * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Event(name="complete", type="flash.events.Event")] /** * Dispatched when a network request is made over HTTP * and Flash Player or AIR can detect the HTTP status code. * * @eventType flash.events.HTTPStatusEvent.HTTP_STATUS * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Event(name="httpStatus", type="flash.events.HTTPStatusEvent")] /** * Dispatched when the properties and methods of a loaded SWF file * are accessible. The following two conditions must exist * for this event to be dispatched: * * * * @eventType flash.events.Event.INIT * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Event(name="init", type="flash.events.Event")] /** * Dispatched when an input/output error occurs. * @see flash.events.IOErrorEvent * * @eventType flash.events.IOErrorEvent.IO_ERROR * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Event(name="ioError", type="flash.events.IOErrorEvent")] /** * Dispatched when a network operation starts. * * @eventType flash.events.Event.OPEN * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Event(name="open", type="flash.events.Event")] /** * Dispatched when content is loading. * *

This event is dispatched regardless of whether the load was triggered * by an autoload or an explicit call to the load() method.

* *

Note: * The progress event is not guaranteed to be dispatched. * The complete event may be received, without any * progress events being dispatched. * This can happen when the loaded content is a local file.

* * @eventType flash.events.ProgressEvent.PROGRESS * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Event(name="progress", type="flash.events.ProgressEvent")] /** * Dispatched when a security error occurs while content is loading. * For more information, see the SecurityErrorEvent class. * * @eventType flash.events.SecurityErrorEvent.SECURITY_ERROR * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Event(name="securityError", type="flash.events.SecurityErrorEvent")] /** * Dispatched when a loaded object is removed, * or when a second load is performed by the same SWFLoader control * and the original content is removed prior to the new load beginning. * * @eventType flash.events.Event.UNLOAD * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Event(name="unload", type="flash.events.Event")] //-------------------------------------- // Styles //-------------------------------------- /** * The name of class to use as the SWFLoader border skin if the control cannot * load the content. * @default BrokenImageBorderSkin * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Style(name="brokenImageBorderSkin", type="Class", inherit="no")] /** * The name of the class to use as the SWFLoader skin if the control cannot load * the content. * The default value is the "__brokenImage" symbol in the Assets.swf file. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Style(name="brokenImageSkin", type="Class", inherit="no")] /** * The horizontal alignment of the content when it does not have * a one-to-one aspect ratio. * Possible values are "left", "center", * and "right". * @default "left" * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Style(name="horizontalAlign", type="String", enumeration="left,center,right", inherit="no")] /** * The vertical alignment of the content when it does not have * a one-to-one aspect ratio. * Possible values are "top", "middle", * and "bottom". * @default "top" * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Style(name="verticalAlign", type="String", enumeration="bottom,middle,top", inherit="no")] //-------------------------------------- // Effects //-------------------------------------- /** * An effect that is started when the complete event is dispatched. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Effect(name="completeEffect", event="complete")] //-------------------------------------- // Excluded APIs //-------------------------------------- [Exclude(name="chromeColor", kind="style")] //-------------------------------------- // Other metadata //-------------------------------------- [DefaultBindingProperty(source="percentLoaded", destination="source")] [DefaultTriggerEvent("progress")] [IconFile("SWFLoader.png")] [ResourceBundle("controls")] /** * The SWFLoader control loads and displays a specified SWF file. * You typically use SWFLoader for loading one Flex application * into a host Flex application. * *

Note: You can use the SWFLoader control to load * a GIF, JPEG, or PNG image file at runtime, * to load a ByteArray representing a SWF, GIF, JPEG, or PNG image at runtime, * or load an embedded version of any of these file types, * and SVG files, at compile time * by using @Embed(source='filename'). * However, the Image control is better suited for this capability * and should be used for most image loading. * The Image control is also designed to be used * in custom item renderers and item editors. * When using either SWFLoader or Image with an SVG file, * you can only load the SVG if it has been embedded in your * application using an Embed statement; * you cannot load an SVG from the network at runtime.

* *

The SWFLoader control lets you scale its content and set its size. * It can also resize itself to fit the size of its content. * By default, content is scaled to fit the size of the SWFLoader control. * It can also load content on demand programmatically, * and monitor the progress of a load.

* *

A SWFLoader control cannot receive focus. * However, the contents of a SWFLoader control can accept focus * and have its own focus interactions.

* *

The SWFLoader control has the following default characteristics:

* * * * * * * * * * * * * * * * * *
CharacteristicDescription
Default sizeWidth and height large enough for the loaded content
Minimum size0 pixels
Maximum sizeUndefined
* * @mxml * *

The <mx:SWFLoader> tag inherits all of the tag attributes * of its superclass and adds the following tag attributes:

* *
 *  <mx:SWFLoader
 *    Properties
 *    autoLoad="true|false"
 *    loadForCompatibility="false|true"
 *    loaderContext="null"
 *    maintainAspectRatio="true|false"
 *    scaleContent="true|false"
 *    showBusyCursor="false|true"
 *    source="No default"
 *    trustContent="false|true"
 *  
 *    Styles
 *    brokenImageBorderSkin="BrokenImageBorderSkin"
 *    brokenImageSkin="'__brokenImage' symbol in Assets.swf"
 *    horizontalAlign="left|center|right"
 *    verticalAlign="top|middle|bottom"
 *  
 *    Effects
 *    completeEffect="No default"
 *    
 *    Events
 *    complete="No default"
 *    httpStatus="No default"
 *    init="No default"
 *    ioError="No default"
 *    open="No default"
 *    progress="No default"
 *    securityError="No default"
 *    unload="No default"
 *  />
 *  
* * @includeExample examples/local.mxml -noswf * @includeExample examples/SimpleLoader.mxml * * @see mx.controls.Image * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public class SWFLoader extends UIComponent implements ISWFLoader { include "../core/Version.as"; //-------------------------------------------------------------------------- // // Constructor // //-------------------------------------------------------------------------- /** * Constructor. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function SWFLoader() { super(); tabEnabled = false; tabFocusEnabled = false; addEventListener(FlexEvent.INITIALIZE, initializeHandler); addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler); addEventListener(MouseEvent.CLICK, clickHandler); showInAutomationHierarchy = false; } //-------------------------------------------------------------------------- // // Variables // //-------------------------------------------------------------------------- /** * @private */ mx_internal var contentHolder:DisplayObject; /** * @private */ private var contentChanged:Boolean = false; /** * @private */ private var scaleContentChanged:Boolean = false; /** * @private */ private var smoothBitmapContentChanged:Boolean = false; /** * @private */ private var isContentLoaded:Boolean = false; /** * @private */ private var brokenImage:Boolean = false; /** * @private */ private var resizableContent:Boolean = false; // true if we've loaded a SWF /** * @private */ private var flexContent:Boolean = false; // true if we've loaded a Flex SWF /** * @private */ private var contentRequestID:String = null; /** * @private */ private var attemptingChildAppDomain:Boolean = false; /** * @private */ private var requestedURL:URLRequest; /** * @private */ private var brokenImageBorder:IFlexDisplayObject; /** * @private */ private var explicitLoaderContext:Boolean = false; /** * @private */ private var mouseShield:Sprite; /** * @private * * When unloading a swf, check this flag to see if we * should use unload() or unloadAndStop(). */ private var useUnloadAndStop:Boolean; /** * @private * * When using unloadAndStop, pass this flag * as the gc parameter. */ private var unloadAndStopGC:Boolean; //-------------------------------------------------------------------------- // // Properties // //-------------------------------------------------------------------------- //---------------------------------- // autoLoad //---------------------------------- /** * @private * Storage for the autoLoad property. */ private var _autoLoad:Boolean = true; [Bindable("autoLoadChanged")] [Inspectable(defaultValue="true")] /** * A flag that indicates whether content starts loading automatically * or waits for a call to the load() method. * If true, the content loads automatically. * If false, you must call the load() method. * * @default true * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get autoLoad():Boolean { return _autoLoad; } /** * @private */ public function set autoLoad(value:Boolean):void { if (_autoLoad != value) { _autoLoad = value; contentChanged = true; invalidateProperties(); invalidateSize(); invalidateDisplayList(); dispatchEvent(new Event("autoLoadChanged")); } } //---------------------------------- // loadForCompatibility //---------------------------------- /** * @private * Storage for the loadForCompatibility property. */ private var _loadForCompatibility:Boolean = false; [Bindable("loadForCompatibilityChanged")] [Inspectable(defaultValue="false")] /** * A flag that indicates whether the content is loaded so that it can * interoperate with applications built with a different verion of the Flex compiler. * Compatibility with other Flex applications is accomplished by loading * the application into a sibling (or peer) ApplicationDomain. * This flag is ignored if the content must be loaded into a different * SecurityDomain. * If true, the content loads into a sibling ApplicationDomain. * If false, the content loaded into a child ApplicationDomain. * * @default false * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get loadForCompatibility():Boolean { return _loadForCompatibility; } /** * @private */ public function set loadForCompatibility(value:Boolean):void { if (_loadForCompatibility != value) { _loadForCompatibility = value; contentChanged = true; invalidateProperties(); invalidateSize(); invalidateDisplayList(); dispatchEvent(new Event("loadForCompatibilityChanged")); } } //---------------------------------- // bytesLoaded (read only) //---------------------------------- /** * @private * Storage for the autoLoad property. */ private var _bytesLoaded:Number = NaN; [Bindable("progress")] /** * The number of bytes of the SWF or image file already loaded. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get bytesLoaded():Number { return _bytesLoaded; } //---------------------------------- // bytesTotal (read only) //---------------------------------- /** * @private * Storage for the bytesTotal property. */ private var _bytesTotal:Number = NaN; [Bindable("complete")] /** * The total size of the SWF or image file. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get bytesTotal():Number { return _bytesTotal; } //---------------------------------- // content (read only) //---------------------------------- /** * This property contains the object that represents * the content that was loaded in the SWFLoader control. * * @tiptext Returns the content of the SWFLoader. * @helpid 3134 * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get content():DisplayObject { if (contentHolder is Loader) return Loader(contentHolder).content; return contentHolder; } //---------------------------------- // contentHeight //---------------------------------- /** * Height of the scaled content loaded by the control, in pixels. * Note that this is not the height of the control itself, but of the * loaded content. Use the height property of the control * to obtain its height. * *

The value of this property is not final when the complete event is triggered. * You can get the value after the updateComplete event is triggered.

* * @default NaN * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get contentHeight():Number { return contentHolder ? contentHolder.height : NaN; } //---------------------------------- // contentHolderHeight (private) //---------------------------------- /** * @private */ private function get contentHolderHeight():Number { // For externally loaded content, use the loaderInfo structure var loaderInfo:LoaderInfo; if (contentHolder is Loader) loaderInfo = Loader(contentHolder).contentLoaderInfo; if (loaderInfo) { if (loaderInfo.contentType == "application/x-shockwave-flash") { try { var mp:IMarshalSystemManager = IMarshalSystemManager(systemManager.getImplementation("mx.managers::IMarshalSystemManager")); if (mp && mp.swfBridgeGroup) { var bridge:IEventDispatcher = swfBridge; if (bridge) { var request:SWFBridgeRequest = new SWFBridgeRequest(SWFBridgeRequest.GET_SIZE_REQUEST); bridge.dispatchEvent(request); return request.data.height; } } var content:IFlexDisplayObject = Loader(contentHolder).content as IFlexDisplayObject; if (content) return content.measuredHeight; } catch(error:Error) { return contentHolder.height; } } else { try { var testContent:DisplayObject = Loader(contentHolder).content; } catch(error:Error) { return contentHolder.height; } } return loaderInfo.height; } // For internally loaded content, use preferredHeight (if present) or height if (contentHolder is IUIComponent) return IUIComponent(contentHolder).getExplicitOrMeasuredHeight(); if (contentHolder is IFlexDisplayObject) return IFlexDisplayObject(contentHolder).measuredHeight; return contentHolder.height; } //---------------------------------- // contentHolderWidth (private) //---------------------------------- /** * @private */ private function get contentHolderWidth():Number { // For externally loaded content, use the loaderInfo structure var loaderInfo:LoaderInfo; if (contentHolder is Loader) loaderInfo = Loader(contentHolder).contentLoaderInfo; if (loaderInfo) { if (loaderInfo.contentType == "application/x-shockwave-flash") { try { if (swfBridge) { var request:SWFBridgeRequest = new SWFBridgeRequest(SWFBridgeRequest.GET_SIZE_REQUEST); swfBridge.dispatchEvent(request); return request.data.width; } var content:IFlexDisplayObject = Loader(contentHolder).content as IFlexDisplayObject; if (content) return content.measuredWidth; } catch(error:Error) { return contentHolder.width; } } else { try { var testContent:DisplayObject = Loader(contentHolder).content; } catch(error:Error) { return contentHolder.width; } } return loaderInfo.width; } // For internally loaded content, use explicitWidth (if present) or explicitWidth if (contentHolder is IUIComponent) return IUIComponent(contentHolder).getExplicitOrMeasuredWidth(); if (contentHolder is IFlexDisplayObject) return IFlexDisplayObject(contentHolder).measuredWidth; return contentHolder.width; } //---------------------------------- // contentWidth //---------------------------------- /** * Width of the scaled content loaded by the control, in pixels. * Note that this is not the width of the control itself, but of the * loaded content. Use the width property of the control * to obtain its width. * *

The value of this property is not final when the complete event is triggered. * You can get the value after the updateComplete event is triggered.

* * @default NaN * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get contentWidth():Number { return contentHolder ? contentHolder.width : NaN; } //---------------------------------- // loaderContext //---------------------------------- /** * @private * Storage for the loaderContext property. */ private var _loaderContext:LoaderContext; [Bindable("loaderContextChanged")] [Inspectable(defaultValue="true")] /** * A LoaderContext object to use to control loading of the content. * This is an advanced property. * Most of the time you can use the trustContent property. * *

The default value is null, which causes the control * to use the trustContent property to create * a LoaderContext object, which you can read back * after the load starts.

* *

To use a custom LoaderContext object, you must understand the * SecurityDomain and ApplicationDomain classes. * Setting this property will not start a load; * you must set this before the load starts. * This does not mean that you have to set autoLoad property * to false, because the load does not actually start * immediately, but waiting for the creationComplete event * to set it is too late.

* * @default null * @see flash.system.LoaderContext * @see flash.system.ApplicationDomain * @see flash.system.SecurityDomain * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get loaderContext():LoaderContext { return _loaderContext; } /** * @private */ public function set loaderContext(value:LoaderContext):void { _loaderContext = value; explicitLoaderContext = true; dispatchEvent(new Event("loaderContextChanged")); } //---------------------------------- // maintainAspectRatio //---------------------------------- /** * @private * Storage for the maintainAspectRatio property. */ private var _maintainAspectRatio:Boolean = true; [Bindable("maintainAspectRatioChanged")] [Inspectable(defaultValue="true")] /** * A flag that indicates whether to maintain the aspect ratio * of the loaded content. * If true, specifies to display the image with the same ratio of * height to width as the original image. * * @default true * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get maintainAspectRatio():Boolean { return _maintainAspectRatio; } /** * @private */ public function set maintainAspectRatio(value:Boolean):void { _maintainAspectRatio = value; dispatchEvent(new Event("maintainAspectRatioChanged")); } //---------------------------------- // sandBoxBridge (read only) //---------------------------------- private var _swfBridge:IEventDispatcher; //---------------------------------- // percentLoaded (read only) //---------------------------------- [Bindable("progress")] /** * The percentage of the image or SWF file already loaded. * * @default 0 * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get percentLoaded():Number { var p:Number = isNaN(_bytesTotal) || _bytesTotal == 0 ? 0 : 100 * (_bytesLoaded / _bytesTotal); if (isNaN(p)) p = 0; return p; } //---------------------------------- // scaleContent //---------------------------------- /** * @private * Storage for the scaleContent property. */ private var _scaleContent:Boolean = true; [Bindable("scaleContentChanged")] [Inspectable(category="General", defaultValue="true")] /** * A flag that indicates whether to scale the content to fit the * size of the control or resize the control to the content's size. * If true, the content scales to fit the SWFLoader control. * If false, the SWFLoader scales to fit the content. * * @default true * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get scaleContent():Boolean { return _scaleContent; } /** * @private */ public function set scaleContent(value:Boolean):void { if (_scaleContent != value) { _scaleContent = value; scaleContentChanged = true; invalidateDisplayList(); } dispatchEvent(new Event("scaleContentChanged")); } //---------------------------------- // showBusyCursor //---------------------------------- /** * @private * Storage for the scaleContent property. */ private var _showBusyCursor:Boolean = false; [Inspectable(category="General", defaultValue="true")] /** * A flag that indicates whether to show a busy cursor while * the content loads. * If true, shows a busy cursor while the content loads. * The default busy cursor is the mx.skins.halo.BusyCursor * as defined by the busyCursor property of the CursorManager class. * * @default false * * @see mx.managers.CursorManager * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get showBusyCursor():Boolean { return _showBusyCursor; } /** * @private */ public function set showBusyCursor(value:Boolean):void { if (_showBusyCursor != value) { _showBusyCursor = value; if (_showBusyCursor) CursorManager.registerToUseBusyCursor(this); else CursorManager.unRegisterToUseBusyCursor(this); } } //---------------------------------- // smoothBitmapContent //---------------------------------- /** * @private * Storage for the smoothBitmapContent property. */ private var _smoothBitmapContent:Boolean = false; [Bindable("smoothBitmapContentChanged")] [Inspectable(category="General", defaultValue="false")] /** * A flag that indicates whether to smooth the content when it * is scaled. Only Bitmap content can be smoothed. * If true, and the content is a Bitmap then smoothing property * of the content is set to true. * If false, the content isn't smoothed. * * @default false * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get smoothBitmapContent():Boolean { return _smoothBitmapContent; } /** * @private */ public function set smoothBitmapContent(value:Boolean):void { if (_smoothBitmapContent != value) { _smoothBitmapContent = value; smoothBitmapContentChanged = true; invalidateDisplayList(); } dispatchEvent(new Event("smoothBitmapContentChanged")); } //---------------------------------- // source //---------------------------------- /** * @private * Storage for the source property. */ private var _source:Object; [Bindable("sourceChanged")] [Inspectable(category="General", defaultValue="", format="File")] /** * The URL, object, class or string name of a class to * load as the content. * The source property takes the following form: * *

     *  source="URLOrPathOrClass"

* *

     *  source="@Embed(source='PathOrClass')"

* *

The value of the source property represents * a relative or absolute URL; a ByteArray representing a * SWF, GIF, JPEG, or PNG; an object that implements * IFlexDisplayObject; a class whose type implements IFlexDisplayObject; * or a String that represents a class.

* *

When you specify a path to a SWF, GIF, JPEG, PNG, or SVG file, * Flex automatically converts the file to the correct data type * for use with the SWFLoader control.

* *

If you omit the Embed statement, Flex loads the referenced file at runtime; * it is not packaged as part of the generated SWF file. * At runtime, the source property only supports the loading of * GIF, JPEG, PNG images, and SWF files.

* *

Flex Data Services users can use the SWFLoader control to * load a Flex application by using the following form:

* *

     *  source="MXMLPath.mxml.swf"

* *

Flex Data Services compiles the MXML file, * and returns the SWF file to the main application. This technique works well * with SWF files that add graphics or animations to an application, * but are not intended to have a large amount of user interaction. * If you import SWF files that require a large amount of user interaction, * you should build them as custom components.

* * @default null * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get source():Object { return _source; } /** * @private */ public function set source(value:Object):void { if (_source != value) { _source = value; contentChanged = true; invalidateProperties(); invalidateSize(); invalidateDisplayList() dispatchEvent(new Event("sourceChanged")); } } //---------------------------------- // trustContent //---------------------------------- /** * @private * Storage for the trustContent property. */ private var _trustContent:Boolean = false; [Bindable("trustContentChanged")] [Inspectable(defaultValue="false")] /** * If true, the content is loaded * into your security domain. * This means that the load fails if the content is in another domain * and that domain does not have a crossdomain.xml file allowing your * domain to access it. * This property only has an affect on the next load, * it will not start a new load on already loaded content. * *

The default value is false, which means load * any content without failing, but you cannot access the content. * Most importantly, the loaded content cannot * access your objects and code, which is the safest scenario. * Do not set this property to true unless you are absolutely sure of the safety * of the loaded content, especially active content like SWF files.

* *

You can also use the loaderContext property * to exactly determine how content gets loaded, * if setting trustContent does not exactly * meet your needs. * The loaderContext property causes the SWFLoader * to ignore the value of the trustContent property. * But, you should be familiar with the SecurityDomain * and ApplicationDomain classes to use the loaderContext property.

* * @default false * @see flash.system.SecurityDomain * @see flash.system.ApplicationDomain * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get trustContent():Boolean { return _trustContent; } /** * @private */ public function set trustContent(value:Boolean):void { if (_trustContent != value) { _trustContent = value; invalidateProperties(); invalidateSize(); invalidateDisplayList(); dispatchEvent(new Event("trustContentChanged")); } } //-------------------------------------------------------------------------- // // Properties of ISWFBridgeProvider // //-------------------------------------------------------------------------- /** * @inheritDoc * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get swfBridge():IEventDispatcher { return _swfBridge; } /** * @inheritDoc * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get childAllowsParent():Boolean { if (!isContentLoaded) return false; try { if (contentHolder is Loader) return Loader(contentHolder).contentLoaderInfo.childAllowsParent; } catch (error:Error) { // Error #2099: The loading object is not sufficiently loaded to provide this information. // We can get this if this content has been unload return false; } return true; } /** * @inheritDoc * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get parentAllowsChild():Boolean { if (!isContentLoaded) return false; try { if (contentHolder is Loader) return Loader(contentHolder).contentLoaderInfo.parentAllowsChild; } catch (error:Error) { // Error #2099: The loading object is not sufficiently loaded to provide this information. // We can get this if this content has been unload return false; } return true; } //-------------------------------------------------------------------------- // // Overridden methods: UIComponent // //-------------------------------------------------------------------------- /** * @private */ override protected function commitProperties():void { super.commitProperties(); if (contentChanged) { contentChanged = false; if (_autoLoad) load(_source); } } /** * @private */ override protected function measure():void { super.measure(); if (isContentLoaded) { var oldScaleX:Number = contentHolder.scaleX; var oldScaleY:Number = contentHolder.scaleY; contentHolder.scaleX = 1.0; contentHolder.scaleY = 1.0; measuredWidth = contentHolderWidth; measuredHeight = contentHolderHeight; contentHolder.scaleX = oldScaleX; contentHolder.scaleY = oldScaleY; } else { // If we're in the process of loading new content, // keep the old measuredWidth/measuredHeight for now. // Otherwise, we size down to 0,0 for a frame and then // resize back up once the new content has loaded. // Bug 151518. if (!_source || _source == "") { measuredWidth = 0; measuredHeight = 0; } } } /** * @private */ override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void { super.updateDisplayList(unscaledWidth, unscaledHeight); if (contentChanged) { contentChanged = false; if (_autoLoad) load(_source); } if (isContentLoaded) { // We will either scale the content to the size of the SWFLoader, // or we will scale the loader to the size of the content. if (_scaleContent && !brokenImage) doScaleContent(); else doScaleLoader(); scaleContentChanged = false; if (smoothBitmapContentChanged) { doSmoothBitmapContent(); smoothBitmapContentChanged = false; } } if (brokenImage && !brokenImageBorder) { var skinClass:Class = getStyle("brokenImageBorderSkin"); if (skinClass) { brokenImageBorder = IFlexDisplayObject(new skinClass()); if (brokenImageBorder is ISimpleStyleClient) ISimpleStyleClient(brokenImageBorder).styleName = this; addChild(DisplayObject(brokenImageBorder)); } } else if (!brokenImage && brokenImageBorder) { removeChild(DisplayObject(brokenImageBorder)); brokenImageBorder = null; } if (brokenImageBorder) brokenImageBorder.setActualSize(unscaledWidth, unscaledHeight); sizeShield(); } //-------------------------------------------------------------------------- // // Methods // //-------------------------------------------------------------------------- /** * Loads an image or SWF file. * The url argument can reference a GIF, JPEG, PNG, * or SWF file; you cannot use this method to load an SVG file. * Instead, you must load it using an Embed statement * with the source property. * * @param url Absolute or relative URL of the GIF, JPEG, PNG, * or SWF file to load. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function load(url:Object = null):void { if (url) _source = url; unloadContent(); isContentLoaded = false; brokenImage = false; useUnloadAndStop = false; // Prevent double loading an app when properties are set and // then load() is called directly from application code instead // of from commitProperties(). contentChanged = false; if (!_source || _source == "") return; loadContent(_source); } /** * Unloads an image or SWF file. After this method returns the * source property will be null. This is only supported * if the host Flash Player is version 10 or greater. If the host Flash * Player is less than version 10, then this method will unload the * content the same way as if source was set to null. * * This method attempts to unload SWF files by removing references to * EventDispatcher, NetConnection, Timer, Sound, or Video objects of the * child SWF file. As a result, the following occurs for the child SWF file * and the child SWF file's display list: * * * @param invokeGarbageCollector Provides a hint to the garbage collector to run * on the child SWF objects (true) or not (false). * If you are unloading many objects asynchronously, setting the * gc parameter to false might improve application * performance. However, if the parameter is set to false, media * and display objects of the child SWF file might persist in memory after * the child SWF has been unloaded. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function unloadAndStop(invokeGarbageCollector:Boolean = true):void { useUnloadAndStop = true; unloadAndStopGC = invokeGarbageCollector; source = null; // this will cause an unload unless autoload is true if (!autoLoad) load(null); } //-------------------------------------------------------------------------- // // ISWFLoader // //-------------------------------------------------------------------------- /** * @inheritDoc * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function getVisibleApplicationRect(allApplications:Boolean=false):Rectangle { var rect:Rectangle = getVisibleRect(); if (allApplications) rect = systemManager.getVisibleApplicationRect(rect); return rect; } /** * @private * * Unload any existing content. */ private function unloadContent():void { if (contentHolder) { if (isContentLoaded) { // can get rid of bitmap data if it's an image on unload // this helps with garbage collection (SDK-9533) var imageData:Bitmap; if (contentHolder is Loader) { var contentLoader:Loader = Loader(contentHolder); try { if (contentLoader.content is Bitmap) { imageData = Bitmap(contentLoader.content); if (imageData.bitmapData) imageData.bitmapData = null; } } catch(error:Error) { // Ignore any errors trying to access the Bitmap // b/c we may cause a security violation trying to do it } if (_swfBridge) { var request:SWFBridgeEvent = new SWFBridgeEvent( SWFBridgeEvent.BRIDGE_APPLICATION_UNLOADING, false, false, _swfBridge); _swfBridge.dispatchEvent(request); } if (contentLoader.contentLoaderInfo.contentType == "application/x-shockwave-flash" && contentLoader.contentLoaderInfo.parentAllowsChild && contentLoader.contentLoaderInfo.childAllowsParent && contentLoader.content) { contentLoader.content.removeEventListener(Request.GET_PARENT_FLEX_MODULE_FACTORY_REQUEST, contentHolder_getFlexModuleFactoryRequestHandler); } contentHolder.removeEventListener(Event.ADDED, contentHolder_addedHandler); removeInitSystemManagerCompleteListener(contentLoader.contentLoaderInfo); if (useUnloadAndStop) contentLoader.unloadAndStop(unloadAndStopGC); else contentLoader.unload(); if (!explicitLoaderContext) _loaderContext = null; } else { if (contentHolder is Bitmap) { imageData = Bitmap(contentHolder); if (imageData.bitmapData) imageData.bitmapData = null; } } } else { if (contentHolder is Loader) { try { Loader(contentHolder).close(); } catch(error:Error) { // Ignore any errors thrown by close() } } } // when SWFLoader/Image is used with renderer // recycling and the content is a DisplayObject instance // the instance can be stolen from us while // we're on the free list try { if (contentHolder.parent == this) removeChild(contentHolder); } catch(error:Error) { try { // just try to remove it anyway removeChild(contentHolder); } catch(error1:Error) { // Ignore any errors thrown by removeChild() } } contentHolder = null; } } /** * @private * If changes are made to this method, make sure to look at * RectangularBorder.updateDisplayList() * to see if changes are needed there as well. */ private function loadContent(classOrString:Object):void { var child:DisplayObject; var cls:Class; var url:String; var byteArray:ByteArray; var loader:Loader; if (classOrString is Class) { // We've got a class. Use it. cls = Class(classOrString); } else if (classOrString is String) { // We've got a string. First we'll see if it is a class name, // otherwise just use the string. try { cls = Class(systemManager.getDefinitionByName(String(classOrString))); } catch(e:Error) { // ignore } url = String(classOrString); } else if (classOrString is ByteArray) { byteArray = ByteArray(classOrString); } else { // We have something that is not a class or string (XMLNode, for // example). Call toString() and try to load it. url = classOrString.toString(); } // Create a child UIComponent based on a class reference, such as Button. if (cls) { contentHolder = child = new cls(); contentHolder.addEventListener(Event.ADDED, contentHolder_addedHandler, false, 0, true); addChild(child); contentLoaded(); } else if (classOrString is DisplayObject) { contentHolder = child = DisplayObject(classOrString); addChild(child); contentLoaded(); // Listen for requests to get the flex module factory. contentHolder.addEventListener(Request.GET_PARENT_FLEX_MODULE_FACTORY_REQUEST, contentHolder_getFlexModuleFactoryRequestHandler); } else if (byteArray) { loader = new FlexLoader(); contentHolder = child = loader; addChild(child); loader.contentLoaderInfo.addEventListener( Event.COMPLETE, contentLoaderInfo_completeEventHandler); loader.contentLoaderInfo.addEventListener( Event.INIT, contentLoaderInfo_initEventHandler); loader.contentLoaderInfo.addEventListener( IOErrorEvent.IO_ERROR, contentLoaderInfo_ioErrorEventHandler); loader.contentLoaderInfo.addEventListener( Event.UNLOAD, contentLoaderInfo_unloadEventHandler); // if loaderContext null, it will use default, which is AppDomain // of child of Loader's context loader.loadBytes(byteArray, loaderContext); } else if (url) { // Create an instance of the Flash Player Loader class to do all the work loader = new FlexLoader(); contentHolder = child = loader; // addChild needs to be called before load() addChild(loader); // Forward the events from the Flash Loader to anyone // who has registered as an event listener on this Loader. loader.contentLoaderInfo.addEventListener( Event.COMPLETE, contentLoaderInfo_completeEventHandler); loader.contentLoaderInfo.addEventListener( HTTPStatusEvent.HTTP_STATUS, contentLoaderInfo_httpStatusEventHandler); loader.contentLoaderInfo.addEventListener( Event.INIT, contentLoaderInfo_initEventHandler); loader.contentLoaderInfo.addEventListener( IOErrorEvent.IO_ERROR, contentLoaderInfo_ioErrorEventHandler); loader.contentLoaderInfo.addEventListener( Event.OPEN, contentLoaderInfo_openEventHandler); loader.contentLoaderInfo.addEventListener( ProgressEvent.PROGRESS, contentLoaderInfo_progressEventHandler); loader.contentLoaderInfo.addEventListener( SecurityErrorEvent.SECURITY_ERROR, contentLoaderInfo_securityErrorEventHandler); loader.contentLoaderInfo.addEventListener( Event.UNLOAD, contentLoaderInfo_unloadEventHandler); // are we in a debug player and this was a debug=true request if ( (Capabilities.isDebugger == true) && (url.indexOf(".jpg") == -1) && (LoaderUtil.normalizeURL( FlexGlobals.topLevelApplication.systemManager.loaderInfo).indexOf("debug=true") > -1) ) url = url + ( (url.indexOf("?") > -1) ? "&debug=true" : "?debug=true" ); // make relative paths relative to the SWF loading it, not the top-level SWF if (!(url.indexOf(":") > -1 || url.indexOf("/") == 0 || url.indexOf("\\") == 0)) { var rootURL:String; if (SystemManagerGlobals.bootstrapLoaderInfoURL != null && SystemManagerGlobals.bootstrapLoaderInfoURL != "") rootURL = SystemManagerGlobals.bootstrapLoaderInfoURL; else if (root) rootURL = LoaderUtil.normalizeURL(root.loaderInfo); else if (systemManager) rootURL = LoaderUtil.normalizeURL(DisplayObject(systemManager).loaderInfo); url = LoaderUtil.OSToPlayerURI(url, LoaderUtil.isLocal(rootURL ? rootURL : url)); if (rootURL) url = LoaderUtil.createAbsoluteURL(rootURL, url); } else { url = LoaderUtil.OSToPlayerURI(url, LoaderUtil.isLocal(url)); } requestedURL = new URLRequest(url); var lc:LoaderContext = loaderContext; if (!lc) { lc = new LoaderContext(); _loaderContext = lc; var currentDomain:ApplicationDomain; // Try to use the application domain of this component from // the moduleFactory. If we don't have a moduleFactory then // fallback to using ApplicationDomain.currentDomain which // could give us a parent ApplicationDomain of where the first // SWFLoader was used. If no SWFLoaders were used by parent // applications or modules then ApplicationDomain.currentDomain // will be correct. if (moduleFactory && FlexVersion.compatibilityVersion >= FlexVersion.VERSION_4_0) currentDomain = moduleFactory.info()["currentDomain"]; else currentDomain = ApplicationDomain.currentDomain; // To get a peer application domain (relative to framework classes), // get the topmost parent domain of the current domain. This // will either be the application domain of the // bootstrap loader (non-framework classes), or null. Either way we get // an application domain free of framework classes. if (loadForCompatibility) { // the AD.currentDomain.parentDomain could be null, // the domain of the top-level system manager, or // the bootstrap loader. The bootstrap loader will always be topmost // if it is present. var appDomain:ApplicationDomain = currentDomain.parentDomain; var topmostDomain:ApplicationDomain = null; while (appDomain) { topmostDomain = appDomain; appDomain = appDomain.parentDomain; } lc.applicationDomain = new ApplicationDomain(topmostDomain); } if (trustContent) { lc.securityDomain = SecurityDomain.currentDomain; } else if (!loadForCompatibility) { attemptingChildAppDomain = true; // assume the best, which is that it is in the same domain and // we can make it a child app domain. lc.applicationDomain = new ApplicationDomain(currentDomain); } } loader.load(requestedURL, lc); } else { var message:String = resourceManager.getString( "controls", "notLoadable", [ source ]); throw new Error(message); } // contentHolder should inherit the layoutDirection // (sometimes its an asset which defaults to LTR). if (contentHolder && contentHolder is ILayoutDirectionElement) ILayoutDirectionElement(contentHolder).layoutDirection = null; invalidateDisplayList(); } /** * @private * Called when the content has successfully loaded. */ protected function contentLoaded():void { isContentLoaded = true; // For externally loaded content, use the loaderInfo structure var loaderInfo:LoaderInfo; if (contentHolder is Loader) loaderInfo = Loader(contentHolder).contentLoaderInfo; resizableContent = false; if (loaderInfo) { if (loaderInfo.contentType == "application/x-shockwave-flash") resizableContent = true; if (resizableContent) { try { if (Loader(contentHolder).content is IFlexDisplayObject) flexContent = true; else flexContent = swfBridge != null; } catch(e:Error) { // trace("contentLoader: " + e); flexContent = swfBridge != null; } } } try { if (tabChildren && contentHolder is Loader && (loaderInfo.contentType == "application/x-shockwave-flash" || Loader(contentHolder).content is DisplayObjectContainer)) { Loader(contentHolder).tabChildren = true; DisplayObjectContainer(Loader(contentHolder).content).tabChildren = true; } } catch(e:Error) { // eat security errors from x-domain content. } invalidateSize(); invalidateDisplayList(); } /** * @private * If scaleContent = true then two situations arise: * 1) the SWFLoader has explicitWidth/Height set so we * simply scale or resize the content to those dimensions; or * 2) the SWFLoader doesn't have explicitWidth/Height. * In this case we should have had our measure() method called * which would set the measuredWidth/Height to that of the content, * and when we pass through this code we should just end up at scale = 1.0. */ private function doScaleContent():void { if (!isContentLoaded) return; // if not a SWF, then we scale it, otherwise we just set the size of the SWF. if (!resizableContent || (maintainAspectRatio && !flexContent)) { // Make sure any previous scaling is undone. unScaleContent(); // Scale the content to the size of the SWFLoader, preserving aspect ratio. var interiorWidth:Number = unscaledWidth; var interiorHeight:Number = unscaledHeight; var contentWidth:Number = contentHolderWidth; var contentHeight:Number = contentHolderHeight; var x:Number = 0; var y:Number = 0; // bug 84294 a swf may still not have size at this point var newXScale:Number = contentWidth == 0 ? 1 : interiorWidth / contentWidth; var newYScale:Number = contentHeight == 0 ? 1 : interiorHeight / contentHeight; var scale:Number; if (_maintainAspectRatio) { if (newXScale > newYScale) { x = Math.floor((interiorWidth - contentWidth * newYScale) * getHorizontalAlignValue()); scale = newYScale; } else { y = Math.floor((interiorHeight - contentHeight * newXScale) * getVerticalAlignValue()); scale = newXScale; } // Scale by the same amount in both directions. contentHolder.scaleX = scale; contentHolder.scaleY = scale; } else { contentHolder.scaleX = newXScale; contentHolder.scaleY = newYScale; } contentHolder.x = x; contentHolder.y = y; } else { contentHolder.x = 0; contentHolder.y = 0; var w:Number = unscaledWidth; var h:Number = unscaledHeight; if (contentHolder is Loader) { var holder:Loader = Loader(contentHolder); try { // don't resize contentHolder until after it is layed out if (getContentSize().x > 0) { var sizeSet:Boolean = false; if (holder.contentLoaderInfo.contentType == "application/x-shockwave-flash") { if (childAllowsParent) { if (holder.content is IFlexDisplayObject) { IFlexDisplayObject(holder.content).setActualSize(w, h); sizeSet = true; } } if (!sizeSet && swfBridge) { swfBridge.dispatchEvent(new SWFBridgeRequest(SWFBridgeRequest.SET_ACTUAL_SIZE_REQUEST, false, false, null, { width: w, height: h})); sizeSet = true; } } if (!sizeSet) { // Bug 142705 - we can't just set width and height here. If the SWF content // does not fill the stage, the width/height of the content holder is NOT // the same as the loaderInfo width/height. If we just set width/height // here is can scale the content in unpredictable ways. var lInfo:LoaderInfo = holder.contentLoaderInfo; if (lInfo) { contentHolder.scaleX = w / lInfo.width; contentHolder.scaleY = h / lInfo.height; } else { contentHolder.width = w; contentHolder.height = h; } } } else if (childAllowsParent && !(holder.content is IFlexDisplayObject)) { contentHolder.width = w; contentHolder.height = h; } } catch(error:Error) { contentHolder.width = w; contentHolder.height = h; } if (!parentAllowsChild) contentHolder.scrollRect = new Rectangle(0, 0, w / contentHolder.scaleX, h / contentHolder.scaleY); } else { contentHolder.width = w; contentHolder.height = h; } } } /** * @private * If scaleContent = false then two situations arise: * 1) the SWFLoader has been given explicitWidth/Height so we don't change * the size of the SWFLoader and simply place the content at 0,0 * and don't scale it and clip it if needed; or * 2) the SWFLoader does not have explicitWidth/Height in which case * our measure() method should have been called and we should have * been given the right size. * However if some other constraint applies we simply clip as in * situation #1, which is why there is only one code path in here. */ private function doScaleLoader():void { if (!isContentLoaded) return; unScaleContent(); var w:Number = unscaledWidth; var h:Number = unscaledHeight; if ((contentHolderWidth > w) || (contentHolderHeight > h) || !parentAllowsChild) { contentHolder.scrollRect = new Rectangle(0, 0, w, h); } else { contentHolder.scrollRect = null; } contentHolder.x = (w - contentHolderWidth) * getHorizontalAlignValue(); contentHolder.y = (h - contentHolderHeight) * getVerticalAlignValue(); } /** * @private */ private function doSmoothBitmapContent():void { if (content is Bitmap) (content as Bitmap).smoothing = _smoothBitmapContent; } /** * @private */ private function unScaleContent():void { contentHolder.scaleX = 1.0; contentHolder.scaleY = 1.0; contentHolder.x = 0; contentHolder.y = 0; } /** * @private */ private function getHorizontalAlignValue():Number { var horizontalAlign:String = getStyle("horizontalAlign"); if (horizontalAlign == "left") return 0; else if (horizontalAlign == "right") return 1; // default = center return 0.5; } /** * @private */ private function getVerticalAlignValue():Number { var verticalAlign:String = getStyle("verticalAlign"); if (verticalAlign == "top") return 0; else if (verticalAlign == "bottom") return 1; // default = middle return 0.5; } /** * @private * * Dispatch an invalidate request to a parent application using * a sandbox bridge. */ private function dispatchInvalidateRequest(invalidateProperites:Boolean, invalidateSize:Boolean, invalidateDisplayList:Boolean):void { var sm:ISystemManager = systemManager; var mp:IMarshalSystemManager = IMarshalSystemManager(systemManager.getImplementation("mx.managers::IMarshalSystemManager")); if (!mp || !mp.useSWFBridge()) return; var bridge:IEventDispatcher = mp.swfBridgeGroup.parentBridge; var flags:uint = 0; if (invalidateProperites) flags |= InvalidateRequestData.PROPERTIES; if (invalidateSize) flags |= InvalidateRequestData.SIZE; if (invalidateDisplayList) flags |= InvalidateRequestData.DISPLAY_LIST; var request:SWFBridgeRequest = new SWFBridgeRequest( SWFBridgeRequest.INVALIDATE_REQUEST, false, false, bridge, flags); bridge.dispatchEvent(request); } //-------------------------------------------------------------------------- // // Event handlers // //-------------------------------------------------------------------------- /** * @private */ private function initializeHandler(event:FlexEvent):void { if (contentChanged) { contentChanged = false; if (_autoLoad) load(_source); } } /** * @private */ private function addedToStageHandler(event:Event):void { systemManager.getSandboxRoot().addEventListener(InterManagerRequest.DRAG_MANAGER_REQUEST, mouseShieldHandler, false, 0, true); } /** * @private */ mx_internal function contentLoaderInfo_completeEventHandler(event:Event):void { // Sometimes we interrupt a load to start another load after // the bytes are in but before the complete event is dispatched. // In this case we get an IOError when we call close() // and the complete event is dispatched anyway. // Meanwhile we've started the new load. // We ignore the complete if the contentHolder doesn't match // because that means it was for the old content if (LoaderInfo(event.target).loader != contentHolder) return; // Redispatch the event from this SWFLoader. dispatchEvent(event); contentLoaded(); } /** * @private */ private function contentLoaderInfo_httpStatusEventHandler( event:HTTPStatusEvent):void { // Redispatch the event from this SWFLoader. dispatchEvent(event); } /** * @private */ private function contentLoaderInfo_initEventHandler(event:Event):void { // Redispatch the event from this SWFLoader. dispatchEvent(event); // if we are loading a swf listen of a message if it ends up needing to // use a sandbox bridge to communicate. var loaderInfo:LoaderInfo = LoaderInfo(event.target); addInitSystemManagerCompleteListener(loaderInfo.loader.contentLoaderInfo); // Listen for requests to get the flex module factory. if (loaderInfo.contentType == "application/x-shockwave-flash" && loaderInfo.parentAllowsChild && loaderInfo.childAllowsParent && loaderInfo.content) { loaderInfo.content.addEventListener(Request.GET_PARENT_FLEX_MODULE_FACTORY_REQUEST, contentHolder_getFlexModuleFactoryRequestHandler); } } /** * @private * * If we are loading a swf, listen for a message from the swf telling us it was loading * into an application domain where it needs to use a sandbox bridge to communicate. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ private function addInitSystemManagerCompleteListener(loaderInfo:LoaderInfo):void { if (loaderInfo.contentType == "application/x-shockwave-flash") { var bridge:EventDispatcher = loaderInfo.sharedEvents; bridge.addEventListener(SWFBridgeEvent.BRIDGE_NEW_APPLICATION, initSystemManagerCompleteEventHandler); } } /** * @private * * Remove the listener after the swf is loaded. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ private function removeInitSystemManagerCompleteListener(loaderInfo:LoaderInfo):void { if (loaderInfo.contentType == "application/x-shockwave-flash") { var bridge:EventDispatcher = loaderInfo.sharedEvents; bridge.removeEventListener(SWFBridgeEvent.BRIDGE_NEW_APPLICATION, initSystemManagerCompleteEventHandler); } } /** * @private */ private function contentLoaderInfo_ioErrorEventHandler( event:IOErrorEvent):void { // Error loading content, show the broken image. source = getStyle("brokenImageSkin"); // Force the load of the broken image skin here, since that will // clear the brokenImage flag. After the image is loaded we set // the brokenImage flag. load(); contentChanged = false; brokenImage = true; // Redispatch the event from this SWFLoader, // but only if there is a listener. // If there are no listeners for ioError event, // a runtime error is displayed. if (hasEventListener(event.type)) dispatchEvent(event); if (contentHolder is Loader) removeInitSystemManagerCompleteListener(Loader(contentHolder).contentLoaderInfo); } /** * @private */ private function contentLoaderInfo_openEventHandler(event:Event):void { // Redispatch the event from this SWFLoader. dispatchEvent(event); } /** * @private */ private function contentLoaderInfo_progressEventHandler( event:ProgressEvent):void { _bytesTotal = event.bytesTotal; _bytesLoaded = event.bytesLoaded; // Redispatch the event from this SWFLoader. dispatchEvent(event); } /** * @private */ private function contentLoaderInfo_securityErrorEventHandler( event:SecurityErrorEvent):void { if (attemptingChildAppDomain) { attemptingChildAppDomain = false; var lc:LoaderContext = new LoaderContext(); _loaderContext = lc; callLater(load); return; } // Redispatch the event from this SWFLoader. dispatchEvent(event); if (contentHolder is Loader) removeInitSystemManagerCompleteListener(Loader(contentHolder).contentLoaderInfo); } /** * @private */ private function contentLoaderInfo_unloadEventHandler(event:Event):void { isContentLoaded = false; // Redispatch the event from this SWFLoader. dispatchEvent(event); // remove the sandbox bridge if we had one. if (_swfBridge) { _swfBridge.removeEventListener(SWFBridgeRequest.INVALIDATE_REQUEST, invalidateRequestHandler); var sm:ISystemManager = systemManager; var mp:IMarshalSystemManager = IMarshalSystemManager(systemManager.getImplementation("mx.managers::IMarshalSystemManager")); mp.removeChildBridge(_swfBridge); _swfBridge = null; } } /** * @private * * @param request Use type Event instead of Request because the event may be send from * another ApplicationDomain (A.2). */ private function contentHolder_getFlexModuleFactoryRequestHandler(request:Event):void { if ("value" in request) request["value"] = moduleFactory; } /** * @private * * Used when we are loading a class. If the embedded class is a SWF, then wait for * the added event where the target is a IFlexModuleFactory. This will be message after * the event for the class being added. * * All this is done to support the module factory parent request when loading an * embedded swf. */ private function contentHolder_addedHandler(event:Event):void { if (event.target == contentHolder) return; // wait for next message if (event.target is IFlexModuleFactory) { // Listen for requests to get the flex module factory. event.target.addEventListener(Request.GET_PARENT_FLEX_MODULE_FACTORY_REQUEST, contentHolder_getFlexModuleFactoryRequestHandler); } contentHolder.removeEventListener(Event.ADDED, contentHolder_addedHandler); } /** * @private * * Message dispatched from System Manager. This gives us the child bridge * of the application we loaded. */ private function initSystemManagerCompleteEventHandler(event:Event):void { var eObj:Object = Object(event); // make sure this is the child we created by checking the loader info. if (contentHolder is Loader && eObj.data == Loader(contentHolder).contentLoaderInfo.sharedEvents) { _swfBridge = Loader(contentHolder).contentLoaderInfo.sharedEvents; flexContent = true; // if we got validated before we got this event // then we might have accidentally scaled the loader unScaleContent(); var sm:ISystemManager = systemManager; IMarshalSystemManager(sm.getImplementation("mx.managers::IMarshalSystemManager")).addChildBridge(_swfBridge, this); removeInitSystemManagerCompleteListener(Loader(contentHolder).contentLoaderInfo); _swfBridge.addEventListener(SWFBridgeRequest.INVALIDATE_REQUEST, invalidateRequestHandler); } } /** * @private * * Handle invalidate requests send from the child using the * sandbox bridge. * */ private function invalidateRequestHandler(event:Event):void { if (event is SWFBridgeRequest) return; // handle request var request:SWFBridgeRequest = SWFBridgeRequest.marshal(event); var invalidateFlags:uint = uint(request.data); if (invalidateFlags & InvalidateRequestData.PROPERTIES) invalidateProperties(); if (invalidateFlags & InvalidateRequestData.SIZE) invalidateSize(); if (invalidateFlags & InvalidateRequestData.DISPLAY_LIST) invalidateDisplayList(); // redispatch the request up the parent chain dispatchInvalidateRequest( (invalidateFlags & InvalidateRequestData.PROPERTIES) != 0, (invalidateFlags & InvalidateRequestData.SIZE) != 0, (invalidateFlags & InvalidateRequestData.DISPLAY_LIST) != 0); } /** * @private * * Put up or takedown a mouseshield that covers the content * of the application we loaded. */ private function mouseShieldHandler(event:Event):void { if (event["name"] != "mouseShield") return; if (!isContentLoaded || parentAllowsChild) return; if (event["value"]) { if (!mouseShield) { mouseShield = new Sprite(); mouseShield.graphics.beginFill(0, 0); mouseShield.graphics.drawRect(0, 0, 100, 100); mouseShield.graphics.endFill(); } if (!mouseShield.parent) addChild(mouseShield); sizeShield(); } else { if (mouseShield && mouseShield.parent) removeChild(mouseShield) } } /** * @private * * size the shield if needed */ private function sizeShield():void { if (mouseShield && mouseShield.parent) { mouseShield.width = unscaledWidth; mouseShield.height = unscaledHeight; } } /** * @private * * Just push this change, wholesale, onto the loaded content, if the * content is another Flex SWF */ override public function regenerateStyleCache(recursive:Boolean):void { super.regenerateStyleCache(recursive); try { var sm:ISystemManager = content as ISystemManager; if (sm != null) { var cm:Object = sm.getImplementation("mx.managers::ISystemManagerChildManager"); Object(cm).regenerateStyleCache(recursive); } } catch(error:Error) { // Ignore any errors trying to access the content // b/c we may cause a security violation trying to do it // Also ignore if the sm doesn't have a regenerateStyleCache method } } /** * @private * * Just push this change, wholesale, onto the loaded content, if the * content is another Flex SWF */ override public function notifyStyleChangeInChildren(styleProp:String, recursive:Boolean):void { super.notifyStyleChangeInChildren(styleProp, recursive); try { var sm:ISystemManager = content as ISystemManager; if (sm != null) { var cm:Object = sm.getImplementation("mx.managers::ISystemManagerChildManager"); Object(cm).notifyStyleChangeInChildren(styleProp, recursive); } } catch(error:Error) { // Ignore any errors trying to access the content // b/c we may cause a security violation trying to do it // Also ignore if the sm doesn't have a notifyStyleChangeInChildren method } } /** * @private * @throws Error - #2099 if the content has been unloaded */ private function getContentSize():Point { var pt:Point = new Point(); if (!contentHolder is Loader) return pt; var holder:Loader = Loader(contentHolder); if (holder.contentLoaderInfo.childAllowsParent) { pt.x = holder.content.width; pt.y = holder.content.height; } else { var bridge:IEventDispatcher = swfBridge; if (bridge) { var request:SWFBridgeRequest = new SWFBridgeRequest(SWFBridgeRequest.GET_SIZE_REQUEST); bridge.dispatchEvent(request); pt.x = request.data.width; pt.y = request.data.height; } } // don't return zero out of here otherwise the Loader's scale goes to zero if (pt.x == 0) pt.x = holder.contentLoaderInfo.width; if (pt.y == 0) pt.y = holder.contentLoaderInfo.height; return pt; } /** * @private * The default handler for the MouseEvent.CLICK event. * * @param The event object. */ protected function clickHandler(event:MouseEvent):void { if (!enabled) { // Prevent the propagation of click from a disabled component. // This is conceptually a higher-level event and // developers will expect their click handlers not to fire // if the Button is disabled. event.stopImmediatePropagation(); return; } } } }