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