////////////////////////////////////////////////////////////////////////////////
//
// 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 mx.core.Application
, which
* is the main, or top-level, window within an application.
*
*
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.
* *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.
* *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.
* *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 content
of the Loader
* that loaded it and simply serve as the parent of the sub-application
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 numChildren
property or
* call the getChildAt()
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 rawChildren
property.
The SystemManager is the first display class created within an application.
* It is responsible for creating an mx.preloaders.Preloader
that displays and
* mx.preloaders.SparkDownloadProgressBar
while the application finishes loading,
* then creates the mx.core.Application
instance.
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.
* * @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. *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.
* * @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.parameters
.
*
* @return An instance of the module, or null
.
*
* @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 explicitWidth
if defined,
* or the measuredWidth
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 explicitHeight
if defined,
* or the measuredHeight
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 move()
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 setActualSize()
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 true
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++;
super.addChildAt(mouseCatcher, 0);
resizeMouseCatcher();
if (!topLevel)
{
mouseCatcher.visible = false;
mask = mouseCatcher;
}
// Add the application as child 1.
noTopMostIndex++;
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.null
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));
}
}
}