blob: 3edd95b7315213a2c68314e86869c1aec5dc035b [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.systemClasses
{
import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.FocusEvent;
import flash.events.IEventDispatcher;
import flash.events.MouseEvent;
import flash.geom.Rectangle;
import flash.geom.Point;
import flash.utils.Dictionary;
import mx.events.DynamicEvent;
import mx.events.FlexEvent;
import mx.events.FlexChangeEvent;
import mx.events.EventListenerRequest;
import mx.events.InterManagerRequest;
import mx.events.InvalidateRequestData;
import mx.events.Request;
import mx.events.SandboxMouseEvent;
import mx.events.SWFBridgeEvent;
import mx.events.SWFBridgeRequest;
import mx.core.EventPriority;
import mx.core.IChildList;
import mx.core.IFlexDisplayObject;
import mx.core.IFlexModuleFactory;
import mx.core.IRawChildrenContainer;
import mx.core.ISWFBridgeGroup;
import mx.core.ISWFBridgeProvider;
import mx.core.ISWFLoader;
import mx.core.IUIComponent;
import mx.core.mx_internal;
import mx.core.Singleton;
import mx.core.SWFBridgeGroup;
import mx.managers.IFocusManager;
import mx.managers.IFocusManagerContainer;
import mx.managers.IMarshalSystemManager;
import mx.managers.PopUpManagerChildList;
import mx.managers.ISystemManager;
import mx.managers.ISystemManagerChildManager;
import mx.managers.SystemManagerGlobals;
import mx.managers.SystemManagerProxy;
import mx.managers.marshalClasses.CursorManagerMarshalMixin;
import mx.managers.marshalClasses.DragManagerMarshalMixin;
import mx.managers.marshalClasses.FocusManagerMarshalMixin;
import mx.managers.marshalClasses.PopUpManagerMarshalMixin;
import mx.managers.marshalClasses.ToolTipManagerMarshalMixin;
import mx.utils.EventUtil;
import mx.utils.NameUtil;
import mx.utils.SecurityUtil;
use namespace mx_internal;
[ExcludeClass]
[Mixin]
public class MarshallingSupport implements IMarshalSystemManager, ISWFBridgeProvider
{
include "../../core/Version.as";
//--------------------------------------------------------------------------
//
// Class Method
//
//--------------------------------------------------------------------------
public static function init(fbs:IFlexModuleFactory):void
{
Singleton.registerClass("mx.managers::IMarshalSystemManager", MarshallingSupport);
}
/**
* @private
*/
private static function weakDependency():void { CursorManagerMarshalMixin};
/**
* @private
*/
private static function weakDependency2():void { DragManagerMarshalMixin };
/**
* @private
*/
private static function weakDependency3():void { FocusManagerMarshalMixin };
/**
* @private
*/
private static function weakDependency4():void { PopUpManagerMarshalMixin };
/**
* @private
*/
private static function weakDependency5():void { ToolTipManagerMarshalMixin };
//--------------------------------------------------------------------------
//
// 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>
*/
public function MarshallingSupport(systemManager:ISystemManager = null)
{
super();
if (!systemManager)
return;
this.systemManager = systemManager;
systemManager.addEventListener("invalidateParentSizeAndDisplayList", invalidateParentSizeAndDisplayListHandler);
systemManager.addEventListener("addEventListener", addEventListenerHandler);
systemManager.addEventListener("removeEventListener", removeEventListenerHandler);
systemManager.addEventListener("getVisibleApplicationRect", getVisibleApplicationRectHandler);
systemManager.addEventListener("deployMouseShields", deployMouseShieldsHandler);
systemManager.addEventListener("getScreen", Stage_resizeHandler);
var awm:ActiveWindowManager =
ActiveWindowManager(systemManager.getImplementation("mx.managers::IActiveWindowManager"));
awm.addEventListener("removeFocusManager", removeFocusManagerHandler);
awm.addEventListener("activateForm", activateFormHandler);
awm.addEventListener("activatedForm", activatedFormHandler);
awm.addEventListener("deactivateForm", deactivateFormHandler);
awm.addEventListener("deactivatedForm", deactivatedFormHandler);
awm.addEventListener("canActivateForm", canActivateFormHandler);
awm.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
childManager =
ISystemManagerChildManager(systemManager.getImplementation("mx.managers::ISystemManagerChildManager"));
if (useSWFBridge())
{
// create a bridge so we can talk to our parent.
swfBridgeGroup = new SWFBridgeGroup(systemManager);
swfBridgeGroup.parentBridge = DisplayObject(systemManager).loaderInfo.sharedEvents;
addParentBridgeListeners();
// send message to parent that we are ready.
// pass up the sandbox bridge to the parent so its knows who we are.
var bridgeEvent:SWFBridgeEvent = new SWFBridgeEvent(SWFBridgeEvent.BRIDGE_NEW_APPLICATION);
bridgeEvent.data = swfBridgeGroup.parentBridge;
swfBridgeGroup.parentBridge.dispatchEvent(bridgeEvent);
// placeholder popups are started locally
addEventListener(SWFBridgeRequest.ADD_POP_UP_PLACE_HOLDER_REQUEST, addPlaceholderPopupRequestHandler);
DisplayObject(systemManager).root.loaderInfo.addEventListener(Event.UNLOAD, unloadHandler, false, 0, true);
}
var sbRoot:DisplayObject = systemManager.getSandboxRoot();
// every SM has to have this listener in case it is the SM for some child AD that contains a manager
// and the parent ADs don't have that manager.
sbRoot.addEventListener(InterManagerRequest.INIT_MANAGER_REQUEST, initManagerHandler, false, 0, true);
// once managers get initialized, they bounce things off the sandbox root
if (sbRoot == systemManager)
{
sbRoot.addEventListener(InterManagerRequest.SYSTEM_MANAGER_REQUEST, systemManagerHandler);
sbRoot.addEventListener(InterManagerRequest.DRAG_MANAGER_REQUEST, multiWindowRedispatcher);
// listened for w/o use of constants because of dependency issues
//addEventListener(InterDragManagerEvent.DISPATCH_DRAG_EVENT, multiWindowRedispatcher);
sbRoot.addEventListener("dispatchDragEvent", multiWindowRedispatcher);
sbRoot.addEventListener(SWFBridgeRequest.ADD_POP_UP_REQUEST, addPopupRequestHandler);
sbRoot.addEventListener(SWFBridgeRequest.REMOVE_POP_UP_REQUEST, removePopupRequestHandler);
sbRoot.addEventListener(SWFBridgeRequest.ADD_POP_UP_PLACE_HOLDER_REQUEST, addPlaceholderPopupRequestHandler);
sbRoot.addEventListener(SWFBridgeRequest.REMOVE_POP_UP_PLACE_HOLDER_REQUEST, removePlaceholderPopupRequestHandler);
sbRoot.addEventListener(SWFBridgeEvent.BRIDGE_WINDOW_ACTIVATE, activateFormSandboxEventHandler);
sbRoot.addEventListener(SWFBridgeEvent.BRIDGE_WINDOW_DEACTIVATE, deactivateFormSandboxEventHandler);
sbRoot.addEventListener(SWFBridgeRequest.HIDE_MOUSE_CURSOR_REQUEST, hideMouseCursorRequestHandler);
sbRoot.addEventListener(SWFBridgeRequest.SHOW_MOUSE_CURSOR_REQUEST, showMouseCursorRequestHandler);
sbRoot.addEventListener(SWFBridgeRequest.RESET_MOUSE_CURSOR_REQUEST, resetMouseCursorRequestHandler);
}
}
//--------------------------------------------------------------------------
//
// Variables
//
//--------------------------------------------------------------------------
/**
* @private
*/
private var systemManager:ISystemManager;
/**
* @private
*/
private var childManager:ISystemManagerChildManager;
//----------------------------------
// bridgeToFocusManager
//----------------------------------
/**
* @private
* Map a bridge to a FocusManager.
* This dictionary contains both the focus managers for this document as
* well as focus managers that are in documents contained inside of pop
* ups, if the system manager in that pop up requires a bridge to
* communicate with this system manager.
*
* The returned object is an object of type IFocusManager.
*/
private var _bridgeToFocusManager:Dictionary;
/**
* @private
*
* System Managers in child application domains use their parent's
* bridgeToFocusManager's Dictionary. The swfBridgeGroup property
* is maintained in the same way.
*/
mx_internal function get bridgeToFocusManager():Dictionary
{
if (Object(systemManager).topLevel)
return _bridgeToFocusManager;
else if (systemManager.topLevelSystemManager)
{
var topMP:MarshallingSupport = MarshallingSupport(systemManager.topLevelSystemManager.
getImplementation("mx.managers::IMarshalSystemManager"));
return topMP.bridgeToFocusManager;
}
return null;
}
mx_internal function set bridgeToFocusManager(bridgeToFMDictionary:Dictionary):void
{
if (Object(systemManager).topLevel)
_bridgeToFocusManager = bridgeToFMDictionary;
else if (systemManager.topLevelSystemManager)
{
var topMP:MarshallingSupport = MarshallingSupport(systemManager.topLevelSystemManager.
getImplementation("mx.managers::IMarshalSystemManager"));
topMP.bridgeToFocusManager = bridgeToFMDictionary;
}
}
//--------------------------------------------------------------------------
// swf bridge group
//--------------------------------------------------------------------------
/**
* @private
*
* Represents the related parent and child sandboxs this SystemManager may
* communicate with.
*/
private var _swfBridgeGroup:ISWFBridgeGroup;
public function get swfBridgeGroup():ISWFBridgeGroup
{
if (systemManager.isTopLevel())
return _swfBridgeGroup;
else if (systemManager.topLevelSystemManager)
{
var mp:IMarshalSystemManager =
IMarshalSystemManager(systemManager.topLevelSystemManager.getImplementation("mx.managers::IMarshalSystemManager"));
return mp.swfBridgeGroup;
}
return null;
}
public function set swfBridgeGroup(bridgeGroup:ISWFBridgeGroup):void
{
if (systemManager.isTopLevel())
_swfBridgeGroup = bridgeGroup;
else if (systemManager.topLevelSystemManager)
{
var mp:IMarshalSystemManager =
IMarshalSystemManager(systemManager.topLevelSystemManager.getImplementation("mx.managers::IMarshalSystemManager"));
mp.swfBridgeGroup = bridgeGroup;
}
}
//--------------------------------------------------------------------------
//
// Properties: ISWFBridgeProvider
//
//--------------------------------------------------------------------------
/**
* @inheritDoc
*/
public function get swfBridge():IEventDispatcher
{
if (swfBridgeGroup)
return swfBridgeGroup.parentBridge;
return null;
}
/**
* @inheritDoc
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get childAllowsParent():Boolean
{
try
{
return DisplayObject(systemManager).loaderInfo.childAllowsParent;
}
catch (error:Error)
{
//Error #2099: The loading object is not sufficiently loaded to provide this information.
}
return false; // assume the worst
}
/**
* @inheritDoc
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get parentAllowsChild():Boolean
{
try
{
return DisplayObject(systemManager).loaderInfo.parentAllowsChild;
}
catch (error:Error)
{
//Error #2099: The loading object is not sufficiently loaded to provide this information.
}
return false; // assume the worst
}
/**
* @private
*
* Used to locate untrusted forms. Maps string ids to Objects.
* The object make be the SystemManagerProxy of a form or it may be
* the bridge to the child application where the object lives.
*/
private var idToPlaceholder:Object;
private var eventProxy:EventProxy;
private var eventProxyRefCounts:Object = {};
//--------------------------------------------------------------------------
//
// Overridden methods: EventDispatcher
//
//--------------------------------------------------------------------------
/**
* @private
* Only create idle events if someone is listening.
*/
public function addEventListener(type:String, listener:Function,
useCapture:Boolean = false,
priority:int = 0,
useWeakReference:Boolean = false):Boolean
{
if (hasSWFBridges() || SystemManagerGlobals.topLevelSystemManagers.length > 1)
{
if (!eventProxy)
{
eventProxy = new EventProxy(systemManager);
}
var actualType:String = EventUtil.sandboxMouseEventMap[type];
if (actualType)
{
if (systemManager.isTopLevelRoot())
{
systemManager.stage.addEventListener(MouseEvent.MOUSE_MOVE, resetMouseCursorTracking, true, EventPriority.CURSOR_MANAGEMENT + 1, true);
addEventListenerToSandboxes(SandboxMouseEvent.MOUSE_MOVE_SOMEWHERE, resetMouseCursorTracking, true, EventPriority.CURSOR_MANAGEMENT + 1, true);
}
else
{
Object(systemManager).$addEventListener(MouseEvent.MOUSE_MOVE, resetMouseCursorTracking, true, EventPriority.CURSOR_MANAGEMENT + 1, true);
}
addEventListenerToSandboxes(type, sandboxMouseListener, useCapture, priority, useWeakReference);
if (!SystemManagerGlobals.changingListenersInOtherSystemManagers)
addEventListenerToOtherSystemManagers(type, otherSystemManagerMouseListener, useCapture, priority, useWeakReference)
if (systemManager.getSandboxRoot() == systemManager)
{
if (eventProxyRefCounts[actualType] == null)
eventProxyRefCounts[actualType] = 1;
else
eventProxyRefCounts[actualType] ++;
Object(systemManager).$addEventListener(actualType, eventProxy.marshalListener,
useCapture, priority, useWeakReference);
if (actualType == MouseEvent.MOUSE_UP)
{
try
{
if (systemManager.stage)
systemManager.stage.addEventListener(Event.MOUSE_LEAVE, eventProxy.marshalListener,
useCapture, priority, useWeakReference);
else
Object(systemManager).$addEventListener(Event.MOUSE_LEAVE, eventProxy.marshalListener,
useCapture, priority, useWeakReference);
}
catch (e:SecurityError)
{
Object(systemManager).$addEventListener(Event.MOUSE_LEAVE, eventProxy.marshalListener,
useCapture, priority, useWeakReference);
}
}
}
// Set useCapture to false because we will never see an event
// marshalled in the capture phase.
Object(systemManager).$addEventListener(type, listener, false, priority, useWeakReference);
return false;
}
}
return true;
}
/**
* @private
*
* Test if this system manager has any sandbox bridges.
*
* @return true if there are sandbox bridges, false otherwise.
*/
private function hasSWFBridges():Boolean
{
return swfBridgeGroup != null;
}
/**
* @private
*/
public function removeEventListener(type:String, listener:Function,
useCapture:Boolean = false):Boolean
{
if (hasSWFBridges() || SystemManagerGlobals.topLevelSystemManagers.length > 1)
{
var actualType:String = EventUtil.sandboxMouseEventMap[type];
if (actualType)
{
if (systemManager.getSandboxRoot() == systemManager && eventProxy)
{
if (eventProxyRefCounts[actualType] != null)
eventProxyRefCounts[actualType] --;
if (eventProxyRefCounts[actualType] == null || eventProxyRefCounts[actualType] == 0)
{
delete eventProxyRefCounts[actualType];
Object(systemManager).$removeEventListener(actualType, eventProxy.marshalListener,
useCapture);
if (actualType == MouseEvent.MOUSE_UP)
{
try
{
if (systemManager.stage)
systemManager.stage.removeEventListener(Event.MOUSE_LEAVE, eventProxy.marshalListener,
useCapture);
}
catch (e:SecurityError)
{
}
// Remove both listeners in case the system manager was added
// or removed from the stage after the listener was added.
Object(systemManager).$removeEventListener(Event.MOUSE_LEAVE, eventProxy.marshalListener,
useCapture);
}
}
else
return false; // if we didn't actually remove, don't remove on the following lines either
}
if (!SystemManagerGlobals.changingListenersInOtherSystemManagers)
removeEventListenerFromOtherSystemManagers(type, otherSystemManagerMouseListener, useCapture);
removeEventListenerFromSandboxes(type, sandboxMouseListener, useCapture);
Object(systemManager).$removeEventListener(type, listener, false);
return false;
}
}
return true;
}
//--------------------------------------------------------------------------
//
// Methods: Focus
//
//--------------------------------------------------------------------------
/**
* @private
*
* New version of activate that does not require a
* IFocusManagerContainer.
*/
private function activateFormHandler(event:DynamicEvent):void
{
var awm:ActiveWindowManager =
ActiveWindowManager(systemManager.getImplementation("mx.managers::IActiveWindowManager"));
// trace("SM: activate " + f + " " + forms.length);
if (awm.form)
{
if (awm.form != event.form && awm.forms.length > 1)
{
// Switch the active form.
if (isRemotePopUp(awm.form))
{
if (!areRemotePopUpsEqual(awm.form, event.form))
deactivateRemotePopUp(awm.form);
event.preventDefault();
}
}
}
}
private function activatedFormHandler(event:DynamicEvent):void
{
// trace("f = " + f);
if (isRemotePopUp(event.form))
{
activateRemotePopUp(event.form);
event.preventDefault();
}
}
/**
* @private
*
* New version of deactivate that works with remote pop ups.
*
*/
private function deactivateFormHandler(event:DynamicEvent):void
{
var awm:ActiveWindowManager =
ActiveWindowManager(systemManager.getImplementation("mx.managers::IActiveWindowManager"));
// trace(">>SM: deactivate " + f);
if (awm.form)
{
// If there's more than one form and this is it, find a new form.
if (awm.form == event.form && awm.forms.length > 1)
{
if (isRemotePopUp(awm.form))
{
deactivateRemotePopUp(awm.form);
event.preventDefault();
}
}
}
}
private function deactivatedFormHandler(event:DynamicEvent):void
{
if (isRemotePopUp(event.form))
{
activateRemotePopUp(event.form);
event.preventDefault();
}
// trace("<<SM: deactivate " + f);
}
/**
* @private
*
* @return true if the form can be activated, false otherwise.
*/
private function canActivateFormHandler(request:Request):void
{
if (isRemotePopUp(request.value))
{
var remotePopUp:RemotePopUp = RemotePopUp(request.value);
var event:SWFBridgeRequest = new SWFBridgeRequest(SWFBridgeRequest.CAN_ACTIVATE_POP_UP_REQUEST,
false, false, null,
remotePopUp.window);
IEventDispatcher(remotePopUp.bridge).dispatchEvent(event);
request.value = event.data;
request.preventDefault();
}
}
/**
* @private
*
* @return true if the form is a RemotePopUp, false if the form is IFocusManagerContainer.
*
*/
private static function isRemotePopUp(form:Object):Boolean
{
return !(form is IFocusManagerContainer);
}
/**
* @private
*
* @return true if form1 and form2 are both of type RemotePopUp and are equal, false otherwise.
*/
private static function areRemotePopUpsEqual(form1:Object, form2:Object):Boolean
{
if (!(form1 is RemotePopUp))
return false;
if (!(form2 is RemotePopUp))
return false;
var remotePopUp1:RemotePopUp = RemotePopUp(form1);
var remotePopUp2:RemotePopUp = RemotePopUp(form2);
if (remotePopUp1.window == remotePopUp2.window &&
remotePopUp1.bridge && remotePopUp2.bridge)
return true;
return false;
}
/**
* @private
*
* Find a remote form that is hosted by this system manager.
*
* @param window unique id of popUp within a bridged application
* @param bridge bridge of owning application.
*
* @return RemotePopUp if hosted by this system manager, false otherwise.
*/
private function findRemotePopUp(window:Object, bridge:IEventDispatcher):RemotePopUp
{
var awm:ActiveWindowManager =
ActiveWindowManager(systemManager.getImplementation("mx.managers::IActiveWindowManager"));
// remove the placeholder from forms array
var n:int = awm.forms.length;
for (var i:int = 0; i < n; i++)
{
if (isRemotePopUp(awm.forms[i]))
{
var popUp:RemotePopUp = RemotePopUp(awm.forms[i]);
if (popUp.window == window &&
popUp.bridge == bridge)
return popUp;
}
}
return null;
}
/**
* Remote a remote form from the forms array.
*
* form Locally created remote form.
*/
private function removeRemotePopUp(form:RemotePopUp):void
{
var awm:ActiveWindowManager =
ActiveWindowManager(systemManager.getImplementation("mx.managers::IActiveWindowManager"));
// remove popup from forms array
var n:int = awm.forms.length;
for (var i:int = 0; i < n; i++)
{
if (isRemotePopUp(awm.forms[i]))
{
if (awm.forms[i].window == form.window &&
awm.forms[i].bridge == form.bridge)
{
if (awm.forms[i] == form)
awm.deactivate(IFocusManagerContainer(form));
awm.forms.splice(i, 1);
break;
}
}
}
}
/**
* @private
*
* Activate a form that belongs to a system manager in another
* sandbox or peer application domain.
*
* @param form a RemotePopUp object.
* */
private function activateRemotePopUp(form:Object):void
{
var request:SWFBridgeRequest = new SWFBridgeRequest(SWFBridgeRequest.ACTIVATE_POP_UP_REQUEST,
false, false,
form.bridge,
form.window);
var bridge:Object = form.bridge;
if (bridge)
bridge.dispatchEvent(request);
}
private function deactivateRemotePopUp(form:Object):void
{
var request:SWFBridgeRequest = new SWFBridgeRequest(SWFBridgeRequest.DEACTIVATE_POP_UP_REQUEST,
false, false,
form.bridge,
form.window);
var bridge:Object = form.bridge;
if (bridge)
bridge.dispatchEvent(request);
}
/**
* Test if two forms are equal.
*
* @param form1 - may be of type a DisplayObjectContainer or a RemotePopUp
* @param form2 - may be of type a DisplayObjectContainer or a RemotePopUp
*
* @return true if the forms are equal, false otherwise.
*/
private function areFormsEqual(form1:Object, form2:Object):Boolean
{
if (form1 == form2)
return true;
// if the forms are both remote forms, then compare them, otherwise
// return false.
if (form1 is RemotePopUp && form2 is RemotePopUp)
{
return areRemotePopUpsEqual(form1, form2);
}
return false;
}
/**
* @inheritDoc
*/
public function addFocusManager(f:IFocusManagerContainer):void
{
// trace("OLW: add focus manager" + f);
var awm:ActiveWindowManager =
ActiveWindowManager(systemManager.getImplementation("mx.managers::IActiveWindowManager"));
awm.forms.push(f);
// trace("END OLW: add focus manager" + f);
}
/**
* @inheritDoc
*/
public function removeFocusManagerHandler(event:FocusEvent):void
{
dispatchDeactivatedWindowEvent(DisplayObject(event.relatedObject));
}
//--------------------------------------------------------------------------
//
// Methods: Other
//
//--------------------------------------------------------------------------
/**
* @private
*
* Dispatch an invalidate request to invalidate the size and
* display list of the parent application.
*/
private function dispatchInvalidateRequest():void
{
var bridge:IEventDispatcher = swfBridgeGroup.parentBridge;
var request:SWFBridgeRequest = new SWFBridgeRequest(
SWFBridgeRequest.INVALIDATE_REQUEST,
false, false,
bridge,
InvalidateRequestData.SIZE |
InvalidateRequestData.DISPLAY_LIST);
bridge.dispatchEvent(request);
}
//--------------------------------------------------------------------------
//
// Event handlers
//
//--------------------------------------------------------------------------
/**
* @private
* Track mouse clicks to see if we change top-level forms.
* Note that we get a FocusEvent here and not a MouseEvent because we
* use a FocusEvent to forward the MouseEvent to the mixin. That's
* why we use event.relatedObject here and not MouseEvent
*/
private function mouseDownHandler(event:FocusEvent):void
{
var awm:ActiveWindowManager =
ActiveWindowManager(systemManager.getImplementation("mx.managers::IActiveWindowManager"));
event.preventDefault();
// trace("SM:mouseDownHandler " + this);
// If an object was clicked that is inside another system manager
// in a bridged application, activate the current document because
// the bridge application is considered part of the main application.
// We also see mouse clicks on dialogs popped up from compatible applications.
var bridge:IEventDispatcher = getSWFBridgeOfDisplayObject(event.relatedObject as DisplayObject);
if (bridge && bridgeToFocusManager[bridge] == systemManager.document.focusManager)
{
// trace("SM:mouseDownHandler click in a bridged application");
if (systemManager.isTopLevelRoot())
awm.activate(IFocusManagerContainer(systemManager.document));
else
dispatchActivatedApplicationEvent();
return;
}
if (awm.numModalWindows == 0) // no modal windows are up
{
if (!systemManager.isTopLevelRoot() || awm.forms.length > 1)
{
var n:int = awm.forms.length;
var p:DisplayObject = DisplayObject(event.relatedObject);
var isApplication:Boolean = systemManager.document is IRawChildrenContainer ?
IRawChildrenContainer(systemManager.document).rawChildren.contains(p) :
systemManager.document.contains(p);
while (p)
{
for (var i:int = 0; i < n; i++)
{
var form_i:Object = isRemotePopUp(awm.forms[i]) ? awm.forms[i].window : awm.forms[i];
if (form_i == p)
{
var j:int = 0;
var index:int;
var newIndex:int;
var childList:IChildList;
if (((p != awm.form) && p is IFocusManagerContainer) ||
(!systemManager.isTopLevelRoot() && p == awm.form))
{
if (systemManager.isTopLevelRoot())
awm.activate(IFocusManagerContainer(p));
if (p == systemManager.document)
dispatchActivatedApplicationEvent();
else if (p is DisplayObject)
dispatchActivatedWindowEvent(DisplayObject(p));
}
if (systemManager.popUpChildren.contains(p))
childList = systemManager.popUpChildren;
else
childList = systemManager;
index = childList.getChildIndex(p);
newIndex = index;
//we need to reset n because activating p's
//FocusManager could have caused
//forms.length to have changed.
n = awm.forms.length;
for (j = 0; j < n; j++)
{
var f:DisplayObject;
var isRemotePopUp:Boolean = isRemotePopUp(awm.forms[j]);
if (isRemotePopUp)
{
if (awm.forms[j].window is String)
continue;
f = awm.forms[j].window;
}
else
f = awm.forms[j];
if (isRemotePopUp)
{
var fChildIndex:int = getChildListIndex(childList, f);
if (fChildIndex > index)
newIndex = Math.max(fChildIndex, newIndex);
}
else if (childList.contains(f))
if (childList.getChildIndex(f) > index)
newIndex = Math.max(childList.getChildIndex(f), newIndex);
}
if (newIndex > index && !isApplication)
childList.setChildIndex(p, newIndex);
return;
}
}
p = p.parent;
}
}
else
dispatchActivatedApplicationEvent();
}
}
/**
* @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
*
* Handle request to unload
* Forward event, and do some cleanup
*/
private function beforeUnloadHandler(event:Event):void
{
if (systemManager.isTopLevel() && systemManager.stage)
{
var sandboxRoot:DisplayObject = systemManager.getSandboxRoot();
if (sandboxRoot != DisplayObject(systemManager))
sandboxRoot.removeEventListener(Event.RESIZE, Stage_resizeHandler);
}
removeParentBridgeListeners();
systemManager.dispatchEvent(event);
}
//--------------------------------------------------------------------------
//
// Sandbox Event handlers for messages from children
//
//--------------------------------------------------------------------------
/**
* @private
*
* Add a popup request handler for domain local request and
* remote domain requests.
*/
private function addPopupRequestHandler(event:Event):void
{
if (event.target != systemManager && event is SWFBridgeRequest)
return;
var awm:ActiveWindowManager =
ActiveWindowManager(systemManager.getImplementation("mx.managers::IActiveWindowManager"));
var popUpRequest:SWFBridgeRequest = SWFBridgeRequest.marshal(event);
// If there is not for mutual trust between us an the child that wants the
// popup, then don't host the pop up.
if (event.target != systemManager)
{
var bridgeProvider:ISWFBridgeProvider = swfBridgeGroup.getChildBridgeProvider(
IEventDispatcher(event.target));
if (!SecurityUtil.hasMutualTrustBetweenParentAndChild(bridgeProvider))
{
return;
}
}
var topMost:Boolean;
// Need to have mutual trust between two application in order
// for an application to host another application's popup.
if (swfBridgeGroup.parentBridge &&
SecurityUtil.hasMutualTrustBetweenParentAndChild(this))
{
// ask the parent to host the popup
popUpRequest.requestor = swfBridgeGroup.parentBridge;
systemManager.getSandboxRoot().dispatchEvent(popUpRequest);
return;
}
// add popup as a child of this system manager
if (!popUpRequest.data.childList || popUpRequest.data.childList == PopUpManagerChildList.PARENT)
topMost = popUpRequest.data.parent && systemManager.popUpChildren.contains(popUpRequest.data.parent);
else
topMost = (popUpRequest.data.childList == PopUpManagerChildList.POPUP);
var children:IChildList;
children = topMost ? systemManager.popUpChildren : systemManager;
children.addChild(DisplayObject(popUpRequest.data.window));
if (popUpRequest.data.modal)
awm.numModalWindows++;
// add popup to the list of managed forms
var remoteForm:RemotePopUp = new RemotePopUp(popUpRequest.data.window, popUpRequest.requestor);
awm.forms.push(remoteForm);
if (!systemManager.isTopLevelRoot() && swfBridgeGroup)
{
// We've added the popup as far as it can go.
// Add a placeholder to the top level root application
var request:SWFBridgeRequest = new SWFBridgeRequest(SWFBridgeRequest.ADD_POP_UP_PLACE_HOLDER_REQUEST,
false, false,
popUpRequest.requestor,
{ window: popUpRequest.data.window });
request.data.placeHolderId = NameUtil.displayObjectToString(DisplayObject(popUpRequest.data.window));
systemManager.dispatchEvent(request);
}
}
/**
* @private
*
* Message from a child system manager to
* remove the popup that was added by using the
* addPopupRequestHandler.
*/
private function removePopupRequestHandler(event:Event):void
{
var awm:ActiveWindowManager =
ActiveWindowManager(systemManager.getImplementation("mx.managers::IActiveWindowManager"));
var popUpRequest:SWFBridgeRequest = SWFBridgeRequest.marshal(event);
if (swfBridgeGroup.parentBridge &&
SecurityUtil.hasMutualTrustBetweenParentAndChild(this))
{
// since there is mutual trust the popup is hosted by the parent.
popUpRequest.requestor = swfBridgeGroup.parentBridge;
systemManager.getSandboxRoot().dispatchEvent(popUpRequest);
return;
}
if (systemManager.popUpChildren.contains(popUpRequest.data.window))
systemManager.popUpChildren.removeChild(popUpRequest.data.window);
else
systemManager.removeChild(DisplayObject(popUpRequest.data.window));
if (popUpRequest.data.modal)
awm.numModalWindows--;
removeRemotePopUp(new RemotePopUp(popUpRequest.data.window, popUpRequest.requestor));
if (!systemManager.isTopLevelRoot() && swfBridgeGroup)
{
// if we got here we know the parent is untrusted, so remove placeholders
var request:SWFBridgeRequest = new SWFBridgeRequest(SWFBridgeRequest.REMOVE_POP_UP_PLACE_HOLDER_REQUEST,
false, false,
popUpRequest.requestor,
{placeHolderId: NameUtil.displayObjectToString(popUpRequest.data.window)
});
systemManager.dispatchEvent(request);
}
}
/**
* @private
*
* Handle request to add a popup placeholder.
* The placeholder represents an untrusted form that is hosted
* elsewhere.
*/
private function addPlaceholderPopupRequestHandler(event:Event):void
{
var popUpRequest:SWFBridgeRequest = SWFBridgeRequest.marshal(event);
var awm:ActiveWindowManager =
ActiveWindowManager(systemManager.getImplementation("mx.managers::IActiveWindowManager"));
if (event.target != systemManager && event is SWFBridgeRequest)
return;
if (!forwardPlaceholderRequest(popUpRequest, true))
{
// Create a RemotePopUp and add it.
var remoteForm:RemotePopUp = new RemotePopUp(popUpRequest.data.placeHolderId, popUpRequest.requestor);
awm.forms.push(remoteForm);
}
}
/**
* @private
*
* Handle request to add a popup placeholder.
* The placeholder represents an untrusted form that is hosted
* elsewhere.
*/
private function removePlaceholderPopupRequestHandler(event:Event):void
{
var popUpRequest:SWFBridgeRequest = SWFBridgeRequest.marshal(event);
var awm:ActiveWindowManager =
ActiveWindowManager(systemManager.getImplementation("mx.managers::IActiveWindowManager"));
if (!forwardPlaceholderRequest(popUpRequest, false))
{
// remove the placeholder from forms array
var n:int = awm.forms.length;
for (var i:int = 0; i < n; i++)
{
if (isRemotePopUp(awm.forms[i]))
{
if (awm.forms[i].window == popUpRequest.data.placeHolderId &&
awm.forms[i].bridge == popUpRequest.requestor)
{
awm.forms.splice(i, 1);
break;
}
}
}
}
}
/**
* Forward a form event update the parent chain.
* Takes care of removing object references and substituting
* ids when an untrusted boundry is crossed.
*/
private function forwardFormEvent(event:SWFBridgeEvent):Boolean
{
if (systemManager.isTopLevelRoot())
return false;
var bridge:IEventDispatcher = swfBridgeGroup.parentBridge;
if (bridge)
{
var sbRoot:DisplayObject = systemManager.getSandboxRoot();
event.data.notifier = bridge;
if (sbRoot == systemManager)
{
if (!(event.data.window is String))
event.data.window = NameUtil.displayObjectToString(DisplayObject(event.data.window));
else
event.data.window = NameUtil.displayObjectToString(DisplayObject(systemManager)) + "." + event.data.window;
bridge.dispatchEvent(event);
}
else
{
if (event.data.window is String)
event.data.window = NameUtil.displayObjectToString(DisplayObject(systemManager)) + "." + event.data.window;
sbRoot.dispatchEvent(event);
}
}
return true;
}
/**
* Forward an AddPlaceholder request up the parent chain, if needed.
*
* @param request request to either add or remove a pop up placeholder.
* @param addPlaceholder true if adding a placeholder, false it removing a placeholder.
* @return true if the request was forwared, false otherwise
*/
private function forwardPlaceholderRequest(request:SWFBridgeRequest, addPlaceholder:Boolean):Boolean
{
// Only the top level root tracks the placeholders.
// If we are not the top level root then keep passing
// the message up the parent chain.
if (systemManager.isTopLevelRoot())
return false;
// If the window object is passed, then this is the first
// stop on the way up the parent chain.
var refObj:Object = null;
var oldId:String = null;
if (request.data.window)
{
refObj = request.data.window;
// null this ref out so untrusted parent cannot see
request.data.window = null;
}
else
{
refObj = request.requestor;
// prefix the existing id with the id of this object
oldId = request.data.placeHolderId;
request.data.placeHolderId = NameUtil.displayObjectToString(DisplayObject(systemManager)) + "." + request.data.placeHolderId;
}
if (addPlaceholder)
addPlaceholderId(request.data.placeHolderId, oldId, request.requestor, refObj);
else
removePlaceholderId(request.data.placeHolderId);
var sbRoot:DisplayObject = systemManager.getSandboxRoot();
var bridge:IEventDispatcher = swfBridgeGroup.parentBridge;
request.requestor = bridge;
if (sbRoot == systemManager)
bridge.dispatchEvent(request);
else
sbRoot.dispatchEvent(request);
return true;
}
/**
* One of the system managers in another sandbox deactivated and sent a message
* to the top level system manager. In response the top-level system manager
* needs to find a new form to activate.
*/
private function deactivateFormSandboxEventHandler(event:Event):void
{
// trace("bridgeDeactivateFormEventHandler");
var awm:ActiveWindowManager =
ActiveWindowManager(systemManager.getImplementation("mx.managers::IActiveWindowManager"));
if (event is SWFBridgeRequest)
return;
var bridgeEvent:SWFBridgeEvent = SWFBridgeEvent.marshal(event);
if (!forwardFormEvent(bridgeEvent))
{
// deactivate the form
if (isRemotePopUp(awm.form) &&
RemotePopUp(awm.form).window == bridgeEvent.data.window &&
RemotePopUp(awm.form).bridge == bridgeEvent.data.notifier)
awm.deactivate(awm.form);
}
}
/**
* A form in one of the system managers in another sandbox has been activated.
* The form being activate is identified.
* In response the top-level system manager needs to activate the given form
* and deactivate the currently active form, if any.
*/
private function activateFormSandboxEventHandler(event:Event):void
{
// trace("bridgeDeactivateFormEventHandler");
var awm:ActiveWindowManager =
ActiveWindowManager(systemManager.getImplementation("mx.managers::IActiveWindowManager"));
// trace("bridgeActivateFormEventHandler");
var bridgeEvent:SWFBridgeEvent = SWFBridgeEvent.marshal(event);
if (!forwardFormEvent(bridgeEvent))
// just call activate on the remote form.
awm.activate(new RemotePopUp(bridgeEvent.data.window, bridgeEvent.data.notifier));
}
/**
* One of the system managers in another sandbox activated and sent a message
* to the top level system manager to deactivate this form. In response the top-level system manager
* needs to deactivate all other forms except the top level system manager's.
*/
private function activateApplicationSandboxEventHandler(event:Event):void
{
// trace("bridgeDeactivateFormEventHandler");
var awm:ActiveWindowManager =
ActiveWindowManager(systemManager.getImplementation("mx.managers::IActiveWindowManager"));
// trace("bridgeActivateApplicationEventHandler");
if (!systemManager.isTopLevelRoot())
{
swfBridgeGroup.parentBridge.dispatchEvent(event);
return;
}
// An application was activated, active the main document.
awm.activate(IFocusManagerContainer(systemManager.document));
}
/**
* @private
*
* Re-dispatch events sent over the bridge to listeners on this
* system manager. PopUpManager is expected to listen to these
* events.
*/
private function modalWindowRequestHandler(event:Event):void
{
if (event is SWFBridgeRequest)
return;
var request:SWFBridgeRequest = SWFBridgeRequest.marshal(event);
if (!preProcessModalWindowRequest(request, systemManager.getSandboxRoot()))
return;
// Ensure a PopUpManager exists and dispatch the request it is
// listening for.
Singleton.getInstance("mx.managers::IPopUpManager");
systemManager.dispatchEvent(request);
}
/**
* @private
*
* Calculate the visible rectangle of the requesting application in this
* application. Forward the request to our parent to see this the rectangle
* is further reduced. Continue up the parent chain until the top level
* root parent is reached.
*/
private function getVisibleRectRequestHandler(event:Event):void
{
if (event is SWFBridgeRequest)
return;
var request:SWFBridgeRequest = SWFBridgeRequest.marshal(event);
var rect:Rectangle = Rectangle(request.data);
var owner:DisplayObject = DisplayObject(swfBridgeGroup.getChildBridgeProvider(request.requestor));
var localRect:Rectangle;
var forwardRequest:Boolean = true;
// Check if the request in a pop up. If it is then don't
// forward the request to our parent because we don't want
// to reduce the visible rect of the dialog base on the
// visible rect of applications in the main app.
if (!DisplayObjectContainer(systemManager.document).contains(owner))
forwardRequest = false;
if (owner is ISWFLoader)
localRect = ISWFLoader(owner).getVisibleApplicationRect();
else
{
localRect = owner.getBounds(DisplayObject(systemManager));
var pt:Point = DisplayObject(systemManager).localToGlobal(localRect.topLeft);
localRect.x = pt.x;
localRect.y = pt.y;
}
rect = rect.intersection(localRect); // update rect
request.data = rect;
// forward request
if (forwardRequest && useSWFBridge())
{
var bridge:IEventDispatcher = swfBridgeGroup.parentBridge;
request.requestor = bridge;
bridge.dispatchEvent(request);
}
Object(event).data = request.data; // update request
}
/**
* @private
*
* Notify the topLevelRoot that we don't want the mouseCursor shown
* Forward upward if necessary.
*/
private function hideMouseCursorRequestHandler(event:Event):void
{
if (!systemManager.isTopLevelRoot() && event is SWFBridgeRequest)
return;
var request:SWFBridgeRequest = SWFBridgeRequest.marshal(event);
// forward request
if (!systemManager.isTopLevelRoot())
{
var bridge:IEventDispatcher = swfBridgeGroup.parentBridge;
request.requestor = bridge;
bridge.dispatchEvent(request);
}
else if (eventProxy)
SystemManagerGlobals.showMouseCursor = false;
}
/**
* @private
*
* Ask the topLevelRoot if anybody don't want the mouseCursor shown
* Forward upward if necessary.
*/
private function showMouseCursorRequestHandler(event:Event):void
{
if (!systemManager.isTopLevelRoot() && event is SWFBridgeRequest)
return;
var request:SWFBridgeRequest = SWFBridgeRequest.marshal(event);
// forward request
if (!systemManager.isTopLevelRoot())
{
var bridge:IEventDispatcher = swfBridgeGroup.parentBridge;
request.requestor = bridge;
bridge.dispatchEvent(request);
Object(event).data = request.data; // update request
}
else if (eventProxy)
Object(event).data = SystemManagerGlobals.showMouseCursor;
}
/**
* @private
*
* Ask the topLevelRoot if anybody don't want the mouseCursor shown
* Forward upward if necessary.
*/
private function resetMouseCursorRequestHandler(event:Event):void
{
if (!systemManager.isTopLevelRoot() && event is SWFBridgeRequest)
return;
var request:SWFBridgeRequest = SWFBridgeRequest.marshal(event);
// forward request
if (!systemManager.isTopLevelRoot())
{
var bridge:IEventDispatcher = swfBridgeGroup.parentBridge;
request.requestor = bridge;
bridge.dispatchEvent(request);
}
else if (eventProxy)
SystemManagerGlobals.showMouseCursor = true;
}
private function resetMouseCursorTracking(event:Event):void
{
if (systemManager.isTopLevelRoot())
{
SystemManagerGlobals.showMouseCursor = true;
}
else if (swfBridgeGroup.parentBridge)
{
var cursorRequest:SWFBridgeRequest = new SWFBridgeRequest(SWFBridgeRequest.RESET_MOUSE_CURSOR_REQUEST);
var bridge:IEventDispatcher = swfBridgeGroup.parentBridge;
cursorRequest.requestor = bridge;
bridge.dispatchEvent(cursorRequest);
}
}
//--------------------------------------------------------------------------
//
// Sandbox Event handlers for messages from parent
//
//--------------------------------------------------------------------------
/**
* @private
*
* Sent by the SWFLoader to change the size of the application it loaded.
*/
private function setActualSizeRequestHandler(event:Event):void
{
var eObj:Object = Object(event);
IFlexDisplayObject(systemManager).setActualSize(eObj.data.width, eObj.data.height);
}
/**
* @private
*
* Get the size of this System Manager.
* Sent by a SWFLoader.
*/
private function getSizeRequestHandler(event:Event):void
{
var eObj:Object = Object(event);
eObj.data = { width: IFlexDisplayObject(systemManager).measuredWidth, height: IFlexDisplayObject(systemManager).measuredHeight};
}
/**
* @private
*
* Handle request to activate a particular form.
*
*/
private function activateRequestHandler(event:Event):void
{
var request:SWFBridgeRequest = SWFBridgeRequest.marshal(event);
// If data is a String, then we need to parse the id to find
// the form or the next bridge to pass the message to.
// If the data is a SystemMangerProxy we can just activate the
// form.
var child:Object = request.data;
var nextId:String = null;
if (request.data is String)
{
var placeholder:PlaceholderData = idToPlaceholder[request.data];
child = placeholder.data;
nextId = placeholder.id;
// check if the dialog is hosted on this system manager
if (nextId == null)
{
var popUp:RemotePopUp = findRemotePopUp(child, placeholder.bridge);
if (popUp)
{
activateRemotePopUp(popUp);
return;
}
}
}
if (child is SystemManagerProxy)
{
// activate request from the top-level system manager.
var smp:SystemManagerProxy = SystemManagerProxy(child);
var f:IFocusManagerContainer = findFocusManagerContainer(smp);
if (smp && f)
smp.activateByProxy(f);
}
else if (child is IFocusManagerContainer)
IFocusManagerContainer(child).focusManager.activate();
else if (child is IEventDispatcher)
{
request.data = nextId;
request.requestor = IEventDispatcher(child);
IEventDispatcher(child).dispatchEvent(request);
}
else
throw new Error(); // should never get here
}
/**
* @private
*
* Handle request to deactivate a particular form.
*
*/
private function deactivateRequestHandler(event:Event):void
{
var request:SWFBridgeRequest = SWFBridgeRequest.marshal(event);
var child:Object = request.data;
var nextId:String = null;
if (request.data is String)
{
var placeholder:PlaceholderData = idToPlaceholder[request.data];
child = placeholder.data;
nextId = placeholder.id;
// check if the dialog is hosted on this system manager
if (nextId == null)
{
var popUp:RemotePopUp = findRemotePopUp(child, placeholder.bridge);
if (popUp)
{
deactivateRemotePopUp(popUp);
return;
}
}
}
if (child is SystemManagerProxy)
{
// deactivate request from the top-level system manager.
var smp:SystemManagerProxy = SystemManagerProxy(child);
var f:IFocusManagerContainer = findFocusManagerContainer(smp);
if (smp && f)
smp.deactivateByProxy(f);
}
else if (child is IFocusManagerContainer)
IFocusManagerContainer(child).focusManager.deactivate();
else if (child is IEventDispatcher)
{
request.data = nextId;
request.requestor = IEventDispatcher(child);
IEventDispatcher(child).dispatchEvent(request);
return;
}
else
throw new Error();
}
//--------------------------------------------------------------------------
//
// Sandbox Event handlers for messages from either the
// parent or child
//
//--------------------------------------------------------------------------
/**
* Is the child in event.data this system manager or a child of this
* system manager?
*
* Set the data property to indicate if the display object is a child
*/
private function isBridgeChildHandler(event:Event):void
{
// if we are broadcasting messages, ignore the messages
// we send to ourselves.
if (event is SWFBridgeRequest)
return;
var eObj:Object = Object(event);
eObj.data = eObj.data && systemManager.rawChildren.contains(eObj.data as DisplayObject);
}
/**
* Can this form be activated. The current test is if the given pop up
* is visible and is enabled.
*
* Set the data property to indicate if can be activated
*/
private function canActivateHandler(event:Event):void
{
var eObj:Object = Object(event);
// If data is a String, then we need to parse the id to find
// the form or the next bridge to pass the message to.
// If the data is a SystemMangerProxy we can just activate the
// form.
var request:SWFBridgeRequest;
var child:Object = eObj.data;
var nextId:String = null;
if (eObj.data is String)
{
var placeholder:PlaceholderData = idToPlaceholder[eObj.data];
child = placeholder.data;
nextId = placeholder.id;
// check if the dialog is hosted on this system manager
if (nextId == null)
{
var popUp:RemotePopUp = findRemotePopUp(child, placeholder.bridge);
if (popUp)
{
request = new SWFBridgeRequest(SWFBridgeRequest.CAN_ACTIVATE_POP_UP_REQUEST,
false, false,
IEventDispatcher(popUp.bridge),
popUp.window);
if (popUp.bridge)
{
popUp.bridge.dispatchEvent(request);
eObj.data = request.data;
}
return;
}
}
}
if (child is SystemManagerProxy)
{
var smp:SystemManagerProxy = SystemManagerProxy(child);
var f:IFocusManagerContainer = findFocusManagerContainer(smp);
eObj.data = smp && f && canActivateLocalComponent(f);
}
else if (child is IFocusManagerContainer)
{
eObj.data = canActivateLocalComponent(child);
}
else if (child is IEventDispatcher)
{
var bridge:IEventDispatcher = IEventDispatcher(child);
request = new SWFBridgeRequest(SWFBridgeRequest.CAN_ACTIVATE_POP_UP_REQUEST,
false, false,
bridge,
nextId);
if (bridge)
{
bridge.dispatchEvent(request);
eObj.data = request.data;
}
}
else
throw new Error(); // should never get here
}
/**
* @private
*
* Test is a local component can be activated.
*/
private function canActivateLocalComponent(o:Object):Boolean
{
if (o is Sprite && o is IUIComponent &&
Sprite(o).visible && IUIComponent(o).enabled)
return true;
return false;
}
/**
* @private
*
* Test if a display object is in an applcation we want to communicate with over a bridge.
*
*/
public function isDisplayObjectInABridgedApplication(displayObject:DisplayObject):Boolean
{
return getSWFBridgeOfDisplayObject(displayObject) != null;
}
/**
* @private
*
* If a display object is in a bridged application, then return the SWFBridge
* that is used to communcation with that application. Otherwise return null.
*
* @param displayObject The object to test.
*
* @return The IEventDispather that represents the SWFBridge that should
* be used to communicate with this object, if the display object is in a
* bridge application. If the display object is not in a bridge application,
* then null is returned.
*
*/
private function getSWFBridgeOfDisplayObject(displayObject:DisplayObject):IEventDispatcher
{
if (swfBridgeGroup)
{
var request:SWFBridgeRequest = new SWFBridgeRequest(SWFBridgeRequest.IS_BRIDGE_CHILD_REQUEST,
false, false, null, displayObject);
var children:Array = swfBridgeGroup.getChildBridges();
var n:int = children.length;
for (var i:int = 0; i < n; i++)
{
var childBridge:IEventDispatcher = IEventDispatcher(children[i]);
// No need to test a child if it does not trust us, we will never see
// their display objects.
// Also, if the we don't trust the child don't send them a display object.
var bp:ISWFBridgeProvider = swfBridgeGroup.getChildBridgeProvider(childBridge);
if (SecurityUtil.hasMutualTrustBetweenParentAndChild(bp))
{
childBridge.dispatchEvent(request);
if (request.data == true)
return childBridge;
// reset data property
request.data = displayObject;
}
}
}
return null;
}
/**
* redispatch certian events to other top-level windows
*/
private function multiWindowRedispatcher(event:Event):void
{
if (!SystemManagerGlobals.dispatchingEventToOtherSystemManagers)
{
dispatchEventToOtherSystemManagers(event);
}
}
/**
* Create the requested manager.
*/
private function initManagerHandler(event:Event):void
{
if (!SystemManagerGlobals.dispatchingEventToOtherSystemManagers)
{
dispatchEventToOtherSystemManagers(event);
}
// if we are broadcasting messages, ignore the messages
// we send to ourselves.
if (event is InterManagerRequest)
return;
// initialize the registered manager implementation
var name:String = event["name"];
try
{
Singleton.getInstance(name);
}
catch (e:Error)
{
}
}
/**
* Adds a child to the requested childList.
*
* @param layer The child list that the child should be added to. The valid choices are
* "popUpChildren", "cursorChildren", and "toolTipChildren". The choices match the property
* names of ISystemManager and that is the list where the child is added.
*
* @param child The child to add.
*/
public function addChildToSandboxRoot(layer:String, child:DisplayObject):void
{
if (systemManager.getSandboxRoot() == systemManager)
{
systemManager[layer].addChild(child);
}
else
{
childManager.addingChild(child);
var me:InterManagerRequest = new InterManagerRequest(InterManagerRequest.SYSTEM_MANAGER_REQUEST);
me.name = layer + ".addChild";
me.value = child;
systemManager.getSandboxRoot().dispatchEvent(me);
childManager.childAdded(child);
}
}
/**
* Removes a child from the requested childList.
*
* @param layer The child list that the child should be removed from. The valid choices are
* "popUpChildren", "cursorChildren", and "toolTipChildren". The choices match the property
* names of ISystemManager and that is the list where the child is removed from.
*
* @param child The child to remove.
*/
public function removeChildFromSandboxRoot(layer:String, child:DisplayObject):void
{
if (systemManager.getSandboxRoot() == systemManager)
{
systemManager[layer].removeChild(child);
}
else
{
childManager.removingChild(child);
var me:InterManagerRequest = new InterManagerRequest(InterManagerRequest.SYSTEM_MANAGER_REQUEST);
me.name = layer + ".removeChild";
me.value = child;
systemManager.getSandboxRoot().dispatchEvent(me);
childManager.childRemoved(child);
}
}
/**
* Perform the requested action from a trusted dispatcher.
*/
private function systemManagerHandler(event:Event):void
{
if (event["name"] == "sameSandbox")
{
event["value"] = currentSandboxEvent == event["value"];
return;
}
else if (event["name"] == "hasSWFBridges")
{
event["value"] = hasSWFBridges();
return;
}
// if we are broadcasting messages, ignore the messages
// we send to ourselves.
if (event is InterManagerRequest)
return;
// initialize the registered manager implementation
var name:String = event["name"];
switch (name)
{
case "popUpChildren.addChild":
systemManager.popUpChildren.addChild(event["value"]);
break;
case "popUpChildren.removeChild":
systemManager.popUpChildren.removeChild(event["value"]);
break;
case "cursorChildren.addChild":
systemManager.cursorChildren.addChild(event["value"]);
break;
case "cursorChildren.removeChild":
systemManager.cursorChildren.removeChild(event["value"]);
break;
case "toolTipChildren.addChild":
systemManager.toolTipChildren.addChild(event["value"]);
break;
case "toolTipChildren.removeChild":
systemManager.toolTipChildren.removeChild(event["value"]);
break;
case "screen":
event["value"] = systemManager.screen;
break;
case "application":
event["value"] = systemManager.document;
break;
case "isTopLevelRoot":
event["value"] = systemManager.isTopLevelRoot();
break;
case "getVisibleApplicationRect":
event["value"] = getVisibleApplicationRect();
break;
case "bringToFront":
if (event["value"].topMost)
systemManager.popUpChildren.setChildIndex(DisplayObject(event["value"].popUp),
systemManager.popUpChildren.numChildren - 1);
else
systemManager.setChildIndex(DisplayObject(event["value"].popUp), systemManager.numChildren - 1);
break;
}
}
/**
* Get the size of our sandbox's screen property.
*
* Only the screen property should need to call this function.
*
* The function assumes the caller does not have access to the stage.
*
*/
private function getSandboxScreen():Rectangle
{
// If we don't have access to the stage, use the size of
// our sandbox root.
var sandboxRoot:DisplayObject = systemManager.getSandboxRoot();
var sandboxScreen:Rectangle;
if (sandboxRoot == systemManager)
// we don't have access the stage so use the width and
// height of the application.
sandboxScreen = new Rectangle(0, 0, IFlexDisplayObject(systemManager).width, IFlexDisplayObject(systemManager).height);
else if (sandboxRoot == systemManager.topLevelSystemManager)
{
var sm:DisplayObject = DisplayObject(systemManager.topLevelSystemManager);
sandboxScreen = new Rectangle(0, 0, sm.width, sm.height);
}
else
{
var me:InterManagerRequest = new InterManagerRequest(InterManagerRequest.SYSTEM_MANAGER_REQUEST, false, false,
"screen");
sandboxRoot.dispatchEvent(me);
// me.value now contains the screen property of the sandbox root.
sandboxScreen = Rectangle(me.value);
}
return sandboxScreen;
}
/**
* The system manager proxy has only one child that is a focus manager container.
* Iterate thru the children until we find it.
*/
mx_internal function findFocusManagerContainer(smp:SystemManagerProxy):IFocusManagerContainer
{
var children:IChildList = smp.rawChildren;
var numChildren:int = children.numChildren;
for (var i:int = 0; i < numChildren; i++)
{
var child:DisplayObject = children.getChildAt(i);
if (child is IFocusManagerContainer)
{
return IFocusManagerContainer(child);
}
}
return null;
}
/**
* @private
*
* Listen to messages this System Manager needs to service from its children.
*/
mx_internal function addChildBridgeListeners(bridge:IEventDispatcher):void
{
if (!systemManager.isTopLevel() && systemManager.topLevelSystemManager)
{
var mp:MarshallingSupport =
MarshallingSupport(systemManager.topLevelSystemManager.getImplementation("mx.managers::IMarshalSystemManager"));
mp.addChildBridgeListeners(bridge);
return;
}
bridge.addEventListener(SWFBridgeRequest.ADD_POP_UP_REQUEST, addPopupRequestHandler);
bridge.addEventListener(SWFBridgeRequest.REMOVE_POP_UP_REQUEST, removePopupRequestHandler);
bridge.addEventListener(SWFBridgeRequest.ADD_POP_UP_PLACE_HOLDER_REQUEST, addPlaceholderPopupRequestHandler);
bridge.addEventListener(SWFBridgeRequest.REMOVE_POP_UP_PLACE_HOLDER_REQUEST, removePlaceholderPopupRequestHandler);
bridge.addEventListener(SWFBridgeEvent.BRIDGE_WINDOW_ACTIVATE, activateFormSandboxEventHandler);
bridge.addEventListener(SWFBridgeEvent.BRIDGE_WINDOW_DEACTIVATE, deactivateFormSandboxEventHandler);
bridge.addEventListener(SWFBridgeEvent.BRIDGE_APPLICATION_ACTIVATE, activateApplicationSandboxEventHandler);
bridge.addEventListener(EventListenerRequest.ADD_EVENT_LISTENER_REQUEST, eventListenerRequestHandler, false, 0, true);
bridge.addEventListener(EventListenerRequest.REMOVE_EVENT_LISTENER_REQUEST, eventListenerRequestHandler, false, 0, true);
bridge.addEventListener(SWFBridgeRequest.CREATE_MODAL_WINDOW_REQUEST, modalWindowRequestHandler);
bridge.addEventListener(SWFBridgeRequest.SHOW_MODAL_WINDOW_REQUEST, modalWindowRequestHandler);
bridge.addEventListener(SWFBridgeRequest.HIDE_MODAL_WINDOW_REQUEST, modalWindowRequestHandler);
bridge.addEventListener(SWFBridgeRequest.GET_VISIBLE_RECT_REQUEST, getVisibleRectRequestHandler);
bridge.addEventListener(SWFBridgeRequest.HIDE_MOUSE_CURSOR_REQUEST, hideMouseCursorRequestHandler);
bridge.addEventListener(SWFBridgeRequest.SHOW_MOUSE_CURSOR_REQUEST, showMouseCursorRequestHandler);
bridge.addEventListener(SWFBridgeRequest.RESET_MOUSE_CURSOR_REQUEST, resetMouseCursorRequestHandler);
}
/**
* @private
*
* Remove all child listeners.
*/
mx_internal function removeChildBridgeListeners(bridge:IEventDispatcher):void
{
if (!systemManager.isTopLevel() && systemManager.topLevelSystemManager)
{
var mp:MarshallingSupport =
MarshallingSupport(systemManager.topLevelSystemManager.getImplementation("mx.managers::IMarshalSystemManager"));
mp.removeChildBridgeListeners(bridge);
return;
}
bridge.removeEventListener(SWFBridgeRequest.ADD_POP_UP_REQUEST, addPopupRequestHandler);
bridge.removeEventListener(SWFBridgeRequest.REMOVE_POP_UP_REQUEST, removePopupRequestHandler);
bridge.removeEventListener(SWFBridgeRequest.ADD_POP_UP_PLACE_HOLDER_REQUEST, addPlaceholderPopupRequestHandler);
bridge.removeEventListener(SWFBridgeRequest.REMOVE_POP_UP_PLACE_HOLDER_REQUEST, removePlaceholderPopupRequestHandler);
bridge.removeEventListener(SWFBridgeEvent.BRIDGE_WINDOW_ACTIVATE, activateFormSandboxEventHandler);
bridge.removeEventListener(SWFBridgeEvent.BRIDGE_WINDOW_DEACTIVATE, deactivateFormSandboxEventHandler);
bridge.removeEventListener(SWFBridgeEvent.BRIDGE_APPLICATION_ACTIVATE, activateApplicationSandboxEventHandler);
bridge.removeEventListener(EventListenerRequest.ADD_EVENT_LISTENER_REQUEST, eventListenerRequestHandler);
bridge.removeEventListener(EventListenerRequest.REMOVE_EVENT_LISTENER_REQUEST, eventListenerRequestHandler);
bridge.removeEventListener(SWFBridgeRequest.CREATE_MODAL_WINDOW_REQUEST, modalWindowRequestHandler);
bridge.removeEventListener(SWFBridgeRequest.SHOW_MODAL_WINDOW_REQUEST, modalWindowRequestHandler);
bridge.removeEventListener(SWFBridgeRequest.HIDE_MODAL_WINDOW_REQUEST, modalWindowRequestHandler);
bridge.removeEventListener(SWFBridgeRequest.GET_VISIBLE_RECT_REQUEST, getVisibleRectRequestHandler);
bridge.removeEventListener(SWFBridgeRequest.HIDE_MOUSE_CURSOR_REQUEST, hideMouseCursorRequestHandler);
bridge.removeEventListener(SWFBridgeRequest.SHOW_MOUSE_CURSOR_REQUEST, showMouseCursorRequestHandler);
bridge.removeEventListener(SWFBridgeRequest.RESET_MOUSE_CURSOR_REQUEST, resetMouseCursorRequestHandler);
}
/**
* @private
*
* Add listeners for events and requests we might receive from our parent if our
* parent is using a sandbox bridge to communicate with us.
*/
mx_internal function addParentBridgeListeners():void
{
if (!systemManager.isTopLevel() && systemManager.topLevelSystemManager)
{
var mp:MarshallingSupport =
MarshallingSupport(systemManager.topLevelSystemManager.getImplementation("mx.managers::IMarshalSystemManager"));
mp.addParentBridgeListeners();
return;
}
var bridge:IEventDispatcher = swfBridgeGroup.parentBridge;
bridge.addEventListener(SWFBridgeRequest.SET_ACTUAL_SIZE_REQUEST, setActualSizeRequestHandler);
bridge.addEventListener(SWFBridgeRequest.GET_SIZE_REQUEST, getSizeRequestHandler);
// need to listener to parent system manager to get broadcast messages.
bridge.addEventListener(SWFBridgeRequest.ACTIVATE_POP_UP_REQUEST,
activateRequestHandler);
bridge.addEventListener(SWFBridgeRequest.DEACTIVATE_POP_UP_REQUEST,
deactivateRequestHandler);
bridge.addEventListener(SWFBridgeRequest.IS_BRIDGE_CHILD_REQUEST, isBridgeChildHandler);
bridge.addEventListener(EventListenerRequest.ADD_EVENT_LISTENER_REQUEST, eventListenerRequestHandler);
bridge.addEventListener(EventListenerRequest.REMOVE_EVENT_LISTENER_REQUEST, eventListenerRequestHandler);
bridge.addEventListener(SWFBridgeRequest.CAN_ACTIVATE_POP_UP_REQUEST, canActivateHandler);
bridge.addEventListener(SWFBridgeEvent.BRIDGE_APPLICATION_UNLOADING, beforeUnloadHandler);
}
/**
* @private
*
* remove listeners for events and requests we might receive from our parent if
* our parent is using a sandbox bridge to communicate with us.
*/
mx_internal function removeParentBridgeListeners():void
{
if (!systemManager.isTopLevel() && systemManager.topLevelSystemManager)
{
var mp:MarshallingSupport =
MarshallingSupport(systemManager.topLevelSystemManager.getImplementation("mx.managers::IMarshalSystemManager"));
mp.removeParentBridgeListeners();
return;
}
var bridge:IEventDispatcher = swfBridgeGroup.parentBridge;
bridge.removeEventListener(SWFBridgeRequest.SET_ACTUAL_SIZE_REQUEST, setActualSizeRequestHandler);
bridge.removeEventListener(SWFBridgeRequest.GET_SIZE_REQUEST, getSizeRequestHandler);
// need to listener to parent system manager to get broadcast messages.
bridge.removeEventListener(SWFBridgeRequest.ACTIVATE_POP_UP_REQUEST,
activateRequestHandler);
bridge.removeEventListener(SWFBridgeRequest.DEACTIVATE_POP_UP_REQUEST,
deactivateRequestHandler);
bridge.removeEventListener(SWFBridgeRequest.IS_BRIDGE_CHILD_REQUEST, isBridgeChildHandler);
bridge.removeEventListener(EventListenerRequest.ADD_EVENT_LISTENER_REQUEST, eventListenerRequestHandler);
bridge.removeEventListener(EventListenerRequest.REMOVE_EVENT_LISTENER_REQUEST, eventListenerRequestHandler);
bridge.removeEventListener(SWFBridgeRequest.CAN_ACTIVATE_POP_UP_REQUEST, canActivateHandler);
bridge.removeEventListener(SWFBridgeEvent.BRIDGE_APPLICATION_UNLOADING, beforeUnloadHandler);
}
/**
* Add a bridge to talk to the child owned by <code>owner</code>.
*
* @param bridge The bridge used to talk to the parent.
* @param owner The display object that owns the bridge.
*/
public function addChildBridge(bridge:IEventDispatcher, owner:DisplayObject):void
{
// Is the owner in a pop up? If so let the focus manager manage the
// bridge instead of the system manager.
var fm:IFocusManager = null;
var o:DisplayObject = owner;
while (o)
{
if (o is IFocusManagerContainer)
{
fm = IFocusManagerContainer(o).focusManager;
break;
}
o = o.parent;
}
if (!fm)
return;
if (!swfBridgeGroup)
swfBridgeGroup = new SWFBridgeGroup(systemManager);
var event:DynamicEvent = new DynamicEvent("addChildBridge");
event.bridge = bridge;
event.owner = owner;
fm.dispatchEvent(event);
swfBridgeGroup.addChildBridge(bridge, ISWFBridgeProvider(owner));
if (!bridgeToFocusManager)
bridgeToFocusManager = new Dictionary();
bridgeToFocusManager[bridge] = fm;
addChildBridgeListeners(bridge);
// dispatch message that we are adding a bridge.
systemManager.dispatchEvent(new FlexChangeEvent(FlexChangeEvent.ADD_CHILD_BRIDGE, false, false, bridge));
}
/**
* Remove a child bridge.
*
* @param bridge The target bridge to remove.
*/
public function removeChildBridge(bridge:IEventDispatcher):void
{
// dispatch message that we are removing a bridge.
systemManager.dispatchEvent(new FlexChangeEvent(FlexChangeEvent.REMOVE_CHILD_BRIDGE, false, false, bridge));
var fm:IFocusManager = IFocusManager(bridgeToFocusManager[bridge]);
var event:DynamicEvent = new DynamicEvent("removeChildBridge");
event.bridge = bridge;
fm.dispatchEvent(event);
swfBridgeGroup.removeChildBridge(bridge);
delete bridgeToFocusManager[bridge];
removeChildBridgeListeners(bridge);
}
/**
* @inheritDoc
*/
public function useSWFBridge():Boolean
{
if (systemManager.isTopLevelRoot())
return false;
if (!systemManager.isTopLevel() && systemManager.topLevelSystemManager)
{
var mp:IMarshalSystemManager =
IMarshalSystemManager(systemManager.topLevelSystemManager.getImplementation("mx.managers::IMarshalSystemManager"));
return mp.useSWFBridge();
}
var sbRoot:DisplayObject = systemManager.getSandboxRoot();
// if we're toplevel and we aren't the sandbox root, we need a bridge
if (systemManager.isTopLevel() && sbRoot != systemManager)
return true;
// we also need a bridge even if we're the sandbox root
// but not a stage root, but our parent loader is a bootstrap
// that is not the stage root
if (sbRoot == systemManager)
{
try
{
if (parentAllowsChild && childAllowsParent)
{
try
{
if (!DisplayObject(systemManager).parent.dispatchEvent(new Event("mx.managers.SystemManager.isStageRoot", false, true)))
return true;
}
catch (e:Error)
{
}
}
else
return true;
}
catch (e1:Error)
{
// we seem to get here when a SWF is being unloaded, has been unparented, but still
// has a stage and root property, but loaderInfo is invalid.
return false;
}
}
return false;
}
public function getVisibleApplicationRectHandler(event:Request):void
{
var skipToSandboxRoot:Boolean = event.value.skipToSandboxRoot;
var sbRoot:DisplayObject = systemManager.getSandboxRoot();
var screen:Rectangle;
if (skipToSandboxRoot && systemManager != sbRoot)
{
var request:InterManagerRequest = new InterManagerRequest(InterManagerRequest.SYSTEM_MANAGER_REQUEST,
false, false,
"getVisibleApplicationRect");
if (!sbRoot.dispatchEvent(request))
{
event.value = Rectangle(request.value);
event.preventDefault();
}
}
else
{
event.value = getVisibleApplicationRect(event.value.bounds as Rectangle);
event.preventDefault();
}
}
/**
* @inheritDoc
*/
public function getVisibleApplicationRect(bounds:Rectangle = null):Rectangle
{
if (!bounds)
{
bounds = DisplayObject(systemManager).getBounds(DisplayObject(systemManager));
var s:Rectangle = systemManager.screen;
var pt:Point = new Point(Math.max(0, bounds.x), Math.max(0, bounds.y));
pt = DisplayObject(systemManager).localToGlobal(pt);
bounds.x = pt.x;
bounds.y = pt.y;
bounds.width = s.width;
bounds.height = s.height;
}
// send a message to parent for their visible rect.
if (useSWFBridge())
{
var bridge:IEventDispatcher = swfBridgeGroup.parentBridge;
var bridgeRequest:SWFBridgeRequest = new SWFBridgeRequest(SWFBridgeRequest.GET_VISIBLE_RECT_REQUEST,
false, false,
bridge,
bounds);
bridge.dispatchEvent(bridgeRequest);
bounds = Rectangle(bridgeRequest.data);
}
else if (!systemManager.isTopLevel())
{
var obj:DisplayObjectContainer = DisplayObject(systemManager).parent.parent;
if ("getVisibleApplicationRect" in obj)
{
var visibleRect:Rectangle = obj["getVisibleApplicationRect"](true);
bounds = bounds.intersection(visibleRect);
}
}
return bounds;
}
/**
* @inheritDoc
*/
public function deployMouseShieldsHandler(event:DynamicEvent):void
{
var me:InterManagerRequest = new InterManagerRequest(InterManagerRequest.DRAG_MANAGER_REQUEST, false, false,
"mouseShield", event.deploy);
systemManager.getSandboxRoot().dispatchEvent(me);
}
/**
* @private
*
* Notify parent that a new window has been activated.
*
* @param window window that was activated.
*/
public function dispatchActivatedWindowEvent(window:DisplayObject):void
{
var bridge:IEventDispatcher = swfBridgeGroup ? swfBridgeGroup.parentBridge : null;
if (bridge)
{
var sbRoot:DisplayObject = systemManager.getSandboxRoot();
var sendToSbRoot:Boolean = sbRoot != systemManager;
var bridgeEvent:SWFBridgeEvent = new SWFBridgeEvent(SWFBridgeEvent.BRIDGE_WINDOW_ACTIVATE,
false, false,
{ notifier: bridge,
window: sendToSbRoot ? window :
NameUtil.displayObjectToString(window)
});
if (sendToSbRoot)
sbRoot.dispatchEvent(bridgeEvent);
else
bridge.dispatchEvent(bridgeEvent);
}
}
/**
* @private
*
* Notify parent that a window has been deactivated.
*
* @param id window display object or id string that was activated. Ids are used if
* the message is going outside the security domain.
*/
private function dispatchDeactivatedWindowEvent(window:DisplayObject):void
{
var bridge:IEventDispatcher = swfBridgeGroup ? swfBridgeGroup.parentBridge : null;
if (bridge)
{
var sbRoot:DisplayObject = systemManager.getSandboxRoot();
var sendToSbRoot:Boolean = sbRoot != systemManager;
var bridgeEvent:SWFBridgeEvent = new SWFBridgeEvent(SWFBridgeEvent.BRIDGE_WINDOW_DEACTIVATE,
false,
false,
{ notifier: bridge,
window: sendToSbRoot ? window :
NameUtil.displayObjectToString(window)
});
if (sendToSbRoot)
sbRoot.dispatchEvent(bridgeEvent);
else
bridge.dispatchEvent(bridgeEvent);
}
}
/**
* @private
*
* Notify parent that an application has been activated.
*/
private function dispatchActivatedApplicationEvent():void
{
// click on this system manager or one of its sub system managers
// If in a sandbox tell the top-level system manager we are active.
var bridge:IEventDispatcher = swfBridgeGroup ? swfBridgeGroup.parentBridge : null;
if (bridge)
{
var bridgeEvent:SWFBridgeEvent = new SWFBridgeEvent(SWFBridgeEvent.BRIDGE_APPLICATION_ACTIVATE,
false, false);
bridge.dispatchEvent(bridgeEvent);
}
}
/**
* Adjust the forms array so it is sorted by last active.
* The last active form will be at the end of the forms array.
*
* This method assumes the form variable has been set before calling
* this function.
*/
private function updateLastActiveForm():void
{
var awm:ActiveWindowManager =
ActiveWindowManager(systemManager.getImplementation("mx.managers::IActiveWindowManager"));
// find "form" in the forms array and move that entry to
// the end of the array.
var n:int = awm.forms.length;
if (n < 2)
return; // zero or one forms, no need to update
var index:int = -1;
for (var i:int = 0; i < n; i++)
{
if (areFormsEqual(awm.form, awm.forms[i]))
{
index = i;
break;
}
}
if (index >= 0)
{
awm.forms.splice(index, 1);
awm.forms.push(awm.form);
}
}
/**
* @private
*
* Add placeholder information to this instance's list of placeholder data.
*/
private function addPlaceholderId(id:String, previousId:String, bridge:IEventDispatcher,
placeholder:Object):void
{
if (!bridge)
throw new Error(); // bridge is required.
if (!idToPlaceholder)
idToPlaceholder = [];
idToPlaceholder[id] = new PlaceholderData(previousId, bridge, placeholder);
}
private function removePlaceholderId(id:String):void
{
delete idToPlaceholder[id];
}
private var currentSandboxEvent:Event;
private function dispatchEventToOtherSystemManagers(event:Event):void
{
SystemManagerGlobals.dispatchingEventToOtherSystemManagers = true;
var arr:Array = SystemManagerGlobals.topLevelSystemManagers;
var n:int = arr.length;
for (var i:int = 0; i < n; i++)
{
if (arr[i] != systemManager)
{
arr[i].dispatchEvent(event);
}
}
SystemManagerGlobals.dispatchingEventToOtherSystemManagers = false;
}
/**
* @inheritDoc
*/
public function dispatchEventFromSWFBridges(event:Event, skip:IEventDispatcher = null,
trackClones:Boolean = false, toOtherSystemManagers:Boolean = false):void
{
if (toOtherSystemManagers)
{
dispatchEventToOtherSystemManagers(event);
}
if (!swfBridgeGroup)
return;
var clone:Event;
// trace(">>dispatchEventFromSWFBridges", this, event.type);
clone = event.clone();
if (trackClones)
currentSandboxEvent = clone;
var parentBridge:IEventDispatcher = swfBridgeGroup.parentBridge;
if (parentBridge && parentBridge != skip)
{
// Ensure the requestor property has the correct bridge.
if (clone is SWFBridgeRequest)
SWFBridgeRequest(clone).requestor = parentBridge;
parentBridge.dispatchEvent(clone);
}
var children:Array = swfBridgeGroup.getChildBridges();
for (var i:int = 0; i < children.length; i++)
{
if (children[i] != skip)
{
// trace("send to child", i, event.type);
clone = event.clone();
if (trackClones)
currentSandboxEvent = clone;
// Ensure the requestor property has the correct bridge.
if (clone is SWFBridgeRequest)
SWFBridgeRequest(clone).requestor = IEventDispatcher(children[i]);
IEventDispatcher(children[i]).dispatchEvent(clone);
}
}
currentSandboxEvent = null;
// trace("<<dispatchEventFromSWFBridges", this, event.type);
}
/**
* request the parent to add an event listener.
*/
private function addEventListenerToSandboxes(type:String, listener:Function, useCapture:Boolean = false,
priority:int=0, useWeakReference:Boolean=false, skip:IEventDispatcher = null):void
{
if (!swfBridgeGroup)
return;
// trace(">>addEventListenerToSandboxes", this, type);
var request:EventListenerRequest = new EventListenerRequest(EventListenerRequest.ADD_EVENT_LISTENER_REQUEST, false, false,
type, null,
useCapture,
priority,
useWeakReference);
var parentBridge:IEventDispatcher = swfBridgeGroup.parentBridge;
if (parentBridge && parentBridge != skip)
parentBridge.addEventListener(type, listener, false, priority, useWeakReference);
var children:Array = swfBridgeGroup.getChildBridges();
for (var i:int; i < children.length; i++)
{
var childBridge:IEventDispatcher = IEventDispatcher(children[i]);
if (childBridge != skip)
childBridge.addEventListener(type, listener, false, priority, useWeakReference);
}
dispatchEventFromSWFBridges(request, skip);
// trace("<<addEventListenerToSandboxes", this, type);
}
/**
* request the parent to remove an event listener.
*/
private function removeEventListenerFromSandboxes(type:String, listener:Function,
useCapture:Boolean = false,
skip:IEventDispatcher = null):void
{
if (!swfBridgeGroup)
return;
// trace(">>removeEventListenerToSandboxes", this, type);
var request:EventListenerRequest = new EventListenerRequest(EventListenerRequest.REMOVE_EVENT_LISTENER_REQUEST, false, false,
type, null,
useCapture);
var parentBridge:IEventDispatcher = swfBridgeGroup.parentBridge;
if (parentBridge && parentBridge != skip)
parentBridge.removeEventListener(type, listener, useCapture);
var children:Array = swfBridgeGroup.getChildBridges();
for (var i:int; i < children.length; i++)
{
if (children[i] != skip)
IEventDispatcher(children[i]).removeEventListener(type, listener, useCapture);
}
dispatchEventFromSWFBridges(request, skip);
// trace("<<removeEventListenerToSandboxes", this, type);
}
/**
* request the parent to add an event listener.
*/
private function addEventListenerToOtherSystemManagers(type:String, listener:Function, useCapture:Boolean = false,
priority:int=0, useWeakReference:Boolean=false):void
{
var arr:Array = SystemManagerGlobals.topLevelSystemManagers;
if (arr.length < 2)
return;
SystemManagerGlobals.changingListenersInOtherSystemManagers = true;
var n:int = arr.length;
for (var i:int = 0; i < n; i++)
{
if (arr[i] != systemManager)
{
arr[i].addEventListener(type, listener, useCapture, priority, useWeakReference);
}
}
SystemManagerGlobals.changingListenersInOtherSystemManagers = false;
}
/**
* request the parent to remove an event listener.
*/
private function removeEventListenerFromOtherSystemManagers(type:String, listener:Function,
useCapture:Boolean = false):void
{
var arr:Array = SystemManagerGlobals.topLevelSystemManagers;
if (arr.length < 2)
return;
SystemManagerGlobals.changingListenersInOtherSystemManagers = true;
var n:int = arr.length;
for (var i:int = 0; i < n; i++)
{
if (arr[i] != systemManager)
{
arr[i].removeEventListener(type, listener, useCapture);
}
}
SystemManagerGlobals.changingListenersInOtherSystemManagers = false;
}
/**
* @private
*
* @return true if the message should be processed, false if
* no other action is required.
*/
private function preProcessModalWindowRequest(request:SWFBridgeRequest,
sbRoot:DisplayObject):Boolean
{
// should we process this message?
if (request.data.skip)
{
// skipping this sandbox,
// but don't skip the next one.
request.data.skip = false;
if (useSWFBridge())
{
var bridge:IEventDispatcher = swfBridgeGroup.parentBridge;
request.requestor = bridge;
bridge.dispatchEvent(request);
}
return false;
}
// if we are not the sandbox root, dispatch the message to the sandbox root.
if (systemManager != sbRoot)
{
// convert exclude component into a rectangle and forward to parent bridge.
if (request.type == SWFBridgeRequest.CREATE_MODAL_WINDOW_REQUEST ||
request.type == SWFBridgeRequest.SHOW_MODAL_WINDOW_REQUEST)
{
var exclude:ISWFLoader = swfBridgeGroup.getChildBridgeProvider(request.requestor)
as ISWFLoader;
// find the rectangle of the area to exclude
if (exclude)
{
var excludeRect:Rectangle = ISWFLoader(exclude).getVisibleApplicationRect();
request.data.excludeRect = excludeRect;
// If the area to exclude is not contain by our document then it is in a
// pop up. From this point for set the useExclude flag to false to
// tell our parent not to exclude use from their modal window, only
// the excludeRect we have just calculated.
if (!DisplayObjectContainer(systemManager.document).contains(DisplayObject(exclude)))
request.data.useExclude = false; // keep the existing excludeRect
}
}
bridge = swfBridgeGroup.parentBridge;
request.requestor = bridge;
// The HIDE request does not need to be processed by each
// application, so dispatch it directly to the sandbox root.
if (request.type == SWFBridgeRequest.HIDE_MODAL_WINDOW_REQUEST)
sbRoot.dispatchEvent(request);
else
bridge.dispatchEvent(request);
return false;
}
// skip aftering sending the message over a bridge.
request.data.skip = false;
return true;
}
private function otherSystemManagerMouseListener(event:SandboxMouseEvent):void
{
if (SystemManagerGlobals.dispatchingEventToOtherSystemManagers)
return;
dispatchEventFromSWFBridges(event);
// ask the sandbox root if it was the original dispatcher of this event
// if it was then don't dispatch to ourselves because we could have
// got this event by listening to sandboxRoot ourselves.
var me:InterManagerRequest = new InterManagerRequest(InterManagerRequest.SYSTEM_MANAGER_REQUEST);
me.name = "sameSandbox";
me.value = event;
systemManager.getSandboxRoot().dispatchEvent(me);
if (!me.value)
systemManager.dispatchEvent(event);
}
private function sandboxMouseListener(event:Event):void
{
// trace("sandboxMouseListener", this);
if (event is SandboxMouseEvent)
return;
var marshaledEvent:Event = SandboxMouseEvent.marshal(event);
dispatchEventFromSWFBridges(marshaledEvent, event.target as IEventDispatcher);
// ask the sandbox root if it was the original dispatcher of this event
// if it was then don't dispatch to ourselves because we could have
// got this event by listening to sandboxRoot ourselves.
var me:InterManagerRequest = new InterManagerRequest(InterManagerRequest.SYSTEM_MANAGER_REQUEST);
me.name = "sameSandbox";
me.value = event;
systemManager.getSandboxRoot().dispatchEvent(me);
if (!me.value)
systemManager.dispatchEvent(marshaledEvent);
}
private function eventListenerRequestHandler(event:Event):void
{
if (event is EventListenerRequest)
return;
var actualType:String;
var request:EventListenerRequest = EventListenerRequest.marshal(event);
if (event.type == EventListenerRequest.ADD_EVENT_LISTENER_REQUEST)
{
if (!eventProxy)
{
eventProxy = new EventProxy(systemManager);
}
actualType = EventUtil.sandboxMouseEventMap[request.eventType];
if (actualType)
{
if (systemManager.isTopLevelRoot())
{
systemManager.stage.addEventListener(MouseEvent.MOUSE_MOVE, resetMouseCursorTracking, true, EventPriority.CURSOR_MANAGEMENT + 1, true);
}
else
{
Object(systemManager).$addEventListener(MouseEvent.MOUSE_MOVE, resetMouseCursorTracking, true, EventPriority.CURSOR_MANAGEMENT + 1, true);
}
// add listeners in other sandboxes in capture mode so we don't miss anything
addEventListenerToSandboxes(request.eventType, sandboxMouseListener,
true, request.priority, request.useWeakReference, event.target as IEventDispatcher);
addEventListenerToOtherSystemManagers(request.eventType, otherSystemManagerMouseListener,
true, request.priority, request.useWeakReference);
if (systemManager.getSandboxRoot() == systemManager)
{
if (systemManager.isTopLevelRoot() &&
(actualType == MouseEvent.MOUSE_UP || actualType == MouseEvent.MOUSE_MOVE))
{
if (systemManager.stage)
systemManager.stage.addEventListener(actualType, eventProxy.marshalListener,
false, request.priority, request.useWeakReference);
}
Object(systemManager).$addEventListener(actualType, eventProxy.marshalListener,
true, request.priority, request.useWeakReference);
}
}
}
else if (event.type == EventListenerRequest.REMOVE_EVENT_LISTENER_REQUEST)
{
actualType = EventUtil.sandboxMouseEventMap[request.eventType];
if (actualType)
{
removeEventListenerFromOtherSystemManagers(request.eventType, otherSystemManagerMouseListener, true);
removeEventListenerFromSandboxes(request.eventType, sandboxMouseListener,
true, event.target as IEventDispatcher);
if (systemManager.getSandboxRoot() == systemManager)
{
if (systemManager.isTopLevelRoot() &&
(actualType == MouseEvent.MOUSE_UP || actualType == MouseEvent.MOUSE_MOVE))
{
if (systemManager.stage)
systemManager.stage.removeEventListener(actualType, eventProxy.marshalListener);
}
// Remove both listeners in case the system manager was added
// or removed from the stage after the listener was added.
Object(systemManager).$removeEventListener(actualType, eventProxy.marshalListener, true);
}
}
}
}
private function Stage_resizeHandler(event:Event = null):void
{
var sandboxScreen:Rectangle = getSandboxScreen();
if (!Object(systemManager)._screen)
Object(systemManager)._screen = new Rectangle();
Object(systemManager)._screen.width = sandboxScreen.width;
Object(systemManager)._screen.height = sandboxScreen.height;
}
/**
* Override this function if you want to perform any logic
* when the application has finished initializing itself.
*/
private function invalidateParentSizeAndDisplayListHandler(event:Event):void
{
if (systemManager.isTopLevel() && useSWFBridge())
dispatchInvalidateRequest();
}
/**
* @private
*
* Handle request to unload
* Forward event, and do some cleanup
*/
private function unloadHandler(event:Event):void
{
systemManager.dispatchEvent(event);
}
private function addEventListenerHandler(request:DynamicEvent):void
{
if (!addEventListener(request.eventType, request.listener, request.useCapture,
request.priority, request.useWeakReference))
request.preventDefault();
}
private function removeEventListenerHandler(request:DynamicEvent):void
{
if (!removeEventListener(request.eventType, request.listener, request.useCapture))
request.preventDefault();
}
}
}