blob: 9eb9bea653f1155db047a0e1e26b13954e634856 [file] [log] [blame]
////////////////////////////////////////////////////////////////////////////////
//
// 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.managers
{
import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
import flash.display.Graphics;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.display.Stage;
import flash.display.StageAlign;
import flash.display.StageQuality;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.EventPhase;
import flash.events.FocusEvent;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.system.ApplicationDomain;
import flash.text.Font;
import flash.text.TextFormat;
import flash.ui.Keyboard;
import flash.utils.Dictionary;
import flash.utils.Timer;
import flash.utils.getQualifiedClassName;
import mx.core.FlexSprite;
import mx.core.IChildList;
import mx.core.IFlexDisplayObject;
import mx.core.IFlexModuleFactory;
import mx.core.IInvalidating;
import mx.core.IRawChildrenContainer;
import mx.core.IUIComponent;
import mx.core.RSLData;
import mx.core.RSLItem;
import mx.core.Singleton;
import mx.core.mx_internal;
import mx.events.DynamicEvent;
import mx.events.FlexEvent;
import mx.events.RSLEvent;
import mx.events.Request;
import mx.events.SandboxMouseEvent;
import mx.preloaders.Preloader;
import mx.utils.DensityUtil;
import mx.utils.LoaderUtil;
// NOTE: Minimize the non-Flash classes you import here.
// Any dependencies of SystemManager have to load in frame 1,
// before the preloader, or anything else, can be displayed.
use namespace mx_internal;
//--------------------------------------
// Events
//--------------------------------------
/**
* Dispatched when the application has finished initializing
*
* @eventType mx.events.FlexEvent.APPLICATION_COMPLETE
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Event(name="applicationComplete", type="mx.events.FlexEvent")]
/**
* Dispatched every 100 milliseconds when there has been no keyboard
* or mouse activity for 1 second.
*
* @eventType mx.events.FlexEvent.IDLE
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Event(name="idle", type="mx.events.FlexEvent")]
/**
* Dispatched when the Stage is resized.
*
* @eventType flash.events.Event.RESIZE
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Event(name="resize", type="flash.events.Event")]
/**
* The SystemManager class manages an application window.
* Every application that runs on the desktop or in a browser
* has an area where the visuals of the application are
* displayed.
* It may be a window in the operating system
* or an area within the browser. That area is an application window
* and different from an instance of <code>mx.core.Application</code>, which
* is the main, or top-level, window within an application.
*
* <p>Every application has a SystemManager.
* The SystemManager sends an event if
* the size of the application window changes (you cannot change it from
* within the application, but only through interaction with the operating
* system window or browser). It parents all displayable things within the
* application like the main mx.core.Application instance and all popups,
* tooltips, cursors, and so on. Any object parented by the SystemManager is
* considered to be a top-level window, even tooltips and cursors.</p>
*
* <p>The SystemManager also switches focus between top-level windows if there
* are more than one IFocusManagerContainer displayed and users are interacting
* with components within the IFocusManagerContainers. </p>
*
* <p>All keyboard and mouse activity that is not expressly trapped is seen by
* the SystemManager, making it a good place to monitor activity should you need
* to do so.</p>
*
* <p>If an application is loaded into another application, a SystemManager
* will still be created, but will not manage an application window,
* depending on security and domain rules.
* Instead, it will be the <code>content</code> of the <code>Loader</code>
* that loaded it and simply serve as the parent of the sub-application</p>
*
* <p>The SystemManager maintains multiple lists of children, one each for tooltips, cursors,
* popup windows. This is how it ensures that popup windows "float" above the main
* application windows and that tooltips "float" above that and cursors above that.
* If you simply examine the <code>numChildren</code> property or
* call the <code>getChildAt()</code> method on the SystemManager, you are accessing
* the main application window and any other windows that aren't popped up. To get the list
* of all windows, including popups, tooltips and cursors, use
* the <code>rawChildren</code> property.</p>
*
* <p>The SystemManager is the first display class created within an application.
* It is responsible for creating an <code>mx.preloaders.Preloader</code> that displays and
* <code>mx.preloaders.SparkDownloadProgressBar</code> while the application finishes loading,
* then creates the <code>mx.core.Application</code> instance.</p>
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public class SystemManager extends MovieClip
implements IChildList, IFlexDisplayObject,
IFlexModuleFactory, ISystemManager
{
include "../core/Version.as";
//--------------------------------------------------------------------------
//
// Class constants
//
//--------------------------------------------------------------------------
/**
* @private
* The number of milliseconds that must pass without any user activity
* before SystemManager starts dispatching 'idle' events.
*/
private static const IDLE_THRESHOLD:Number = 1000;
/**
* @private
* The number of milliseconds between each 'idle' event.
*/
private static const IDLE_INTERVAL:Number = 100;
//--------------------------------------------------------------------------
//
// Class variables
//
//--------------------------------------------------------------------------
/**
* @private
* An array of SystemManager instances loaded as child app domains
*/
mx_internal static var allSystemManagers:Dictionary = new Dictionary(true);
//--------------------------------------------------------------------------
//
// Constructor
//
//--------------------------------------------------------------------------
/**
* Constructor.
*
* <p>This is the starting point for all Flex applications.
* This class is set to be the root class of a Flex SWF file.
* Flash Player instantiates an instance of this class,
* causing this constructor to be called.</p>
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function SystemManager()
{
CONFIG::performanceInstrumentation
{
var perfUtil:mx.utils.PerfUtil = mx.utils.PerfUtil.getInstance();
perfUtil.startSampling("Application Startup", true /*absoluteTime*/);
perfUtil.markTime("SystemManager c-tor");
}
super();
// Loaded SWFs don't get a stage right away
// and shouldn't override the main SWF's setting anyway.
if (stage)
{
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
stage.quality = StageQuality.HIGH;
}
// If we don't have a stage then we are not top-level,
// unless there are no other top-level managers, in which
// case we got loaded by a non-Flex shell or are sandboxed.
if (SystemManagerGlobals.topLevelSystemManagers.length > 0 && !stage)
topLevel = false;
if (!stage)
isStageRoot = false;
if (topLevel)
SystemManagerGlobals.topLevelSystemManagers.push(this);
// Make sure to stop the playhead on the current frame.
stop();
// Listen for the last frame (param is 0-indexed) to be executed.
//addFrameScript(totalFrames - 1, frameEndHandler);
if (root && root.loaderInfo)
root.loaderInfo.addEventListener(Event.INIT, initHandler);
}
/**
* @private
*/
private function deferredNextFrame():void
{
if (currentFrame + 1 > totalFrames)
return;
if (currentFrame + 1 <= framesLoaded)
{
CONFIG::performanceInstrumentation
{
var perfUtil:mx.utils.PerfUtil = mx.utils.PerfUtil.getInstance();
perfUtil.markTime("SystemManager.nextFrame().start");
}
nextFrame();
CONFIG::performanceInstrumentation
{
perfUtil.markTime("SystemManager.nextFrame().end");
}
}
else
{
// Next frame isn't baked yet, so we'll check back...
nextFrameTimer = new Timer(100);
nextFrameTimer.addEventListener(TimerEvent.TIMER,
nextFrameTimerHandler);
nextFrameTimer.start();
}
}
//--------------------------------------------------------------------------
//
// Variables
//
//--------------------------------------------------------------------------
/**
* @private
* Whether we are in the top-level list or not;
* top-level means we are the highest level SystemManager
* for this stage.
*/
mx_internal var topLevel:Boolean = true;
/**
* @private
*
* true if redipatching a resize event.
*/
private var isDispatchingResizeEvent:Boolean;
/**
* @private
* Whether we are the stage root or not.
* We are only the stage root if we were the root
* of the first SWF that got loaded by the player.
* Otherwise we could be top level but not stage root
* if we are loaded by some other non-Flex shell
* or are sandboxed.
*/
mx_internal var isStageRoot:Boolean = true;
/**
* @private
* Whether we are the first SWF loaded into a bootstrap
* and therefore, the topLevelRoot
*/
mx_internal var isBootstrapRoot:Boolean = false;
/**
* @private
* If we're not top level, then we delegate many things
* to the top level SystemManager.
*/
private var _topLevelSystemManager:ISystemManager;
/**
* @private
* The childAdded/removed code
*/
mx_internal var childManager:ISystemManagerChildManager;
/**
* cached value of the stage.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
private var _stage:Stage;
/**
* Depth of this object in the containment hierarchy.
* This number is used by the measurement and layout code.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
mx_internal var nestLevel:int = 0;
/**
* @private
* A reference to the preloader.
*/
mx_internal var preloader:Preloader;
/**
* @private
* The mouseCatcher is the 0th child of the SystemManager,
* behind the application, which is child 1.
* It is the same size as the stage and is filled with
* transparent pixels; i.e., they've been drawn, but with alpha 0.
*
* Its purpose is to make every part of the stage
* able to detect the mouse.
* For example, a Button puts a mouseUp handler on the SystemManager
* in order to capture mouseUp events that occur outside the Button.
* But if the children of the SystemManager don't have "drawn-on"
* pixels everywhere, the player won't dispatch the mouseUp.
* We can't simply fill the SystemManager itself with
* transparent pixels, because the player's pixel detection
* logic doesn't look at pixels drawn into the root DisplayObject.
*
* Here is an example of what would happen without the mouseCatcher:
* Run a fixed-size Application (e.g. width="600" height="600")
* in the standalone player. Make the player window larger
* to reveal part of the stage. Press a Button, drag off it
* into the stage area, and release the mouse button.
* Without the mouseCatcher, the Button wouldn't return to its "up" state.
*/
private var mouseCatcher:Sprite;
/**
* @private
* The top level window.
*/
mx_internal var topLevelWindow:IUIComponent;
/**
* @private
* Number of frames since the last mouse or key activity.
*/
mx_internal var idleCounter:int = 0;
/**
* @private
* The Timer used to determine when to dispatch idle events.
*/
private var idleTimer:Timer;
/**
* @private
* A timer used when it is necessary to wait before incrementing the frame
*/
private var nextFrameTimer:Timer = null;
/**
* @private
* Track which frame was last processed
*/
private var lastFrame:int;
/**
* @private
* A boolean as to whether we've seen COMPLETE event from preloader
*/
private var readyForKickOff:Boolean;
/**
* @private
*
* This variable exists only to provide a reference to this
* app's resource bundles. This application is opting
* into referencing its own resource bundles so the
* ResourceManager does not need to do it. This
* arrangement keeps the ResourceManager from pinning
* the application in memory.
*
* If this is the main app, then this variable will be null.
* If this is a sub-app then ResourceManagerImpl set
* this variable to the apps resource bundles. This variable
* is public so it is visible to ResourceManagerImpl but starts
* with an underscore to hint that it is an implementation detail
* and should not be relied on.
*/
public var _resourceBundles:Array;
/**
* @private
* Array of RSLData objects that represent the list of RSLs this
* module factory is loading. Each element of the Array is an
* Array of RSLData.
*/
private var rslDataList:Array
//--------------------------------------------------------------------------
//
// Overridden properties: DisplayObject
//
//--------------------------------------------------------------------------
//----------------------------------
// height
//----------------------------------
/**
* @private
*/
private var _height:Number;
/**
* The height of this object. For the SystemManager
* this should always be the width of the stage unless the application was loaded
* into another application. If the application was not loaded
* into another application, setting this value has no effect.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
override public function get height():Number
{
return _height;
}
//----------------------------------
// stage
//----------------------------------
/**
* @private
* get the main stage if we're loaded into another swf in the same sandbox
*/
override public function get stage():Stage
{
if (_stage)
return _stage;
var s:Stage = super.stage;
if (s)
{
_stage = s;
return s;
}
if (!topLevel && _topLevelSystemManager)
{
_stage = _topLevelSystemManager.stage;
return _stage;
}
// Case for version skew, we are a top level system manager, but
// a child of the top level root system manager and we have access
// to the stage.
if (!isStageRoot && topLevel)
{
var root:DisplayObject = getTopLevelRoot();
if (root)
{
_stage = root.stage;
return _stage;
}
}
return null;
}
//----------------------------------
// width
//----------------------------------
/**
* @private
*/
private var _width:Number;
/**
* The width of this object. For the SystemManager
* this should always be the width of the stage unless the application was loaded
* into another application. If the application was not loaded
* into another application, setting this value will have no effect.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
override public function get width():Number
{
return _width;
}
//--------------------------------------------------------------------------
//
// Overridden properties: DisplayObjectContainer
//
//--------------------------------------------------------------------------
//----------------------------------
// numChildren
//----------------------------------
/**
* The number of non-floating windows. This is the main application window
* plus any other windows added to the SystemManager that are not popups,
* tooltips or cursors.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
override public function get numChildren():int
{
return noTopMostIndex - applicationIndex;
}
//--------------------------------------------------------------------------
//
// Properties
//
//--------------------------------------------------------------------------
//----------------------------------
// allowDomainsInNewRSLs
//----------------------------------
/**
* @private
*/
private var _allowDomainsInNewRSLs:Boolean = true;
/**
* @inheritDoc
*
* @langversion 3.0
* @playerversion Flash 10.2
* @playerversion AIR 2.6
* @productversion Flex 4.5
*/
public function get allowDomainsInNewRSLs():Boolean
{
return _allowDomainsInNewRSLs;
}
/**
* @private
*/
public function set allowDomainsInNewRSLs(value:Boolean):void
{
_allowDomainsInNewRSLs = value;
}
//----------------------------------
// allowInsecureDomainsInNewRSLs
//----------------------------------
/**
* @private
*/
private var _allowInsecureDomainsInNewRSLs:Boolean = true;
/**
* @inheritDoc
*
* @langversion 3.0
* @playerversion Flash 10.2
* @playerversion AIR 2.6
* @productversion Flex 4.5
*/
public function get allowInsecureDomainsInNewRSLs():Boolean
{
return _allowInsecureDomainsInNewRSLs;
}
/**
* @private
*/
public function set allowInsecureDomainsInNewRSLs(value:Boolean):void
{
_allowInsecureDomainsInNewRSLs = value;
}
//----------------------------------
// application
//----------------------------------
/**
* The application parented by this SystemManager.
* SystemManagers create an instance of an Application
* even if they are loaded into another Application.
* Thus, this may not match mx.core.Application.application
* if the SWF has been loaded into another application.
* <p>Note that this property is not typed as mx.core.Application
* because of load-time performance considerations
* but can be coerced into an mx.core.Application.</p>
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get application():IUIComponent
{
return IUIComponent(_document);
}
//----------------------------------
// applicationIndex
//----------------------------------
/**
* @private
* Storage for the applicationIndex property.
*/
private var _applicationIndex:int = 1;
/**
* @private
* The index of the main mx.core.Application window, which is
* effectively its z-order.
*/
mx_internal function get applicationIndex():int
{
return _applicationIndex;
}
/**
* @private
*/
mx_internal function set applicationIndex(value:int):void
{
_applicationIndex = value;
}
//----------------------------------
// cursorChildren
//----------------------------------
/**
* @private
* Storage for the cursorChildren property.
*/
private var _cursorChildren:SystemChildrenList;
/**
* @inheritDoc
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get cursorChildren():IChildList
{
if (!topLevel)
return _topLevelSystemManager.cursorChildren;
if (!_cursorChildren)
{
_cursorChildren = new SystemChildrenList(this,
new QName(mx_internal, "toolTipIndex"),
new QName(mx_internal, "cursorIndex"));
}
return _cursorChildren;
}
//----------------------------------
// cursorIndex
//----------------------------------
/**
* @private
* Storage for the toolTipIndex property.
*/
private var _cursorIndex:int = 0;
/**
* @private
* The index of the highest child that is a cursor.
*/
mx_internal function get cursorIndex():int
{
return _cursorIndex;
}
/**
* @private
*/
mx_internal function set cursorIndex(value:int):void
{
var delta:int = value - _cursorIndex;
_cursorIndex = value;
}
//----------------------------------
// densityScale
//----------------------------------
/**
* @private
* Storage for the densityScale property
*/
private var _densityScale:Number = NaN;
/**
* The density scale factor of the application.
*
* When density scaling is enabled, Flex applies a scale factor based on
* the application author density and the density of the current device
* that Flex is running on.
*
* Returns 1.0 when there is no scaling.
*
* @see spark.components.Application#applicationDPI
* @see mx.core.DensityUtil
*
* @private
*/
mx_internal function get densityScale():Number
{
if (isNaN(_densityScale))
{
var applicationDPI:Number = info()["applicationDPI"];
var runtimeDPI:Number = DensityUtil.getRuntimeDPI();
_densityScale = DensityUtil.getDPIScale(applicationDPI, runtimeDPI);
if (isNaN(_densityScale))
_densityScale = 1;
}
return _densityScale;
}
//----------------------------------
// document
//----------------------------------
/**
* @private
* Storage for the document property.
*/
private var _document:Object;
/**
* @inheritDoc
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get document():Object
{
return _document;
}
/**
* @private
*/
public function set document(value:Object):void
{
_document = value;
}
//----------------------------------
// embeddedFontList
//----------------------------------
/**
* @private
* Storage for the fontList property.
*/
private var _fontList:Object = null;
/**
* A table of embedded fonts in this application. The
* object is a table indexed by the font name.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get embeddedFontList():Object
{
if (_fontList == null)
{
_fontList = {};
var o:Object = info()["fonts"];
var p:String;
for (p in o)
{
_fontList[p] = o[p];
}
// Top level systemManager may not be defined if SWF is loaded
// as a background image in download progress bar.
if (!topLevel && _topLevelSystemManager)
{
var fl:Object = _topLevelSystemManager.embeddedFontList;
for (p in fl)
{
_fontList[p] = fl[p];
}
}
}
return _fontList;
}
//----------------------------------
// explicitHeight
//----------------------------------
/**
* @private
*/
private var _explicitHeight:Number;
/**
* The explicit width of this object. For the SystemManager
* this should always be NaN unless the application was loaded
* into another application. If the application was not loaded
* into another application, setting this value has no effect.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get explicitHeight():Number
{
return _explicitHeight;
}
/**
* @private
*/
public function set explicitHeight(value:Number):void
{
_explicitHeight = value;
}
//----------------------------------
// explicitWidth
//----------------------------------
/**
* @private
*/
private var _explicitWidth:Number;
/**
* The explicit width of this object. For the SystemManager
* this should always be NaN unless the application was loaded
* into another application. If the application was not loaded
* into another application, setting this value has no effect.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get explicitWidth():Number
{
return _explicitWidth;
}
/**
* @private
*/
public function set explicitWidth(value:Number):void
{
_explicitWidth = value;
}
//----------------------------------
// focusPane
//----------------------------------
/**
* @private
*/
private var _focusPane:Sprite;
/**
* @copy mx.core.UIComponent#focusPane
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get focusPane():Sprite
{
return _focusPane;
}
/**
* @private
*/
public function set focusPane(value:Sprite):void
{
if (value)
{
addChild(value);
value.x = 0;
value.y = 0;
value.scrollRect = null;
_focusPane = value;
}
else
{
removeChild(_focusPane);
_focusPane = null;
}
}
//----------------------------------
// isProxy
//----------------------------------
/**
* True if SystemManager is a proxy and not a root class
*/
public function get isProxy():Boolean
{
return false;
}
//----------------------------------
// measuredHeight
//----------------------------------
/**
* The measuredHeight is the explicit or measuredHeight of
* the main mx.core.Application window
* or the starting height of the SWF if the main window
* has not yet been created or does not exist.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get measuredHeight():Number
{
return topLevelWindow ?
topLevelWindow.getExplicitOrMeasuredHeight() :
loaderInfo.height;
}
//----------------------------------
// measuredWidth
//----------------------------------
/**
* The measuredWidth is the explicit or measuredWidth of
* the main mx.core.Application window,
* or the starting width of the SWF if the main window
* has not yet been created or does not exist.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get measuredWidth():Number
{
return topLevelWindow ?
topLevelWindow.getExplicitOrMeasuredWidth() :
loaderInfo.width;
}
//----------------------------------
// noTopMostIndex
//----------------------------------
/**
* @private
* Storage for the noTopMostIndex property.
*/
private var _noTopMostIndex:int = 0;
/**
* @private
* The index of the highest child that isn't a topmost/popup window
*/
mx_internal function get noTopMostIndex():int
{
return _noTopMostIndex;
}
/**
* @private
*/
mx_internal function set noTopMostIndex(value:int):void
{
var delta:int = value - _noTopMostIndex;
_noTopMostIndex = value;
topMostIndex += delta;
}
//----------------------------------
// $numChildren
//----------------------------------
/**
* @private
* This property allows access to the Player's native implementation
* of the numChildren property, which can be useful since components
* can override numChildren and thereby hide the native implementation.
* Note that this "base property" is final and cannot be overridden,
* so you can count on it to reflect what is happening at the player level.
*/
mx_internal final function get $numChildren():int
{
return super.numChildren;
}
//----------------------------------
// numModalWindows
//----------------------------------
/**
* @private
* Storage for the numModalWindows property.
*/
private var _numModalWindows:int = 0;
/**
* The number of modal windows. Modal windows don't allow
* clicking in another windows which would normally
* activate the FocusManager in that window. The PopUpManager
* modifies this count as it creates and destroys modal windows.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get numModalWindows():int
{
return _numModalWindows;
}
/**
* @private
*/
public function set numModalWindows(value:int):void
{
_numModalWindows = value;
}
//----------------------------------
// preloadedRSLs
//----------------------------------
/**
* @inheritDoc
*
*/
public function get preloadedRSLs():Dictionary
{
// Overridden by compiler generate code.
return null;
}
/**
* @inheritDoc
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 4.5
*/
public function addPreloadedRSL(loaderInfo:LoaderInfo, rsl:Vector.<RSLData>):void
{
preloadedRSLs[loaderInfo] = rsl;
if (hasEventListener(RSLEvent.RSL_ADD_PRELOADED))
{
var rslEvent:RSLEvent = new RSLEvent(RSLEvent.RSL_ADD_PRELOADED);
rslEvent.loaderInfo = loaderInfo;
dispatchEvent(rslEvent);
}
}
//----------------------------------
// preloaderBackgroundAlpha
//----------------------------------
/**
* The background alpha used by the child of the preloader.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get preloaderBackgroundAlpha():Number
{
return info()["backgroundAlpha"];
}
//----------------------------------
// preloaderBackgroundColor
//----------------------------------
/**
* The background color used by the child of the preloader.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get preloaderBackgroundColor():uint
{
var value:* = info()["backgroundColor"];
if (value == undefined)
return 0xFFFFFFFF;
else
return value;
}
//----------------------------------
// preloaderBackgroundImage
//----------------------------------
/**
* The background color used by the child of the preloader.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get preloaderBackgroundImage():Object
{
return info()["backgroundImage"];
}
//----------------------------------
// preloaderBackgroundSize
//----------------------------------
/**
* The background size used by the child of the preloader.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get preloaderBackgroundSize():String
{
return info()["backgroundSize"];
}
//----------------------------------
// popUpChildren
//----------------------------------
/**
* @private
* Storage for the popUpChildren property.
*/
private var _popUpChildren:SystemChildrenList;
/**
* @inheritDoc
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get popUpChildren():IChildList
{
if (!topLevel)
return _topLevelSystemManager.popUpChildren;
if (!_popUpChildren)
{
_popUpChildren = new SystemChildrenList(this,
new QName(mx_internal, "noTopMostIndex"),
new QName(mx_internal, "topMostIndex"));
}
return _popUpChildren;
}
//----------------------------------
// rawChildren
//----------------------------------
/**
* @private
* Storage for the rawChildren property.
*/
private var _rawChildren:SystemRawChildrenList;
/**
* @inheritDoc
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get rawChildren():IChildList
{
//if (!topLevel)
// return _topLevelSystemManager.rawChildren;
if (!_rawChildren)
_rawChildren = new SystemRawChildrenList(this);
return _rawChildren;
}
//--------------------------------------------------------------------------
// screen
//--------------------------------------------------------------------------
/**
* @private
* Storage for the screen property.
*/
mx_internal var _screen:Rectangle;
/**
* @inheritDoc
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get screen():Rectangle
{
if (!_screen)
Stage_resizeHandler();
if (!isStageRoot)
{
Stage_resizeHandler();
}
return _screen;
}
//----------------------------------
// toolTipChildren
//----------------------------------
/**
* @private
* Storage for the toolTipChildren property.
*/
private var _toolTipChildren:SystemChildrenList;
/**
* @inheritDoc
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get toolTipChildren():IChildList
{
if (!topLevel)
return _topLevelSystemManager.toolTipChildren;
if (!_toolTipChildren)
{
_toolTipChildren = new SystemChildrenList(this,
new QName(mx_internal, "topMostIndex"),
new QName(mx_internal, "toolTipIndex"));
}
return _toolTipChildren;
}
//----------------------------------
// toolTipIndex
//----------------------------------
/**
* @private
* Storage for the toolTipIndex property.
*/
private var _toolTipIndex:int = 0;
/**
* @private
* The index of the highest child that is a tooltip
*/
mx_internal function get toolTipIndex():int
{
return _toolTipIndex;
}
/**
* @private
*/
mx_internal function set toolTipIndex(value:int):void
{
var delta:int = value - _toolTipIndex;
_toolTipIndex = value;
cursorIndex += delta;
}
//----------------------------------
// topLevelSystemManager
//----------------------------------
/**
* Returns the SystemManager responsible for the application window. This will be
* the same SystemManager unless this application has been loaded into another
* application.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get topLevelSystemManager():ISystemManager
{
if (topLevel)
return this;
return _topLevelSystemManager;
}
//----------------------------------
// topMostIndex
//----------------------------------
/**
* @private
* Storage for the topMostIndex property.
*/
private var _topMostIndex:int = 0;
/**
* @private
* The index of the highest child that is a topmost/popup window
*/
mx_internal function get topMostIndex():int
{
return _topMostIndex;
}
mx_internal function set topMostIndex(value:int):void
{
var delta:int = value - _topMostIndex;
_topMostIndex = value;
toolTipIndex += delta;
}
//--------------------------------------------------------------------------
//
// Overridden methods: EventDispatcher
//
//--------------------------------------------------------------------------
/**
* @private
* allows marshal implementation to add events
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
mx_internal final function $addEventListener(type:String, listener:Function,
useCapture:Boolean = false,
priority:int = 0,
useWeakReference:Boolean = false):void
{
super.addEventListener(type, listener, useCapture, priority, useWeakReference);
}
/**
* @inheritDoc
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get childAllowsParent():Boolean
{
try
{
return loaderInfo.childAllowsParent;
}
catch (error:Error)
{
//Error #2099: The loading object is not sufficiently loaded to provide this information.
}
return false; // assume the worst
}
/**
* @copy mx.core.ISWFBridgeProvider#parentAllowsChild
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get parentAllowsChild():Boolean
{
try
{
return loaderInfo.parentAllowsChild;
}
catch (error:Error)
{
//Error #2099: The loading object is not sufficiently loaded to provide this information.
}
return false; // assume the worst
}
/**
* @private
* Only create idle events if someone is listening.
*/
override public function addEventListener(type:String, listener:Function,
useCapture:Boolean = false,
priority:int = 0,
useWeakReference:Boolean = false):void
{
if (type == MouseEvent.MOUSE_MOVE || type == MouseEvent.MOUSE_UP || type == MouseEvent.MOUSE_DOWN
|| type == Event.ACTIVATE || type == Event.DEACTIVATE)
{
// also listen to stage if allowed
try
{
if (stage)
{
// Use weak listener because we don't always know when we
// no longer need this listener
stage.addEventListener(type, stageEventHandler, false, 0, true);
}
}
catch (error:SecurityError)
{
}
}
if (hasEventListener("addEventListener"))
{
var request:DynamicEvent = new DynamicEvent("addEventListener", false, true);
request.eventType = type;
request.listener = listener;
request.useCapture = useCapture;
request.priority = priority;
request.useWeakReference = useWeakReference;
if (!dispatchEvent(request))
return;
}
if (type == SandboxMouseEvent.MOUSE_UP_SOMEWHERE)
{
// If someone wants this event, also listen for mouseLeave.
// Use weak listener because we don't always know when we
// no longer need this listener
try
{
if (stage)
{
stage.addEventListener(Event.MOUSE_LEAVE, mouseLeaveHandler, false, 0, true);
}
else
{
super.addEventListener(Event.MOUSE_LEAVE, mouseLeaveHandler, false, 0, true);
}
}
catch (error:SecurityError)
{
super.addEventListener(Event.MOUSE_LEAVE, mouseLeaveHandler, false, 0, true);
}
}
// These two events will dispatched to applications in sandboxes.
if (type == FlexEvent.RENDER || type == FlexEvent.ENTER_FRAME)
{
if (type == FlexEvent.RENDER)
type = Event.RENDER;
else
type = Event.ENTER_FRAME;
try
{
if (stage)
stage.addEventListener(type, listener, useCapture, priority, useWeakReference);
else
super.addEventListener(type, listener, useCapture, priority, useWeakReference);
}
catch (error:SecurityError)
{
super.addEventListener(type, listener, useCapture, priority, useWeakReference);
}
if (stage && type == Event.RENDER)
stage.invalidate();
return;
}
// When the first listener registers for 'idle' events,
// create a Timer that will fire every IDLE_INTERVAL.
if (type == FlexEvent.IDLE && !idleTimer)
{
idleTimer = new Timer(IDLE_INTERVAL);
idleTimer.addEventListener(TimerEvent.TIMER,
idleTimer_timerHandler);
idleTimer.start();
// Make sure we get all activity
// in case someone calls stopPropagation().
addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler, true);
addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler, true);
}
super.addEventListener(type, listener, useCapture, priority, useWeakReference);
}
/**
* @private
*/
mx_internal final function $removeEventListener(type:String, listener:Function,
useCapture:Boolean = false):void
{
super.removeEventListener(type, listener, useCapture);
}
/**
* @private
*/
override public function removeEventListener(type:String, listener:Function,
useCapture:Boolean = false):void
{
if (hasEventListener("removeEventListener"))
{
var request:DynamicEvent = new DynamicEvent("removeEventListener", false, true);
request.eventType = type;
request.listener = listener;
request.useCapture = useCapture;
if (!dispatchEvent(request))
return;
}
// These two events will dispatched to applications in sandboxes.
if (type == FlexEvent.RENDER || type == FlexEvent.ENTER_FRAME)
{
if (type == FlexEvent.RENDER)
type = Event.RENDER;
else
type = Event.ENTER_FRAME;
try
{
if (stage)
stage.removeEventListener(type, listener, useCapture);
}
catch (error:SecurityError)
{
}
// Remove both listeners in case the system manager was added
// or removed from the stage after the listener was added.
super.removeEventListener(type, listener, useCapture);
return;
}
// When the last listener unregisters for 'idle' events,
// stop and release the Timer.
if (type == FlexEvent.IDLE)
{
super.removeEventListener(type, listener, useCapture);
if (!hasEventListener(FlexEvent.IDLE) && idleTimer)
{
idleTimer.stop();
idleTimer = null;
removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
}
}
else
{
super.removeEventListener(type, listener, useCapture);
}
if (type == MouseEvent.MOUSE_MOVE || type == MouseEvent.MOUSE_UP || type == MouseEvent.MOUSE_DOWN
|| type == Event.ACTIVATE || type == Event.DEACTIVATE)
{
if (!hasEventListener(type))
{
// also listen to stage if allowed
try
{
if (stage)
{
stage.removeEventListener(type, stageEventHandler, false);
}
}
catch (error:SecurityError)
{
}
}
}
if (type == SandboxMouseEvent.MOUSE_UP_SOMEWHERE)
{
if (!hasEventListener(SandboxMouseEvent.MOUSE_UP_SOMEWHERE))
{
// nobody wants this event any more for now
try
{
if (stage)
{
stage.removeEventListener(Event.MOUSE_LEAVE, mouseLeaveHandler);
}
}
catch (error:SecurityError)
{
}
// Remove both listeners in case the system manager was added
// or removed from the stage after the listener was added.
super.removeEventListener(Event.MOUSE_LEAVE, mouseLeaveHandler);
}
}
}
//--------------------------------------------------------------------------
//
// Overridden methods: DisplayObjectContainer
//
//--------------------------------------------------------------------------
/**
* @private
*/
override public function addChild(child:DisplayObject):DisplayObject
{
var addIndex:int = numChildren;
if (child.parent == this)
addIndex--;
return addChildAt(child, addIndex);
}
/**
* @private
*/
override public function addChildAt(child:DisplayObject,
index:int):DisplayObject
{
// Adjust the partition indexes before the
// "added" event is dispatched.
noTopMostIndex = noTopMostIndex + 1;
var oldParent:DisplayObjectContainer = child.parent;
if (oldParent)
oldParent.removeChild(child);
return rawChildren_addChildAt(child, applicationIndex + index);
}
/**
* @private
*
* Used by SystemManagerProxy to add a mouse catcher as a child.
*/
mx_internal final function $addChildAt(child:DisplayObject,
index:int):DisplayObject
{
return super.addChildAt(child, index);
}
/**
* @private
*
* Companion to $addChildAt.
*/
mx_internal final function $removeChildAt(index:int):DisplayObject
{
return super.removeChildAt(index);
}
/**
* @private
*/
override public function removeChild(child:DisplayObject):DisplayObject
{
// Adjust the partition indexes
// before the "removed" event is dispatched.
noTopMostIndex = noTopMostIndex - 1;
return rawChildren_removeChild(child);
}
/**
* @private
*/
override public function removeChildAt(index:int):DisplayObject
{
// Adjust the partition indexes
// before the "removed" event is dispatched.
noTopMostIndex = noTopMostIndex - 1;
return rawChildren_removeChildAt(applicationIndex + index);
}
/**
* @private
*/
override public function getChildAt(index:int):DisplayObject
{
return super.getChildAt(applicationIndex + index)
}
/**
* @private
*/
override public function getChildByName(name:String):DisplayObject
{
return super.getChildByName(name);
}
/**
* @private
*/
override public function getChildIndex(child:DisplayObject):int
{
return super.getChildIndex(child) - applicationIndex;
}
/**
* @private
*/
override public function setChildIndex(child:DisplayObject, newIndex:int):void
{
super.setChildIndex(child, applicationIndex + newIndex)
}
/**
* @private
*/
override public function getObjectsUnderPoint(point:Point):Array
{
var children:Array = [];
// Get all the children that aren't tooltips and cursors.
var n:int = topMostIndex;
for (var i:int = 0; i < n; i++)
{
var child:DisplayObject = super.getChildAt(i);
if (child is DisplayObjectContainer)
{
var temp:Array =
DisplayObjectContainer(child).getObjectsUnderPoint(point);
if (temp)
children = children.concat(temp);
}
}
return children;
}
/**
* @private
*/
override public function contains(child:DisplayObject):Boolean
{
if (super.contains(child))
{
if (child.parent == this)
{
var childIndex:int = super.getChildIndex(child);
if (childIndex < noTopMostIndex)
return true;
}
else
{
for (var i:int = 0; i < noTopMostIndex; i++)
{
var myChild:DisplayObject = super.getChildAt(i);
if (myChild is IRawChildrenContainer)
{
if (IRawChildrenContainer(myChild).rawChildren.contains(child))
return true;
}
if (myChild is DisplayObjectContainer)
{
if (DisplayObjectContainer(myChild).contains(child))
return true;
}
}
}
}
return false;
}
//--------------------------------------------------------------------------
//
// Methods: IFlexModuleFactory
//
//--------------------------------------------------------------------------
/**
* @private
* This method is overridden in the autogenerated subclass.
* It is part of TLF's ISWFContext interface.
* Although this class does not declare that it implements this interface,
* the autogenerated subclass does.
*/
public function callInContext(fn:Function, thisArg:Object,
argArray:Array, returns:Boolean = true):*
{
return undefined;
}
/**
* A factory method that requests an instance of a
* definition known to the module.
*
* You can provide an optional set of parameters to let building
* factories change what they create based on the
* input. Passing null indicates that the default definition
* is created, if possible.
*
* This method is overridden in the autogenerated subclass.
*
* @param params An optional list of arguments. You can pass
* any number of arguments, which are then stored in an Array
* called <code>parameters</code>.
*
* @return An instance of the module, or <code>null</code>.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function create(... params):Object
{
var mainClassName:String = info()["mainClassName"];
if (mainClassName == null)
{
var url:String = loaderInfo.loaderURL;
var dot:int = url.lastIndexOf(".");
var slash:int = url.lastIndexOf("/");
mainClassName = url.substring(slash + 1, dot);
}
var mainClass:Class = Class(getDefinitionByName(mainClassName));
return mainClass ? new mainClass() : null;
}
/**
* @private
*/
public function info():Object
{
return {};
}
//--------------------------------------------------------------------------
//
// Methods
//
//--------------------------------------------------------------------------
/**
* @private
* Creates an instance of the preloader, adds it as a child, and runs it.
* This is needed by Flash Builder. Do not modify this function.
*/
mx_internal function initialize():void
{
var runtimeDPIProviderClass:Class = info()["runtimeDPIProvider"] as Class;
if (runtimeDPIProviderClass)
Singleton.registerClass("mx.core::RuntimeDPIProvider", runtimeDPIProviderClass);
if (isStageRoot)
{
// TODO: Finalize scaling behavior
Stage_resizeHandler();
// _width = stage.stageWidth;
// _height = stage.stageHeight;
}
else
{
_width = loaderInfo.width;
_height = loaderInfo.height;
}
// Create an instance of the preloader and add it to the stage
preloader = new Preloader();
// Listen for preloader events
// preloader notifes when it is ok to go to frame2
preloader.addEventListener(FlexEvent.PRELOADER_DOC_FRAME_READY,
preloader_preloaderDocFrameReadyHandler);
// wait for a complete event. This gives the preloader
// a chance to load resource modules before
// everything really gets kicked off
preloader.addEventListener(Event.COMPLETE,
preloader_completeHandler);
// when the app is fully backed remove the preloader and show the app
preloader.addEventListener(FlexEvent.PRELOADER_DONE,
preloader_preloaderDoneHandler);
preloader.addEventListener(RSLEvent.RSL_COMPLETE,
preloader_rslCompleteHandler);
// Add the preloader as a child. Use backing variable because when loaded
// we redirect public API to parent systemmanager
if (!_popUpChildren)
{
_popUpChildren = new SystemChildrenList(
this, new QName(mx_internal, "noTopMostIndex"), new QName(mx_internal, "topMostIndex"));
}
_popUpChildren.addChild(preloader);
var rsls:Array = info()["rsls"];
var cdRsls:Array = info()["cdRsls"];
var usePreloader:Boolean = true;
if (info()["usePreloader"] != undefined)
usePreloader = info()["usePreloader"];
var preloaderDisplayClass:Class = info()["preloader"] as Class;
// Put cross-domain RSL information in the RSL list.
var rslItemList:Array = [];
var n:int;
var i:int;
if (cdRsls && cdRsls.length > 0)
{
if (isTopLevel())
rslDataList = cdRsls;
else
rslDataList = LoaderUtil.processRequiredRSLs(this, cdRsls);
var normalizedURL:String = LoaderUtil.normalizeURL(this.loaderInfo);
var crossDomainRSLItem:Class = Class(getDefinitionByName("mx.core::CrossDomainRSLItem"));
n = rslDataList.length;
for (i = 0; i < n; i++)
{
var rslWithFailovers:Array = rslDataList[i];
// If crossDomainRSLItem is null, then this is a compiler error. It should not be null.
var cdNode:Object = new crossDomainRSLItem(rslWithFailovers,
normalizedURL,
this);
rslItemList.push(cdNode);
}
}
// Append RSL information in the RSL list.
if (rsls != null && rsls.length > 0)
{
if (rslDataList == null)
rslDataList = [];
if (normalizedURL == null)
normalizedURL = LoaderUtil.normalizeURL(this.loaderInfo);
n = rsls.length;
for (i = 0; i < n; i++)
{
var node:RSLItem = new RSLItem(rsls[i].url,
normalizedURL,
this);
rslItemList.push(node);
rslDataList.push([new RSLData(rsls[i].url, null, null, null,
false, false, "current")]);
}
}
// They can also specify a comma-separated list of URLs
// for resource modules to be preloaded during frame 1.
var resourceModuleURLList:String =
loaderInfo.parameters["resourceModuleURLs"];
var resourceModuleURLs:Array =
resourceModuleURLList ? resourceModuleURLList.split(",") : null;
var domain:ApplicationDomain =
!topLevel && parent is Loader ?
Loader(parent).contentLoaderInfo.applicationDomain :
info()["currentDomain"] as ApplicationDomain;
// Initialize the preloader.
preloader.initialize(
usePreloader,
preloaderDisplayClass,
preloaderBackgroundColor,
preloaderBackgroundAlpha,
preloaderBackgroundImage,
preloaderBackgroundSize,
isStageRoot ? stage.stageWidth : loaderInfo.width,
isStageRoot ? stage.stageHeight : loaderInfo.height,
null,
null,
rslItemList,
resourceModuleURLs,
domain);
}
//--------------------------------------------------------------------------
//
// Methods: Support for rawChildren access
//
//--------------------------------------------------------------------------
/**
* @private
*/
mx_internal function rawChildren_addChild(child:DisplayObject):DisplayObject
{
childManager.addingChild(child);
super.addChild(child);
childManager.childAdded(child); // calls child.createChildren()
return child;
}
/**
* @private
*/
mx_internal function rawChildren_addChildAt(child:DisplayObject,
index:int):DisplayObject
{
// preloader goes through here before childManager is set up
if (childManager)
childManager.addingChild(child);
super.addChildAt(child, index);
if (childManager)
childManager.childAdded(child); // calls child.createChildren()
return child;
}
/**
* @private
*/
mx_internal function rawChildren_removeChild(child:DisplayObject):DisplayObject
{
childManager.removingChild(child);
super.removeChild(child);
childManager.childRemoved(child);
return child;
}
/**
* @private
*/
mx_internal function rawChildren_removeChildAt(index:int):DisplayObject
{
var child:DisplayObject = super.getChildAt(index);
childManager.removingChild(child);
super.removeChildAt(index);
childManager.childRemoved(child);
return child;
}
/**
* @private
*/
mx_internal function rawChildren_getChildAt(index:int):DisplayObject
{
return super.getChildAt(index);
}
/**
* @private
*/
mx_internal function rawChildren_getChildByName(name:String):DisplayObject
{
return super.getChildByName(name);
}
/**
* @private
*/
mx_internal function rawChildren_getChildIndex(child:DisplayObject):int
{
return super.getChildIndex(child);
}
/**
* @private
*/
mx_internal function rawChildren_setChildIndex(child:DisplayObject, newIndex:int):void
{
super.setChildIndex(child, newIndex);
}
/**
* @private
*/
mx_internal function rawChildren_getObjectsUnderPoint(pt:Point):Array
{
return super.getObjectsUnderPoint(pt);
}
/**
* @private
*/
mx_internal function rawChildren_contains(child:DisplayObject):Boolean
{
return super.contains(child);
}
//--------------------------------------------------------------------------
//
// Methods: Security
//
//--------------------------------------------------------------------------
/**
* Calls Security.allowDomain() for the SWF associated with this SystemManager
* plus all the SWFs assocatiated with RSLs preloaded by this SystemManager.
*
*/
public function allowDomain(... domains):void
{
// Overridden by compiler generated code.
}
/**
* Calls Security.allowInsecureDomain() for the SWF associated with this SystemManager
* plus all the SWFs assocatiated with RSLs preloaded by this SystemManager.
*
*/
public function allowInsecureDomain(... domains):void
{
// Overridden by compiler generated code.
}
//--------------------------------------------------------------------------
//
// Methods: Measurement and Layout
//
//--------------------------------------------------------------------------
/**
* A convenience method for determining whether to use the
* explicit or measured width.
*
* @return A Number that is the <code>explicitWidth</code> if defined,
* or the <code>measuredWidth</code> property if not.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function getExplicitOrMeasuredWidth():Number
{
return !isNaN(explicitWidth) ? explicitWidth : measuredWidth;
}
/**
* A convenience method for determining whether to use the
* explicit or measured height.
*
* @return A Number that is the <code>explicitHeight</code> if defined,
* or the <code>measuredHeight</code> property if not.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function getExplicitOrMeasuredHeight():Number
{
return !isNaN(explicitHeight) ? explicitHeight : measuredHeight;
}
/**
* Calling the <code>move()</code> method
* has no effect as it is directly mapped
* to the application window or the loader.
*
* @param x The new x coordinate.
*
* @param y The new y coordinate.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function move(x:Number, y:Number):void
{
}
/**
* Calling the <code>setActualSize()</code> method
* has no effect if it is directly mapped
* to the application window and if it is the top-level window.
* Otherwise attempts to resize itself, clipping children if needed.
*
* @param newWidth The new width.
*
* @param newHeight The new height.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function setActualSize(newWidth:Number, newHeight:Number):void
{
if (isStageRoot) return;
// mouseCatcher is a mask if not stage root
// sometimes it is not in sync so we always
// sync it up
if (mouseCatcher)
{
mouseCatcher.width = newWidth;
mouseCatcher.height = newHeight;
}
if (_width != newWidth || _height != newHeight)
{
_width = newWidth;
_height = newHeight;
dispatchEvent(new Event(Event.RESIZE));
}
}
//--------------------------------------------------------------------------
//
// Methods: Other
//
//--------------------------------------------------------------------------
/**
* @inheritDoc
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function getDefinitionByName(name:String):Object
{
var domain:ApplicationDomain =
!topLevel && parent is Loader ?
Loader(parent).contentLoaderInfo.applicationDomain :
info()["currentDomain"] as ApplicationDomain;
//trace("SysMgr.getDefinitionByName domain",domain,"currentDomain",info()["currentDomain"]);
var definition:Object;
if (domain.hasDefinition(name))
{
definition = domain.getDefinition(name);
//trace("SysMgr.getDefinitionByName got definition",definition,"name",name);
}
return definition;
}
/**
* Returns the root DisplayObject of the SWF that contains the code
* for the given object.
*
* @param object Any Object.
*
* @return The root DisplayObject
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public static function getSWFRoot(object:Object):DisplayObject
{
var className:String = getQualifiedClassName(object);
for (var p:* in allSystemManagers)
{
var sm:ISystemManager = p as ISystemManager;
var domain:ApplicationDomain = sm.loaderInfo.applicationDomain;
try
{
var cls:Class = Class(domain.getDefinition(className));
if (object is cls)
return sm as DisplayObject;
}
catch(e:Error)
{
}
}
return null;
}
/**
* @inheritDoc
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function isTopLevel():Boolean
{
return topLevel;
}
/**
* @inheritDoc
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function isTopLevelRoot():Boolean
{
return isStageRoot || isBootstrapRoot;
}
/**
* Determines if the given DisplayObject is the
* top-level window.
*
* @param object The DisplayObject to test.
*
* @return <code>true</code> if the given DisplayObject is the
* top-level window.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function isTopLevelWindow(object:DisplayObject):Boolean
{
return object is IUIComponent &&
IUIComponent(object) == topLevelWindow;
}
/**
* @inheritDoc
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function isFontFaceEmbedded(textFormat:TextFormat):Boolean
{
var fontName:String = textFormat.font;
var bold:Boolean = textFormat.bold;
var italic:Boolean = textFormat.italic;
var fontList:Array = Font.enumerateFonts();
var n:int = fontList.length;
for (var i:int = 0; i < n; i++)
{
var font:Font = Font(fontList[i]);
if (font.fontName == fontName)
{
var style:String = "regular";
if (bold && italic)
style = "boldItalic";
else if (bold)
style = "bold";
else if (italic)
style = "italic";
if (font.fontStyle == style)
return true;
}
}
if (!fontName ||
!embeddedFontList ||
!embeddedFontList[fontName])
{
return false;
}
var info:Object = embeddedFontList[fontName];
return !((bold && !info.bold) ||
(italic && !info.italic) ||
(!bold && !italic && !info.regular));
}
/**
* @private
* Makes the mouseCatcher the same size as the stage,
* filling it with transparent pixels.
*/
private function resizeMouseCatcher():void
{
if (mouseCatcher)
{
try
{
var g:Graphics = mouseCatcher.graphics;
var s:Rectangle = screen;
g.clear();
g.beginFill(0x000000, 0);
g.drawRect(0, 0, s.width, s.height);
g.endFill();
}
catch (e:SecurityError)
{
// trace("resizeMouseCatcher: ignoring security error " + e);
}
}
}
//--------------------------------------------------------------------------
//
// Event handlers
//
//--------------------------------------------------------------------------
/**
* @private
*/
private function initHandler(event:Event):void
{
CONFIG::performanceInstrumentation
{
var perfUtil:mx.utils.PerfUtil = mx.utils.PerfUtil.getInstance();
perfUtil.markTime("SystemManager.initHandler().start");
}
// we can still be the top level root if we can access our
// parent and get a positive response to the query or
// or there is not a listener for the new application event
// that SWFLoader always adds.
if (!isStageRoot)
{
if (root.loaderInfo.parentAllowsChild)
{
try
{
if (!parent.dispatchEvent(new Event("mx.managers.SystemManager.isBootstrapRoot", false, true)) ||
// use string literal to avoid link dependency on SWFBridgeEvent.BRIDGE_NEW_APPLICATION
!root.loaderInfo.sharedEvents.hasEventListener("bridgeNewApplication"))
isBootstrapRoot = true;
}
catch (e:Error)
{
}
}
}
allSystemManagers[this] = this.loaderInfo.url;
root.loaderInfo.removeEventListener(Event.INIT, initHandler);
if (!SystemManagerGlobals.info)
SystemManagerGlobals.info = info();
if (!SystemManagerGlobals.parameters)
SystemManagerGlobals.parameters = loaderInfo.parameters;
var docFrame:int = (totalFrames == 1)? 0 : 1;
addEventListener(Event.ENTER_FRAME, docFrameListener);
/*
addFrameScript(docFrame, docFrameHandler);
for (var f:int = docFrame + 1; f < totalFrames; ++f)
{
addFrameScript(f, extraFrameHandler);
}
*/
initialize();
CONFIG::performanceInstrumentation
{
perfUtil.markTime("SystemManager.initHandler().end");
}
}
private function docFrameListener(event:Event):void
{
if (currentFrame == 2)
{
removeEventListener(Event.ENTER_FRAME, docFrameListener);
if (totalFrames > 2)
addEventListener(Event.ENTER_FRAME, extraFrameListener);
docFrameHandler();
}
}
private function extraFrameListener(event:Event):void
{
if (lastFrame == currentFrame)
return;
lastFrame = currentFrame;
if (currentFrame + 1 > totalFrames)
removeEventListener(Event.ENTER_FRAME, extraFrameListener);
extraFrameHandler();
}
/**
* @private
* Once the swf has been fully downloaded,
* advance the playhead to the next frame.
* This will cause the framescript to run, which runs frameEndHandler().
*/
private function preloader_preloaderDocFrameReadyHandler(event:Event):void
{
// Advance the next frame
preloader.removeEventListener(FlexEvent.PRELOADER_DOC_FRAME_READY,
preloader_preloaderDocFrameReadyHandler);
deferredNextFrame();
}
/**
* @private
* Remove the preloader and add the application as a child.
*/
private function preloader_preloaderDoneHandler(event:Event):void
{
var app:IUIComponent = topLevelWindow;
// Once the preloader dispatches the PRELOADER_DONE event, remove the preloader
// and add the application as the child
preloader.removeEventListener(FlexEvent.PRELOADER_DONE,
preloader_preloaderDoneHandler);
preloader.removeEventListener(RSLEvent.RSL_COMPLETE,
preloader_rslCompleteHandler);
_popUpChildren.removeChild(preloader);
preloader = null;
// Add the mouseCatcher as child 0.
mouseCatcher = new FlexSprite();
mouseCatcher.name = "mouseCatcher";
// Must use addChildAt because a creationComplete handler can create a
// dialog and insert it at 0.
noTopMostIndex = noTopMostIndex + 1;
super.addChildAt(mouseCatcher, 0);
resizeMouseCatcher();
if (!topLevel)
{
mouseCatcher.visible = false;
mask = mouseCatcher;
}
// Add the application as child 1.
noTopMostIndex = noTopMostIndex + 1;
super.addChildAt(DisplayObject(app), 1);
CONFIG::performanceInstrumentation
{
var perfUtil:mx.utils.PerfUtil = mx.utils.PerfUtil.getInstance();
perfUtil.markTime("APPLICATION_COMPLETE");
perfUtil.finishSampling("Application Startup");
}
// Dispatch the applicationComplete event from the Application
// and then agaom from the SystemManager
// (so that loading apps know we're done).
app.dispatchEvent(new FlexEvent(FlexEvent.APPLICATION_COMPLETE));
dispatchEvent(new FlexEvent(FlexEvent.APPLICATION_COMPLETE));
}
/**
* @private
* The preloader has completed loading an RSL.
*/
private function preloader_rslCompleteHandler(event:RSLEvent):void
{
if (!event.isResourceModule && event.loaderInfo)
{
var rsl:Vector.<RSLData> = Vector.<RSLData>(rslDataList[event.rslIndex]);
var moduleFactory:IFlexModuleFactory = this;
if (rsl && rsl[0].moduleFactory)
moduleFactory = rsl[0].moduleFactory;
if (moduleFactory == this)
preloadedRSLs[event.loaderInfo] = rsl;
else
moduleFactory.addPreloadedRSL(event.loaderInfo, rsl);
}
}
/**
* @private
* This is attached as the framescript at the end of frame 2.
* When this function is called, we know that the application
* class has been defined and read in by the Player.
*/
mx_internal function docFrameHandler(event:Event = null):void
{
if (readyForKickOff)
kickOff();
}
/**
* @private
* kick off if we're ready
*/
mx_internal function preloader_completeHandler(event:Event):void
{
preloader.removeEventListener(Event.COMPLETE,
preloader_completeHandler);
readyForKickOff = true;
if (currentFrame >= 2)
kickOff();
}
/**
* @private
* kick off
*/
mx_internal function kickOff():void
{
// already been here
if (document)
return;
CONFIG::performanceInstrumentation
{
var perfUtil:mx.utils.PerfUtil = mx.utils.PerfUtil.getInstance();
perfUtil.markTime("SystemManager.kickOff().start");
}
if (!isTopLevel())
SystemManagerGlobals.topLevelSystemManagers[0].
// dispatch a FocusEvent so we can pass ourselves along
dispatchEvent(new FocusEvent(FlexEvent.NEW_CHILD_APPLICATION, false, false, this));
// Generated code will bring in EmbeddedFontRegistry
Singleton.registerClass("mx.core::IEmbeddedFontRegistry",
Class(getDefinitionByName("mx.core::EmbeddedFontRegistry")));
Singleton.registerClass("mx.styles::IStyleManager",
Class(getDefinitionByName("mx.styles::StyleManagerImpl")));
Singleton.registerClass("mx.styles::IStyleManager2",
Class(getDefinitionByName("mx.styles::StyleManagerImpl")));
// Register other singleton classes.
// Note: getDefinitionByName() will return null
// if the class can't be found.
Singleton.registerClass("mx.managers::IBrowserManager",
Class(getDefinitionByName("mx.managers::BrowserManagerImpl")));
Singleton.registerClass("mx.managers::ICursorManager",
Class(getDefinitionByName("mx.managers::CursorManagerImpl")));
Singleton.registerClass("mx.managers::IHistoryManager",
Class(getDefinitionByName("mx.managers::HistoryManagerImpl")));
Singleton.registerClass("mx.managers::ILayoutManager",
Class(getDefinitionByName("mx.managers::LayoutManager")));
Singleton.registerClass("mx.managers::IPopUpManager",
Class(getDefinitionByName("mx.managers::PopUpManagerImpl")));
Singleton.registerClass("mx.managers::IToolTipManager2",
Class(getDefinitionByName("mx.managers::ToolTipManagerImpl")));
var dragManagerClass:Class = null;
// Make this call to create a new instance of the DragManager singleton.
// Try to link in the NativeDragManager first. This will allow the
// application to receive NativeDragEvents that originate from the
// desktop. If it can't be found, then we're
// not in AIR, and it can't be linked in, so we should just work off of
// the regular Flex DragManager.
var dmInfo:Object = info()["useNativeDragManager"];
var useNative:Boolean = dmInfo == null ? true : String(dmInfo) == "true";
if (useNative)
dragManagerClass = Class(getDefinitionByName("mx.managers::NativeDragManagerImpl"));
if (dragManagerClass == null)
dragManagerClass = Class(getDefinitionByName("mx.managers::DragManagerImpl"));
Singleton.registerClass("mx.managers::IDragManager", dragManagerClass);
Singleton.registerClass("mx.core::ITextFieldFactory",
Class(getDefinitionByName("mx.core::TextFieldFactory")));
var mixinList:Array = info()["mixins"];
if (mixinList && mixinList.length > 0)
{
var n:int = mixinList.length;
for (var i:int = 0; i < n; ++i)
{
CONFIG::performanceInstrumentation
{
var token:int = perfUtil.markStart();
}
// trace("initializing mixin " + mixinList[i]);
var c:Class = Class(getDefinitionByName(mixinList[i]));
c["init"](this);
CONFIG::performanceInstrumentation
{
perfUtil.markEnd(mixinList[i], token);
}
}
}
c = Singleton.getClass("mx.managers::IActiveWindowManager");
if (c)
{
registerImplementation("mx.managers::IActiveWindowManager", new c(this));
}
// depends on having IActiveWindowManager installed first
c = Singleton.getClass("mx.managers::IMarshalSystemManager");
if (c)
{
registerImplementation("mx.managers::IMarshalSystemManager", new c(this));
}
CONFIG::performanceInstrumentation
{
// Finish here, since initializeTopLevelWidnow is instrumented separately???
perfUtil.markTime("SystemManager.kickOff().end");
}
initializeTopLevelWindow(null);
deferredNextFrame();
}
/**
* @private
* The Flash Player dispatches KeyboardEvents with cancelable=false.
* We'd like to be able to use the preventDefault() method on some
* KeyBoard events to record the fact that they've been handled.
* This method stops propagation of the original event and redispatches
* the new one from the original event's target.
*
* We're only handling a small subset of keyboard events, to
* avoid unnecessary copying. Most of events in the subset are
* handled by both Scroller and by Spark classes like TextArea or
* or List that include a Scroller in their skin.
*/
private function keyDownHandler(e:KeyboardEvent):void
{
if (!e.cancelable)
{
switch (e.keyCode)
{
case Keyboard.UP:
case Keyboard.DOWN:
case Keyboard.PAGE_UP:
case Keyboard.PAGE_DOWN:
case Keyboard.HOME:
case Keyboard.END:
case Keyboard.LEFT:
case Keyboard.RIGHT:
case Keyboard.ENTER:
{
e.stopImmediatePropagation();
var cancelableEvent:KeyboardEvent =
new KeyboardEvent(e.type, e.bubbles, true, e.charCode, e.keyCode,
e.keyLocation, e.ctrlKey, e.altKey, e.shiftKey)
e.target.dispatchEvent(cancelableEvent);
}
}
}
}
/**
* @private
* Similar to keyDownHandler above. We want to re-dispatch
* mouse events that are cancellable. Currently we are only doing
* this for a few mouse events and not all of them (MOUSE_WHEEL and
* MOUSE_DOWN).
*/
private function mouseEventHandler(e:MouseEvent):void
{
if (!e.cancelable && e.eventPhase != EventPhase.BUBBLING_PHASE)
{
e.stopImmediatePropagation();
var cancelableEvent:MouseEvent = null;
if ("clickCount" in e)
{
// AIR MouseEvent. We need to use a constructor so we can
// pass in clickCount because it is a read-only property.
var mouseEventClass:Class = MouseEvent;
cancelableEvent = new mouseEventClass(e.type, e.bubbles, true, e.localX,
e.localY, e.relatedObject, e.ctrlKey, e.altKey,
e.shiftKey, e.buttonDown, e.delta,
e["commandKey"], e["controlKey"], e["clickCount"]);
}
else
{
cancelableEvent = new MouseEvent(e.type, e.bubbles, true, e.localX,
e.localY, e.relatedObject, e.ctrlKey, e.altKey,
e.shiftKey, e.buttonDown, e.delta);
}
e.target.dispatchEvent(cancelableEvent);
}
}
private function extraFrameHandler(event:Event = null):void
{
var frameList:Object = info()["frames"];
if (frameList && frameList[currentLabel])
{
var c:Class = Class(getDefinitionByName(frameList[currentLabel]));
c["frame"](this);
}
deferredNextFrame();
}
/**
* @private
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
private function nextFrameTimerHandler(event:TimerEvent):void
{
if (currentFrame + 1 <= framesLoaded)
{
nextFrame();
nextFrameTimer.removeEventListener(TimerEvent.TIMER, nextFrameTimerHandler);
// stop the timer
nextFrameTimer.reset();
}
}
/**
* @private
* Instantiates an instance of the top level window
* and adds it as a child of the SystemManager.
*/
private function initializeTopLevelWindow(event:Event):void
{
// This listener is intended to run before any other KeyboardEvent listeners
// so that it can redispatch a cancelable=true copy of the event.
if (getSandboxRoot() == this)
{
addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler, true, 1000);
addEventListener(MouseEvent.MOUSE_WHEEL, mouseEventHandler, true, 1000);
addEventListener(MouseEvent.MOUSE_DOWN, mouseEventHandler, true, 1000);
}
if (isTopLevelRoot() && stage)
{
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler, false, 1000);
stage.addEventListener(MouseEvent.MOUSE_WHEEL, mouseEventHandler, false, 1000);
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseEventHandler, false, 1000);
}
// Parent may be null if in another sandbox and don't have
// access to our parent. Add a check for this case.
if (!parent && parentAllowsChild)
return;
if (!topLevel)
{
// We are not top-level and don't have a parent. This can happen
// when the application has already been unloaded by the time
// we get to this point.
if (!parent)
return;
var obj:DisplayObjectContainer = parent.parent;
// if there is no grandparent at this point, we might have been removed and
// are about to be killed so just bail. Other code that runs after
// this point expects us to be grandparented. Another scenario
// is that someone loaded us but not into a parented loader, but that
// is not allowed.
if (!obj)
return;
while (obj)
{
if (obj is IUIComponent)
{
var sm:ISystemManager = IUIComponent(obj).systemManager;
if (sm && !sm.isTopLevel())
sm = sm.topLevelSystemManager;
_topLevelSystemManager = sm;
break;
}
obj = obj.parent;
}
}
if (isTopLevelRoot() && stage)
stage.addEventListener(Event.RESIZE, Stage_resizeHandler, false, 0, true);
else if (topLevel && stage)
{
// listen to resizes on the sandbox root
var sandboxRoot:DisplayObject = getSandboxRoot();
if (sandboxRoot != this)
sandboxRoot.addEventListener(Event.RESIZE, Stage_resizeHandler, false, 0, true);
}
var w:Number;
var h:Number;
if (isStageRoot && stage)
{
// stageWidth/stageHeight may have changed between initialize() and now,
// so refresh our _width and _height here.
// TODO: finalize scaling behavior
Stage_resizeHandler();
//_width = stage.stageWidth;
//_height = stage.stageHeight;
// Detect and account for special case where our stage in some
// contexts has not actually been initialized fully, as is the
// case with IE if the window is fully obscured upon loading.
if (_width == 0 && _height == 0 &&
loaderInfo.width != _width &&
loaderInfo.height != _height)
{
_width = loaderInfo.width;
_height = loaderInfo.height;
}
w = _width;
h = _height;
}
else
{
w = loaderInfo.width;
h = loaderInfo.height;
}
childManager.initializeTopLevelWindow(w, h);
}
/**
* listen for creationComplete" on the application
* if you want to perform any logic
* when the application has finished initializing itself.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
private function appCreationCompleteHandler(event:FlexEvent):void
{
invalidateParentSizeAndDisplayList();
}
/**
* Attempts to notify the parent SWFLoader that the
* Application's size has changed.
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion Flex 4
*/
public function invalidateParentSizeAndDisplayList():void
{
if (!topLevel && parent)
{
var obj:DisplayObjectContainer = parent.parent;
while (obj)
{
if (obj is IInvalidating)
{
IInvalidating(obj).invalidateSize();
IInvalidating(obj).invalidateDisplayList();
return;
}
obj = obj.parent;
}
}
// re-dispatch from here so MarshallPlan mixins can see it
dispatchEvent(new Event("invalidateParentSizeAndDisplayList"));
}
/**
* @private
* Keep track of the size and position of the stage.
*/
private function Stage_resizeHandler(event:Event = null):void
{
if (isDispatchingResizeEvent)
return;
var w:Number = 0;
var h:Number = 0;
var m:Number;
var n:Number;
try
{
m = loaderInfo.width;
n = loaderInfo.height;
}
catch (error:Error)
{
// Error #2099: The loading object is not sufficiently loaded to provide this information.
// We get this error because an old Event.RESIZE listener with a weak reference
// is being called but the SWF has been unloaded.
if (!_screen)
_screen = new Rectangle();
return;
}
var align:String = StageAlign.TOP_LEFT;
// If we don't have access to the stage, then use the size of
// the sandbox root and align to StageAlign.TOP_LEFT.
try
{
if (stage)
{
w = stage.stageWidth;
h = stage.stageHeight;
align = stage.align;
}
}
catch (error:SecurityError)
{
if (hasEventListener("getScreen"))
{
dispatchEvent(new Event("getScreen"));
if (_screen)
{
w = _screen.width;
h = _screen.height;
}
}
}
var x:Number = (m - w) / 2;
var y:Number = (n - h) / 2;
if (align == StageAlign.TOP)
{
y = 0;
}
else if (align == StageAlign.BOTTOM)
{
y = n - h;
}
else if (align == StageAlign.LEFT)
{
x = 0;
}
else if (align == StageAlign.RIGHT)
{
x = m - w;
}
else if (align == StageAlign.TOP_LEFT || align == "LT") // player bug 125020
{
y = 0;
x = 0;
}
else if (align == StageAlign.TOP_RIGHT)
{
y = 0;
x = m - w;
}
else if (align == StageAlign.BOTTOM_LEFT)
{
y = n - h;
x = 0;
}
else if (align == StageAlign.BOTTOM_RIGHT)
{
y = n - h;
x = m - w;
}
if (!_screen)
_screen = new Rectangle();
_screen.x = x;
_screen.y = y;
_screen.width = w;
_screen.height = h;
if (isStageRoot)
{
var scale:Number = densityScale;
root.scaleX = root.scaleY = scale;
_width = stage.stageWidth / scale;
_height = stage.stageHeight / scale;
// Update the screen
_screen.x /= scale;
_screen.y /= scale;
_screen.width /= scale;
_screen.height /= scale;
}
if (event)
{
resizeMouseCatcher();
isDispatchingResizeEvent = true;
dispatchEvent(event);
isDispatchingResizeEvent = false;
}
}
/**
* @private
*
* Get the index of an object in a given child list.
*
* @return index of f in childList, -1 if f is not in childList.
*/
private static function getChildListIndex(childList:IChildList, f:Object):int
{
var index:int = -1;
try
{
index = childList.getChildIndex(DisplayObject(f));
}
catch (e:ArgumentError)
{
// index has been preset to -1 so just continue.
}
return index;
}
/**
* @private
* Track mouse moves in order to determine idle
*/
private function mouseMoveHandler(event:MouseEvent):void
{
// Reset the idle counter.
idleCounter = 0;
}
/**
* @private
* Track mouse moves in order to determine idle.
*/
private function mouseUpHandler(event:MouseEvent):void
{
// Reset the idle counter.
idleCounter = 0;
}
/**
* @private
* Called every IDLE_INTERVAL after the first listener
* registers for 'idle' events.
* After IDLE_THRESHOLD goes by without any user activity,
* we dispatch an 'idle' event.
*/
private function idleTimer_timerHandler(event:TimerEvent):void
{
idleCounter++;
if (idleCounter * IDLE_INTERVAL > IDLE_THRESHOLD)
dispatchEvent(new FlexEvent(FlexEvent.IDLE));
}
// fake out mouseX/mouseY
mx_internal var _mouseX:*;
mx_internal var _mouseY:*;
/**
* @private
*/
override public function get mouseX():Number
{
if (_mouseX === undefined)
return super.mouseX;
return _mouseX;
}
/**
* @private
*/
override public function get mouseY():Number
{
if (_mouseY === undefined)
return super.mouseY;
return _mouseY;
}
private function getTopLevelSystemManager(parent:DisplayObject):ISystemManager
{
var localRoot:DisplayObjectContainer = DisplayObjectContainer(parent.root);
var sm:ISystemManager;
// If the parent isn't rooted yet,
// Or the root is the stage (which is the case in a second AIR window)
// use the global system manager instance.
if ((!localRoot || localRoot is Stage) && parent is IUIComponent)
localRoot = DisplayObjectContainer(IUIComponent(parent).systemManager);
if (localRoot is ISystemManager)
{
sm = ISystemManager(localRoot);
if (!sm.isTopLevel())
sm = sm.topLevelSystemManager;
}
return sm;
}
/**
* Override parent property to handle the case where the parent is in
* a differnt sandbox. If the parent is in the same sandbox it is returned.
* If the parent is in a diffent sandbox, then null is returned.
*
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
override public function get parent():DisplayObjectContainer
{
try
{
return super.parent;
}
catch (e:SecurityError)
{
// trace("parent: ignoring security error");
}
return null;
}
/**
* Go up the parent chain to get the top level system manager.
*
* Returns <code>null</code> if not on the display list or we don't have
* access to the top-level system manager.
*
* @return The root system manager.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function getTopLevelRoot():DisplayObject
{
// work our say up the parent chain to the root. This way we
// don't have to rely on this object being added to the stage.
try
{
var sm:ISystemManager = this;
if (sm.topLevelSystemManager)
sm = sm.topLevelSystemManager;
var parent:DisplayObject = DisplayObject(sm).parent;
var lastParent:DisplayObject = DisplayObject(sm);
while (parent)
{
if (parent is Stage)
return lastParent;
lastParent = parent;
parent = parent.parent;
}
}
catch (error:SecurityError)
{
}
return null;
}
/**
* Go up the parent chain to get the top level system manager in this
* SecurityDomain.
*
* @return The root system manager in this SecurityDomain.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function getSandboxRoot():DisplayObject
{
// work our say up the parent chain to the root. This way we
// don't have to rely on this object being added to the stage.
var sm:ISystemManager = this;
try
{
if (sm.topLevelSystemManager)
sm = sm.topLevelSystemManager;
var parent:DisplayObject = DisplayObject(sm).parent;
if (parent is Stage)
return DisplayObject(sm);
// test to see if parent is a Bootstrap
if (parent && !parent.dispatchEvent(new Event("mx.managers.SystemManager.isBootstrapRoot", false, true)))
return this;
var lastParent:DisplayObject = this;
while (parent)
{
if (parent is Stage)
return lastParent;
// test to see if parent is a Bootstrap
if (!parent.dispatchEvent(new Event("mx.managers.SystemManager.isBootstrapRoot", false, true)))
return lastParent;
// Test if the childAllowsParent so we know there is mutual trust between
// the sandbox root and this sm.
// The parentAllowsChild is taken care of by the player because it returns null
// for the parent if we do not have access.
if (parent is Loader)
{
var loader:Loader = Loader(parent);
var loaderInfo:LoaderInfo = loader.contentLoaderInfo;
if (!loaderInfo.childAllowsParent)
return loaderInfo.content;
}
// If an object is listening for system manager request we assume it is a sandbox
// root. If not, don't assign lastParent to this parent because it may be a
// non-Flex application. We only want Flex apps to be returned as sandbox roots.
// use constant to avoid link dependency on InterManagerRequest.SYSTEM_MANAGER_REQUEST
if (parent.hasEventListener("systemManagerRequest"
))
lastParent = parent;
parent = parent.parent;
}
}
catch (error:Error)
{
// Either we don't have security access to a parent or
// the swf is unloaded and loaderInfo.childAllowsParent is throwing Error #2099.
}
return lastParent != null ? lastParent : DisplayObject(sm);
}
/**
* @private
* A map of fully-qualified interface names,
* such as "mx.managers::IPopUpManager",
* to instances,
*/
private var implMap:Object = {};
/**
* @private
* Adds an interface-name-to-implementation-class mapping to the registry,
* if a class hasn't already been registered for the specified interface.
* The class must implement a getInstance() method which returns
* its singleton instance.
*/
public function registerImplementation(interfaceName:String,
impl:Object):void
{
var c:Object = implMap[interfaceName];
if (!c)
implMap[interfaceName] = impl;
}
/**
* @private
* Returns the singleton instance of the implementation class
* that was registered for the specified interface,
* by looking up the class in the registry
* and calling its getInstance() method.
*
* This method should not be called at static initialization time,
* because the factory class may not have called registerClass() yet.
*/
public function getImplementation(interfaceName:String):Object
{
var c:Object = implMap[interfaceName];
return c;
}
/**
* @inheritDoc
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function getVisibleApplicationRect(bounds:Rectangle = null, skipToSandboxRoot:Boolean = false):Rectangle
{
if (hasEventListener("getVisibleApplicationRect"))
{
var request:Request = new Request("getVisibleApplicationRect", false, true);
request.value = { bounds: bounds, skipToSandboxRoot: skipToSandboxRoot };
if (!dispatchEvent(request))
return Rectangle(request.value);
}
if (skipToSandboxRoot && !topLevel)
return topLevelSystemManager.getVisibleApplicationRect(bounds, skipToSandboxRoot);
if (!bounds)
{
bounds = getBounds(DisplayObject(this));
var sandboxRoot:DisplayObject = getSandboxRoot();
var s:Rectangle = screen.clone();
s.topLeft = sandboxRoot.localToGlobal(screen.topLeft);
s.bottomRight = sandboxRoot.localToGlobal(screen.bottomRight);
var pt:Point = new Point(Math.max(0, bounds.x), Math.max(0, bounds.y));
pt = localToGlobal(pt);
bounds.x = pt.x;
bounds.y = pt.y;
bounds.width = s.width;
bounds.height = s.height;
// No backwards compatibility
// See https://bugs.adobe.com/jira/browse/SDK-31377
// FlexVersion.compatibilityVersion >= FlexVersion.VERSION_4_6
// softKeyboardRect is in global coordinates.
// Keyboard size may change size while active. Listen for
// SoftKeyboardEvents on the stage and call
// getVisibleApplicationRect() to get updated visible bounds.
var softKeyboardRect:Rectangle = stage.softKeyboardRect;
bounds.height = bounds.height - softKeyboardRect.height;
}
if (!topLevel)
{
var obj:DisplayObjectContainer = parent.parent;
if ("getVisibleApplicationRect" in obj)
{
var visibleRect:Rectangle = obj["getVisibleApplicationRect"](true);
bounds = bounds.intersection(visibleRect);
}
}
return bounds;
}
/**
* @inheritDoc
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function deployMouseShields(deploy:Boolean):void
{
if (hasEventListener("deployMouseShields"))
{
var dynamicEvent:DynamicEvent = new DynamicEvent("deployMouseShields");
dynamicEvent.deploy = deploy;
dispatchEvent(dynamicEvent);
}
}
/**
* @private
* dispatch certain stage events from sandbox root
*/
private function stageEventHandler(event:Event):void
{
if (event.target is Stage && mouseCatcher)
{
// need to fix up the coordinate space before re-dispatching the mouse event
// to put it in the same coordinate space as the mouseCatcher since the
// mouseCatcher may be scaled while outside of the stage, we are not
if (event is MouseEvent)
{
var mouseEvent:MouseEvent = MouseEvent(event);
var stagePoint:Point = new Point(mouseEvent.stageX, mouseEvent.stageY);
var mouesCatcherLocalPoint:Point = mouseCatcher.globalToLocal(stagePoint);
mouseEvent.localX = mouesCatcherLocalPoint.x;
mouseEvent.localY = mouesCatcherLocalPoint.y;
}
// dispatch them from mouseCatcher so capture phase listeners on
// systemManager will work
mouseCatcher.dispatchEvent(event);
}
}
/**
* @private
* convert MOUSE_LEAVE to MOUSE_UP_SOMEWHERE
*/
private function mouseLeaveHandler(event:Event):void
{
dispatchEvent(new SandboxMouseEvent(SandboxMouseEvent.MOUSE_UP_SOMEWHERE));
}
}
}