1//////////////////////////////////////////////////////////////////////////////// 2// 3// ADOBE SYSTEMS INCORPORATED 4// Copyright 2007 Adobe Systems Incorporated 5// All Rights Reserved. 6// 7// NOTICE: Adobe permits you to use, modify, and distribute this file 8// in accordance with the terms of the license agreement accompanying it. 9// 10//////////////////////////////////////////////////////////////////////////////// 11 12package mx.managers 13{ 14 15import flash.display.DisplayObject; 16import flash.display.DisplayObjectContainer; 17import flash.display.Graphics; 18import flash.display.InteractiveObject; 19import flash.display.Loader; 20import flash.display.LoaderInfo; 21import flash.display.MovieClip; 22import flash.display.Sprite; 23import flash.display.Stage; 24import flash.display.StageAlign; 25import flash.display.StageScaleMode; 26import flash.events.Event; 27import flash.events.IEventDispatcher; 28import flash.events.MouseEvent; 29import flash.geom.Point; 30import flash.geom.Rectangle; 31import flash.net.getClassByAlias; 32import flash.net.registerClassAlias; 33import flash.system.ApplicationDomain; 34import flash.text.Font; 35import flash.text.TextFormat; 36import flash.ui.ContextMenu; 37import flash.utils.ByteArray; 38import flash.utils.Dictionary; 39 40import mx.core.EventPriority; 41import mx.core.FlexSprite; 42import mx.core.ISWFBridgeGroup; 43import mx.core.ISWFBridgeProvider; 44import mx.core.ISWFLoader; 45import mx.core.IChildList; 46import mx.core.IFlexDisplayObject; 47import mx.core.IFlexModule; 48import mx.core.IFlexModuleFactory; 49import mx.core.IUIComponent; 50import mx.core.Singleton; 51import mx.core.SWFBridgeGroup; 52import mx.core.Window; 53import mx.core.mx_internal; 54import mx.events.FlexEvent; 55import mx.events.FlexChangeEvent; 56import mx.events.EventListenerRequest; 57import mx.events.InvalidateRequestData; 58import mx.events.InterManagerRequest; 59import mx.events.SandboxMouseEvent; 60import mx.events.SWFBridgeRequest; 61import mx.events.SWFBridgeEvent; 62import mx.managers.systemClasses.RemotePopUp; 63import mx.managers.systemClasses.EventProxy; 64import mx.managers.systemClasses.PlaceholderData; 65import mx.styles.ISimpleStyleClient; 66import mx.styles.IStyleClient; 67import mx.utils.EventUtil; 68import mx.utils.NameUtil; 69import mx.utils.ObjectUtil; 70import mx.utils.SecurityUtil; 71 72 73use namespace mx_internal; 74 75/** 76 * The WindowedSystemManager class manages any non-Application windows in a 77 * Flex-based AIR application. This includes all windows that are instances of 78 * the Window component or a Window subclass, but not a WindowedApplication 79 * window. For those windows, the WindowedSystemManager serves the same role 80 * that a SystemManager serves for a WindowedApplication instance or an 81 * Application instance in a browser-based Flex application. 82 * 83 * <p>As this comparison suggests, the WindowedSystemManager class serves 84 * many roles. For instance, it is the root display object of a Window, and 85 * manages tooltips, cursors, popups, and other content for the Window.</p> 86 * 87 * @see mx.managers.SystemManager 88 * 89 * @playerversion AIR 1.1 90 */ 91public class WindowedSystemManager extends MovieClip implements ISystemManager, ISWFBridgeProvider 92{ 93 94 public function WindowedSystemManager(rootObj:IUIComponent) 95 { 96 super(); 97 _topLevelSystemManager = this; 98 topLevelWindow = rootObj; 99 SystemManagerGlobals.topLevelSystemManagers.push(this); 100 //docFrameHandler(null); 101 addEventListener(Event.ADDED, docFrameHandler); 102 } 103 104 /** 105 * @private 106 * List of top level windows. 107 */ 108 private var forms:Array = []; 109 110 /** 111 * @private 112 * The current top level window. 113 */ 114 private var form:Object; 115 116 private var topLevel:Boolean = true; 117 118 private var initialized:Boolean = false; 119 120 /** 121 * @private 122 * Number of frames since the last mouse or key activity. 123 */ 124 mx_internal var idleCounter:int = 0; 125 126 /** 127 * @private 128 * The top level window. 129 */ 130 mx_internal var topLevelWindow:IUIComponent; 131 132 /** 133 * @private 134 * pointer to Window, for cleanup 135 */ 136 private var myWindow:Window; 137 138 /** 139 * @private 140 */ 141 private var originalSystemManager:SystemManager; 142 143 /** 144 * @private 145 */ 146 private var _topLevelSystemManager:ISystemManager; 147 148 /** 149 * @private 150 * Whether we are the stage root or not. 151 * We are only the stage root if we were the root 152 * of the first SWF that got loaded by the player. 153 * Otherwise we could be top level but not stage root 154 * if we are loaded by some other non-Flex shell 155 * or are sandboxed. 156 */ 157 private var isStageRoot:Boolean = true; 158 159 /** 160 * @private 161 * Whether we are the first SWF loaded into a bootstrap 162 * and therefore, the topLevelRoot 163 */ 164 private var isBootstrapRoot:Boolean = false; 165 166 /** 167 * Depth of this object in the containment hierarchy. 168 * This number is used by the measurement and layout code. 169 */ 170 mx_internal var nestLevel:int = 0; 171 172 /** 173 * @private 174 * The mouseCatcher is the 0th child of the SystemManager, 175 * behind the application, which is child 1. 176 * It is the same size as the stage and is filled with 177 * transparent pixels; i.e., they've been drawn, but with alpha 0. 178 * 179 * Its purpose is to make every part of the stage 180 * able to detect the mouse. 181 * For example, a Button puts a mouseUp handler on the SystemManager 182 * in order to capture mouseUp events that occur outside the Button. 183 * But if the children of the SystemManager don't have "drawn-on" 184 * pixels everywhere, the player won't dispatch the mouseUp. 185 * We can't simply fill the SystemManager itself with 186 * transparent pixels, because the player's pixel detection 187 * logic doesn't look at pixels drawn into the root DisplayObject. 188 * 189 * Here is an example of what would happen without the mouseCatcher: 190 * Run a fixed-size Application (e.g. width="600" height="600") 191 * in the standalone player. Make the player window larger 192 * to reveal part of the stage. Press a Button, drag off it 193 * into the stage area, and release the mouse button. 194 * Without the mouseCatcher, the Button wouldn't return to its "up" state. 195 */ 196 private var mouseCatcher:Sprite; 197 198 //---------------------------------- 199 // applicationIndex 200 //---------------------------------- 201 202 /** 203 * @private 204 * Storage for the applicationIndex property. 205 */ 206 private var _applicationIndex:int = 1; 207 208 /** 209 * @private 210 * The index of the main mx.core.Application window, which is 211 * effectively its z-order. 212 */ 213 mx_internal function get applicationIndex():int 214 { 215 return _applicationIndex; 216 } 217 218 /** 219 * @private 220 */ 221 mx_internal function set applicationIndex(value:int):void 222 { 223 _applicationIndex = value; 224 } 225 226 //---------------------------------- 227 // bridgeToFocusManager 228 //---------------------------------- 229 230 /** 231 * @private 232 * Map a bridge to a FocusManager. 233 * This dictionary contains both the focus managers for this document as 234 * well as focus managers that are in documents contained inside of pop 235 * ups, if the system manager in that pop up requires a bridge to 236 * communicate with this system manager. 237 * 238 * The returned object is an object of type IFocusManager. 239 */ 240 private var _bridgeToFocusManager:Dictionary; 241 242 /** 243 * @private 244 * 245 * System Managers in child application domains use their parent's 246 * bridgeToFocusManager's Dictionary. The swfBridgeGroup property 247 * is maintained in the same way. 248 */ 249 mx_internal function get bridgeToFocusManager():Dictionary 250 { 251 if (topLevel) 252 return _bridgeToFocusManager; 253 else if (topLevelSystemManager) 254 return SystemManager(topLevelSystemManager).bridgeToFocusManager; 255 256 return null; 257 } 258 259 mx_internal function set bridgeToFocusManager(bridgeToFMDictionary:Dictionary):void 260 { 261 if (topLevel) 262 _bridgeToFocusManager = bridgeToFMDictionary; 263 else if (topLevelSystemManager) 264 SystemManager(topLevelSystemManager).bridgeToFocusManager = bridgeToFMDictionary; 265 266 } 267 268 //----------------------------------- 269 // ISystemManager implementations 270 //----------------------------------- 271 272 //---------------------------------- 273 // cursorChildren 274 //---------------------------------- 275 276 /** 277 * @private 278 * Storage for the cursorChildren property. 279 */ 280 private var _cursorChildren:WindowedSystemChildrenList; 281 282 /** 283 * @inheritDoc 284 */ 285 public function get cursorChildren():IChildList 286 { 287 if (!topLevel) 288 return _topLevelSystemManager.cursorChildren; 289 290 if (!_cursorChildren) 291 { 292 _cursorChildren = new WindowedSystemChildrenList(this, 293 new QName(mx_internal, "toolTipIndex"), 294 new QName(mx_internal, "cursorIndex")); 295 } 296 297 return _cursorChildren; 298 } 299 300 //---------------------------------- 301 // cursorIndex 302 //---------------------------------- 303 304 /** 305 * @private 306 * Storage for the toolTipIndex property. 307 */ 308 private var _cursorIndex:int = 0; 309 310 /** 311 * @private 312 * The index of the highest child that is a cursor. 313 */ 314 mx_internal function get cursorIndex():int 315 { 316 return _cursorIndex; 317 } 318 319 /** 320 * @private 321 */ 322 mx_internal function set cursorIndex(value:int):void 323 { 324 var delta:int = value - _cursorIndex; 325 _cursorIndex = value; 326 } 327 328 //---------------------------------- 329 // document 330 //---------------------------------- 331 332 /** 333 * @private 334 * Storage for the document property. 335 */ 336 private var _document:Object; 337 338 /** 339 * @inheritDoc 340 */ 341 public function get document():Object 342 { 343 return _document; 344 } 345 346 /** 347 * @private 348 */ 349 public function set document(value:Object):void 350 { 351 _document = value; 352 } 353 354 //---------------------------------- 355 // embeddedFontList 356 //---------------------------------- 357 358 /** 359 * @private 360 * Storage for the fontList property. 361 */ 362 private var _fontList:Object = null; 363 364 /** 365 * A table of embedded fonts in this application. The 366 * object is a table indexed by the font name. 367 */ 368 public function get embeddedFontList():Object 369 { 370 if (_fontList == null) 371 { 372 _fontList = {}; 373 374 var o:Object = info()["fonts"]; 375 376 var p:String; 377 378 for (p in o) 379 { 380 _fontList[p] = o[p]; 381 } 382 383 // FIXME: font rules across SWF boundaries have not been finalized! 384 385 // Top level systemManager may not be defined if SWF is loaded 386 // as a background image in download progress bar. 387 if (!topLevel && _topLevelSystemManager) 388 { 389 var fl:Object = _topLevelSystemManager.embeddedFontList; 390 for (p in fl) 391 { 392 _fontList[p] = fl[p]; 393 } 394 } 395 } 396 397 return _fontList; 398 } 399 400 //---------------------------------- 401 // focusPane 402 //---------------------------------- 403 404 /** 405 * @private 406 */ 407 private var _focusPane:Sprite; 408 409 /** 410 * @copy mx.core.UIComponent#focusPane 411 */ 412 public function get focusPane():Sprite 413 { 414 return _focusPane; 415 } 416 417 /** 418 * @private 419 */ 420 public function set focusPane(value:Sprite):void 421 { 422 if (value) 423 { 424 addChild(value); 425 426 value.x = 0; 427 value.y = 0; 428 value.scrollRect = null; 429 430 _focusPane = value; 431 } 432 else 433 { 434 removeChild(_focusPane); 435 436 _focusPane = null; 437 } 438 } 439 440 //---------------------------------- 441 // $numChildren 442 //---------------------------------- 443 444 /** 445 * @private 446 * This property allows access to the Player's native implementation 447 * of the numChildren property, which can be useful since components 448 * can override numChildren and thereby hide the native implementation. 449 * Note that this "base property" is final and cannot be overridden, 450 * so you can count on it to reflect what is happening at the player level. 451 */ 452 mx_internal final function get $numChildren():int 453 { 454 return super.numChildren; 455 } 456 457 //---------------------------------- 458 // numModalWindows 459 //---------------------------------- 460 461 /** 462 * @private 463 * Storage for the numModalWindows property. 464 */ 465 private var _numModalWindows:int = 0; 466 467 /** 468 * The number of modal windows. Modal windows don't allow 469 * clicking in another windows which would normally 470 * activate the FocusManager in that window. The PopUpManager 471 * modifies this count as it creates and destroys modal windows. 472 */ 473 public function get numModalWindows():int 474 { 475 return _numModalWindows; 476 } 477 478 /** 479 * @private 480 */ 481 public function set numModalWindows(value:int):void 482 { 483 _numModalWindows = value; 484 } 485 486 //---------------------------------- 487 // preloadedRSLs 488 //---------------------------------- 489 490 /** 491 * @private 492 * 493 * This is a stub to satisfy the IFlexModuleFactory interface. 494 * 495 * The RSLs loaded by this system manager before the application 496 * starts. RSLs loaded by the application are not included in this list. 497 * 498 * Information about preloadedRSLs is stored in a Dictionary. The key is 499 * the RSL's LoaderInfo. The value is the url the RSL was loaded from. 500 */ 501 public function get preloadedRSLs():Dictionary 502 { 503 // Overriden by compiler generate code. 504 return null; 505 } 506 507 //---------------------------------- 508 // popUpChildren 509 //---------------------------------- 510 511 /** 512 * @private 513 * Storage for the popUpChildren property. 514 */ 515 private var _popUpChildren:WindowedSystemChildrenList; 516 517 /** 518 * @inheritDoc 519 */ 520 public function get popUpChildren():IChildList 521 { 522 if (!topLevel) 523 return _topLevelSystemManager.popUpChildren; 524 525 if (!_popUpChildren) 526 { 527 _popUpChildren = new WindowedSystemChildrenList(this, 528 new QName(mx_internal, "noTopMostIndex"), 529 new QName(mx_internal, "topMostIndex")); 530 } 531 532 return _popUpChildren; 533 } 534 535 //---------------------------------- 536 // noTopMostIndex 537 //---------------------------------- 538 539 /** 540 * @private 541 * Storage for the noTopMostIndex property. 542 */ 543 private var _noTopMostIndex:int = 0; 544 545 /** 546 * @private 547 * The index of the highest child that isn't a topmost/popup window 548 */ 549 mx_internal function get noTopMostIndex():int 550 { 551 return _noTopMostIndex; 552 } 553 554 /** 555 * @private 556 */ 557 mx_internal function set noTopMostIndex(value:int):void 558 { 559 var delta:int = value - _noTopMostIndex; 560 _noTopMostIndex = value; 561 topMostIndex += delta; 562 } 563 //---------------------------------- 564 // rawChildren 565 //---------------------------------- 566 567 /** 568 * @private 569 * Storage for the rawChildren property. 570 */ 571 private var _rawChildren:WindowedSystemRawChildrenList; 572 573 /** 574 * @inheritDoc 575 */ 576 public function get rawChildren():IChildList 577 { 578 if (!topLevel) 579 return _topLevelSystemManager.rawChildren; 580 581 if (!_rawChildren) 582 _rawChildren = new WindowedSystemRawChildrenList(this); 583 584 return _rawChildren; 585 } 586 587 //-------------------------------------------------------------------------- 588 // sandbox bridge group 589 //-------------------------------------------------------------------------- 590 591 /** 592 * @private 593 * 594 * Represents the related parent and child sandboxs this SystemManager may 595 * communicate with. 596 */ 597 private var _swfBridgeGroup:ISWFBridgeGroup; 598 599 600 public function get swfBridgeGroup():ISWFBridgeGroup 601 { 602 if (topLevel) 603 return _swfBridgeGroup; 604 else if (topLevelSystemManager) 605 return topLevelSystemManager.swfBridgeGroup; 606 607 return null; 608 } 609 610 public function set swfBridgeGroup(bridgeGroup:ISWFBridgeGroup):void 611 { 612 if (topLevel) 613 _swfBridgeGroup = bridgeGroup; 614 else if (topLevelSystemManager) 615 SystemManager(topLevelSystemManager).swfBridgeGroup = bridgeGroup; 616 617 } 618 619 //-------------------------------------------------------------------------- 620 // screen 621 //-------------------------------------------------------------------------- 622 623 /** 624 * @private 625 * Storage for the screen property. 626 */ 627 private var _screen:Rectangle; 628 629 /** 630 * @inheritDoc 631 */ 632 public function get screen():Rectangle 633 { 634 if (!_screen) 635 _screen = new Rectangle(); 636 _screen.x = 0; 637 _screen.y = 0; 638 _screen.width = stage.stageWidth; //Capabilities.screenResolutionX; 639 _screen.height = stage.stageHeight; //Capabilities.screenResolutionY; 640 641 642 return _screen; 643 } 644 645 //---------------------------------- 646 // toolTipChildren 647 //---------------------------------- 648 649 /** 650 * @private 651 * Storage for the toolTipChildren property. 652 */ 653 private var _toolTipChildren:WindowedSystemChildrenList; 654 655 /** 656 * @inheritDoc 657 */ 658 public function get toolTipChildren():IChildList 659 { 660 if (!topLevel) 661 return _topLevelSystemManager.toolTipChildren; 662 663 if (!_toolTipChildren) 664 { 665 _toolTipChildren = new WindowedSystemChildrenList(this, 666 new QName(mx_internal, "topMostIndex"), 667 new QName(mx_internal, "toolTipIndex")); 668 } 669 670 return _toolTipChildren; 671 } 672 //---------------------------------- 673 // toolTipIndex 674 //---------------------------------- 675 676 /** 677 * @private 678 * Storage for the toolTipIndex property. 679 */ 680 private var _toolTipIndex:int = 0; 681 682 /** 683 * @private 684 * The index of the highest child that is a tooltip 685 */ 686 mx_internal function get toolTipIndex():int 687 { 688 return _toolTipIndex; 689 } 690 691 /** 692 * @private 693 */ 694 mx_internal function set toolTipIndex(value:int):void 695 { 696 var delta:int = value - _toolTipIndex; 697 _toolTipIndex = value; 698 cursorIndex += delta; 699 } 700 701 //---------------------------------- 702 // topLevelSystemManager 703 //---------------------------------- 704 705 /** 706 * Returns the SystemManager responsible for the application window. This will be 707 * the same SystemManager unless this application has been loaded into another 708 * application. 709 */ 710 public function get topLevelSystemManager():ISystemManager 711 { 712 if (topLevel) 713 return this; 714 715 return _topLevelSystemManager; 716 } 717 718 //---------------------------------- 719 // topMostIndex 720 //---------------------------------- 721 722 /** 723 * @private 724 * Storage for the topMostIndex property. 725 */ 726 private var _topMostIndex:int = 0; 727 728 /** 729 * @private 730 * The index of the highest child that is a topmost/popup window 731 */ 732 mx_internal function get topMostIndex():int 733 { 734 return _topMostIndex; 735 } 736 737 mx_internal function set topMostIndex(value:int):void 738 { 739 var delta:int = value - _topMostIndex; 740 _topMostIndex = value; 741 toolTipIndex += delta; 742 } 743 744 //---------------------------------- 745 // width 746 //---------------------------------- 747 748 /** 749 * @private 750 */ 751 private var _width:Number; 752 753 /** 754 * The width of this object. For the SystemManager 755 * this should always be the width of the stage unless the application was loaded 756 * into another application. If the application was not loaded 757 * into another application, setting this value will have no effect. 758 */ 759 override public function get width():Number 760 { 761 return _width; 762 } 763 764 //---------------------------------- 765 // window 766 //---------------------------------- 767 /** 768 * @private 769 */ 770 private var _window:Window = null; 771 772 mx_internal function get window():Window 773 { 774 return _window; 775 } 776 777 mx_internal function set window(value:Window):void 778 { 779 _window = value; 780 } 781 782 783 //---------------------------------- 784 // height 785 //---------------------------------- 786 787 /** 788 * @private 789 */ 790 private var _height:Number; 791 792 /** 793 * The height of this object. For the SystemManager 794 * this should always be the width of the stage unless the application was loaded 795 * into another application. If the application was not loaded 796 * into another application, setting this value has no effect. 797 */ 798 override public function get height():Number 799 { 800 return _height; 801 } 802 803 //-------------------------------------------------------------------------- 804 // 805 // Properties: ISWFBridgeProvider 806 // 807 //-------------------------------------------------------------------------- 808 809 /** 810 * @inheritdoc 811 */ 812 public function get swfBridge():IEventDispatcher 813 { 814 if (swfBridgeGroup) 815 return swfBridgeGroup.parentBridge; 816 817 return null; 818 } 819 820 /** 821 * @inheritdoc 822 */ 823 public function get childAllowsParent():Boolean 824 { 825 try 826 { 827 return loaderInfo.childAllowsParent; 828 } 829 catch (error:Error) 830 { 831 //Error #2099: The loading object is not sufficiently loaded to provide this information. 832 } 833 834 return false; // assume the worst 835 } 836 837 /** 838 * @inheritdoc 839 */ 840 public function get parentAllowsChild():Boolean 841 { 842 try 843 { 844 return loaderInfo.parentAllowsChild; 845 } 846 catch (error:Error) 847 { 848 //Error #2099: The loading object is not sufficiently loaded to provide this information. 849 } 850 851 return false; // assume the worst 852 } 853 854 //-------------------------------------------------------------------------- 855 // 856 // Methods: Focus 857 // 858 //-------------------------------------------------------------------------- 859 860 /** 861 * @inheritDoc 862 */ 863 public function activate(f:IFocusManagerContainer):void 864 { 865 activateForm(f); 866 } 867 868 /** 869 * @private 870 * 871 * New version of activate that does not require a 872 * IFocusManagerContainer. 873 */ 874 private function activateForm(f:Object):void 875 { 876 877 // trace("SM: activate " + f + " " + forms.length); 878 if (form) 879 { 880 if (form != f && forms.length > 1) 881 { 882 // Switch the active form. 883 if (isRemotePopUp(form)) 884 { 885 if (!areRemotePopUpsEqual(form, f)) 886 deactivateRemotePopUp(form); 887 } 888 else 889 { 890 var z:IFocusManagerContainer = IFocusManagerContainer(form); 891 // trace("OLW " + f + " deactivating old form " + z); 892 z.focusManager.deactivate(); 893 } 894 } 895 } 896 897 form = f; 898 899 // trace("f = " + f); 900 if (isRemotePopUp(f)) 901 { 902 activateRemotePopUp(f); 903 } 904 else if (f.focusManager) 905 { 906 // trace("has focus manager"); 907 f.focusManager.activate(); 908 } 909 910 updateLastActiveForm(); 911 912 // trace("END SM: activate " + f); 913 } 914 915 /** 916 * @inheritDoc 917 */ 918 public function deactivate(f:IFocusManagerContainer):void 919 { 920 deactivateForm(Object(f)); 921 } 922 923 /** 924 * @private 925 * 926 * New version of deactivate that works with remote pop ups. 927 * 928 */ 929 private function deactivateForm(f:Object):void 930 { 931 // trace(">>SM: deactivate " + f); 932 933 if (form) 934 { 935 // If there's more than one form and this is it, find a new form. 936 if (form == f && forms.length > 1) 937 { 938 if (isRemotePopUp(form)) 939 deactivateRemotePopUp(form); 940 else 941 form.focusManager.deactivate(); 942 943 form = findLastActiveForm(f); 944 945 // make sure we have a valid top level window. 946 // This can be null if top level window has been hidden for some reason. 947 if (form) 948 { 949 if (isRemotePopUp(form)) 950 activateRemotePopUp(form); 951 else 952 form.focusManager.activate(); 953 } 954 } 955 } 956 957 // trace("<<SM: deactivate " + f); 958 } 959 960 961 /** 962 * @private 963 * 964 * @param f form being deactivated 965 * 966 * @return the next form to activate, excluding the form being deactivated. 967 */ 968 private function findLastActiveForm(f:Object):Object 969 { 970 var n:int = forms.length; 971 for (var i:int = forms.length - 1; i >= 0; i--) 972 { 973 // Verify the form is visible and enabled 974 if (forms[i] != f && canActivatePopUp(forms[i])) 975 return forms[i]; 976 } 977 978 return null; // shouldn't get here 979 } 980 981 982 /** 983 * @private 984 * 985 * @return true if the form can be activated, false otherwise. 986 */ 987 private function canActivatePopUp(f:Object):Boolean 988 { 989 if (isRemotePopUp(f)) 990 { 991 var remotePopUp:RemotePopUp = RemotePopUp(f); 992 var event:SWFBridgeRequest = new SWFBridgeRequest(SWFBridgeRequest.CAN_ACTIVATE_POP_UP_REQUEST, 993 false, false, null, 994 remotePopUp.window); 995 IEventDispatcher(remotePopUp.bridge).dispatchEvent(event); 996 return event.data; 997 } 998 else if (canActivateLocalComponent(f)) 999 return true; 1000 1001 return false; 1002 } 1003 1004 1005 /** 1006 * @private 1007 * 1008 * Test is a local component can be activated. 1009 */ 1010 private function canActivateLocalComponent(o:Object):Boolean 1011 { 1012 1013 if (o is Sprite && o is IUIComponent && 1014 Sprite(o).visible && IUIComponent(o).enabled) 1015 return true; 1016 1017 return false; 1018 } 1019 1020 /** 1021 * @private 1022 * 1023 * @return true if the form is a RemotePopUp, false if the form is IFocusManagerContainer. 1024 * 1025 */ 1026 private static function isRemotePopUp(form:Object):Boolean 1027 { 1028 return !(form is IFocusManagerContainer); 1029 } 1030 1031 /** 1032 * @private 1033 * 1034 * @return true if form1 and form2 are both of type RemotePopUp and are equal, false otherwise. 1035 */ 1036 private static function areRemotePopUpsEqual(form1:Object, form2:Object):Boolean 1037 { 1038 if (!(form1 is RemotePopUp)) 1039 return false; 1040 1041 if (!(form2 is RemotePopUp)) 1042 return false; 1043 1044 var remotePopUp1:RemotePopUp = RemotePopUp(form1); 1045 var remotePopUp2:RemotePopUp = RemotePopUp(form2); 1046 1047 if (remotePopUp1.window == remotePopUp2.window && 1048 remotePopUp1.bridge && remotePopUp2.bridge) 1049 return true; 1050 1051 return false; 1052 } 1053 1054 1055 /** 1056 * @private 1057 * 1058 * Find a remote form that is hosted by this system manager. 1059 * 1060 * @param window unique id of popUp within a bridged application 1061 * @param bridge bridge of owning application. 1062 * 1063 * @return RemotePopUp if hosted by this system manager, false otherwise. 1064 */ 1065 private function findRemotePopUp(window:Object, bridge:IEventDispatcher):RemotePopUp 1066 { 1067 // remove the placeholder from forms array 1068 var n:int = forms.length; 1069 for (var i:int = 0; i < n; i++) 1070 { 1071 if (isRemotePopUp(forms[i])) 1072 { 1073 var popUp:RemotePopUp = RemotePopUp(forms[i]); 1074 if (popUp.window == window && 1075 popUp.bridge == bridge) 1076 return popUp; 1077 } 1078 } 1079 1080 return null; 1081 } 1082 1083 /** 1084 * Remote a remote form from the forms array. 1085 * 1086 * form Locally created remote form. 1087 */ 1088 private function removeRemotePopUp(form:RemotePopUp):void 1089 { 1090 // remove popup from forms array 1091 var n:int = forms.length; 1092 for (var i:int = 0; i < n; i++) 1093 { 1094 if (isRemotePopUp(forms[i])) 1095 { 1096 if (forms[i].window == form.window && 1097 forms[i].bridge == form.bridge) 1098 { 1099 if (forms[i] == form) 1100 deactivateForm(form); 1101 forms.splice(i, 1); 1102 break; 1103 } 1104 } 1105 } 1106 } 1107 1108 /** 1109 * @private 1110 * 1111 * Activate a form that belongs to a system manager in another 1112 * sandbox or peer application domain. 1113 * 1114 * @param form a RemotePopUp object. 1115 * */ 1116 private function activateRemotePopUp(form:Object):void 1117 { 1118 var request:SWFBridgeRequest = new SWFBridgeRequest(SWFBridgeRequest.ACTIVATE_POP_UP_REQUEST, 1119 false, false, 1120 form.bridge, 1121 form.window); 1122 var bridge:Object = form.bridge; 1123 if (bridge) 1124 bridge.dispatchEvent(request); 1125 } 1126 1127 1128 private function deactivateRemotePopUp(form:Object):void 1129 { 1130 var request:SWFBridgeRequest = new SWFBridgeRequest(SWFBridgeRequest.DEACTIVATE_POP_UP_REQUEST, 1131 false, false, 1132 form.bridge, 1133 form.window); 1134 var bridge:Object = form.bridge; 1135 if (bridge) 1136 bridge.dispatchEvent(request); 1137 } 1138 /** 1139 * Test if two forms are equal. 1140 * 1141 * @param form1 - may be of type a DisplayObjectContainer or a RemotePopUp 1142 * @param form2 - may be of type a DisplayObjectContainer or a RemotePopUp 1143 * 1144 * @return true if the forms are equal, false otherwise. 1145 */ 1146 private function areFormsEqual(form1:Object, form2:Object):Boolean 1147 { 1148 if (form1 == form2) 1149 return true; 1150 1151 // if the forms are both remote forms, then compare them, otherwise 1152 // return false. 1153 if (form1 is RemotePopUp && form2 is RemotePopUp) 1154 { 1155 return areRemotePopUpsEqual(form1, form2); 1156 } 1157 1158 return false; 1159 } 1160 1161 /** 1162 * @inheritDoc 1163 */ 1164 public function addFocusManager(f:IFocusManagerContainer):void 1165 { 1166 // trace("OLW: add focus manager" + f); 1167 1168 forms.push(f); 1169 1170 // trace("END OLW: add focus manager" + f); 1171 } 1172 1173 /** 1174 * @inheritDoc 1175 */ 1176 public function removeFocusManager(f:IFocusManagerContainer):void 1177 { 1178 // trace("OLW: remove focus manager" + f); 1179 1180 var n:int = forms.length; 1181 for (var i:int = 0; i < n; i++) 1182 { 1183 if (forms[i] == f) 1184 { 1185 if (form == f) 1186 deactivate(f); 1187 forms.splice(i, 1); 1188 // trace("END OLW: successful remove focus manager" + f); 1189 return; 1190 } 1191 } 1192 1193 // trace("END OLW: remove focus manager" + f); 1194 } 1195 1196 //-------------------------------------------------------------------------- 1197 // 1198 // Methods: Access to overridden methods of base classes 1199 // 1200 //-------------------------------------------------------------------------- 1201 1202 /** 1203 * @private 1204 * This method allows access to the Player's native implementation 1205 * of addChild(), which can be useful since components 1206 * can override addChild() and thereby hide the native implementation. 1207 * Note that this "base method" is final and cannot be overridden, 1208 * so you can count on it to reflect what is happening at the player level. 1209 */ 1210 mx_internal final function $addChild(child:DisplayObject):DisplayObject 1211 { 1212 return super.addChild(child); 1213 } 1214 1215 /** 1216 * @private 1217 * This method allows access to the Player's native implementation 1218 * of addChildAt(), which can be useful since components 1219 * can override addChildAt() and thereby hide the native implementation. 1220 * Note that this "base method" is final and cannot be overridden, 1221 * so you can count on it to reflect what is happening at the player level. 1222 */ 1223 mx_internal final function $addChildAt(child:DisplayObject, 1224 index:int):DisplayObject 1225 { 1226 return super.addChildAt(child, index); 1227 } 1228 1229 /** 1230 * @private 1231 * This method allows access to the Player's native implementation 1232 * of removeChild(), which can be useful since components 1233 * can override removeChild() and thereby hide the native implementation. 1234 * Note that this "base method" is final and cannot be overridden, 1235 * so you can count on it to reflect what is happening at the player level. 1236 */ 1237 mx_internal final function $removeChild(child:DisplayObject):DisplayObject 1238 { 1239 return super.removeChild(child); 1240 } 1241 1242 /** 1243 * @private 1244 * This method allows access to the Player's native implementation 1245 * of removeChildAt(), which can be useful since components 1246 * can override removeChildAt() and thereby hide the native implementation. 1247 * Note that this "base method" is final and cannot be overridden, 1248 * so you can count on it to reflect what is happening at the player level. 1249 */ 1250 mx_internal final function $removeChildAt(index:int):DisplayObject 1251 { 1252 return super.removeChildAt(index); 1253 } 1254 1255 //-------------------------------------------------------------------------- 1256 // 1257 // Methods: Initialization 1258 // 1259 //-------------------------------------------------------------------------- 1260 1261 /** 1262 * This method is overridden in the autogenerated subclass. 1263 */ 1264 public function create(... params):Object 1265 { 1266 var mainClassName:String = String(params[0]); 1267 1268 var mainClass:Class = Class(getDefinitionByName(mainClassName)); 1269 if (!mainClass) 1270 throw new Error("Class '" + mainClassName + "' not found."); 1271 1272 var instance:Object = new mainClass(); 1273 if (instance is IFlexModule) 1274 (IFlexModule(instance)).moduleFactory = this; 1275 return instance; 1276 } 1277 1278 /** 1279 * @private 1280 * This is attached as the framescript at the end of frame 2. 1281 * When this function is called, we know that the application 1282 * class has been defined and read in by the Player. 1283 */ 1284 protected function docFrameHandler(event:Event = null):void 1285 { 1286 removeEventListener(Event.ADDED, docFrameHandler); 1287 1288 // every SM has to have this listener in case it is the SM for some child AD that contains a manager 1289 // and the parent ADs don't have that manager. 1290 getSandboxRoot().addEventListener(InterManagerRequest.INIT_MANAGER_REQUEST, initManagerHandler, false, 0, true); 1291 // once managers get initialized, they bounce things off the sandbox root 1292 if (getSandboxRoot() == this) 1293 { 1294 addEventListener(InterManagerRequest.SYSTEM_MANAGER_REQUEST, systemManagerHandler); 1295 addEventListener(InterManagerRequest.DRAG_MANAGER_REQUEST, multiWindowRedispatcher); 1296 // listened for w/o use of constants because of dependency issues 1297 //addEventListener(InterDragManagerEvent.DISPATCH_DRAG_EVENT, multiWindowRedispatcher); 1298 addEventListener("dispatchDragEvent", multiWindowRedispatcher); 1299 1300 addEventListener(SWFBridgeRequest.ADD_POP_UP_REQUEST, addPopupRequestHandler); 1301 addEventListener(SWFBridgeRequest.REMOVE_POP_UP_REQUEST, removePopupRequestHandler); 1302 addEventListener(SWFBridgeRequest.ADD_POP_UP_PLACE_HOLDER_REQUEST, addPlaceholderPopupRequestHandler); 1303 addEventListener(SWFBridgeRequest.REMOVE_POP_UP_PLACE_HOLDER_REQUEST, removePlaceholderPopupRequestHandler); 1304 addEventListener(SWFBridgeEvent.BRIDGE_WINDOW_ACTIVATE, activateFormSandboxEventHandler); 1305 addEventListener(SWFBridgeEvent.BRIDGE_WINDOW_DEACTIVATE, deactivateFormSandboxEventHandler); 1306 addEventListener(SWFBridgeRequest.HIDE_MOUSE_CURSOR_REQUEST, hideMouseCursorRequestHandler); 1307 addEventListener(SWFBridgeRequest.SHOW_MOUSE_CURSOR_REQUEST, showMouseCursorRequestHandler); 1308 addEventListener(SWFBridgeRequest.RESET_MOUSE_CURSOR_REQUEST, resetMouseCursorRequestHandler); 1309 } 1310 1311 // Register singleton classes. 1312 // Note: getDefinitionByName() will return null 1313 // if the class can't be found. 1314 /* 1315 Singleton.registerClass("mx.managers::ICursorManager", 1316 Class(getDefinitionByName("mx.managers::CursorManagerImpl"))); 1317 1318 Singleton.registerClass("mx.managers::IDragManager", 1319 Class(getDefinitionByName("mx.managers::DragManagerImpl"))); 1320 1321 Singleton.registerClass("mx.managers::IHistoryManager", 1322 Class(getDefinitionByName("mx.managers::HistoryManagerImpl"))); 1323 1324 Singleton.registerClass("mx.managers::ILayoutManager", 1325 Class(getDefinitionByName("mx.managers::LayoutManager"))); 1326 1327 Singleton.registerClass("mx.managers::IPopUpManager", 1328 Class(getDefinitionByName("mx.managers::PopUpManagerImpl"))); 1329 1330 Singleton.registerClass("mx.styles::IStyleManager", 1331 Class(getDefinitionByName("mx.styles::StyleManagerImpl"))); 1332 1333 Singleton.registerClass("mx.styles::IStyleManager2", 1334 Class(getDefinitionByName("mx.styles::StyleManagerImpl"))); 1335 1336 Singleton.registerClass("mx.managers::IToolTipManager2", 1337 Class(getDefinitionByName("mx.managers::ToolTipManagerImpl")));*/ 1338 1339// executeCallbacks(); 1340// doneExecutingInitCallbacks = true; 1341 1342 // Loaded SWFs don't get a stage right away 1343 // and shouldn't override the main SWF's setting anyway. 1344 if (stage) 1345 { 1346 stage.scaleMode = StageScaleMode.NO_SCALE; 1347 stage.align = StageAlign.TOP_LEFT; 1348 } 1349 1350 var mixinList:Array = info()["mixins"]; 1351 if (mixinList && mixinList.length > 0) 1352 { 1353 var n:int = mixinList.length; 1354 for (var i:int = 0; i < n; ++i) 1355 { 1356 // trace("initializing mixin " + mixinList[i]); 1357 var c:Class = Class(getDefinitionByName(mixinList[i])); 1358 c["init"](this); 1359 } 1360 } 1361 1362 // installCompiledResourceBundles(); 1363 1364 initializeTopLevelWindow(null); 1365 1366 if (Singleton.getClass("mx.managers::IDragManager").getInstance() is NativeDragManagerImpl) 1367 NativeDragManagerImpl(Singleton.getClass("mx.managers::IDragManager").getInstance()).registerSystemManager(this); 1368 } 1369 1370 /** 1371 * @private 1372 * Instantiates an instance of the top level window 1373 * and adds it as a child of the SystemManager. 1374 */ 1375 protected function initializeTopLevelWindow(event:Event):void 1376 { 1377 initialized = true; 1378 1379 if (!parent) 1380 return; 1381 1382 initContextMenu(); 1383 if (!topLevel) 1384 { 1385 // We are not top-level and don't have a parent. This can happen 1386 // when the application has already been unloaded by the time 1387 // we get to this point. 1388 if (!parent) 1389 return; 1390 1391 var obj:DisplayObjectContainer = parent.parent; 1392 1393 // if there is no grandparent at this point, we might have been removed and 1394 // are about to be killed so just bail. Other code that runs after 1395 // this point expects us to be grandparented. Another scenario 1396 // is that someone loaded us but not into a parented loader, but that 1397 // is not allowed. 1398 if (!obj) 1399 return; 1400 1401 while (obj) 1402 { 1403 if (obj is IUIComponent) 1404 { 1405 _topLevelSystemManager = IUIComponent(obj).systemManager; 1406 break; 1407 } 1408 obj = obj.parent; 1409 } 1410 } 1411 1412 // capture mouse down so we can switch top level windows and activate 1413 // the right focus manager before the components inside start 1414 // processing the event 1415 addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler, true); 1416 1417 // if (topLevel && stage) 1418 stage.addEventListener(Event.RESIZE, Stage_resizeHandler, false, 0, true); 1419 1420 var app:IUIComponent; 1421 // Create a new instance of the toplevel class 1422 document = app = topLevelWindow;// = IUIComponent(create()); 1423 1424 if (document) 1425 { 1426 // Add listener for the creationComplete event 1427/* IEventDispatcher(app).addEventListener(FlexEvent.CREATION_COMPLETE, 1428 appCreationCompleteHandler); 1429*/ 1430 if (topLevel && stage) 1431 { 1432 // LoaderConfig._url = loaderInfo.url; 1433 // LoaderConfig._parameters = loaderInfo.parameters; 1434 1435 // stageWidth/stageHeight may have changed between initialize() and now, 1436 // so refresh our _width and _height here. 1437 _width = stage.stageWidth; 1438 _height = stage.stageHeight; 1439 //trace("width", _width); 1440 1441 IFlexDisplayObject(app).setActualSize(stage.stageWidth, stage.stageHeight); 1442 } 1443 else 1444 { 1445 IFlexDisplayObject(app).setActualSize(loaderInfo.width, loaderInfo.height); 1446 } 1447 1448 // Wait for the app to finish its initialization sequence 1449 // before doing an addChild(). 1450 // Otherwise, the measurement/layout code will cause the 1451 // player to do a bunch of unnecessary screen repaints, 1452 // which slows application startup time. 1453 1454 // Pass in the application instance to the preloader using registerApplication 1455 // preloader.registerApplication(app); 1456 1457 // The Application doesn't get added to the SystemManager in the standard way. 1458 // We want to recursively create the entire application subtree and process 1459 // it with the LayoutManager before putting the Application on the display list. 1460 // So here we what would normally happen inside an override of addChild(). 1461 // Leter, when we actually attach the Application instance, 1462 // we call super.addChild(), which is the bare player method. 1463 addingChild(DisplayObject(app)); 1464 childAdded(DisplayObject(app)); // calls app.createChildren() 1465 } 1466 else 1467 { 1468 document = this; 1469 } 1470 1471 // because we have no preload done handler, we need to 1472 // do that work elsewhere 1473 addChildAndMouseCatcher(); 1474 } 1475 1476 /** 1477 * @private 1478 * Same as SystemManager's preload done handler. It adds 1479 * the window to the application (and a mouse catcher) 1480 * 1481 * Called from initializeTopLevelWindow() 1482 */ 1483 private function addChildAndMouseCatcher():void 1484 { 1485 var app:IUIComponent = topLevelWindow; 1486 // Add the mouseCatcher as child 0. 1487 mouseCatcher = new FlexSprite(); 1488 mouseCatcher.name = "mouseCatcher"; 1489 1490 // Must use addChildAt because a creationComplete handler can create a 1491 // dialog and insert it at 0. 1492 noTopMostIndex++; 1493 super.addChildAt(mouseCatcher, 0); 1494 resizeMouseCatcher(); 1495 1496 // topLevel seems to always be true, but keeping it here just in case 1497 if (!topLevel) 1498 { 1499 mouseCatcher.visible = false; 1500 mask = mouseCatcher; 1501 } 1502 1503 noTopMostIndex++; 1504 super.addChild(DisplayObject(app)); 1505 } 1506 1507 1508 //---------------------------------- 1509 // info 1510 //---------------------------------- 1511 1512 /** 1513 * @private 1514 */ 1515 public function info():Object 1516 { 1517 return {}; 1518 } 1519 1520 //-------------------------------------------------------------------------- 1521 // 1522 // Methods: Styles 1523 // 1524 //-------------------------------------------------------------------------- 1525 1526 /** 1527 * @private 1528 * Call regenerateStyleCache() on all children of this SystemManager. 1529 * If the recursive parameter is true, continue doing this 1530 * for all descendants of these children. 1531 */ 1532 mx_internal function regenerateStyleCache(recursive:Boolean):void 1533 { 1534 var foundTopLevelWindow:Boolean = false; 1535 1536 var n:int = rawChildren.numChildren; 1537 for (var i:int = 0; i < n; i++) 1538 { 1539 var child:IStyleClient = 1540 rawChildren.getChildAt(i) as IStyleClient; 1541 1542 if (child) 1543 child.regenerateStyleCache(recursive); 1544 1545 if (isTopLevelWindow(DisplayObject(child))) 1546 foundTopLevelWindow = true; 1547 1548 // Refetch numChildren because notifyStyleChangedInChildren() 1549 // can add/delete a child and therefore change numChildren. 1550 n = rawChildren.numChildren; 1551 } 1552 1553 // During startup the top level window isn't added 1554 // to the child list until late into the startup sequence. 1555 // Make sure we call regenerateStyleCache() 1556 // on the top level window even if it isn't a child yet. 1557 if (!foundTopLevelWindow && topLevelWindow is IStyleClient) 1558 IStyleClient(topLevelWindow).regenerateStyleCache(recursive); 1559 } 1560 1561 /** 1562 * @private 1563 * Call styleChanged() and notifyStyleChangeInChildren() 1564 * on all children of this SystemManager. 1565 * If the recursive parameter is true, continue doing this 1566 * for all descendants of these children. 1567 */ 1568 mx_internal function notifyStyleChangeInChildren(styleProp:String, 1569 recursive:Boolean):void 1570 { 1571 var foundTopLevelWindow:Boolean = false; 1572 1573 var n:int = rawChildren.numChildren; 1574 for (var i:int = 0; i < n; i++) 1575 { 1576 var child:IStyleClient = 1577 rawChildren.getChildAt(i) as IStyleClient; 1578 1579 if (child) 1580 { 1581 child.styleChanged(styleProp); 1582 child.notifyStyleChangeInChildren(styleProp, recursive); 1583 } 1584 1585 if (isTopLevelWindow(DisplayObject(child))) 1586 foundTopLevelWindow = true; 1587 1588 // Refetch numChildren because notifyStyleChangedInChildren() 1589 // can add/delete a child and therefore change numChildren. 1590 n = rawChildren.numChildren; 1591 } 1592 1593 // During startup the top level window isn't added 1594 // to the child list until late into the startup sequence. 1595 // Make sure we call notifyStyleChangeInChildren() 1596 // on the top level window even if it isn't a child yet. 1597 if (!foundTopLevelWindow && topLevelWindow is IStyleClient) 1598 { 1599 IStyleClient(topLevelWindow).styleChanged(styleProp); 1600 IStyleClient(topLevelWindow).notifyStyleChangeInChildren( 1601 styleProp, recursive); 1602 } 1603 } 1604 1605 1606 /** 1607 * @private 1608 * Disable all the built-in items except "Print...". 1609 */ 1610 private function initContextMenu():void 1611 { 1612 var defaultMenu:ContextMenu = new ContextMenu(); 1613 defaultMenu.hideBuiltInItems(); 1614 defaultMenu.builtInItems.print = true; 1615 contextMenu = defaultMenu; 1616 } 1617 1618 /** 1619 * @inheritdoc 1620 */ 1621 public function isTopLevelRoot():Boolean 1622 { 1623 return isStageRoot || isBootstrapRoot; 1624 } 1625 1626 /** 1627 * The system manager proxy has only one child that is a focus manager container. 1628 * Iterate thru the children until we find it. 1629 */ 1630 mx_internal function findFocusManagerContainer(smp:SystemManagerProxy):IFocusManagerContainer 1631 { 1632 var children:IChildList = smp.rawChildren; 1633 var numChildren:int = children.numChildren; 1634 for (var i:int = 0; i < numChildren; i++) 1635 { 1636 var child:DisplayObject = children.getChildAt(i); 1637 if (child is IFocusManagerContainer) 1638 { 1639 return IFocusManagerContainer(child); 1640 } 1641 } 1642 1643 return null; 1644 } 1645 1646 /** 1647 * @private 1648 * 1649 * Listen to messages this System Manager needs to service from its children. 1650 */ 1651 mx_internal function addChildBridgeListeners(bridge:IEventDispatcher):void 1652 { 1653 if (!topLevel && topLevelSystemManager) 1654 { 1655 SystemManager(topLevelSystemManager).addChildBridgeListeners(bridge); 1656 return; 1657 } 1658 1659 bridge.addEventListener(SWFBridgeRequest.ADD_POP_UP_REQUEST, addPopupRequestHandler); 1660 bridge.addEventListener(SWFBridgeRequest.REMOVE_POP_UP_REQUEST, removePopupRequestHandler); 1661 bridge.addEventListener(SWFBridgeRequest.ADD_POP_UP_PLACE_HOLDER_REQUEST, addPlaceholderPopupRequestHandler); 1662 bridge.addEventListener(SWFBridgeRequest.REMOVE_POP_UP_PLACE_HOLDER_REQUEST, removePlaceholderPopupRequestHandler); 1663 bridge.addEventListener(SWFBridgeEvent.BRIDGE_WINDOW_ACTIVATE, activateFormSandboxEventHandler); 1664 bridge.addEventListener(SWFBridgeEvent.BRIDGE_WINDOW_DEACTIVATE, deactivateFormSandboxEventHandler); 1665 bridge.addEventListener(SWFBridgeEvent.BRIDGE_APPLICATION_ACTIVATE, activateApplicationSandboxEventHandler); 1666 bridge.addEventListener(EventListenerRequest.ADD_EVENT_LISTENER_REQUEST, eventListenerRequestHandler, false, 0, true); 1667 bridge.addEventListener(EventListenerRequest.REMOVE_EVENT_LISTENER_REQUEST, eventListenerRequestHandler, false, 0, true); 1668 bridge.addEventListener(SWFBridgeRequest.CREATE_MODAL_WINDOW_REQUEST, modalWindowRequestHandler); 1669 bridge.addEventListener(SWFBridgeRequest.SHOW_MODAL_WINDOW_REQUEST, modalWindowRequestHandler); 1670 bridge.addEventListener(SWFBridgeRequest.HIDE_MODAL_WINDOW_REQUEST, modalWindowRequestHandler); 1671 bridge.addEventListener(SWFBridgeRequest.GET_VISIBLE_RECT_REQUEST, getVisibleRectRequestHandler); 1672 bridge.addEventListener(SWFBridgeRequest.HIDE_MOUSE_CURSOR_REQUEST, hideMouseCursorRequestHandler); 1673 bridge.addEventListener(SWFBridgeRequest.SHOW_MOUSE_CURSOR_REQUEST, showMouseCursorRequestHandler); 1674 bridge.addEventListener(SWFBridgeRequest.RESET_MOUSE_CURSOR_REQUEST, resetMouseCursorRequestHandler); 1675 } 1676 1677 /** 1678 * @private 1679 * 1680 * Remove all child listeners. 1681 */ 1682 mx_internal function removeChildBridgeListeners(bridge:IEventDispatcher):void 1683 { 1684 if (!topLevel && topLevelSystemManager) 1685 { 1686 SystemManager(topLevelSystemManager).removeChildBridgeListeners(bridge); 1687 return; 1688 } 1689 1690 bridge.removeEventListener(SWFBridgeRequest.ADD_POP_UP_REQUEST, addPopupRequestHandler); 1691 bridge.removeEventListener(SWFBridgeRequest.REMOVE_POP_UP_REQUEST, removePopupRequestHandler); 1692 bridge.removeEventListener(SWFBridgeRequest.ADD_POP_UP_PLACE_HOLDER_REQUEST, addPlaceholderPopupRequestHandler); 1693 bridge.removeEventListener(SWFBridgeRequest.REMOVE_POP_UP_PLACE_HOLDER_REQUEST, removePlaceholderPopupRequestHandler); 1694 bridge.removeEventListener(SWFBridgeEvent.BRIDGE_WINDOW_ACTIVATE, activateFormSandboxEventHandler); 1695 bridge.removeEventListener(SWFBridgeEvent.BRIDGE_WINDOW_DEACTIVATE, deactivateFormSandboxEventHandler); 1696 bridge.removeEventListener(SWFBridgeEvent.BRIDGE_APPLICATION_ACTIVATE, activateApplicationSandboxEventHandler); 1697 bridge.removeEventListener(EventListenerRequest.ADD_EVENT_LISTENER_REQUEST, eventListenerRequestHandler); 1698 bridge.removeEventListener(EventListenerRequest.REMOVE_EVENT_LISTENER_REQUEST, eventListenerRequestHandler); 1699 bridge.removeEventListener(SWFBridgeRequest.CREATE_MODAL_WINDOW_REQUEST, modalWindowRequestHandler); 1700 bridge.removeEventListener(SWFBridgeRequest.SHOW_MODAL_WINDOW_REQUEST, modalWindowRequestHandler); 1701 bridge.removeEventListener(SWFBridgeRequest.HIDE_MODAL_WINDOW_REQUEST, modalWindowRequestHandler); 1702 bridge.removeEventListener(SWFBridgeRequest.GET_VISIBLE_RECT_REQUEST, getVisibleRectRequestHandler); 1703 bridge.removeEventListener(SWFBridgeRequest.HIDE_MOUSE_CURSOR_REQUEST, hideMouseCursorRequestHandler); 1704 bridge.removeEventListener(SWFBridgeRequest.SHOW_MOUSE_CURSOR_REQUEST, showMouseCursorRequestHandler); 1705 bridge.removeEventListener(SWFBridgeRequest.RESET_MOUSE_CURSOR_REQUEST, resetMouseCursorRequestHandler); 1706 } 1707 1708 /** 1709 * @private 1710 * 1711 * Add listeners for events and requests we might receive from our parent if our 1712 * parent is using a sandbox bridge to communicate with us. 1713 */ 1714 mx_internal function addParentBridgeListeners():void 1715 { 1716 if (!topLevel && topLevelSystemManager) 1717 { 1718 SystemManager(topLevelSystemManager).addParentBridgeListeners(); 1719 return; 1720 } 1721 1722 var bridge:IEventDispatcher = swfBridgeGroup.parentBridge; 1723 bridge.addEventListener(SWFBridgeRequest.SET_ACTUAL_SIZE_REQUEST, setActualSizeRequestHandler); 1724 bridge.addEventListener(SWFBridgeRequest.GET_SIZE_REQUEST, getSizeRequestHandler); 1725 1726 // need to listener to parent system manager to get broadcast messages. 1727 bridge.addEventListener(SWFBridgeRequest.ACTIVATE_POP_UP_REQUEST, 1728 activateRequestHandler); 1729 bridge.addEventListener(SWFBridgeRequest.DEACTIVATE_POP_UP_REQUEST, 1730 deactivateRequestHandler); 1731 bridge.addEventListener(SWFBridgeRequest.IS_BRIDGE_CHILD_REQUEST, isBridgeChildHandler); 1732 bridge.addEventListener(EventListenerRequest.ADD_EVENT_LISTENER_REQUEST, eventListenerRequestHandler); 1733 bridge.addEventListener(EventListenerRequest.REMOVE_EVENT_LISTENER_REQUEST, eventListenerRequestHandler); 1734 bridge.addEventListener(SWFBridgeRequest.CAN_ACTIVATE_POP_UP_REQUEST, canActivateHandler); 1735 } 1736 1737 /** 1738 * @private 1739 * 1740 * remove listeners for events and requests we might receive from our parent if 1741 * our parent is using a sandbox bridge to communicate with us. 1742 */ 1743 mx_internal function removeParentBridgeListeners():void 1744 { 1745 if (!topLevel && topLevelSystemManager) 1746 { 1747 SystemManager(topLevelSystemManager).removeParentBridgeListeners(); 1748 return; 1749 } 1750 1751 var bridge:IEventDispatcher = swfBridgeGroup.parentBridge; 1752 bridge.removeEventListener(SWFBridgeRequest.SET_ACTUAL_SIZE_REQUEST, setActualSizeRequestHandler); 1753 bridge.removeEventListener(SWFBridgeRequest.GET_SIZE_REQUEST, getSizeRequestHandler); 1754 1755 // need to listener to parent system manager to get broadcast messages. 1756 bridge.removeEventListener(SWFBridgeRequest.ACTIVATE_POP_UP_REQUEST, 1757 activateRequestHandler); 1758 bridge.removeEventListener(SWFBridgeRequest.DEACTIVATE_POP_UP_REQUEST, 1759 deactivateRequestHandler); 1760 bridge.removeEventListener(SWFBridgeRequest.IS_BRIDGE_CHILD_REQUEST, isBridgeChildHandler); 1761 bridge.removeEventListener(EventListenerRequest.ADD_EVENT_LISTENER_REQUEST, eventListenerRequestHandler); 1762 bridge.removeEventListener(EventListenerRequest.REMOVE_EVENT_LISTENER_REQUEST, eventListenerRequestHandler); 1763 bridge.removeEventListener(SWFBridgeRequest.CAN_ACTIVATE_POP_UP_REQUEST, canActivateHandler); 1764 } 1765 1766 /** 1767 * Add a bridge to talk to the child owned by <code>owner</code>. 1768 * 1769 * @param bridge the bridge used to talk to the parent. 1770 * @param owner the display object that owns the bridge. 1771 */ 1772 public function addChildBridge(bridge:IEventDispatcher, owner:DisplayObject):void 1773 { 1774 // Is the owner in a pop up? If so let the focus manager manage the 1775 // bridge instead of the system manager. 1776 var fm:IFocusManager = null; 1777 var o:DisplayObject = owner; 1778 1779 while (o) 1780 { 1781 if (o is IFocusManagerContainer) 1782 { 1783 fm = IFocusManagerContainer(o).focusManager; 1784 break; 1785 } 1786 1787 o = o.parent; 1788 } 1789 1790 if (!fm) 1791 return; 1792 1793 if (!swfBridgeGroup) 1794 swfBridgeGroup = new SWFBridgeGroup(this); 1795 1796 swfBridgeGroup.addChildBridge(bridge, ISWFBridgeProvider(owner)); 1797 fm.addSWFBridge(bridge, owner); 1798 1799 if (!bridgeToFocusManager) 1800 bridgeToFocusManager = new Dictionary(); 1801 1802 bridgeToFocusManager[bridge] = fm; 1803 1804 addChildBridgeListeners(bridge); 1805 1806 // dispatch message that we are adding a bridge. 1807 dispatchEvent(new FlexChangeEvent(FlexChangeEvent.ADD_CHILD_BRIDGE, false, false, bridge)); 1808 } 1809 1810 /** 1811 * Remove a child bridge. 1812 */ 1813 public function removeChildBridge(bridge:IEventDispatcher):void 1814 { 1815 // dispatch message that we are removing a bridge. 1816 dispatchEvent(new FlexChangeEvent(FlexChangeEvent.REMOVE_CHILD_BRIDGE, false, false, bridge)); 1817 1818 var fm:IFocusManager = IFocusManager(bridgeToFocusManager[bridge]); 1819 fm.removeSWFBridge(bridge); 1820 swfBridgeGroup.removeChildBridge(bridge); 1821 1822 delete bridgeToFocusManager[bridge]; 1823 removeChildBridgeListeners(bridge); 1824 } 1825 1826 /** 1827 * @inheritdoc 1828 */ 1829 public function useSWFBridge():Boolean 1830 { 1831 if (isStageRoot) 1832 return false; 1833 1834 if (!topLevel && topLevelSystemManager) 1835 return topLevelSystemManager.useSWFBridge(); 1836 1837 var sbRoot:DisplayObject = getSandboxRoot(); 1838 1839 // if we're toplevel and we aren't the sandbox root, we need a bridge 1840 if (topLevel && sbRoot != this) 1841 return true; 1842 1843 // we also need a bridge even if we're the sandbox root 1844 // but not a stage root, but our parent loader is a bootstrap 1845 // that is not the stage root 1846 if (sbRoot == this) 1847 { 1848 try 1849 { 1850 // check if the loader info is valid. 1851 root.loaderInfo.parentAllowsChild; 1852 1853 if (parentAllowsChild && childAllowsParent) 1854 { 1855 try 1856 { 1857 if (!parent.dispatchEvent(new Event("mx.managers.SystemManager.isStageRoot", false, true))) 1858 return true; 1859 } 1860 catch (e:Error) 1861 { 1862 } 1863 } 1864 else 1865 return true; 1866 } 1867 catch (e1:Error) 1868 { 1869 // we seem to get here when a SWF is being unloaded, has been unparented, but still 1870 // has a stage and root property, but loaderInfo is invalid. 1871 return false; 1872 } 1873 } 1874 1875 return false; 1876 } 1877 1878 /** 1879 * Go up our parent chain to get the top level system manager. 1880 * 1881 * returns null if we are not on the display list or we don't have 1882 * access to the top level system manager. 1883 */ 1884 public function getTopLevelRoot():DisplayObject 1885 { 1886 // work our say up the parent chain to the root. This way we 1887 // don't have to rely on this object being added to the stage. 1888 try 1889 { 1890 var sm:ISystemManager = this; 1891 if (sm.topLevelSystemManager) 1892 sm = ISystemManager(sm.topLevelSystemManager); 1893 var parent:DisplayObject = DisplayObject(sm).parent; 1894 var lastParent:DisplayObject = parent; 1895 while (parent) 1896 { 1897 if (parent is Stage) 1898 return lastParent; 1899 lastParent = parent; 1900 parent = parent.parent; 1901 } 1902 } 1903 catch (error:SecurityError) 1904 { 1905 } 1906 1907 return null; 1908 } 1909 1910 /** 1911 * Go up our parent chain to get the top level system manager in this 1912 * SecurityDomain 1913 * 1914 */ 1915 public function getSandboxRoot():DisplayObject 1916 { 1917 // work our say up the parent chain to the root. This way we 1918 // don't have to rely on this object being added to the stage. 1919 var sm:ISystemManager = this; 1920 1921 try 1922 { 1923 if (sm.topLevelSystemManager) 1924 sm = ISystemManager(sm.topLevelSystemManager); 1925 var parent:DisplayObject = DisplayObject(sm).parent; 1926 if (parent is Stage) 1927 return DisplayObject(sm); 1928 // test to see if parent is a Bootstrap 1929 if (parent && !parent.dispatchEvent(new Event("mx.managers.SystemManager.isBootstrapRoot", false, true))) 1930 return this; 1931 var lastParent:DisplayObject = this; 1932 while (parent) 1933 { 1934 if (parent is Stage) 1935 return lastParent; 1936 // test to see if parent is a Bootstrap 1937 if (!parent.dispatchEvent(new Event("mx.managers.SystemManager.isBootstrapRoot", false, true))) 1938 return lastParent; 1939 1940 // Test if the childAllowsParent so we know there is mutual trust between 1941 // the sandbox root and this sm. 1942 // The parentAllowsChild is taken care of by the player because it returns null 1943 // for the parent if we do not have access. 1944 if (parent is Loader) 1945 { 1946 var loader:Loader = Loader(parent); 1947 var loaderInfo:LoaderInfo = loader.contentLoaderInfo; 1948 if (!loaderInfo.childAllowsParent) 1949 return loaderInfo.content; 1950 } 1951 1952 // If an object is listening for system manager request we assume it is a sandbox 1953 // root. If not, don't assign lastParent to this parent because it may be a 1954 // non-Flex application. We only want Flex apps to be returned as sandbox roots. 1955 if (parent.hasEventListener(InterManagerRequest.SYSTEM_MANAGER_REQUEST)) 1956 lastParent = parent; 1957 parent = parent.parent; 1958 } 1959 } 1960 catch (error:Error) 1961 { 1962 // Either we don't have security access to a parent or 1963 // the swf is unloaded and loaderInfo.childAllowsParent is throwing Error #2099. 1964 } 1965 1966 return lastParent != null ? lastParent : DisplayObject(sm); 1967 } 1968 1969 /** 1970 * @inheritdoc 1971 */ 1972 public function getVisibleApplicationRect(bounds:Rectangle = null):Rectangle 1973 { 1974 if (!bounds) 1975 { 1976 bounds = getBounds(DisplayObject(this)); 1977 1978 var s:Rectangle = screen; 1979 var pt:Point = new Point(Math.max(0, bounds.x), Math.max(0, bounds.y)); 1980 pt = localToGlobal(pt); 1981 bounds.x = pt.x; 1982 bounds.y = pt.y; 1983 bounds.width = s.width; 1984 bounds.height = s.height; 1985 } 1986 1987 // send a message to parent for their visible rect. 1988 if (useSWFBridge()) 1989 { 1990 var bridge:IEventDispatcher = swfBridgeGroup.parentBridge; 1991 var request:SWFBridgeRequest = new SWFBridgeRequest(SWFBridgeRequest.GET_VISIBLE_RECT_REQUEST, 1992 false, false, 1993 bridge, 1994 bounds); 1995 bridge.dispatchEvent(request); 1996 bounds = Rectangle(request.data); 1997 } 1998 1999 return bounds; 2000 } 2001 2002 /** 2003 * @inheritdoc 2004 */ 2005 public function deployMouseShields(deploy:Boolean):void 2006 { 2007 var me:InterManagerRequest = new InterManagerRequest(InterManagerRequest.DRAG_MANAGER_REQUEST, false, false, 2008 "mouseShield", deploy); 2009 getSandboxRoot().dispatchEvent(me); 2010 } 2011 2012 /** 2013 * @private 2014 * 2015 * Notify parent that a new window has been activated. 2016 * 2017 * @param window window that was activated. 2018 */ 2019 mx_internal function dispatchActivatedWindowEvent(window:DisplayObject):void 2020 { 2021 var bridge:IEventDispatcher = swfBridgeGroup ? swfBridgeGroup.parentBridge : null; 2022 if (bridge) 2023 { 2024 var sbRoot:DisplayObject = getSandboxRoot(); 2025 var sendToSbRoot:Boolean = sbRoot != this; 2026 var bridgeEvent:SWFBridgeEvent = new SWFBridgeEvent(SWFBridgeEvent.BRIDGE_WINDOW_ACTIVATE, 2027 false, false, 2028 { notifier: bridge, 2029 window: sendToSbRoot ? window : 2030 NameUtil.displayObjectToString(window) 2031 }); 2032 if (sendToSbRoot) 2033 sbRoot.dispatchEvent(bridgeEvent); 2034 else 2035 bridge.dispatchEvent(bridgeEvent); 2036 } 2037 2038 } 2039 2040 /** 2041 * @private 2042 * 2043 * Notify parent that a window has been deactivated. 2044 * 2045 * @param id window display object or id string that was activated. Ids are used if 2046 * the message is going outside the security domain. 2047 */ 2048 private function dispatchDeactivatedWindowEvent(window:DisplayObject):void 2049 { 2050 var bridge:IEventDispatcher = swfBridgeGroup ? swfBridgeGroup.parentBridge : null; 2051 if (bridge) 2052 { 2053 var sbRoot:DisplayObject = getSandboxRoot(); 2054 var sendToSbRoot:Boolean = sbRoot != this; 2055 var bridgeEvent:SWFBridgeEvent = new SWFBridgeEvent(SWFBridgeEvent.BRIDGE_WINDOW_DEACTIVATE, 2056 false, 2057 false, 2058 { notifier: bridge, 2059 window: sendToSbRoot ? window : 2060 NameUtil.displayObjectToString(window) 2061 }); 2062 if (sendToSbRoot) 2063 sbRoot.dispatchEvent(bridgeEvent); 2064 else 2065 bridge.dispatchEvent(bridgeEvent); 2066 } 2067 2068 } 2069 2070 /** 2071 * @private 2072 * 2073 * Notify parent that an application has been activated. 2074 */ 2075 private function dispatchActivatedApplicationEvent():void 2076 { 2077 // click on this system manager or one of its sub system managers 2078 // If in a sandbox tell the top-level system manager we are active. 2079 var bridge:IEventDispatcher = swfBridgeGroup ? swfBridgeGroup.parentBridge : null; 2080 if (bridge) 2081 { 2082 var bridgeEvent:SWFBridgeEvent = new SWFBridgeEvent(SWFBridgeEvent.BRIDGE_APPLICATION_ACTIVATE, 2083 false, false); 2084 bridge.dispatchEvent(bridgeEvent); 2085 } 2086 } 2087 2088 /** 2089 * Adjust the forms array so it is sorted by last active. 2090 * The last active form will be at the end of the forms array. 2091 * 2092 * This method assumes the form variable has been set before calling 2093 * this function. 2094 */ 2095 private function updateLastActiveForm():void 2096 { 2097 // find "form" in the forms array and move that entry to 2098 // the end of the array. 2099 var n:int = forms.length; 2100 if (n < 2) 2101 return; // zero or one forms, no need to update 2102 2103 var index:int = -1; 2104 for (var i:int = 0; i < n; i++) 2105 { 2106 if (areFormsEqual(form, forms[i])) 2107 { 2108 index = i; 2109 break; 2110 } 2111 } 2112 2113 if (index >= 0) 2114 { 2115 forms.splice(index, 1); 2116 forms.push(form); 2117 } 2118 2119 } 2120 2121 /** 2122 * @private 2123 * 2124 * Add placeholder information to this instance's list of placeholder data. 2125 */ 2126 private function addPlaceholderId(id:String, previousId:String, bridge:IEventDispatcher, 2127 placeholder:Object):void 2128 { 2129 if (!bridge) 2130 throw new Error(); // bridge is required. 2131 2132 if (!idToPlaceholder) 2133 idToPlaceholder = []; 2134 2135 idToPlaceholder[id] = new PlaceholderData(previousId, bridge, placeholder); 2136 } 2137 2138 private function removePlaceholderId(id:String):void 2139 { 2140 delete idToPlaceholder[id]; 2141 } 2142 2143 private var currentSandboxEvent:Event; 2144 2145 /** 2146 * request the parent to add an event listener. 2147 */ 2148 private function addEventListenerToOtherSystemManagers(type:String, listener:Function, useCapture:Boolean = false, 2149 priority:int=0, useWeakReference:Boolean=false):void 2150 { 2151 var arr:Array = SystemManagerGlobals.topLevelSystemManagers; 2152 if (arr.length < 2) 2153 return; 2154 2155 SystemManagerGlobals.changingListenersInOtherSystemManagers = true; 2156 var n:int = arr.length; 2157 for (var i:int = 0; i < n; i++) 2158 { 2159 if (arr[i] != this) 2160 { 2161 arr[i].addEventListener(type, listener, useCapture, priority, useWeakReference); 2162 } 2163 } 2164 SystemManagerGlobals.changingListenersInOtherSystemManagers = false; 2165 } 2166 2167 /** 2168 * request the parent to remove an event listener. 2169 */ 2170 private function removeEventListenerFromOtherSystemManagers(type:String, listener:Function, 2171 useCapture:Boolean = false):void 2172 { 2173 var arr:Array = SystemManagerGlobals.topLevelSystemManagers; 2174 if (arr.length < 2) 2175 return; 2176 2177 SystemManagerGlobals.changingListenersInOtherSystemManagers = true; 2178 var n:int = arr.length; 2179 for (var i:int = 0; i < n; i++) 2180 { 2181 if (arr[i] != this) 2182 { 2183 arr[i].removeEventListener(type, listener, useCapture); 2184 } 2185 } 2186 SystemManagerGlobals.changingListenersInOtherSystemManagers = false; 2187 } 2188 2189 private var dispatchingToSystemManagers:Boolean = false; 2190 2191 private function dispatchEventToOtherSystemManagers(event:Event):void 2192 { 2193 SystemManagerGlobals.dispatchingEventToOtherSystemManagers = true; 2194 var arr:Array = SystemManagerGlobals.topLevelSystemManagers; 2195 var n:int = arr.length; 2196 for (var i:int = 0; i < n; i++) 2197 { 2198 if (arr[i] != this) 2199 { 2200 arr[i].dispatchEvent(event); 2201 } 2202 } 2203 SystemManagerGlobals.dispatchingEventToOtherSystemManagers = false 2204 } 2205 2206 /** 2207 * dispatch the event to all sandboxes except the specified one 2208 */ 2209 public function dispatchEventFromSWFBridges(event:Event, skip:IEventDispatcher = null, 2210 trackClones:Boolean = false, toOtherSystemManagers:Boolean = false):void 2211 { 2212 if (toOtherSystemManagers) 2213 { 2214 dispatchEventToOtherSystemManagers(event); 2215 } 2216 2217 if (!swfBridgeGroup) 2218 return; 2219 2220 var clone:Event; 2221 // trace(">>dispatchEventFromSWFBridges", this, event.type); 2222 clone = event.clone(); 2223 if (trackClones) 2224 currentSandboxEvent = clone; 2225 var parentBridge:IEventDispatcher = swfBridgeGroup.parentBridge; 2226 if (parentBridge && parentBridge != skip) 2227 { 2228 // Ensure the requestor property has the correct bridge. 2229 if (clone is SWFBridgeRequest) 2230 SWFBridgeRequest(clone).requestor = parentBridge; 2231 2232 parentBridge.dispatchEvent(clone); 2233 } 2234 2235 var children:Array = swfBridgeGroup.getChildBridges(); 2236 for (var i:int = 0; i < children.length; i++) 2237 { 2238 if (children[i] != skip) 2239 { 2240 // trace("send to child", i, event.type); 2241 clone = event.clone(); 2242 if (trackClones) 2243 currentSandboxEvent = clone; 2244 2245 // Ensure the requestor property has the correct bridge. 2246 if (clone is SWFBridgeRequest) 2247 SWFBridgeRequest(clone).requestor = IEventDispatcher(children[i]); 2248 2249 IEventDispatcher(children[i]).dispatchEvent(clone); 2250 } 2251 } 2252 currentSandboxEvent = null; 2253 2254 // trace("<<dispatchEventFromSWFBridges", this, event.type); 2255 } 2256 /** 2257 * request the parent to add an event listener. 2258 */ 2259 private function addEventListenerToSandboxes(type:String, listener:Function, useCapture:Boolean = false, 2260 priority:int=0, useWeakReference:Boolean=false, skip:IEventDispatcher = null):void 2261 { 2262 if (!swfBridgeGroup) 2263 return; 2264 2265 // trace(">>addEventListenerToSandboxes", this, type); 2266 2267 var request:EventListenerRequest = new EventListenerRequest(EventListenerRequest.ADD_EVENT_LISTENER_REQUEST, false, false, 2268 type, 2269 useCapture, 2270 priority, 2271 useWeakReference); 2272 2273 var parentBridge:IEventDispatcher = swfBridgeGroup.parentBridge; 2274 if (parentBridge && parentBridge != skip) 2275 parentBridge.addEventListener(type, listener, false, priority, useWeakReference); 2276 2277 var children:Array = swfBridgeGroup.getChildBridges(); 2278 for (var i:int; i < children.length; i++) 2279 { 2280 var childBridge:IEventDispatcher = IEventDispatcher(children[i]); 2281 2282 if (childBridge != skip) 2283 childBridge.addEventListener(type, listener, false, priority, useWeakReference); 2284 } 2285 2286 dispatchEventFromSWFBridges(request, skip); 2287 // trace("<<addEventListenerToSandboxes", this, type); 2288 } 2289 2290 /** 2291 * request the parent to remove an event listener. 2292 */ 2293 private function removeEventListenerFromSandboxes(type:String, listener:Function, 2294 useCapture:Boolean = false, 2295 skip:IEventDispatcher = null):void 2296 { 2297 if (!swfBridgeGroup) 2298 return; 2299 2300 // trace(">>removeEventListenerToSandboxes", this, type); 2301 var request:EventListenerRequest = new EventListenerRequest(EventListenerRequest.REMOVE_EVENT_LISTENER_REQUEST, false, false, 2302 type, 2303 useCapture); 2304 var parentBridge:IEventDispatcher = swfBridgeGroup.parentBridge; 2305 if (parentBridge && parentBridge != skip) 2306 parentBridge.removeEventListener(type, listener, useCapture); 2307 2308 var children:Array = swfBridgeGroup.getChildBridges(); 2309 for (var i:int; i < children.length; i++) 2310 { 2311 if (children[i] != skip) 2312 IEventDispatcher(children[i]).removeEventListener(type, listener, useCapture); 2313 } 2314 2315 dispatchEventFromSWFBridges(request, skip); 2316 // trace("<<removeEventListenerToSandboxes", this, type); 2317 } 2318 2319 2320 /** 2321 * @private 2322 * 2323 * @return true if the message should be processed, false if 2324 * no other action is required. 2325 */ 2326 private function preProcessModalWindowRequest(request:SWFBridgeRequest, 2327 sbRoot:DisplayObject):Boolean 2328 { 2329 // should we process this message? 2330 if (request.data.skip) 2331 { 2332 // skipping this sandbox, 2333 // but don't skip the next one. 2334 request.data.skip = false; 2335 2336 if (useSWFBridge()) 2337 { 2338 var bridge:IEventDispatcher = swfBridgeGroup.parentBridge; 2339 request.requestor = bridge; 2340 bridge.dispatchEvent(request); 2341 } 2342 return false; 2343 } 2344 2345 // if we are not the sandbox root, dispatch the message to the sandbox root. 2346 if (this != sbRoot) 2347 { 2348 // convert exclude component into a rectangle and forward to parent bridge. 2349 if (request.type == SWFBridgeRequest.CREATE_MODAL_WINDOW_REQUEST || 2350 request.type == SWFBridgeRequest.SHOW_MODAL_WINDOW_REQUEST) 2351 { 2352 var exclude:ISWFLoader = swfBridgeGroup.getChildBridgeProvider(request.requestor) 2353 as ISWFLoader; 2354 2355 // find the rectangle of the area to exclude 2356 if (exclude) 2357 { 2358 var excludeRect:Rectangle = ISWFLoader(exclude).getVisibleApplicationRect(); 2359 request.data.excludeRect = excludeRect; 2360 2361 // If the area to exclude is not contain by our document then it is in a 2362 // pop up. From this point for set the useExclude flag to false to 2363 // tell our parent not to exclude use from their modal window, only 2364 // the excludeRect we have just calculated. 2365 if (!DisplayObjectContainer(document).contains(DisplayObject(exclude))) 2366 request.data.useExclude = false; // keep the existing excludeRect 2367 } 2368 } 2369 2370 bridge = swfBridgeGroup.parentBridge; 2371 request.requestor = bridge; 2372 2373 // The HIDE request does not need to be processed by each 2374 // application, so dispatch it directly to the sandbox root. 2375 if (request.type == SWFBridgeRequest.HIDE_MODAL_WINDOW_REQUEST) 2376 sbRoot.dispatchEvent(request); 2377 else 2378 bridge.dispatchEvent(request); 2379 return false; 2380 } 2381 2382 // skip aftering sending the message over a bridge. 2383 request.data.skip = false; 2384 2385 return true; 2386 } 2387 2388 private function otherSystemManagerMouseListener(event:SandboxMouseEvent):void 2389 { 2390 if (SystemManagerGlobals.dispatchingEventToOtherSystemManagers) 2391 return; 2392 2393 dispatchEventFromSWFBridges(event); 2394 2395 // ask the sandbox root if it was the original dispatcher of this event 2396 // if it was then don't dispatch to ourselves because we could have 2397 // got this event by listening to sandboxRoot ourselves. 2398 var me:InterManagerRequest = new InterManagerRequest(InterManagerRequest.SYSTEM_MANAGER_REQUEST); 2399 me.name = "sameSandbox"; 2400 me.value = event; 2401 getSandboxRoot().dispatchEvent(me); 2402 2403 if (!me.value) 2404 dispatchEvent(event); 2405 } 2406 2407 private function sandboxMouseListener(event:Event):void 2408 { 2409 // trace("sandboxMouseListener", this); 2410 if (event is SandboxMouseEvent) 2411 return; 2412 2413 var marshaledEvent:Event = SandboxMouseEvent.marshal(event); 2414 dispatchEventFromSWFBridges(marshaledEvent, event.target as IEventDispatcher); 2415 2416 // ask the sandbox root if it was the original dispatcher of this event 2417 // if it was then don't dispatch to ourselves because we could have 2418 // got this event by listening to sandboxRoot ourselves. 2419 var me:InterManagerRequest = new InterManagerRequest(InterManagerRequest.SYSTEM_MANAGER_REQUEST); 2420 me.name = "sameSandbox"; 2421 me.value = event; 2422 getSandboxRoot().dispatchEvent(me); 2423 2424 if (!me.value) 2425 dispatchEvent(marshaledEvent); 2426 } 2427 2428 private function eventListenerRequestHandler(event:Event):void 2429 { 2430 if (event is EventListenerRequest) 2431 return; 2432 2433 var actualType:String; 2434 var request:EventListenerRequest = EventListenerRequest.marshal(event); 2435 if (event.type == EventListenerRequest.ADD_EVENT_LISTENER_REQUEST) 2436 { 2437 if (!eventProxy) 2438 { 2439 eventProxy = new EventProxy(this); 2440 } 2441 2442 actualType = EventUtil.sandboxMouseEventMap[request.eventType]; 2443 if (actualType) 2444 { 2445 if (isTopLevelRoot()) 2446 { 2447 stage.addEventListener(MouseEvent.MOUSE_MOVE, resetMouseCursorTracking, true, EventPriority.CURSOR_MANAGEMENT + 1, true); 2448 } 2449 else 2450 { 2451 super.addEventListener(MouseEvent.MOUSE_MOVE, resetMouseCursorTracking, true, EventPriority.CURSOR_MANAGEMENT + 1, true); 2452 } 2453 2454 // add listeners in other sandboxes in capture mode so we don't miss anything 2455 addEventListenerToSandboxes(request.eventType, sandboxMouseListener, 2456 true, request.priority, request.useWeakReference, event.target as IEventDispatcher); 2457 addEventListenerToOtherSystemManagers(request.eventType, otherSystemManagerMouseListener, 2458 true, request.priority, request.useWeakReference); 2459 if (getSandboxRoot() == this) 2460 { 2461 if (isTopLevelRoot() && 2462 (actualType == MouseEvent.MOUSE_UP || actualType == MouseEvent.MOUSE_MOVE)) 2463 { 2464 stage.addEventListener(actualType, eventProxy.marshalListener, 2465 false, request.priority, request.useWeakReference); 2466 } 2467 2468 super.addEventListener(actualType, eventProxy.marshalListener, 2469 true, request.priority, request.useWeakReference); 2470 } 2471 } 2472 } 2473 else if (event.type == EventListenerRequest.REMOVE_EVENT_LISTENER_REQUEST) 2474 { 2475 actualType = EventUtil.sandboxMouseEventMap[request.eventType]; 2476 if (actualType) 2477 { 2478 removeEventListenerFromOtherSystemManagers(request.eventType, otherSystemManagerMouseListener, true); 2479 removeEventListenerFromSandboxes(request.eventType, sandboxMouseListener, 2480 true, event.target as IEventDispatcher); 2481 if (getSandboxRoot() == this) 2482 { 2483 if (isTopLevelRoot() && 2484 (actualType == MouseEvent.MOUSE_UP || actualType == MouseEvent.MOUSE_MOVE)) 2485 { 2486 stage.removeEventListener(actualType, eventProxy.marshalListener); 2487 } 2488 // Remove both listeners in case the system manager was added 2489 // or removed from the stage after the listener was added. 2490 super.removeEventListener(actualType, eventProxy.marshalListener, true); 2491 } 2492 } 2493 } 2494 } 2495 2496 /** 2497 * @private 2498 * 2499 * This is a stub to satisfy the IFlexModuleFactory interface. 2500 * 2501 * Calls Security.allowDomain() for the SWF associated with this SystemManager 2502 * plus all the SWFs assocatiated with RSLs preloaded by this SystemManager. 2503 * 2504 */ 2505 public function allowDomain(... domains):void 2506 { 2507 } 2508 2509 /** 2510 * @private 2511 * 2512 * This is a stub to satisfy the IFlexModuleFactory interface. 2513 * 2514 * Calls Security.allowInsecureDomain() for the SWF associated with this SystemManager 2515 * plus all the SWFs assocatiated with RSLs preloaded by this SystemManager. 2516 * 2517 */ 2518 public function allowInsecureDomain(... domains):void 2519 { 2520 } 2521 2522 /** 2523 * Returns <code>true</code> if the given DisplayObject is the 2524 * top-level window. 2525 * 2526 * @param object 2527 * 2528 * @return <code>true</code> if the given DisplayObject is the 2529 * top-level window. 2530 */ 2531 public function isTopLevelWindow(object:DisplayObject):Boolean 2532 { 2533 return object is IUIComponent && 2534 IUIComponent(object) == topLevelWindow; 2535 } 2536 2537 /** 2538 * @inheritDoc 2539 */ 2540 public function getDefinitionByName(name:String):Object 2541 { 2542 var domain:ApplicationDomain = ApplicationDomain.currentDomain; 2543 /* !topLevel && parent is Loader ? 2544 Loader(parent).contentLoaderInfo.applicationDomain : 2545 info()["currentDomain"] as ApplicationDomain; 2546*/ 2547 //trace("SysMgr.getDefinitionByName domain",domain,"currentDomain",info()["currentDomain"]); 2548 2549 var definition:Object; 2550 2551 if (domain.hasDefinition(name)) 2552 { 2553 definition = domain.getDefinition(name); 2554 //trace("SysMgr.getDefinitionByName got definition",definition,"name",name); 2555 } 2556 2557 return definition; 2558 } 2559 2560 /** 2561 * @inheritDoc 2562 */ 2563 public function isTopLevel():Boolean 2564 { 2565 return topLevel; 2566 } 2567 2568 /** 2569 * @inheritDoc 2570 */ 2571 public function isFontFaceEmbedded(textFormat:TextFormat):Boolean 2572 { 2573 var fontName:String = textFormat.font; 2574 2575 var fl:Array = Font.enumerateFonts(); 2576 for (var f:int = 0; f < fl.length; ++f) 2577 { 2578 var font:Font = Font(fl[f]); 2579 if (font.fontName == fontName) 2580 { 2581 var style:String = "regular"; 2582 if (textFormat.bold && textFormat.italic) 2583 style = "boldItalic"; 2584 else if (textFormat.bold) 2585 style = "bold"; 2586 else if (textFormat.italic) 2587 style = "italic"; 2588 2589 if (font.fontStyle == style) 2590 return true; 2591 } 2592 } 2593 2594 if (!fontName || 2595 !embeddedFontList || 2596 !embeddedFontList[fontName]) 2597 { 2598 return false; 2599 } 2600 2601 var info:Object = embeddedFontList[fontName]; 2602 2603 return !((textFormat.bold && !info.bold) || 2604 (textFormat.italic && !info.italic) || 2605 (!textFormat.bold && !textFormat.italic && 2606 !info.regular)); 2607 } 2608 2609 2610 /** 2611 * @private 2612 * Keep track of the size and position of the stage. 2613 */ 2614 private function Stage_resizeHandler(event:Event = null):void 2615 { 2616 var w:Number = stage.stageWidth; 2617 var h:Number = stage.stageHeight; 2618 2619 var y:Number = 0; 2620 var x:Number = 0; 2621 2622 if (!_screen) 2623 _screen = new Rectangle(); 2624 _screen.x = x; 2625 _screen.y = y; 2626 _screen.width = w; 2627 _screen.height = h; 2628 2629 2630 _width = stage.stageWidth; 2631 _height = stage.stageHeight; 2632 2633//trace(_width, event.type); 2634 if (event) 2635 { 2636 resizeMouseCatcher(); 2637 dispatchEvent(event); 2638 } 2639 } 2640 2641 /** 2642 * @private 2643 * Track mouse clicks to see if we change top-level forms. 2644 */ 2645 private function mouseDownHandler(event:MouseEvent):void 2646 { 2647 // Reset the idle counter. 2648 idleCounter = 0; 2649 2650 // If an object was clicked that is inside another system manager 2651 // in a bridged application, activate the current document because 2652 // the bridge application is considered part of the main application. 2653 // We also see mouse clicks on dialogs popped up from compatible applications. 2654 if (isDisplayObjectInABridgedApplication(event.target as DisplayObject)) 2655 { 2656 // trace("SM:mouseDownHandler click in a bridged application"); 2657 if (isTopLevelRoot()) 2658 activateForm(document); 2659 else 2660 dispatchActivatedApplicationEvent(); 2661 2662 return; 2663 } 2664 2665 if (numModalWindows == 0) // no modal windows are up 2666 { 2667 // Activate a window if we need to. 2668 if (forms.length > 1) 2669 { 2670 var n:int = forms.length; 2671 var p:DisplayObject = DisplayObject(event.target); 2672 var isApplication:Boolean = document.rawChildren.contains(p); 2673 while (p) 2674 { 2675 for (var i:int = 0; i < n; i++) 2676 { 2677 var form_i:Object = isRemotePopUp(forms[i]) ? forms[i].window : forms[i]; 2678 if (form_i == p) 2679 { 2680 var j:int = 0; 2681 var index:int; 2682 var newIndex:int; 2683 var childList:IChildList; 2684 2685 if (p != form && p is IFocusManagerContainer) 2686 activate(IFocusManagerContainer(p)); 2687 if (popUpChildren.contains(p)) 2688 childList = popUpChildren; 2689 else 2690 childList = this; 2691 2692 index = childList.getChildIndex(p); 2693 newIndex = index; 2694 2695 //we need to reset n because activating p's 2696 //FocusManager could have caused 2697 //forms.length to have changed. 2698 n = forms.length; 2699 for (j = 0; j < n; j++) 2700 { 2701 var f:DisplayObject; 2702 var isRemotePopUp:Boolean = isRemotePopUp(forms[j]); 2703 if (isRemotePopUp) 2704 { 2705 if (forms[j].window is String) 2706 continue; 2707 f = forms[j].window; 2708 } 2709 else 2710 f = forms[j]; 2711 if (isRemotePopUp) 2712 { 2713 var fChildIndex:int = getChildListIndex(childList, f); 2714 if (fChildIndex > index) 2715 newIndex = Math.max(fChildIndex, newIndex); 2716 } 2717 else if (childList.contains(f)) 2718 if (childList.getChildIndex(f) > index) 2719 newIndex = Math.max(childList.getChildIndex(f), newIndex); 2720 } 2721 if (newIndex > index && !isApplication) 2722 childList.setChildIndex(p, newIndex); 2723 return; 2724 } 2725 } 2726 p = p.parent; 2727 } 2728 } 2729 } 2730 } 2731 2732 /** 2733 * @private 2734 * 2735 * Get the index of an object in a given child list. 2736 * 2737 * @return index of f in childList, -1 if f is not in childList. 2738 */ 2739 private static function getChildListIndex(childList:IChildList, f:Object):int 2740 { 2741 var index:int = -1; 2742 try 2743 { 2744 index = childList.getChildIndex(DisplayObject(f)); 2745 } 2746 catch (e:ArgumentError) 2747 { 2748 // index has been preset to -1 so just continue. 2749 } 2750 2751 return index; 2752 } 2753 2754 /** 2755 * @private 2756 * Makes the mouseCatcher the same size as the stage, 2757 * filling it with transparent pixels. 2758 */ 2759 private function resizeMouseCatcher():void 2760 { 2761 if (mouseCatcher) 2762 { 2763 var g:Graphics = mouseCatcher.graphics; 2764 g.clear(); 2765 g.beginFill(0x000000, 0); 2766 g.drawRect(0, 0, stage.stageWidth, stage.stageHeight); 2767 g.endFill(); 2768 } 2769 } 2770 2771 /** 2772 * @private 2773 * 2774 * true if redipatching a resize event. 2775 */ 2776 private var isDispatchingResizeEvent:Boolean; 2777 2778 /** 2779 * @private 2780 * 2781 * Used to locate untrusted forms. Maps string ids to Objects. 2782 * The object make be the SystemManagerProxy of a form or it may be 2783 * the bridge to the child application where the object lives. 2784 */ 2785 private var idToPlaceholder:Object; 2786 2787 private var eventProxy:EventProxy; 2788 private var weakReferenceProxies:Dictionary = new Dictionary(true); 2789 private var strongReferenceProxies:Dictionary = new Dictionary(false); 2790 2791 //-------------------------------------------------------------------------- 2792 // 2793 // Overridden methods: EventDispatcher 2794 // 2795 //-------------------------------------------------------------------------- 2796 2797 /** 2798 * @private 2799 * Only create idle events if someone is listening. 2800 */ 2801 override public function addEventListener(type:String, listener:Function, 2802 useCapture:Boolean = false, 2803 priority:int = 0, 2804 useWeakReference:Boolean = false):void 2805 { 2806 // These two events will dispatched to applications in sandboxes. 2807 if (type == FlexEvent.RENDER || type == FlexEvent.ENTER_FRAME) 2808 { 2809 if (type == FlexEvent.RENDER) 2810 type = Event.RENDER; 2811 else 2812 type = Event.ENTER_FRAME; 2813 2814 try 2815 { 2816 if (stage) 2817 stage.addEventListener(type, listener, useCapture, priority, useWeakReference); 2818 else 2819 super.addEventListener(type, listener, useCapture, priority, useWeakReference); 2820 } 2821 catch (error:SecurityError) 2822 { 2823 super.addEventListener(type, listener, useCapture, priority, useWeakReference); 2824 } 2825 2826 if (stage && type == Event.RENDER) 2827 stage.invalidate(); 2828 2829 return; 2830 } 2831 2832 if (type == MouseEvent.MOUSE_MOVE || type == MouseEvent.MOUSE_UP || type == MouseEvent.MOUSE_DOWN 2833 || type == Event.ACTIVATE || type == Event.DEACTIVATE) 2834 { 2835 // also listen to stage if allowed 2836 try 2837 { 2838 if (stage) 2839 { 2840 // Use weak listener because we don't always know when we 2841 // no longer need this listener 2842 stage.addEventListener(type, stageEventHandler, false, 0, true); 2843 } 2844 } 2845 catch (error:SecurityError) 2846 { 2847 } 2848 } 2849 2850 if (hasSWFBridges() || SystemManagerGlobals.topLevelSystemManagers.length > 1) 2851 { 2852 if (!eventProxy) 2853 { 2854 eventProxy = new EventProxy(this); 2855 } 2856 2857 var actualType:String = EventUtil.sandboxMouseEventMap[type]; 2858 if (actualType) 2859 { 2860 if (isTopLevelRoot()) 2861 { 2862 stage.addEventListener(MouseEvent.MOUSE_MOVE, resetMouseCursorTracking, true, EventPriority.CURSOR_MANAGEMENT + 1, true); 2863 addEventListenerToSandboxes(SandboxMouseEvent.MOUSE_MOVE_SOMEWHERE, resetMouseCursorTracking, true, EventPriority.CURSOR_MANAGEMENT + 1, true); 2864 } 2865 else 2866 { 2867 super.addEventListener(MouseEvent.MOUSE_MOVE, resetMouseCursorTracking, true, EventPriority.CURSOR_MANAGEMENT + 1, true); 2868 } 2869 2870 addEventListenerToSandboxes(type, sandboxMouseListener, useCapture, priority, useWeakReference); 2871 if (!SystemManagerGlobals.changingListenersInOtherSystemManagers) 2872 addEventListenerToOtherSystemManagers(type, otherSystemManagerMouseListener, useCapture, priority, useWeakReference) 2873 if (getSandboxRoot() == this) 2874 { 2875 super.addEventListener(actualType, eventProxy.marshalListener, 2876 useCapture, priority, useWeakReference); 2877 if (actualType == MouseEvent.MOUSE_UP) 2878 { 2879 try 2880 { 2881 if (stage) 2882 stage.addEventListener(Event.MOUSE_LEAVE, eventProxy.marshalListener, 2883 useCapture, priority, useWeakReference); 2884 else 2885 super.addEventListener(Event.MOUSE_LEAVE, eventProxy.marshalListener, 2886 useCapture, priority, useWeakReference); 2887 } 2888 catch (e:SecurityError) 2889 { 2890 super.addEventListener(Event.MOUSE_LEAVE, eventProxy.marshalListener, 2891 useCapture, priority, useWeakReference); 2892 } 2893 } 2894 } 2895 2896 // Set useCapture to false because we will never see an event 2897 // marshalled in the capture phase. 2898 super.addEventListener(type, listener, false, priority, useWeakReference); 2899 return; 2900 } 2901 } 2902 2903 if (type == SandboxMouseEvent.MOUSE_UP_SOMEWHERE) 2904 { 2905 // If someone wants this event, also listen for mouseLeave. 2906 // Use weak listener because we don't always know when we 2907 // no longer need this listener 2908 try 2909 { 2910 if (stage) 2911 { 2912 stage.addEventListener(Event.MOUSE_LEAVE, mouseLeaveHandler, false, 0, true); 2913 } 2914 else 2915 { 2916 super.addEventListener(Event.MOUSE_LEAVE, mouseLeaveHandler, false, 0, true); 2917 } 2918 } 2919 catch (error:SecurityError) 2920 { 2921 super.addEventListener(Event.MOUSE_LEAVE, mouseLeaveHandler, false, 0, true); 2922 } 2923 } 2924 2925 super.addEventListener(type, listener, useCapture, priority, useWeakReference); 2926 } 2927 2928 /** 2929 * @private 2930 * 2931 * Test if this system manager has any sandbox bridges. 2932 * 2933 * @return true if there are sandbox bridges, false otherwise. 2934 */ 2935 private function hasSWFBridges():Boolean 2936 { 2937 if (swfBridgeGroup) 2938 return true; 2939 2940 return false; 2941 } 2942 2943 /** 2944 * @private 2945 */ 2946 override public function removeEventListener(type:String, listener:Function, 2947 useCapture:Boolean = false):void 2948 { 2949 // These two events will dispatched to applications in sandboxes. 2950 if (type == FlexEvent.RENDER || type == FlexEvent.ENTER_FRAME) 2951 { 2952 if (type == FlexEvent.RENDER) 2953 type = Event.RENDER; 2954 else 2955 type = Event.ENTER_FRAME; 2956 2957 try 2958 { 2959 if (stage) 2960 stage.removeEventListener(type, listener, useCapture); 2961 } 2962 catch (error:SecurityError) 2963 { 2964 } 2965 // Remove both listeners in case the system manager was added 2966 // or removed from the stage after the listener was added. 2967 super.removeEventListener(type, listener, useCapture); 2968 2969 return; 2970 } 2971 2972 2973 if (hasSWFBridges() || SystemManagerGlobals.topLevelSystemManagers.length > 1) 2974 { 2975 var actualType:String = EventUtil.sandboxMouseEventMap[type]; 2976 if (actualType) 2977 { 2978 if (getSandboxRoot() == this && eventProxy) 2979 { 2980 super.removeEventListener(actualType, eventProxy.marshalListener, 2981 useCapture); 2982 if (actualType == MouseEvent.MOUSE_UP) 2983 { 2984 try 2985 { 2986 if (stage) 2987 stage.removeEventListener(Event.MOUSE_LEAVE, eventProxy.marshalListener, 2988 useCapture); 2989 } 2990 catch (e:SecurityError) 2991 { 2992 } 2993 // Remove both listeners in case the system manager was added 2994 // or removed from the stage after the listener was added. 2995 super.removeEventListener(Event.MOUSE_LEAVE, eventProxy.marshalListener, 2996 useCapture); 2997 } 2998 } 2999 if (!SystemManagerGlobals.changingListenersInOtherSystemManagers) 3000 removeEventListenerFromOtherSystemManagers(type, otherSystemManagerMouseListener, useCapture); 3001 removeEventListenerFromSandboxes(type, sandboxMouseListener, useCapture); 3002 super.removeEventListener(type, listener, false); 3003 return; 3004 } 3005 } 3006 3007 super.removeEventListener(type, listener, useCapture); 3008 3009 if (type == MouseEvent.MOUSE_MOVE || type == MouseEvent.MOUSE_UP || type == MouseEvent.MOUSE_DOWN 3010 || type == Event.ACTIVATE || type == Event.DEACTIVATE) 3011 { 3012 if (!hasEventListener(type)) 3013 { 3014 // also listen to stage if allowed 3015 try 3016 { 3017 if (stage) 3018 { 3019 stage.removeEventListener(type, stageEventHandler, false); 3020 } 3021 } 3022 catch (error:SecurityError) 3023 { 3024 } 3025 } 3026 } 3027 3028 if (type == SandboxMouseEvent.MOUSE_UP_SOMEWHERE) 3029 { 3030 if (!hasEventListener(SandboxMouseEvent.MOUSE_UP_SOMEWHERE)) 3031 { 3032 // nobody wants this event any more for now 3033 try 3034 { 3035 if (stage) 3036 { 3037 stage.removeEventListener(Event.MOUSE_LEAVE, mouseLeaveHandler); 3038 } 3039 } 3040 catch (error:SecurityError) 3041 { 3042 } 3043 // Remove both listeners in case the system manager was added 3044 // or removed from the stage after the listener was added. 3045 super.removeEventListener(Event.MOUSE_LEAVE, mouseLeaveHandler); 3046 } 3047 } 3048 } 3049 3050 //-------------------------------------------------------------------------- 3051 // 3052 // Overridden methods: DisplayObjectContainer 3053 // 3054 //-------------------------------------------------------------------------- 3055 3056 /** 3057 * @private 3058 */ 3059 override public function addChild(child:DisplayObject):DisplayObject 3060 { 3061 // Adjust the partition indexes 3062 // before the "added" event is dispatched. 3063 noTopMostIndex++; 3064 3065 return rawChildren_addChildAt(child, noTopMostIndex - 1); 3066 } 3067 3068 //---------------------------------- 3069 // numChildren 3070 //---------------------------------- 3071 3072 /** 3073 * The number of non-floating windows. This is the main application window 3074 * plus any other windows added to the SystemManager that are not popups, 3075 * tooltips or cursors. 3076 */ 3077 override public function get numChildren():int 3078 { 3079 return noTopMostIndex - applicationIndex; 3080 } 3081 3082 /** 3083 * @private 3084 */ 3085 override public function addChildAt(child:DisplayObject, 3086 index:int):DisplayObject 3087 { 3088 // Adjust the partition indexes 3089 // before the "added" event is dispatched. 3090 noTopMostIndex++; 3091 3092 return rawChildren_addChildAt(child, applicationIndex + index); 3093 } 3094 3095 /** 3096 * @private 3097 */ 3098 override public function removeChild(child:DisplayObject):DisplayObject 3099 { 3100 // Adjust the partition indexes 3101 // before the "removed" event is dispatched. 3102 noTopMostIndex--; 3103 3104 return rawChildren_removeChild(child); 3105 } 3106 3107 /** 3108 * @private 3109 */ 3110 override public function removeChildAt(index:int):DisplayObject 3111 { 3112 // Adjust the partition indexes 3113 // before the "removed" event is dispatched. 3114 noTopMostIndex--; 3115 3116 return rawChildren_removeChildAt(applicationIndex + index); 3117 } 3118 3119 /** 3120 * @private 3121 */ 3122 override public function getChildAt(index:int):DisplayObject 3123 { 3124 return super.getChildAt(applicationIndex + index); 3125 } 3126 3127 /** 3128 * @private 3129 */ 3130 override public function getChildByName(name:String):DisplayObject 3131 { 3132 return super.getChildByName(name); 3133 } 3134 3135 /** 3136 * @private 3137 */ 3138 override public function getChildIndex(child:DisplayObject):int 3139 { 3140 return super.getChildIndex(child) - applicationIndex; 3141 } 3142 3143 /** 3144 * @private 3145 */ 3146 override public function setChildIndex(child:DisplayObject, newIndex:int):void 3147 { 3148 super.setChildIndex(child, applicationIndex + newIndex); 3149 } 3150 3151 /** 3152 * @private 3153 */ 3154 override public function getObjectsUnderPoint(point:Point):Array 3155 { 3156 var children:Array = []; 3157 3158 // Get all the children that aren't tooltips and cursors. 3159 var n:int = topMostIndex; 3160 for (var i:int = 0; i < n; i++) 3161 { 3162 var child:DisplayObject = super.getChildAt(i); 3163 if (child is DisplayObjectContainer) 3164 { 3165 var temp:Array = 3166 DisplayObjectContainer(child).getObjectsUnderPoint(point); 3167 3168 if (temp) 3169 children = children.concat(temp); 3170 } 3171 } 3172 3173 return children; 3174 } 3175 3176 //-------------------------------------------------------------------------- 3177 // 3178 // Methods: Child management 3179 // 3180 //-------------------------------------------------------------------------- 3181 3182 /** 3183 * @private 3184 */ 3185 mx_internal function addingChild(child:DisplayObject):void 3186 { 3187 var newNestLevel:int = 1; 3188 if (!topLevel) 3189 { 3190 // non-topLevel SystemManagers are buried by Flash.display.Loader and 3191 // other non-framework layers so we have to figure out the nestlevel 3192 // by searching up the parent chain. 3193 var obj:DisplayObjectContainer = parent.parent; 3194 while (obj) 3195 { 3196 if (obj is ILayoutManagerClient) 3197 { 3198 newNestLevel = ILayoutManagerClient(obj).nestLevel + 1; 3199 break; 3200 } 3201 obj = obj.parent; 3202 } 3203 } 3204 nestLevel = newNestLevel; 3205 3206 if (child is IUIComponent) 3207 IUIComponent(child).systemManager = this; 3208 3209 // Local variables for certain classes we need to check against below. 3210 // This is the backdoor way around linking in the class in question. 3211 var uiComponentClassName:Class = 3212 Class(getDefinitionByName("mx.core.UIComponent")); 3213 3214 // If the document property isn't already set on the child, 3215 // set it to be the same as this component's document. 3216 // The document setter will recursively set it on any 3217 // descendants of the child that exist. 3218 if (child is IUIComponent && 3219 !IUIComponent(child).document) 3220 { 3221 IUIComponent(child).document = document; 3222 } 3223 3224 // Set the nestLevel of the child to be one greater 3225 // than the nestLevel of this component. 3226 // The nestLevel setter will recursively set it on any 3227 // descendants of the child that exist. 3228 if (child is ILayoutManagerClient) 3229 ILayoutManagerClient(child).nestLevel = nestLevel + 1; 3230 3231 if (child is InteractiveObject) 3232 if (doubleClickEnabled) 3233 InteractiveObject(child).doubleClickEnabled = true; 3234 3235 if (child is IUIComponent) 3236 IUIComponent(child).parentChanged(this); 3237 3238 // Sets up the inheritingStyles and nonInheritingStyles objects 3239 // and their proto chains so that getStyle() works. 3240 // If this object already has some children, 3241 // then reinitialize the children's proto chains. 3242 if (child is IStyleClient) 3243 IStyleClient(child).regenerateStyleCache(true); 3244 3245 if (child is ISimpleStyleClient) 3246 ISimpleStyleClient(child).styleChanged(null); 3247 3248 if (child is IStyleClient) 3249 IStyleClient(child).notifyStyleChangeInChildren(null, true); 3250 3251 // Need to check to see if the child is an UIComponent 3252 // without actually linking in the UIComponent class. 3253 if (uiComponentClassName && child is uiComponentClassName) 3254 uiComponentClassName(child).initThemeColor(); 3255 3256 // Inform the component that it's style properties 3257 // have been fully initialized. Most components won't care, 3258 // but some need to react to even this early change. 3259 if (uiComponentClassName && child is uiComponentClassName) 3260 uiComponentClassName(child).stylesInitialized(); 3261 } 3262 3263 /** 3264 * @private 3265 */ 3266 mx_internal function childAdded(child:DisplayObject):void 3267 { 3268 child.dispatchEvent(new FlexEvent(FlexEvent.ADD)); 3269 3270 if (child is IUIComponent) 3271 IUIComponent(child).initialize(); // calls child.createChildren() 3272 } 3273 3274 /** 3275 * @private 3276 */ 3277 mx_internal function removingChild(child:DisplayObject):void 3278 { 3279 child.dispatchEvent(new FlexEvent(FlexEvent.REMOVE)); 3280 } 3281 3282 /** 3283 * @private 3284 */ 3285 mx_internal function childRemoved(child:DisplayObject):void 3286 { 3287 if (child is IUIComponent) 3288 IUIComponent(child).parentChanged(null); 3289 } 3290 3291 //-------------------------------------------------------------------------- 3292 // 3293 // Methods: Support for rawChildren access 3294 // 3295 //-------------------------------------------------------------------------- 3296 3297 /** 3298 * @private 3299 */ 3300 mx_internal function rawChildren_addChild(child:DisplayObject):DisplayObject 3301 { 3302 addingChild(child); 3303 3304 super.addChild(child); 3305 3306 childAdded(child); // calls child.createChildren() 3307 3308 return child; 3309 } 3310 3311 /** 3312 * @private 3313 */ 3314 mx_internal function rawChildren_addChildAt(child:DisplayObject, 3315 index:int):DisplayObject 3316 { 3317 addingChild(child); 3318 3319 super.addChildAt(child, index); 3320 3321 childAdded(child); // calls child.createChildren() 3322 3323 return child; 3324 } 3325 3326 /** 3327 * @private 3328 */ 3329 mx_internal function rawChildren_removeChild(child:DisplayObject):DisplayObject 3330 { 3331 removingChild(child); 3332 3333 super.removeChild(child); 3334 3335 childRemoved(child); 3336 3337 return child; 3338 } 3339 3340 /** 3341 * @private 3342 */ 3343 mx_internal function rawChildren_removeChildAt(index:int):DisplayObject 3344 { 3345 var child:DisplayObject = super.getChildAt(index); 3346 3347 removingChild(child); 3348 3349 super.removeChildAt(index); 3350 3351 childRemoved(child); 3352 3353 return child; 3354 } 3355 3356 /** 3357 * @private 3358 */ 3359 mx_internal function rawChildren_getChildAt(index:int):DisplayObject 3360 { 3361 return super.getChildAt(index); 3362 } 3363 3364 /** 3365 * @private 3366 */ 3367 mx_internal function rawChildren_getChildByName(name:String):DisplayObject 3368 { 3369 return super.getChildByName(name); 3370 } 3371 3372 /** 3373 * @private 3374 */ 3375 mx_internal function rawChildren_getChildIndex(child:DisplayObject):int 3376 { 3377 return super.getChildIndex(child); 3378 } 3379 3380 /** 3381 * @private 3382 */ 3383 mx_internal function rawChildren_setChildIndex(child:DisplayObject, newIndex:int):void 3384 { 3385 super.setChildIndex(child, newIndex); 3386 } 3387 3388 /** 3389 * @private 3390 */ 3391 mx_internal function rawChildren_getObjectsUnderPoint(pt:Point):Array 3392 { 3393 return super.getObjectsUnderPoint(pt); 3394 } 3395 3396 /** 3397 * @private 3398 */ 3399 mx_internal function rawChildren_contains(child:DisplayObject):Boolean 3400 { 3401 return super.contains(child); 3402 } 3403 3404 //-------------------------------------------------------------------------- 3405 // 3406 // Sandbox Event handlers for messages from children 3407 // 3408 //-------------------------------------------------------------------------- 3409 3410 /** 3411 * @private 3412 * 3413 * Add a popup request handler for domain local request and 3414 * remote domain requests. 3415 */ 3416 private function addPopupRequestHandler(event:Event):void 3417 { 3418 if (event.target != this && event is SWFBridgeRequest) 3419 return; 3420 3421 var popUpRequest:SWFBridgeRequest = SWFBridgeRequest.marshal(event); 3422 3423 // If there is not for mutual trust between us an the child that wants the 3424 // popup, then don't host the pop up. 3425 if (event.target != this) 3426 { 3427 var bridgeProvider:ISWFBridgeProvider = swfBridgeGroup.getChildBridgeProvider( 3428 IEventDispatcher(event.target)); 3429 if (!SecurityUtil.hasMutualTrustBetweenParentAndChild(bridgeProvider)) 3430 { 3431 return; 3432 } 3433 } 3434 3435 var topMost:Boolean; 3436 3437 // Need to have mutual trust between two application in order 3438 // for an application to host another application's popup. 3439 if (swfBridgeGroup.parentBridge && 3440 SecurityUtil.hasMutualTrustBetweenParentAndChild(this)) 3441 { 3442 // ask the parent to host the popup 3443 popUpRequest.requestor = swfBridgeGroup.parentBridge; 3444 getSandboxRoot().dispatchEvent(popUpRequest); 3445 return; 3446 } 3447 3448 // add popup as a child of this system manager 3449 if (!popUpRequest.data.childList || popUpRequest.data.childList == PopUpManagerChildList.PARENT) 3450 topMost = popUpRequest.data.parent && popUpChildren.contains(popUpRequest.data.parent); 3451 else 3452 topMost = (popUpRequest.data.childList == PopUpManagerChildList.POPUP); 3453 3454 var children:IChildList; 3455 children = topMost ? popUpChildren : this; 3456 children.addChild(DisplayObject(popUpRequest.data.window)); 3457 3458 if (popUpRequest.data.modal) 3459 numModalWindows++; 3460 3461 // add popup to the list of managed forms 3462 var remoteForm:RemotePopUp = new RemotePopUp(popUpRequest.data.window, popUpRequest.requestor); 3463 forms.push(remoteForm); 3464 3465 if (!isTopLevelRoot() && swfBridgeGroup) 3466 { 3467 // We've added the popup as far as it can go. 3468 // Add a placeholder to the top level root application 3469 var request:SWFBridgeRequest = new SWFBridgeRequest(SWFBridgeRequest.ADD_POP_UP_PLACE_HOLDER_REQUEST, 3470 false, false, 3471 popUpRequest.requestor, 3472 { window: popUpRequest.data.window }); 3473 request.data.placeHolderId = NameUtil.displayObjectToString(DisplayObject(popUpRequest.data.window)); 3474 dispatchEvent(request); 3475 } 3476 } 3477 3478 /** 3479 * @private 3480 * 3481 * Message from a child system manager to 3482 * remove the popup that was added by using the 3483 * addPopupRequestHandler. 3484 */ 3485 private function removePopupRequestHandler(event:Event):void 3486 { 3487 var popUpRequest:SWFBridgeRequest = SWFBridgeRequest.marshal(event); 3488 3489 if (swfBridgeGroup.parentBridge && 3490 SecurityUtil.hasMutualTrustBetweenParentAndChild(this)) 3491 { 3492 // since there is mutual trust the popup is hosted by the parent. 3493 popUpRequest.requestor = swfBridgeGroup.parentBridge; 3494 getSandboxRoot().dispatchEvent(popUpRequest); 3495 return; 3496 } 3497 3498 if (popUpChildren.contains(popUpRequest.data.window)) 3499 popUpChildren.removeChild(popUpRequest.data.window); 3500 else 3501 removeChild(DisplayObject(popUpRequest.data.window)); 3502 3503 if (popUpRequest.data.modal) 3504 numModalWindows--; 3505 3506 removeRemotePopUp(new RemotePopUp(popUpRequest.data.window, popUpRequest.requestor)); 3507 3508 if (!isTopLevelRoot() && swfBridgeGroup) 3509 { 3510 // if we got here we know the parent is untrusted, so remove placeholders 3511 var request:SWFBridgeRequest = new SWFBridgeRequest(SWFBridgeRequest.REMOVE_POP_UP_PLACE_HOLDER_REQUEST, 3512 false, false, 3513 popUpRequest.requestor, 3514 {placeHolderId: NameUtil.displayObjectToString(popUpRequest.data.window) 3515 }); 3516 dispatchEvent(request); 3517 } 3518 3519 } 3520 3521 /** 3522 * @private 3523 * 3524 * Handle request to add a popup placeholder. 3525 * The placeholder represents an untrusted form that is hosted 3526 * elsewhere. 3527 */ 3528 private function addPlaceholderPopupRequestHandler(event:Event):void 3529 { 3530 var popUpRequest:SWFBridgeRequest = SWFBridgeRequest.marshal(event); 3531 3532 if (event.target != this && event is SWFBridgeRequest) 3533 return; 3534 3535 if (!forwardPlaceholderRequest(popUpRequest, true)) 3536 { 3537 // Create a RemotePopUp and add it. 3538 var remoteForm:RemotePopUp = new RemotePopUp(popUpRequest.data.placeHolderId, popUpRequest.requestor); 3539 forms.push(remoteForm); 3540 } 3541 3542 } 3543 3544 /** 3545 * @private 3546 * 3547 * Handle request to add a popup placeholder. 3548 * The placeholder represents an untrusted form that is hosted 3549 * elsewhere. 3550 */ 3551 private function removePlaceholderPopupRequestHandler(event:Event):void 3552 { 3553 var popUpRequest:SWFBridgeRequest = SWFBridgeRequest.marshal(event); 3554 3555 if (!forwardPlaceholderRequest(popUpRequest, false)) 3556 { 3557 // remove the placeholder from forms array 3558 var n:int = forms.length; 3559 for (var i:int = 0; i < n; i++) 3560 { 3561 if (isRemotePopUp(forms[i])) 3562 { 3563 if (forms[i].window == popUpRequest.data.placeHolderId && 3564 forms[i].bridge == popUpRequest.requestor) 3565 { 3566 forms.splice(i, 1); 3567 break; 3568 } 3569 } 3570 } 3571 } 3572 3573 } 3574 3575 /** 3576 * Forward a form event update the parent chain. 3577 * Takes care of removing object references and substituting 3578 * ids when an untrusted boundry is crossed. 3579 */ 3580 private function forwardFormEvent(event:SWFBridgeEvent):Boolean 3581 { 3582 3583 if (isTopLevelRoot()) 3584 return false; 3585 3586 var bridge:IEventDispatcher = swfBridgeGroup.parentBridge; 3587 if (bridge) 3588 { 3589 var sbRoot:DisplayObject = getSandboxRoot(); 3590 event.data.notifier = bridge; 3591 if (sbRoot == this) 3592 { 3593 if (!(event.data.window is String)) 3594 event.data.window = NameUtil.displayObjectToString(DisplayObject(event.data.window)); 3595 else 3596 event.data.window = NameUtil.displayObjectToString(DisplayObject(this)) + "." + event.data.window; 3597 3598 bridge.dispatchEvent(event); 3599 } 3600 else 3601 { 3602 if (event.data.window is String) 3603 event.data.window = NameUtil.displayObjectToString(DisplayObject(this)) + "." + event.data.window; 3604 3605 sbRoot.dispatchEvent(event); 3606 } 3607 } 3608 3609 return true; 3610 } 3611 3612 /** 3613 * Forward an AddPlaceholder request up the parent chain, if needed. 3614 * 3615 * @param eObj PopupRequest as and Object. 3616 * @param addPlaceholder true if adding a placeholder, false it removing a placeholder. 3617 * @return true if the request was forwared, false otherwise 3618 */ 3619 private function forwardPlaceholderRequest(request:SWFBridgeRequest, addPlaceholder:Boolean):Boolean 3620 { 3621 // Only the top level root tracks the placeholders. 3622 // If we are not the top level root then keep passing 3623 // the message up the parent chain. 3624 if (isTopLevelRoot()) 3625 return false; 3626 3627 // If the window object is passed, then this is the first 3628 // stop on the way up the parent chain. 3629 var refObj:Object = null; 3630 var oldId:String = null; 3631 if (request.data.window) 3632 { 3633 refObj = request.data.window; 3634 3635 // null this ref out so untrusted parent cannot see 3636 request.data.window = null; 3637 } 3638 else 3639 { 3640 refObj = request.requestor; 3641 3642 // prefix the existing id with the id of this object 3643 oldId = request.data.placeHolderId; 3644 request.data.placeHolderId = NameUtil.displayObjectToString(this) + "." + request.data.placeHolderId; 3645 } 3646 3647 if (addPlaceholder) 3648 addPlaceholderId(request.data.placeHolderId, oldId, request.requestor, refObj); 3649 else 3650 removePlaceholderId(request.data.placeHolderId); 3651 3652 3653 var sbRoot:DisplayObject = getSandboxRoot(); 3654 var bridge:IEventDispatcher = swfBridgeGroup.parentBridge; 3655 request.requestor = bridge; 3656 if (sbRoot == this) 3657 bridge.dispatchEvent(request); 3658 else 3659 sbRoot.dispatchEvent(request); 3660 3661 return true; 3662 } 3663 3664 /** 3665 * One of the system managers in another sandbox deactivated and sent a message 3666 * to the top level system manager. In response the top-level system manager 3667 * needs to find a new form to activate. 3668 */ 3669 private function deactivateFormSandboxEventHandler(event:Event):void 3670 { 3671 // trace("bridgeDeactivateFormEventHandler"); 3672 3673 if (event is SWFBridgeRequest) 3674 return; 3675 3676 var bridgeEvent:SWFBridgeEvent = SWFBridgeEvent.marshal(event); 3677 3678 if (!forwardFormEvent(bridgeEvent)) 3679 { 3680 // deactivate the form 3681 if (isRemotePopUp(form) && 3682 RemotePopUp(form).window == bridgeEvent.data.window && 3683 RemotePopUp(form).bridge == bridgeEvent.data.notifier) 3684 deactivateForm(form); 3685 } 3686 } 3687 3688 /** 3689 * A form in one of the system managers in another sandbox has been activated. 3690 * The form being activate is identified. 3691 * In response the top-level system manager needs to activate the given form 3692 * and deactivate the currently active form, if any. 3693 */ 3694 private function activateFormSandboxEventHandler(event:Event):void 3695 { 3696 // trace("bridgeActivateFormEventHandler"); 3697 var bridgeEvent:SWFBridgeEvent = SWFBridgeEvent.marshal(event); 3698 3699 if (!forwardFormEvent(bridgeEvent)) 3700 // just call activate on the remote form. 3701 activateForm(new RemotePopUp(bridgeEvent.data.window, bridgeEvent.data.notifier)); 3702 } 3703 3704 /** 3705 * One of the system managers in another sandbox activated and sent a message 3706 * to the top level system manager to deactivate this form. In response the top-level system manager 3707 * needs to deactivate all other forms except the top level system manager's. 3708 */ 3709 private function activateApplicationSandboxEventHandler(event:Event):void 3710 { 3711 // trace("bridgeActivateApplicationEventHandler"); 3712 if (!isTopLevelRoot()) 3713 { 3714 swfBridgeGroup.parentBridge.dispatchEvent(event); 3715 return; 3716 } 3717 3718 // An application was activated, active the main document. 3719 activateForm(document); 3720 } 3721 3722 3723 /** 3724 * @private 3725 * 3726 * Re-dispatch events sent over the bridge to listeners on this 3727 * system manager. PopUpManager is expected to listen to these 3728 * events. 3729 */ 3730 private function modalWindowRequestHandler(event:Event):void 3731 { 3732 if (event is SWFBridgeRequest) 3733 return; 3734 3735 var request:SWFBridgeRequest = SWFBridgeRequest.marshal(event); 3736 3737 if (!preProcessModalWindowRequest(request, getSandboxRoot())) 3738 return; 3739 3740 // Ensure a PopUpManager exists and dispatch the request it is 3741 // listening for. 3742 Singleton.getInstance("mx.managers::IPopUpManager"); 3743 dispatchEvent(request); 3744 } 3745 3746 /** 3747 * @private 3748 * 3749 * Calculate the visible rectangle of the requesting application in this 3750 * application. Forward the request to our parent to see this the rectangle 3751 * is further reduced. Continue up the parent chain until the top level 3752 * root parent is reached. 3753 */ 3754 private function getVisibleRectRequestHandler(event:Event):void 3755 { 3756 if (event is SWFBridgeRequest) 3757 return; 3758 3759 var request:SWFBridgeRequest = SWFBridgeRequest.marshal(event); 3760 var rect:Rectangle = Rectangle(request.data); 3761 var owner:DisplayObject = DisplayObject(swfBridgeGroup.getChildBridgeProvider(request.requestor)); 3762 var localRect:Rectangle; 3763 var forwardRequest:Boolean = true; 3764 3765 // Check if the request in a pop up. If it is then don't 3766 // forward the request to our parent because we don't want 3767 // to reduce the visible rect of the dialog base on the 3768 // visible rect of applications in the main app. 3769 if (!DisplayObjectContainer(document).contains(owner)) 3770 forwardRequest = false; 3771 3772 if (owner is ISWFLoader) 3773 localRect = ISWFLoader(owner).getVisibleApplicationRect(); 3774 else 3775 { 3776 localRect = owner.getBounds(this); 3777 var pt:Point = localToGlobal(localRect.topLeft); 3778 localRect.x = pt.x; 3779 localRect.y = pt.y; 3780 } 3781 3782 rect = rect.intersection(localRect); // update rect 3783 request.data = rect; 3784 3785 // forward request 3786 if (forwardRequest && useSWFBridge()) 3787 { 3788 var bridge:IEventDispatcher = swfBridgeGroup.parentBridge; 3789 request.requestor = bridge; 3790 bridge.dispatchEvent(request); 3791 } 3792 3793 Object(event).data = request.data; // update request 3794 } 3795 3796 /** 3797 * @private 3798 * 3799 * Notify the topLevelRoot that we don't want the mouseCursor shown 3800 * Forward upward if necessary. 3801 */ 3802 private function hideMouseCursorRequestHandler(event:Event):void 3803 { 3804 if (!isTopLevelRoot() && event is SWFBridgeRequest) 3805 return; 3806 3807 var request:SWFBridgeRequest = SWFBridgeRequest.marshal(event); 3808 3809 // forward request 3810 if (!isTopLevelRoot()) 3811 { 3812 var bridge:IEventDispatcher = swfBridgeGroup.parentBridge; 3813 request.requestor = bridge; 3814 bridge.dispatchEvent(request); 3815 } 3816 else if (eventProxy) 3817 SystemManagerGlobals.showMouseCursor = false; 3818 } 3819 3820 /** 3821 * @private 3822 * 3823 * Ask the topLevelRoot if anybody don't want the mouseCursor shown 3824 * Forward upward if necessary. 3825 */ 3826 private function showMouseCursorRequestHandler(event:Event):void 3827 { 3828 if (!isTopLevelRoot() && event is SWFBridgeRequest) 3829 return; 3830 3831 var request:SWFBridgeRequest = SWFBridgeRequest.marshal(event); 3832 3833 // forward request 3834 if (!isTopLevelRoot()) 3835 { 3836 var bridge:IEventDispatcher = swfBridgeGroup.parentBridge; 3837 request.requestor = bridge; 3838 bridge.dispatchEvent(request); 3839 Object(event).data = request.data; // update request 3840 } 3841 else if (eventProxy) 3842 Object(event).data = SystemManagerGlobals.showMouseCursor; 3843 3844 } 3845 3846 /** 3847 * @private 3848 * 3849 * Ask the topLevelRoot if anybody don't want the mouseCursor shown 3850 * Forward upward if necessary. 3851 */ 3852 private function resetMouseCursorRequestHandler(event:Event):void 3853 { 3854 if (!isTopLevelRoot() && event is SWFBridgeRequest) 3855 return; 3856 3857 var request:SWFBridgeRequest = SWFBridgeRequest.marshal(event); 3858 3859 // forward request 3860 if (!isTopLevelRoot()) 3861 { 3862 var bridge:IEventDispatcher = swfBridgeGroup.parentBridge; 3863 request.requestor = bridge; 3864 bridge.dispatchEvent(request); 3865 } 3866 else if (eventProxy) 3867 SystemManagerGlobals.showMouseCursor = true; 3868 3869 } 3870 3871 private function resetMouseCursorTracking(event:Event):void 3872 { 3873 if (isTopLevelRoot()) 3874 { 3875 SystemManagerGlobals.showMouseCursor = true; 3876 } 3877 else if (swfBridgeGroup.parentBridge) 3878 { 3879 var cursorRequest:SWFBridgeRequest = new SWFBridgeRequest(SWFBridgeRequest.RESET_MOUSE_CURSOR_REQUEST); 3880 var bridge:IEventDispatcher = swfBridgeGroup.parentBridge; 3881 cursorRequest.requestor = bridge; 3882 bridge.dispatchEvent(cursorRequest); 3883 } 3884 3885 } 3886 3887 //-------------------------------------------------------------------------- 3888 // 3889 // Sandbox Event handlers for messages from parent 3890 // 3891 //-------------------------------------------------------------------------- 3892 3893 /** 3894 * @private 3895 * 3896 * Sent by the SWFLoader to change the size of the application it loaded. 3897 */ 3898 private function setActualSizeRequestHandler(event:Event):void 3899 { 3900 // empty. This should never be the root of a SWF 3901 } 3902 3903 /** 3904 * @private 3905 * 3906 * Get the size of this System Manager. 3907 * Sent by a SWFLoader. 3908 */ 3909 private function getSizeRequestHandler(event:Event):void 3910 { 3911 // empty. This should never be the root of a SWF 3912 } 3913 3914 /** 3915 * @private 3916 * 3917 * Handle request to activate a particular form. 3918 * 3919 */ 3920 private function activateRequestHandler(event:Event):void 3921 { 3922 var request:SWFBridgeRequest = SWFBridgeRequest.marshal(event); 3923 3924 // If data is a String, then we need to parse the id to find 3925 // the form or the next bridge to pass the message to. 3926 // If the data is a SystemMangerProxy we can just activate the 3927 // form. 3928 var child:Object = request.data; 3929 var nextId:String = null; 3930 if (request.data is String) 3931 { 3932 var placeholder:PlaceholderData = idToPlaceholder[request.data]; 3933 child = placeholder.data; 3934 nextId = placeholder.id; 3935 3936 // check if the dialog is hosted on this system manager 3937 if (nextId == null) 3938 { 3939 var popUp:RemotePopUp = findRemotePopUp(child, placeholder.bridge); 3940 3941 if (popUp) 3942 { 3943 activateRemotePopUp(popUp); 3944 return; 3945 } 3946 } 3947 } 3948 3949 if (child is SystemManagerProxy) 3950 { 3951 // activate request from the top-level system manager. 3952 var smp:SystemManagerProxy = SystemManagerProxy(child); 3953 var f:IFocusManagerContainer = findFocusManagerContainer(smp); 3954 if (smp && f) 3955 smp.activateByProxy(f); 3956 } 3957 else if (child is IFocusManagerContainer) 3958 IFocusManagerContainer(child).focusManager.activate(); 3959 else if (child is IEventDispatcher) 3960 { 3961 request.data = nextId; 3962 request.requestor = IEventDispatcher(child); 3963 IEventDispatcher(child).dispatchEvent(request); 3964 } 3965 else 3966 throw new Error(); // should never get here 3967 } 3968 3969 /** 3970 * @private 3971 * 3972 * Handle request to deactivate a particular form. 3973 * 3974 */ 3975 private function deactivateRequestHandler(event:Event):void 3976 { 3977 var request:SWFBridgeRequest = SWFBridgeRequest.marshal(event); 3978 var child:Object = request.data; 3979 var nextId:String = null; 3980 if (request.data is String) 3981 { 3982 var placeholder:PlaceholderData = idToPlaceholder[request.data]; 3983 child = placeholder.data; 3984 nextId = placeholder.id; 3985 3986 // check if the dialog is hosted on this system manager 3987 if (nextId == null) 3988 { 3989 var popUp:RemotePopUp = findRemotePopUp(child, placeholder.bridge); 3990 3991 if (popUp) 3992 { 3993 deactivateRemotePopUp(popUp); 3994 return; 3995 } 3996 } 3997 } 3998 3999 if (child is SystemManagerProxy) 4000 { 4001 // deactivate request from the top-level system manager. 4002 var smp:SystemManagerProxy = SystemManagerProxy(child); 4003 var f:IFocusManagerContainer = findFocusManagerContainer(smp); 4004 if (smp && f) 4005 smp.deactivateByProxy(f); 4006 } 4007 else if (child is IFocusManagerContainer) 4008 IFocusManagerContainer(child).focusManager.deactivate(); 4009 4010 else if (child is IEventDispatcher) 4011 { 4012 request.data = nextId; 4013 request.requestor = IEventDispatcher(child); 4014 IEventDispatcher(child).dispatchEvent(request); 4015 return; 4016 } 4017 else 4018 throw new Error(); 4019 } 4020 4021 //-------------------------------------------------------------------------- 4022 // 4023 // Sandbox Event handlers for messages from either the 4024 // parent or child 4025 // 4026 //-------------------------------------------------------------------------- 4027 4028 /** 4029 * Is the child in event.data this system manager or a child of this 4030 * system manager? 4031 * 4032 * Set the data property to indicate if the display object is a child 4033 */ 4034 private function isBridgeChildHandler(event:Event):void 4035 { 4036 // if we are broadcasting messages, ignore the messages 4037 // we send to ourselves. 4038 if (event is SWFBridgeRequest) 4039 return; 4040 4041 var eObj:Object = Object(event); 4042 4043 eObj.data = eObj.data && rawChildren.contains(eObj.data as DisplayObject); 4044 } 4045 4046 /** 4047 * Can this form be activated. The current test is if the given pop up 4048 * is visible and is enabled. 4049 * 4050 * Set the data property to indicate if can be activated 4051 */ 4052 private function canActivateHandler(event:Event):void 4053 { 4054 var eObj:Object = Object(event); 4055 4056 // If data is a String, then we need to parse the id to find 4057 // the form or the next bridge to pass the message to. 4058 // If the data is a SystemMangerProxy we can just activate the 4059 // form. 4060 var request:SWFBridgeRequest; 4061 var child:Object = eObj.data; 4062 var nextId:String = null; 4063 if (eObj.data is String) 4064 { 4065 var placeholder:PlaceholderData = idToPlaceholder[eObj.data]; 4066 child = placeholder.data; 4067 nextId = placeholder.id; 4068 4069 // check if the dialog is hosted on this system manager 4070 if (nextId == null) 4071 { 4072 var popUp:RemotePopUp = findRemotePopUp(child, placeholder.bridge); 4073 4074 if (popUp) 4075 { 4076 request = new SWFBridgeRequest(SWFBridgeRequest.CAN_ACTIVATE_POP_UP_REQUEST, 4077 false, false, 4078 IEventDispatcher(popUp.bridge), 4079 popUp.window); 4080 if (popUp.bridge) 4081 { 4082 popUp.bridge.dispatchEvent(request); 4083 eObj.data = request.data; 4084 } 4085 return; 4086 } 4087 } 4088 } 4089 4090 if (child is SystemManagerProxy) 4091 { 4092 var smp:SystemManagerProxy = SystemManagerProxy(child); 4093 var f:IFocusManagerContainer = findFocusManagerContainer(smp); 4094 eObj.data = smp && f && canActivateLocalComponent(f); 4095 } 4096 else if (child is IFocusManagerContainer) 4097 { 4098 eObj.data = canActivateLocalComponent(child); 4099 } 4100 else if (child is IEventDispatcher) 4101 { 4102 var bridge:IEventDispatcher = IEventDispatcher(child); 4103 request = new SWFBridgeRequest(SWFBridgeRequest.CAN_ACTIVATE_POP_UP_REQUEST, 4104 false, false, 4105 bridge, 4106 nextId); 4107 4108 if (bridge) 4109 { 4110 bridge.dispatchEvent(request); 4111 eObj.data = request.data; 4112 } 4113 } 4114 else 4115 throw new Error(); // should never get here 4116 } 4117 4118 /** 4119 * @private 4120 * 4121 * Test if a display object is in an applcation we want to communicate with over a bridge. 4122 * 4123 */ 4124 public function isDisplayObjectInABridgedApplication(displayObject:DisplayObject):Boolean 4125 { 4126 if (swfBridgeGroup) 4127 { 4128 var request:SWFBridgeRequest = new SWFBridgeRequest(SWFBridgeRequest.IS_BRIDGE_CHILD_REQUEST, 4129 false, false, null, displayObject); 4130 var children:Array = swfBridgeGroup.getChildBridges(); 4131 var n:int = children.length; 4132 for (var i:int = 0; i < n; i++) 4133 { 4134 var childBridge:IEventDispatcher = IEventDispatcher(children[i]); 4135 4136 // No need to test a child if it does not trust us, we will never see 4137 // their display objects. 4138 // Also, if the we don't trust the child don't send them a display object. 4139 var bp:ISWFBridgeProvider = swfBridgeGroup.getChildBridgeProvider(childBridge); 4140 if (SecurityUtil.hasMutualTrustBetweenParentAndChild(bp)) 4141 { 4142 childBridge.dispatchEvent(request); 4143 if (request.data == true) 4144 return true; 4145 4146 // reset data property 4147 request.data = displayObject; 4148 } 4149 } 4150 } 4151 4152 return false; 4153 } 4154 4155 /** 4156 * redispatch certian events to other top-level windows 4157 */ 4158 private function multiWindowRedispatcher(event:Event):void 4159 { 4160 if (!SystemManagerGlobals.dispatchingEventToOtherSystemManagers) 4161 { 4162 dispatchEventToOtherSystemManagers(event); 4163 } 4164 } 4165 4166 /** 4167 * Create the requested manager 4168 */ 4169 private function initManagerHandler(event:Event):void 4170 { 4171 if (!SystemManagerGlobals.dispatchingEventToOtherSystemManagers) 4172 { 4173 dispatchEventToOtherSystemManagers(event); 4174 } 4175 4176 // if we are broadcasting messages, ignore the messages 4177 // we send to ourselves. 4178 if (event is InterManagerRequest) 4179 return; 4180 4181 // initialize the registered manager implementation 4182 var name:String = event["name"]; 4183 try 4184 { 4185 Singleton.getInstance(name); 4186 } 4187 catch (e:Error) 4188 { 4189 } 4190 } 4191 4192 /** 4193 * Add child to requested childList 4194 */ 4195 public function addChildToSandboxRoot(layer:String, child:DisplayObject):void 4196 { 4197 if (getSandboxRoot() == this) 4198 { 4199 this[layer].addChild(child); 4200 } 4201 else 4202 { 4203 addingChild(child); 4204 var me:InterManagerRequest = new InterManagerRequest(InterManagerRequest.SYSTEM_MANAGER_REQUEST); 4205 me.name = layer + ".addChild"; 4206 me.value = child; 4207 getSandboxRoot().dispatchEvent(me); 4208 childAdded(child); 4209 } 4210 } 4211 4212 /** 4213 * Remove child from requested childList 4214 */ 4215 public function removeChildFromSandboxRoot(layer:String, child:DisplayObject):void 4216 { 4217 if (getSandboxRoot() == this) 4218 { 4219 this[layer].removeChild(child); 4220 } 4221 else 4222 { 4223 removingChild(child); 4224 var me:InterManagerRequest = new InterManagerRequest(InterManagerRequest.SYSTEM_MANAGER_REQUEST); 4225 me.name = layer + ".removeChild"; 4226 me.value = child; 4227 getSandboxRoot().dispatchEvent(me); 4228 childRemoved(child); 4229 } 4230 } 4231 4232 4233 /** 4234 * perform the requested action from a trusted dispatcher 4235 */ 4236 private function systemManagerHandler(event:Event):void 4237 { 4238 if (event["name"] == "sameSandbox") 4239 { 4240 event["value"] = currentSandboxEvent == event["value"]; 4241 return; 4242 } 4243 else if (event["name"] == "hasSWFBridges") 4244 { 4245 event["value"] = hasSWFBridges(); 4246 return; 4247 } 4248 4249 // if we are broadcasting messages, ignore the messages 4250 // we send to ourselves. 4251 if (event is InterManagerRequest) 4252 return; 4253 4254 // initialize the registered manager implementation 4255 var name:String = event["name"]; 4256 4257 switch (name) 4258 { 4259 case "popUpChildren.addChild": 4260 popUpChildren.addChild(event["value"]); 4261 break; 4262 case "popUpChildren.removeChild": 4263 popUpChildren.removeChild(event["value"]); 4264 break; 4265 case "cursorChildren.addChild": 4266 cursorChildren.addChild(event["value"]); 4267 break; 4268 case "cursorChildren.removeChild": 4269 cursorChildren.removeChild(event["value"]); 4270 break; 4271 case "toolTipChildren.addChild": 4272 toolTipChildren.addChild(event["value"]); 4273 break; 4274 case "toolTipChildren.removeChild": 4275 toolTipChildren.removeChild(event["value"]); 4276 break; 4277 case "screen": 4278 event["value"] = screen; 4279 break; 4280 case "application": 4281 event["value"] = document; 4282 break; 4283 case "isTopLevelRoot": 4284 event["value"] = isTopLevelRoot(); 4285 break; 4286 case "getVisibleApplicationRect": 4287 event["value"] = getVisibleApplicationRect(); 4288 break; 4289 case "bringToFront": 4290 if (event["value"].topMost) 4291 popUpChildren.setChildIndex(DisplayObject(event["value"].popUp), popUpChildren.numChildren - 1); 4292 else 4293 setChildIndex(DisplayObject(event["value"].popUp), numChildren - 1); 4294 4295 break; 4296 } 4297 } 4298 4299 // fake out mouseX/mouseY 4300 mx_internal var _mouseX:*; 4301 mx_internal var _mouseY:*; 4302 4303 4304 /** 4305 * @private 4306 */ 4307 override public function get mouseX():Number 4308 { 4309 if (_mouseX === undefined) 4310 return super.mouseX; 4311 return _mouseX; 4312 } 4313 4314 /** 4315 * @private 4316 */ 4317 override public function get mouseY():Number 4318 { 4319 if (_mouseY === undefined) 4320 return super.mouseY; 4321 return _mouseY; 4322 } 4323 4324 /** 4325 * Return the object the player sees as having focus. 4326 * 4327 * @return An object of type InteractiveObject that the 4328 * player sees as having focus. If focus is currently 4329 * in a sandbox the caller does not have access to 4330 * null will be returned. 4331 */ 4332 public function getFocus():InteractiveObject 4333 { 4334 try 4335 { 4336 return stage.focus; 4337 } 4338 catch (e:SecurityError) 4339 { 4340 // trace("SM getFocus(): ignoring security error " + e); 4341 } 4342 4343 return null; 4344 } 4345 4346 /** 4347 * @private 4348 * Cleans up references to Window. Also removes self from topLevelSystemManagers list. 4349 */ 4350 mx_internal function cleanup(e:Event):void 4351 { 4352 if (Singleton.getClass("mx.managers::IDragManager").getInstance() 4353 is NativeDragManagerImpl) 4354 NativeDragManagerImpl(Singleton.getClass("mx.managers::IDragManager").getInstance()).unregisterSystemManager(this); 4355 SystemManagerGlobals.topLevelSystemManagers.splice(SystemManagerGlobals.topLevelSystemManagers.indexOf(this), 1); 4356 myWindow.nativeWindow.removeEventListener(Event.CLOSE, cleanup); 4357 myWindow = null; 4358 } 4359 4360 /** 4361 * @private 4362 * only registers Window for later cleanup. 4363 */ 4364 mx_internal function addWindow(win:Window):void 4365 { 4366 myWindow = win; 4367 myWindow.nativeWindow.addEventListener("close", cleanup); 4368 } 4369 4370 /** 4371 * @private 4372 * dispatch certain stage events from sandbox root 4373 */ 4374 private function stageEventHandler(event:Event):void 4375 { 4376 if (event.target is Stage) 4377 mouseCatcher.dispatchEvent(event); 4378 } 4379 4380 /** 4381 * @private 4382 * convert MOUSE_LEAVE to MOUSE_UP_SOMEWHERE 4383 */ 4384 private function mouseLeaveHandler(event:Event):void 4385 { 4386 dispatchEvent(new SandboxMouseEvent(SandboxMouseEvent.MOUSE_UP_SOMEWHERE)); 4387 } 4388 4389} 4390} 4391