forked from mozilla/gecko-dev
-
Notifications
You must be signed in to change notification settings - Fork 2
/
nsGlobalWindow.h
1092 lines (883 loc) · 37.3 KB
/
nsGlobalWindow.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 sw=2 et tw=80: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Travis Bogard <travis@netscape.com>
* Dan Rosen <dr@netscape.com>
* Vidur Apparao <vidur@netscape.com>
* Johnny Stenback <jst@netscape.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsGlobalWindow_h___
#define nsGlobalWindow_h___
#include "mozilla/XPCOM.h" // for TimeStamp/TimeDuration
// Local Includes
// Helper Classes
#include "nsCOMPtr.h"
#include "nsAutoPtr.h"
#include "nsWeakReference.h"
#include "nsHashtable.h"
#include "nsDataHashtable.h"
#include "nsCycleCollectionParticipant.h"
#include "nsDOMScriptObjectHolder.h"
// Interfaces Needed
#include "nsDOMWindowList.h"
#include "nsIBaseWindow.h"
#include "nsIBrowserDOMWindow.h"
#include "nsIDocShellTreeOwner.h"
#include "nsIDocShellTreeItem.h"
#include "nsIDOMClientInformation.h"
#include "nsIDOMEventTarget.h"
#include "nsIDOMNavigator.h"
#include "nsIDOMNavigatorGeolocation.h"
#include "nsIDOMNavigatorDesktopNotification.h"
#include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIDOMJSWindow.h"
#include "nsIDOMChromeWindow.h"
#include "nsIScriptGlobalObject.h"
#include "nsIScriptContext.h"
#include "nsIScriptObjectPrincipal.h"
#include "nsIScriptTimeoutHandler.h"
#include "nsITimer.h"
#include "nsIWebBrowserChrome.h"
#include "nsPIDOMWindow.h"
#include "nsIDOMModalContentWindow.h"
#include "nsIScriptSecurityManager.h"
#include "nsEventListenerManager.h"
#include "nsIDOMDocument.h"
#ifndef MOZ_DISABLE_DOMCRYPTO
#include "nsIDOMCrypto.h"
#endif
#include "nsIPrincipal.h"
#include "nsPluginArray.h"
#include "nsMimeTypeArray.h"
#include "nsIXPCScriptable.h"
#include "nsPoint.h"
#include "nsSize.h"
#include "nsRect.h"
#include "mozFlushType.h"
#include "prclist.h"
#include "nsIDOMStorageObsolete.h"
#include "nsIDOMStorageList.h"
#include "nsIDOMStorageEvent.h"
#include "nsIDOMStorageIndexedDB.h"
#include "nsIDOMOfflineResourceList.h"
#include "nsIArray.h"
#include "nsIContent.h"
#include "nsIIDBFactory.h"
#include "nsFrameMessageManager.h"
#include "mozilla/TimeStamp.h"
// JS includes
#include "jsapi.h"
#include "jswrapper.h"
#define DEFAULT_HOME_PAGE "www.mozilla.org"
#define PREF_BROWSER_STARTUP_HOMEPAGE "browser.startup.homepage"
// Amount of time allowed between alert/prompt/confirm before enabling
// the stop dialog checkbox.
#define SUCCESSIVE_DIALOG_TIME_LIMIT 3 // 3 sec
// During click or mousedown events (and others, see nsDOMEvent) we allow modal
// dialogs up to this limit, even if they were disabled.
#define MAX_DIALOG_COUNT 10
class nsIDOMBarProp;
class nsIDocument;
class nsPresContext;
class nsIDOMEvent;
class nsIScrollableFrame;
class nsIControllers;
class nsBarProp;
class nsLocation;
class nsNavigator;
class nsScreen;
class nsHistory;
class nsPerformance;
class nsIDocShellLoadInfo;
class WindowStateHolder;
class nsGlobalWindowObserver;
class nsGlobalWindow;
class nsDummyJavaPluginOwner;
class PostMessageEvent;
class nsRunnable;
class nsDOMOfflineResourceList;
class nsGeolocation;
class nsDesktopNotificationCenter;
class nsDOMMozURLProperty;
#ifdef MOZ_DISABLE_DOMCRYPTO
class nsIDOMCrypto;
#endif
extern nsresult
NS_CreateJSTimeoutHandler(nsGlobalWindow *aWindow,
PRBool *aIsInterval,
PRInt32 *aInterval,
nsIScriptTimeoutHandler **aRet);
/*
* Timeout struct that holds information about each script
* timeout. Holds a strong reference to an nsIScriptTimeoutHandler, which
* abstracts the language specific cruft.
*/
struct nsTimeout : PRCList
{
nsTimeout();
~nsTimeout();
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(nsTimeout)
nsrefcnt Release();
nsrefcnt AddRef();
nsTimeout* Next() {
// Note: might not actually return an nsTimeout. Use IsTimeout to check.
return static_cast<nsTimeout*>(PR_NEXT_LINK(this));
}
nsTimeout* Prev() {
// Note: might not actually return an nsTimeout. Use IsTimeout to check.
return static_cast<nsTimeout*>(PR_PREV_LINK(this));
}
// Window for which this timeout fires
nsRefPtr<nsGlobalWindow> mWindow;
// The actual timer object
nsCOMPtr<nsITimer> mTimer;
// True if the timeout was cleared
PRPackedBool mCleared;
// True if this is one of the timeouts that are currently running
PRPackedBool mRunning;
// True if this is a repeating/interval timer
PRPackedBool mIsInterval;
// Returned as value of setTimeout()
PRUint32 mPublicId;
// Interval in milliseconds
PRUint32 mInterval;
// mWhen and mTimeRemaining can't be in a union, sadly, because they
// have constructors.
// Nominal time to run this timeout. Use only when timeouts are not
// suspended.
mozilla::TimeStamp mWhen;
// Remaining time to wait. Used only when timeouts are suspended.
mozilla::TimeDuration mTimeRemaining;
// Principal with which to execute
nsCOMPtr<nsIPrincipal> mPrincipal;
// stack depth at which timeout is firing
PRUint32 mFiringDepth;
//
PRUint32 mNestingLevel;
// The popup state at timeout creation time if not created from
// another timeout
PopupControlState mPopupState;
// The language-specific information about the callback.
nsCOMPtr<nsIScriptTimeoutHandler> mScriptHandler;
private:
// reference count for shared usage
nsAutoRefCnt mRefCnt;
};
//*****************************************************************************
// nsOuterWindow: Outer Window Proxy
//*****************************************************************************
class nsOuterWindowProxy : public JSWrapper
{
public:
nsOuterWindowProxy() : JSWrapper((uintN)0) {}
virtual bool isOuterWindow() {
return true;
}
JSString *obj_toString(JSContext *cx, JSObject *wrapper);
static nsOuterWindowProxy singleton;
};
JSObject *NS_NewOuterWindowProxy(JSContext *cx, JSObject *parent);
//*****************************************************************************
// nsGlobalWindow: Global Object for Scripting
//*****************************************************************************
// Beware that all scriptable interfaces implemented by
// nsGlobalWindow will be reachable from JS, if you make this class
// implement new interfaces you better know what you're
// doing. Security wise this is very sensitive code. --
// jst@netscape.com
// nsGlobalWindow inherits PRCList for maintaining a list of all inner
// windows still in memory for any given outer window. This list is
// needed to ensure that mOuterWindow doesn't end up dangling. The
// nature of PRCList means that the window itself is always in the
// list, and an outer window's list will also contain all inner window
// objects that are still in memory (and in reality all inner window
// object's lists also contain its outer and all other inner windows
// belonging to the same outer window, but that's an unimportant
// side effect of inheriting PRCList).
class nsGlobalWindow : public nsPIDOMWindow,
public nsIScriptGlobalObject,
public nsIDOMJSWindow,
public nsIScriptObjectPrincipal,
public nsIDOMEventTarget,
public nsIDOMStorageIndexedDB,
public nsSupportsWeakReference,
public nsIInterfaceRequestor,
public nsWrapperCache,
public PRCListStr,
public nsIDOMWindowPerformance
{
public:
friend class nsDOMMozURLProperty;
typedef mozilla::TimeStamp TimeStamp;
typedef mozilla::TimeDuration TimeDuration;
typedef nsDataHashtable<nsUint64HashKey, nsGlobalWindow*> WindowByIdTable;
// public methods
nsPIDOMWindow* GetPrivateParent();
// callback for close event
void ReallyCloseWindow();
// nsISupports
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
// nsIScriptGlobalObject
virtual nsIScriptContext *GetContext();
virtual JSObject *GetGlobalJSObject();
JSObject *FastGetGlobalJSObject()
{
return mJSObject;
}
virtual nsresult EnsureScriptEnvironment(PRUint32 aLangID);
virtual nsIScriptContext *GetScriptContext(PRUint32 lang);
virtual void *GetScriptGlobal(PRUint32 lang);
// Set a new script language context for this global. The native global
// for the context is created by the context's GetNativeGlobal() method.
virtual nsresult SetScriptContext(PRUint32 lang, nsIScriptContext *aContext);
virtual void OnFinalize(JSObject* aObject);
virtual void SetScriptsEnabled(PRBool aEnabled, PRBool aFireTimeouts);
// nsIScriptObjectPrincipal
virtual nsIPrincipal* GetPrincipal();
// nsIDOMWindow
NS_DECL_NSIDOMWINDOW
// nsIDOMWindowPerformance
NS_DECL_NSIDOMWINDOWPERFORMANCE
// nsIDOMJSWindow
NS_DECL_NSIDOMJSWINDOW
// nsIDOMEventTarget
NS_DECL_NSIDOMEVENTTARGET
// nsPIDOMWindow
virtual NS_HIDDEN_(nsPIDOMWindow*) GetPrivateRoot();
virtual NS_HIDDEN_(void) ActivateOrDeactivate(PRBool aActivate);
virtual NS_HIDDEN_(void) SetActive(PRBool aActive);
virtual NS_HIDDEN_(void) SetIsBackground(PRBool aIsBackground);
virtual NS_HIDDEN_(void) SetChromeEventHandler(nsIDOMEventTarget* aChromeEventHandler);
virtual NS_HIDDEN_(void) SetOpenerScriptPrincipal(nsIPrincipal* aPrincipal);
virtual NS_HIDDEN_(nsIPrincipal*) GetOpenerScriptPrincipal();
virtual NS_HIDDEN_(PopupControlState) PushPopupControlState(PopupControlState state, PRBool aForce) const;
virtual NS_HIDDEN_(void) PopPopupControlState(PopupControlState state) const;
virtual NS_HIDDEN_(PopupControlState) GetPopupControlState() const;
virtual NS_HIDDEN_(nsresult) SaveWindowState(nsISupports **aState);
virtual NS_HIDDEN_(nsresult) RestoreWindowState(nsISupports *aState);
virtual NS_HIDDEN_(void) SuspendTimeouts(PRUint32 aIncrease = 1,
PRBool aFreezeChildren = PR_TRUE);
virtual NS_HIDDEN_(nsresult) ResumeTimeouts(PRBool aThawChildren = PR_TRUE);
virtual NS_HIDDEN_(PRUint32) TimeoutSuspendCount();
virtual NS_HIDDEN_(nsresult) FireDelayedDOMEvents();
virtual NS_HIDDEN_(PRBool) IsFrozen() const
{
return mIsFrozen;
}
virtual NS_HIDDEN_(PRBool) WouldReuseInnerWindow(nsIDocument *aNewDocument);
virtual NS_HIDDEN_(void) SetDocShell(nsIDocShell* aDocShell);
virtual NS_HIDDEN_(nsresult) SetNewDocument(nsIDocument *aDocument,
nsISupports *aState,
PRBool aForceReuseInnerWindow);
void DispatchDOMWindowCreated();
virtual NS_HIDDEN_(void) SetOpenerWindow(nsIDOMWindow* aOpener,
PRBool aOriginalOpener);
virtual NS_HIDDEN_(void) EnsureSizeUpToDate();
virtual NS_HIDDEN_(nsIDOMWindow*) EnterModalState();
virtual NS_HIDDEN_(void) LeaveModalState(nsIDOMWindow* aWindow);
virtual NS_HIDDEN_(PRBool) CanClose();
virtual NS_HIDDEN_(nsresult) ForceClose();
virtual NS_HIDDEN_(void) SetHasOrientationEventListener();
virtual NS_HIDDEN_(void) MaybeUpdateTouchState();
virtual NS_HIDDEN_(void) UpdateTouchState();
virtual NS_HIDDEN_(PRBool) DispatchCustomEvent(const char *aEventName);
// nsIDOMStorageIndexedDB
NS_DECL_NSIDOMSTORAGEINDEXEDDB
// nsIInterfaceRequestor
NS_DECL_NSIINTERFACEREQUESTOR
// Object Management
nsGlobalWindow(nsGlobalWindow *aOuterWindow);
static nsGlobalWindow *FromSupports(nsISupports *supports)
{
// Make sure this matches the casts we do in QueryInterface().
return (nsGlobalWindow *)(nsIScriptGlobalObject *)supports;
}
static nsISupports *ToSupports(nsGlobalWindow *win)
{
// Make sure this matches the casts we do in QueryInterface().
return (nsISupports *)(nsIScriptGlobalObject *)win;
}
static nsGlobalWindow *FromWrapper(nsIXPConnectWrappedNative *wrapper)
{
return FromSupports(wrapper->Native());
}
inline nsGlobalWindow *GetTop()
{
nsCOMPtr<nsIDOMWindow> top;
GetTop(getter_AddRefs(top));
if (top)
return static_cast<nsGlobalWindow *>(static_cast<nsIDOMWindow *>(top.get()));
return nsnull;
}
// Call this when a modal dialog is about to be opened. Returns
// true if we've reached the state in this top level window where we
// ask the user if further dialogs should be blocked.
bool DialogOpenAttempted();
// Returns true if dialogs have already been blocked for this
// window.
bool AreDialogsBlocked();
// Ask the user if further dialogs should be blocked. This is used
// in the cases where we have no modifiable UI to show, in that case
// we show a separate dialog when asking this question.
bool ConfirmDialogAllowed();
// Prevent further dialogs in this (top level) window
void PreventFurtherDialogs();
nsIScriptContext *GetContextInternal()
{
if (mOuterWindow) {
return GetOuterWindowInternal()->mContext;
}
return mContext;
}
nsIScriptContext *GetScriptContextInternal(PRUint32 aLangID)
{
NS_ASSERTION(aLangID == nsIProgrammingLanguage::JAVASCRIPT,
"We don't support this language ID");
if (mOuterWindow) {
return GetOuterWindowInternal()->mContext;
}
return mContext;
}
nsGlobalWindow *GetOuterWindowInternal()
{
return static_cast<nsGlobalWindow *>(GetOuterWindow());
}
nsGlobalWindow *GetCurrentInnerWindowInternal()
{
return static_cast<nsGlobalWindow *>(mInnerWindow);
}
nsGlobalWindow *EnsureInnerWindowInternal()
{
return static_cast<nsGlobalWindow *>(EnsureInnerWindow());
}
PRBool IsCreatingInnerWindow() const
{
return mCreatingInnerWindow;
}
PRBool IsChromeWindow() const
{
return mIsChrome;
}
nsresult Observe(nsISupports* aSubject, const char* aTopic,
const PRUnichar* aData);
static void ShutDown();
static void CleanupCachedXBLHandlers(nsGlobalWindow* aWindow);
static PRBool IsCallerChrome();
static void CloseBlockScriptTerminationFunc(nsISupports *aRef);
static void RunPendingTimeoutsRecursive(nsGlobalWindow *aTopWindow,
nsGlobalWindow *aWindow);
friend class WindowStateHolder;
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsGlobalWindow,
nsIScriptGlobalObject)
void InitJavaProperties();
virtual NS_HIDDEN_(void*)
GetCachedXBLPrototypeHandler(nsXBLPrototypeHandler* aKey);
virtual NS_HIDDEN_(void)
CacheXBLPrototypeHandler(nsXBLPrototypeHandler* aKey,
nsScriptObjectHolder& aHandler);
virtual PRBool TakeFocus(PRBool aFocus, PRUint32 aFocusMethod);
virtual void SetReadyForFocus();
virtual void PageHidden();
virtual nsresult DispatchAsyncHashchange(nsIURI *aOldURI, nsIURI *aNewURI);
virtual nsresult DispatchSyncPopState();
virtual nsresult SetArguments(nsIArray *aArguments, nsIPrincipal *aOrigin);
static PRBool DOMWindowDumpEnabled();
void MaybeForgiveSpamCount();
PRBool IsClosedOrClosing() {
return (mIsClosed ||
mInClose ||
mHavePendingClose ||
mCleanedUp);
}
static void FirePopupBlockedEvent(nsIDOMDocument* aDoc,
nsIDOMWindow *aRequestingWindow, nsIURI *aPopupURI,
const nsAString &aPopupWindowName,
const nsAString &aPopupWindowFeatures);
virtual PRUint32 GetSerial() {
return mSerial;
}
static nsGlobalWindow* GetOuterWindowWithId(PRUint64 aWindowID) {
nsGlobalWindow* outerWindow = sWindowsById->Get(aWindowID);
return outerWindow && !outerWindow->IsInnerWindow() ? outerWindow : nsnull;
}
static bool HasIndexedDBSupport();
static bool HasPerformanceSupport();
static WindowByIdTable* GetWindowsTable() {
return sWindowsById;
}
PRInt64 SizeOf() const;
private:
// Enable updates for the accelerometer.
void EnableDeviceMotionUpdates();
// Disables updates for the accelerometer.
void DisableDeviceMotionUpdates();
protected:
friend class HashchangeCallback;
friend class nsBarProp;
// Object Management
virtual ~nsGlobalWindow();
void CleanUp(PRBool aIgnoreModalDialog);
void ClearControllers();
static void TryClearWindowScope(nsISupports* aWindow);
void ClearScopeWhenAllScriptsStop();
nsresult FinalClose();
void FreeInnerObjects(PRBool aClearScope);
nsGlobalWindow *CallerInnerWindow();
nsresult InnerSetNewDocument(nsIDocument* aDocument);
nsresult DefineArgumentsProperty(nsIArray *aArguments);
// Get the parent, returns null if this is a toplevel window
nsIDOMWindow* GetParentInternal();
// popup tracking
PRBool IsPopupSpamWindow()
{
if (IsInnerWindow() && !mOuterWindow) {
return PR_FALSE;
}
return GetOuterWindowInternal()->mIsPopupSpam;
}
void SetPopupSpamWindow(PRBool aPopup)
{
if (IsInnerWindow() && !mOuterWindow) {
NS_ERROR("SetPopupSpamWindow() called on inner window w/o an outer!");
return;
}
GetOuterWindowInternal()->mIsPopupSpam = aPopup;
}
// Window Control Functions
/**
* @param aURL the URL to load in the new window
* @param aName the name to use for the new window
* @param aOptions the window options to use for the new window
* @param aDialog true when called from variants of OpenDialog. If this is
* true, this method will skip popup blocking checks. The
* aDialog argument is passed on to the window watcher.
* @param aCalledNoScript true when called via the [noscript] open()
* and openDialog() methods. When this is true, we do
* NOT want to use the JS stack for things like caller
* determination.
* @param aDoJSFixups true when this is the content-accessible JS version of
* window opening. When true, popups do not cause us to
* throw, we save the caller's principal in the new window
* for later consumption, and we make sure that there is a
* document in the newly-opened window. Note that this
* last will only be done if the newly-opened window is
* non-chrome.
* @param argv The arguments to pass to the new window. The first
* three args, if present, will be aURL, aName, and aOptions. So
* this param only matters if there are more than 3 arguments.
* @param argc The number of arguments in argv.
* @param aExtraArgument Another way to pass arguments in. This is mutually
* exclusive with the argv/argc approach.
* @param aJSCallerContext The calling script's context. This must be nsnull
* when aCalledNoScript is true.
* @param aReturn [out] The window that was opened, if any.
*
* @note that the boolean args are const because the function shouldn't be
* messing with them. That also makes it easier for the compiler to sort out
* its build warning stuff.
*/
NS_HIDDEN_(nsresult) OpenInternal(const nsAString& aUrl,
const nsAString& aName,
const nsAString& aOptions,
PRBool aDialog,
PRBool aContentModal,
PRBool aCalledNoScript,
PRBool aDoJSFixups,
nsIArray *argv,
nsISupports *aExtraArgument,
nsIPrincipal *aCalleePrincipal,
JSContext *aJSCallerContext,
nsIDOMWindow **aReturn);
static void CloseWindow(nsISupports* aWindow);
static void ClearWindowScope(nsISupports* aWindow);
// Timeout Functions
// Language agnostic timeout function (all args passed).
// |interval| is in milliseconds.
nsresult SetTimeoutOrInterval(nsIScriptTimeoutHandler *aHandler,
PRInt32 interval,
PRBool aIsInterval, PRInt32 *aReturn);
nsresult ClearTimeoutOrInterval(PRInt32 aTimerID);
// JS specific timeout functions (JS args grabbed from context).
nsresult SetTimeoutOrInterval(PRBool aIsInterval, PRInt32* aReturn);
nsresult ClearTimeoutOrInterval();
nsresult ResetTimersForNonBackgroundWindow();
// The timeout implementation functions.
void RunTimeout(nsTimeout *aTimeout);
void RunTimeout() { RunTimeout(nsnull); }
void ClearAllTimeouts();
// Insert aTimeout into the list, before all timeouts that would
// fire after it, but no earlier than mTimeoutInsertionPoint, if any.
void InsertTimeoutIntoList(nsTimeout *aTimeout);
static void TimerCallback(nsITimer *aTimer, void *aClosure);
// Helper Functions
nsresult GetTreeOwner(nsIDocShellTreeOwner** aTreeOwner);
nsresult GetTreeOwner(nsIBaseWindow** aTreeOwner);
nsresult GetWebBrowserChrome(nsIWebBrowserChrome** aBrowserChrome);
// GetScrollFrame does not flush. Callers should do it themselves as needed,
// depending on which info they actually want off the scrollable frame.
nsIScrollableFrame *GetScrollFrame();
nsresult SecurityCheckURL(const char *aURL);
nsresult BuildURIfromBase(const char *aURL,
nsIURI **aBuiltURI,
PRBool *aFreeSecurityPass, JSContext **aCXused);
PRBool PopupWhitelisted();
PopupControlState RevisePopupAbuseLevel(PopupControlState);
void FireAbuseEvents(PRBool aBlocked, PRBool aWindow,
const nsAString &aPopupURL,
const nsAString &aPopupWindowName,
const nsAString &aPopupWindowFeatures);
void FireOfflineStatusEvent();
nsresult FireHashchange(const nsAString &aOldURL, const nsAString &aNewURL);
void FlushPendingNotifications(mozFlushType aType);
void EnsureReflowFlushAndPaint();
nsresult CheckSecurityWidthAndHeight(PRInt32* width, PRInt32* height);
nsresult CheckSecurityLeftAndTop(PRInt32* left, PRInt32* top);
// Arguments to this function should have values in app units
nsresult SetCSSViewportWidthAndHeight(nscoord width, nscoord height);
// Arguments to this function should have values in device pixels
nsresult SetDocShellWidthAndHeight(PRInt32 width, PRInt32 height);
static PRBool CanSetProperty(const char *aPrefName);
static void MakeScriptDialogTitle(nsAString &aOutTitle);
PRBool CanMoveResizeWindows();
PRBool GetBlurSuppression();
// If aDoFlush is true, we'll flush our own layout; otherwise we'll try to
// just flush our parent and only flush ourselves if we think we need to.
nsresult GetScrollXY(PRInt32* aScrollX, PRInt32* aScrollY,
PRBool aDoFlush);
nsresult GetScrollMaxXY(PRInt32* aScrollMaxX, PRInt32* aScrollMaxY);
nsresult GetOuterSize(nsIntSize* aSizeCSSPixels);
nsresult SetOuterSize(PRInt32 aLengthCSSPixels, PRBool aIsWidth);
nsRect GetInnerScreenRect();
PRBool IsFrame()
{
return GetParentInternal() != nsnull;
}
// If aLookForCallerOnJSStack is true, this method will look at the JS stack
// to determine who the caller is. If it's false, it'll use |this| as the
// caller.
PRBool WindowExists(const nsAString& aName, PRBool aLookForCallerOnJSStack);
already_AddRefed<nsIWidget> GetMainWidget();
nsIWidget* GetNearestWidget();
void Freeze()
{
NS_ASSERTION(!IsFrozen(), "Double-freezing?");
mIsFrozen = PR_TRUE;
NotifyDOMWindowFrozen(this);
}
void Thaw()
{
mIsFrozen = PR_FALSE;
NotifyDOMWindowThawed(this);
}
PRBool IsInModalState();
nsTimeout* FirstTimeout() {
// Note: might not actually return an nsTimeout. Use IsTimeout to check.
return static_cast<nsTimeout*>(PR_LIST_HEAD(&mTimeouts));
}
nsTimeout* LastTimeout() {
// Note: might not actually return an nsTimeout. Use IsTimeout to check.
return static_cast<nsTimeout*>(PR_LIST_TAIL(&mTimeouts));
}
PRBool IsTimeout(PRCList* aList) {
return aList != &mTimeouts;
}
// Convenience functions for the many methods that need to scale
// from device to CSS pixels or vice versa. Note: if a presentation
// context is not available, they will assume a 1:1 ratio.
PRInt32 DevToCSSIntPixels(PRInt32 px);
PRInt32 CSSToDevIntPixels(PRInt32 px);
nsIntSize DevToCSSIntPixels(nsIntSize px);
nsIntSize CSSToDevIntPixels(nsIntSize px);
virtual void SetFocusedNode(nsIContent* aNode,
PRUint32 aFocusMethod = 0,
PRBool aNeedsFocus = PR_FALSE);
virtual PRUint32 GetFocusMethod();
virtual PRBool ShouldShowFocusRing();
virtual void SetKeyboardIndicators(UIStateChangeType aShowAccelerators,
UIStateChangeType aShowFocusRings);
virtual void GetKeyboardIndicators(PRBool* aShowAccelerators,
PRBool* aShowFocusRings);
void UpdateCanvasFocus(PRBool aFocusChanged, nsIContent* aNewContent);
already_AddRefed<nsPIWindowRoot> GetTopWindowRoot();
static void NotifyDOMWindowDestroyed(nsGlobalWindow* aWindow);
void NotifyWindowIDDestroyed(const char* aTopic);
static void NotifyDOMWindowFrozen(nsGlobalWindow* aWindow);
static void NotifyDOMWindowThawed(nsGlobalWindow* aWindow);
void ClearStatus();
virtual void UpdateParentTarget();
PRBool GetIsTabModalPromptAllowed();
inline PRInt32 DOMMinTimeoutValue() const;
// When adding new member variables, be careful not to create cycles
// through JavaScript. If there is any chance that a member variable
// could own objects that are implemented in JavaScript, then those
// objects will keep the global object (this object) alive. To prevent
// these cycles, ownership of such members must be released in
// |CleanUp| and |SetDocShell|.
// This member is also used on both inner and outer windows, but
// for slightly different purposes. On inner windows it means the
// inner window is held onto by session history and should not
// change. On outer windows it means that the window is in a state
// where we don't want to force creation of a new inner window since
// we're in the middle of doing just that.
PRPackedBool mIsFrozen : 1;
// True if the Java properties have been initialized on this
// window. Only used on inner windows.
PRPackedBool mDidInitJavaProperties : 1;
// These members are only used on outer window objects. Make sure
// you never set any of these on an inner object!
PRPackedBool mFullScreen : 1;
PRPackedBool mIsClosed : 1;
PRPackedBool mInClose : 1;
// mHavePendingClose means we've got a termination function set to
// close us when the JS stops executing or that we have a close
// event posted. If this is set, just ignore window.close() calls.
PRPackedBool mHavePendingClose : 1;
PRPackedBool mHadOriginalOpener : 1;
PRPackedBool mIsPopupSpam : 1;
// Indicates whether scripts are allowed to close this window.
PRPackedBool mBlockScriptedClosingFlag : 1;
// Track what sorts of events we need to fire when thawed
PRPackedBool mFireOfflineStatusChangeEventOnThaw : 1;
// Indicates whether we're in the middle of creating an initializing
// a new inner window object.
PRPackedBool mCreatingInnerWindow : 1;
// Fast way to tell if this is a chrome window (without having to QI).
PRPackedBool mIsChrome : 1;
// Hack to indicate whether a chrome window needs its message manager
// to be disconnected, since clean up code is shared in the global
// window superclass.
PRPackedBool mCleanMessageManager : 1;
// Indicates that the current document has never received a document focus
// event.
PRPackedBool mNeedsFocus : 1;
PRPackedBool mHasFocus : 1;
// whether to show keyboard accelerators
PRPackedBool mShowAccelerators : 1;
// whether to show focus rings
PRPackedBool mShowFocusRings : 1;
// when true, show focus rings for the current focused content only.
// This will be reset when another element is focused
PRPackedBool mShowFocusRingForContent : 1;
// true if tab navigation has occurred for this window. Focus rings
// should be displayed.
PRPackedBool mFocusByKeyOccurred : 1;
// Indicates whether this window is getting device motion change events
PRPackedBool mHasDeviceMotion : 1;
// whether we've sent the destroy notification for our window id
PRPackedBool mNotifiedIDDestroyed : 1;
nsCOMPtr<nsIScriptContext> mContext;
nsWeakPtr mOpener;
nsCOMPtr<nsIControllers> mControllers;
nsCOMPtr<nsIArray> mArguments;
nsCOMPtr<nsIArray> mArgumentsLast;
nsCOMPtr<nsIPrincipal> mArgumentsOrigin;
nsRefPtr<nsNavigator> mNavigator;
nsRefPtr<nsScreen> mScreen;
nsRefPtr<nsPerformance> mPerformance;
nsRefPtr<nsDOMWindowList> mFrames;
nsRefPtr<nsBarProp> mMenubar;
nsRefPtr<nsBarProp> mToolbar;
nsRefPtr<nsBarProp> mLocationbar;
nsRefPtr<nsBarProp> mPersonalbar;
nsRefPtr<nsBarProp> mStatusbar;
nsRefPtr<nsBarProp> mScrollbars;
nsCOMPtr<nsIWeakReference> mWindowUtils;
nsString mStatus;
nsString mDefaultStatus;
// index 0->language_id 1, so index MAX-1 == language_id MAX
nsGlobalWindowObserver* mObserver;
#ifndef MOZ_DISABLE_DOMCRYPTO
nsCOMPtr<nsIDOMCrypto> mCrypto;
#endif
nsCOMPtr<nsIDOMStorage> mLocalStorage;
nsCOMPtr<nsIDOMStorage> mSessionStorage;
nsCOMPtr<nsIXPConnectJSObjectHolder> mInnerWindowHolder;
nsCOMPtr<nsIPrincipal> mOpenerScriptPrincipal; // strong; used to determine
// whether to clear scope
// These member variable are used only on inner windows.
nsRefPtr<nsEventListenerManager> mListenerManager;
// mTimeouts is generally sorted by mWhen, unless mTimeoutInsertionPoint is
// non-null. In that case, the dummy timeout pointed to by
// mTimeoutInsertionPoint may have a later mWhen than some of the timeouts
// that come after it.
PRCList mTimeouts;
// If mTimeoutInsertionPoint is non-null, insertions should happen after it.
// This is a dummy timeout at the moment; if that ever changes, the logic in
// ResetTimersForNonBackgroundWindow needs to change.
nsTimeout* mTimeoutInsertionPoint;
PRUint32 mTimeoutPublicIdCounter;
PRUint32 mTimeoutFiringDepth;
nsRefPtr<nsLocation> mLocation;
nsRefPtr<nsHistory> mHistory;
// Holder of the dummy java plugin, used to expose window.java and
// window.packages.
nsRefPtr<nsDummyJavaPluginOwner> mDummyJavaPluginOwner;
// These member variables are used on both inner and the outer windows.
nsCOMPtr<nsIPrincipal> mDocumentPrincipal;
nsCOMPtr<nsIDocument> mDoc; // For fast access to principals
JSObject* mJSObject;
typedef nsCOMArray<nsIDOMStorageEvent> nsDOMStorageEventArray;
nsDOMStorageEventArray mPendingStorageEvents;
nsAutoPtr< nsDataHashtable<nsStringHashKey, PRBool> > mPendingStorageEventsObsolete;
PRUint32 mTimeoutsSuspendDepth;
// the method that was used to focus mFocusedNode
PRUint32 mFocusMethod;
PRUint32 mSerial;
#ifdef DEBUG
PRBool mSetOpenerWindowCalled;
nsCOMPtr<nsIURI> mLastOpenedURI;
#endif
PRBool mCleanedUp, mCallCleanUpAfterModalDialogCloses;
nsCOMPtr<nsIDOMOfflineResourceList> mApplicationCache;
nsDataHashtable<nsVoidPtrHashKey, void*> mCachedXBLPrototypeHandlers;
nsCOMPtr<nsIDocument> mSuspendedDoc;
nsCOMPtr<nsIIDBFactory> mIndexedDB;
// In the case of a "trusted" dialog (@see PopupControlState), we
// set this counter to ensure a max of MAX_DIALOG_LIMIT
PRUint32 mDialogAbuseCount;
// This holds the time when the last modal dialog was shown, if two
// dialogs are shown within CONCURRENT_DIALOG_TIME_LIMIT the
// checkbox is shown. In the case of ShowModalDialog another Confirm
// dialog will be shown, the result of the checkbox/confirm dialog
// will be stored in mDialogDisabled variable.
TimeStamp mLastDialogQuitTime;
PRPackedBool mDialogDisabled;
nsRefPtr<nsDOMMozURLProperty> mURLProperty;
friend class nsDOMScriptableHelper;
friend class nsDOMWindowUtils;
friend class PostMessageEvent;
static nsIDOMStorageList* sGlobalStorageList;
static WindowByIdTable* sWindowsById;
static bool sWarnedAboutWindowInternal;
};
/*
* nsGlobalChromeWindow inherits from nsGlobalWindow. It is the global
* object created for a Chrome Window only.
*/
class nsGlobalChromeWindow : public nsGlobalWindow,
public nsIDOMChromeWindow
{
public:
// nsISupports
NS_DECL_ISUPPORTS_INHERITED
// nsIDOMChromeWindow interface
NS_DECL_NSIDOMCHROMEWINDOW
nsGlobalChromeWindow(nsGlobalWindow *aOuterWindow)
: nsGlobalWindow(aOuterWindow)
{
mIsChrome = PR_TRUE;
mCleanMessageManager = PR_TRUE;
}
~nsGlobalChromeWindow()
{
NS_ABORT_IF_FALSE(mCleanMessageManager,
"chrome windows may always disconnect the msg manager");
if (mMessageManager) {
static_cast<nsFrameMessageManager *>(
mMessageManager.get())->Disconnect();