Bug Summary

File:root/firefox-clang/dom/base/nsGlobalWindowInner.cpp
Warning:line 2263, column 15
Value stored to 'blocklistPref' during its initialization is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -O2 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name nsGlobalWindowInner.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/dom/base -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/dom/base -resource-dir /usr/lib/llvm-23/lib/clang/23 -include /root/firefox-clang/config/gcc_hidden.h -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -D _GLIBCXX_ASSERTIONS=1 -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D MOZ_HAS_MOZGLUE -D MOZILLA_INTERNAL_API -D IMPL_LIBXUL -D MOZ_SUPPORT_LEAKCHECKING -D STATIC_EXPORTABLE_JS_API -I /root/firefox-clang/dom/base -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dom/base -I /root/firefox-clang/dom/battery -I /root/firefox-clang/dom/events -I /root/firefox-clang/dom/media -I /root/firefox-clang/dom/network -I /root/firefox-clang/caps -I /root/firefox-clang/docshell/base -I /root/firefox-clang/dom/base -I /root/firefox-clang/dom/file -I /root/firefox-clang/dom/geolocation -I /root/firefox-clang/dom/html -I /root/firefox-clang/dom/ipc -I /root/firefox-clang/dom/storage -I /root/firefox-clang/dom/svg -I /root/firefox-clang/dom/xml -I /root/firefox-clang/dom/xslt/xpath -I /root/firefox-clang/dom/xul -I /root/firefox-clang/extensions/spellcheck/src -I /root/firefox-clang/gfx/2d -I /root/firefox-clang/image -I /root/firefox-clang/js/xpconnect/loader -I /root/firefox-clang/js/xpconnect/src -I /root/firefox-clang/js/xpconnect/wrappers -I /root/firefox-clang/layout/base -I /root/firefox-clang/layout/forms -I /root/firefox-clang/layout/generic -I /root/firefox-clang/layout/style -I /root/firefox-clang/layout/xul -I /root/firefox-clang/netwerk/base -I /root/firefox-clang/netwerk/protocol/http -I /root/firefox-clang/netwerk/url-classifier -I /root/firefox-clang/parser/htmlparser -I /root/firefox-clang/security/manager/ssl -I /root/firefox-clang/third_party/xsimd/include -I /root/firefox-clang/widget -I /root/firefox-clang/xpcom/build -I /root/firefox-clang/xpcom/ds -I /root/firefox-clang/netwerk/sctp/datachannel -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/ipc/ipdl/_ipdlheaders -I /root/firefox-clang/ipc/chromium/src -I /root/firefox-clang/third_party/abseil-cpp -I /root/firefox-clang/toolkit/components/telemetry -I /root/firefox-clang/xpcom/base -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -I /usr/include/gtk-3.0/unix-print -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/cloudproviders -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/fribidi -I /usr/include/harfbuzz -I /usr/include/atk-1.0 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/glycin-2 -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/gio-unix-2.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/sysprof-6 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/x86_64-linux-gnu/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16/backward -internal-isystem /usr/lib/llvm-23/lib/clang/23/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-error=pessimizing-move -Wno-error=large-by-value-copy=128 -Wno-error=implicit-int-float-conversion -Wno-error=thread-safety-analysis -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-deprecated-anon-enum-enum-conversion -Wno-deprecated-enum-enum-conversion -Wno-inline-new-delete -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-vla-cxx-extension -Wno-unknown-warning-option -Wno-character-conversion -std=gnu++20 -fdeprecated-macro -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fno-implicit-modules -fskip-odr-check-in-gmf -fno-sized-deallocation -fno-aligned-allocation -fdiagnostics-absolute-paths -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -mllvm -dwarf-linkage-names=Abstract -faddrsig -fdwarf2-cfi-asm -o /tmp/scan-build-2026-09-01-224014-2642839-1 -x c++ /root/firefox-clang/dom/base/nsGlobalWindowInner.cpp
1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5#include "nsGlobalWindowInner.h"
6
7#include <inttypes.h>
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11
12#include <cstdint>
13#include <new>
14#include <utility>
15
16#include "AudioChannelService.h"
17#include "AutoplayPolicy.h"
18#include "Crypto.h"
19#include "MainThreadUtils.h"
20#include "Navigator.h"
21#include "PaintWorkletImpl.h"
22#include "SessionStorageCache.h"
23#include "Units.h"
24#include "VRManagerChild.h"
25#include "WindowDestroyedEvent.h"
26#include "WindowNamedPropertiesHandler.h"
27#include "js/ComparisonOperators.h"
28#include "js/CompilationAndEvaluation.h"
29#include "js/CompileOptions.h"
30#include "js/Id.h"
31#include "js/PropertyAndElement.h" // JS_DefineProperty, JS_GetProperty
32#include "js/PropertyDescriptor.h"
33#include "js/RealmOptions.h"
34#include "js/RootingAPI.h"
35#include "js/TypeDecls.h"
36#include "js/Value.h"
37#include "js/Warnings.h"
38#include "js/friend/PerformanceHint.h"
39#include "js/loader/LoadedScript.h"
40#include "js/shadow/String.h"
41#include "jsapi.h"
42#include "jsfriendapi.h"
43#include "mozIDOMWindow.h"
44#include "moz_external_vr.h"
45#include "mozilla/AlreadyAddRefed.h"
46#include "mozilla/AppShutdown.h"
47#include "mozilla/ArrayIterator.h"
48#include "mozilla/Attributes.h"
49#include "mozilla/BaseProfilerMarkersPrerequisites.h"
50#include "mozilla/BasicEvents.h"
51#include "mozilla/CallState.h"
52#include "mozilla/Components.h"
53#include "mozilla/CycleCollectedJSContext.h"
54#include "mozilla/DOMEventTargetHelper.h"
55#include "mozilla/ErrorResult.h"
56#include "mozilla/EventDispatcher.h"
57#include "mozilla/EventListenerManager.h"
58#include "mozilla/EventQueue.h"
59#include "mozilla/ExtensionPolicyService.h"
60#include "mozilla/FloatingPoint.h"
61#include "mozilla/FlushType.h"
62#include "mozilla/Likely.h"
63#include "mozilla/Logging.h"
64#include "mozilla/LookAndFeel.h"
65#include "mozilla/Maybe.h"
66#include "mozilla/OwningNonNull.h"
67#include "mozilla/PermissionDelegateHandler.h"
68#include "mozilla/Preferences.h"
69#include "mozilla/PresShell.h"
70#include "mozilla/ProcessHangMonitor.h"
71#include "mozilla/RefPtr.h"
72#include "mozilla/Result.h"
73#include "mozilla/ScrollContainerFrame.h"
74#include "mozilla/ScrollTypes.h"
75#include "mozilla/SizeOfState.h"
76#include "mozilla/SpinEventLoopUntil.h"
77#include "mozilla/Sprintf.h"
78#include "mozilla/StaticPrefs_browser.h"
79#include "mozilla/StaticPrefs_docshell.h"
80#include "mozilla/StaticPrefs_dom.h"
81#include "mozilla/StaticPrefs_extensions.h"
82#include "mozilla/StorageAccess.h"
83#include "mozilla/StoragePrincipalHelper.h"
84#include "mozilla/TelemetryHistogramEnums.h"
85#include "mozilla/ThrottledEventQueue.h"
86#include "mozilla/TimeStamp.h"
87#include "mozilla/UniquePtr.h"
88#include "mozilla/Utf16.h"
89#include "mozilla/dom/AudioContext.h"
90#include "mozilla/dom/AutoEntryScript.h"
91#include "mozilla/dom/BarProps.h"
92#include "mozilla/dom/BindingDeclarations.h"
93#include "mozilla/dom/BindingUtils.h"
94#include "mozilla/dom/BrowserChild.h"
95#include "mozilla/dom/BrowsingContext.h"
96#include "mozilla/dom/CSPEvalChecker.h"
97#include "mozilla/dom/CallbackDebuggerNotification.h"
98#include "mozilla/dom/ChromeMessageBroadcaster.h"
99#include "mozilla/dom/ClientInfo.h"
100#include "mozilla/dom/ClientManager.h"
101#include "mozilla/dom/ClientSource.h"
102#include "mozilla/dom/ClientState.h"
103#include "mozilla/dom/ClientsBinding.h"
104#include "mozilla/dom/CloseWatcher.h"
105#include "mozilla/dom/CloseWatcherManager.h"
106#include "mozilla/dom/Console.h"
107#include "mozilla/dom/ContentChild.h"
108#include "mozilla/dom/ContentFrameMessageManager.h"
109#include "mozilla/dom/ContentMediaController.h"
110#include "mozilla/dom/CookieStore.h"
111#include "mozilla/dom/Credential.h"
112#include "mozilla/dom/CustomElementRegistry.h"
113#include "mozilla/dom/DebuggerNotification.h"
114#include "mozilla/dom/DebuggerNotificationBinding.h"
115#include "mozilla/dom/DebuggerNotificationManager.h"
116#include "mozilla/dom/DocGroup.h"
117#include "mozilla/dom/Document.h"
118#include "mozilla/dom/DocumentInlines.h"
119#include "mozilla/dom/DocumentPictureInPicture.h"
120#include "mozilla/dom/Element.h"
121#include "mozilla/dom/Event.h"
122#include "mozilla/dom/EventTarget.h"
123#include "mozilla/dom/External.h"
124#include "mozilla/dom/Fetch.h"
125#include "mozilla/dom/Gamepad.h"
126#include "mozilla/dom/GamepadHandle.h"
127#include "mozilla/dom/GamepadManager.h"
128#include "mozilla/dom/HashChangeEvent.h"
129#include "mozilla/dom/HashChangeEventBinding.h"
130#include "mozilla/dom/IDBFactory.h"
131#include "mozilla/dom/IdleRequest.h"
132#include "mozilla/dom/ImageBitmap.h"
133#include "mozilla/dom/ImageBitmapSource.h"
134#include "mozilla/dom/IntlUtils.h"
135#include "mozilla/dom/JSExecutionUtils.h" // mozilla::dom::Compile, mozilla::dom::EvaluationExceptionToNSResult
136#include "mozilla/dom/LSObject.h"
137#include "mozilla/dom/LocalStorage.h"
138#include "mozilla/dom/LocalStorageCommon.h"
139#include "mozilla/dom/Location.h"
140#include "mozilla/dom/MediaDevices.h"
141#include "mozilla/dom/MediaKeys.h"
142#include "mozilla/dom/ModuleLoader.h"
143#include "mozilla/dom/Navigation.h"
144#include "mozilla/dom/NavigatorBinding.h"
145#include "mozilla/dom/Nullable.h"
146#include "mozilla/dom/PartitionedLocalStorage.h"
147#include "mozilla/dom/Performance.h"
148#include "mozilla/dom/PerformanceMainThread.h"
149#include "mozilla/dom/PolicyContainer.h"
150#include "mozilla/dom/PopStateEvent.h"
151#include "mozilla/dom/PopStateEventBinding.h"
152#include "mozilla/dom/PopupBlocker.h"
153#include "mozilla/dom/PrimitiveConversions.h"
154#include "mozilla/dom/Promise.h"
155#include "mozilla/dom/RootedDictionary.h"
156#include "mozilla/dom/ScriptLoader.h"
157#include "mozilla/dom/ScriptSettings.h"
158#include "mozilla/dom/ServiceWorker.h"
159#include "mozilla/dom/ServiceWorkerDescriptor.h"
160#include "mozilla/dom/ServiceWorkerRegistration.h"
161#include "mozilla/dom/SessionStorageManager.h"
162#include "mozilla/dom/SharedWorker.h"
163#include "mozilla/dom/Storage.h"
164#include "mozilla/dom/StorageEvent.h"
165#include "mozilla/dom/StorageEventBinding.h"
166#include "mozilla/dom/StorageNotifierService.h"
167#include "mozilla/dom/StorageUtils.h"
168#include "mozilla/dom/TabMessageTypes.h"
169#include "mozilla/dom/Timeout.h"
170#include "mozilla/dom/TimeoutHandler.h"
171#include "mozilla/dom/TimeoutManager.h"
172#include "mozilla/dom/ToJSValue.h"
173#include "mozilla/dom/TrustedTypePolicyFactory.h"
174#include "mozilla/dom/TrustedTypeUtils.h"
175#include "mozilla/dom/TrustedTypesConstants.h"
176#include "mozilla/dom/VRDisplay.h"
177#include "mozilla/dom/VRDisplayEvent.h"
178#include "mozilla/dom/VRDisplayEventBinding.h"
179#include "mozilla/dom/VREventObserver.h"
180#include "mozilla/dom/VisualViewport.h"
181#include "mozilla/dom/WebCompatBinding.h"
182#include "mozilla/dom/WebIDLGlobalNameHash.h"
183#include "mozilla/dom/WebIdentityHandler.h"
184#include "mozilla/dom/WebTaskSchedulerMainThread.h"
185#include "mozilla/dom/WindowBinding.h"
186#include "mozilla/dom/WindowContext.h"
187#include "mozilla/dom/WindowGlobalChild.h"
188#include "mozilla/dom/WindowOrWorkerGlobalScopeBinding.h"
189#include "mozilla/dom/WindowProxyHolder.h"
190#include "mozilla/dom/WorkerCommon.h"
191#include "mozilla/dom/Worklet.h"
192#include "mozilla/dom/XRPermissionRequest.h"
193#include "mozilla/dom/cache/CacheStorage.h"
194#include "mozilla/dom/cache/Types.h"
195#include "mozilla/extensions/WebExtensionPolicy.h"
196#include "mozilla/fallible.h"
197#include "mozilla/gfx/BasePoint.h"
198#include "mozilla/gfx/BaseRect.h"
199#include "mozilla/gfx/BaseSize.h"
200#include "mozilla/gfx/Rect.h"
201#include "mozilla/gfx/Types.h"
202#include "mozilla/glean/DomMetrics.h"
203#include "mozilla/glean/bindings/Glean.h"
204#include "mozilla/glean/bindings/GleanPings.h"
205#include "mozilla/intl/LocaleService.h"
206#include "mozilla/ipc/BackgroundUtils.h"
207#include "mozilla/ipc/PBackgroundSharedTypes.h"
208#include "mozilla/net/CookieJarSettings.h"
209#include "nsAtom.h"
210#include "nsBaseHashtable.h"
211#include "nsCCUncollectableMarker.h"
212#include "nsCOMPtr.h"
213#include "nsCRT.h"
214#include "nsCRTGlue.h"
215#include "nsCanvasFrame.h"
216#include "nsCheapSets.h"
217#include "nsContentUtils.h"
218#include "nsCoord.h"
219#include "nsCycleCollectionNoteChild.h"
220#include "nsCycleCollectionTraversalCallback.h"
221#include "nsDOMNavigationTiming.h"
222#include "nsDebug.h"
223#include "nsDeviceContext.h"
224#include "nsDocShell.h"
225#include "nsFocusManager.h"
226#include "nsFrameMessageManager.h"
227#include "nsGkAtoms.h"
228#include "nsGlobalWindowOuter.h"
229#include "nsHashKeys.h"
230#include "nsHistory.h"
231#include "nsIAddonPolicyService.h"
232#include "nsIArray.h"
233#include "nsIBrowserChild.h"
234#include "nsICancelableRunnable.h"
235#include "nsIChannel.h"
236#include "nsIClipboard.h"
237#include "nsIContentSecurityPolicy.h"
238#include "nsIControllers.h"
239#include "nsICookieJarSettings.h"
240#include "nsICookieService.h"
241#include "nsID.h"
242#include "nsIDOMStorageManager.h"
243#include "nsIDOMXULControlElement.h"
244#include "nsIDeviceSensors.h"
245#include "nsIDocShell.h"
246#include "nsIDocShellTreeItem.h"
247#include "nsIDocShellTreeOwner.h"
248#include "nsIDocumentLoader.h"
249#include "nsIDragService.h"
250#include "nsIFocusManager.h"
251#include "nsIFrame.h"
252#include "nsIGlobalObject.h"
253#include "nsIIOService.h"
254#include "nsIIdleRunnable.h"
255#include "nsIInterfaceRequestorUtils.h"
256#include "nsILoadContext.h"
257#include "nsILoadGroup.h"
258#include "nsILoadInfo.h"
259#include "nsINamed.h"
260#include "nsINode.h"
261#include "nsIObserver.h"
262#include "nsIObserverService.h"
263#include "nsIPermission.h"
264#include "nsIPermissionManager.h"
265#include "nsIPrefBranch.h"
266#include "nsIPrincipal.h"
267#include "nsIPrompt.h"
268#include "nsIRunnable.h"
269#include "nsIScreen.h"
270#include "nsIScreenManager.h"
271#include "nsIScriptContext.h"
272#include "nsIScriptGlobalObject.h"
273#include "nsIScriptObjectPrincipal.h"
274#include "nsISerialEventTarget.h"
275#include "nsISimpleEnumerator.h"
276#include "nsISizeOfEventTarget.h"
277#include "nsISlowScriptDebug.h"
278#include "nsISupportsPrimitives.h"
279#include "nsISupportsUtils.h"
280#include "nsIThread.h"
281#include "nsITimedChannel.h"
282#include "nsIURI.h"
283#include "nsIWeakReference.h"
284#include "nsIWebBrowserChrome.h"
285#include "nsIWebNavigation.h"
286#include "nsIWebProgressListener.h"
287#include "nsIWidget.h"
288#include "nsIWidgetListener.h"
289#include "nsIXULRuntime.h"
290#include "nsJSPrincipals.h"
291#include "nsJSUtils.h"
292#include "nsLayoutStatics.h"
293#include "nsLiteralString.h"
294#include "nsNetUtil.h"
295#include "nsPIDOMWindow.h"
296#include "nsPIDOMWindowInlines.h"
297#include "nsPIWindowRoot.h"
298#include "nsPoint.h"
299#include "nsPresContext.h"
300#include "nsQueryObject.h"
301#include "nsSandboxFlags.h"
302#include "nsScreen.h"
303#include "nsServiceManagerUtils.h"
304#include "nsString.h"
305#include "nsStringFlags.h"
306#include "nsStringFwd.h"
307#include "nsTArray.h"
308#include "nsTLiteralString.h"
309#include "nsTObserverArray.h"
310#include "nsTStringRepr.h"
311#include "nsThreadUtils.h"
312#include "nsWeakReference.h"
313#include "nsWindowMemoryReporter.h"
314#include "nsWindowSizes.h"
315#include "nsWrapperCache.h"
316#include "nsWrapperCacheInlines.h"
317#include "nsXULAppAPI.h"
318#include "nsrootidl.h"
319#include "prclist.h"
320#include "prtypes.h"
321#include "xpcprivate.h"
322#include "xpcpublic.h"
323
324#ifdef NS_PRINTING1
325# include "nsIPrintSettings.h"
326#endif
327
328#ifdef MOZ_WEBSPEECH1
329# include "mozilla/dom/SpeechSynthesis.h"
330#endif
331
332#ifdef ANDROID
333# include <android/log.h>
334#endif
335
336#ifdef XP_WIN
337# include <process.h>
338
339# include "mozilla/Debug.h"
340# define getpid _getpid
341#else
342# include <unistd.h> // for getpid()
343#endif
344
345using namespace mozilla;
346using namespace mozilla::dom;
347using namespace mozilla::dom::ipc;
348using mozilla::TimeDuration;
349using mozilla::TimeStamp;
350using mozilla::dom::GamepadHandle;
351using mozilla::dom::cache::CacheStorage;
352
353#define FORWARD_TO_OUTER(method, args, err_rval) \
354 PR_BEGIN_MACROdo { \
355 RefPtr<nsGlobalWindowOuter> outer = GetOuterWindowInternal(); \
356 if (!HasActiveDocument()) { \
357 NS_WARNING(outer ? "Inner window does not have active document." \NS_DebugBreak(NS_DEBUG_WARNING, outer ? "Inner window does not have active document."
: "No outer window available!", nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 358)
358 : "No outer window available!")NS_DebugBreak(NS_DEBUG_WARNING, outer ? "Inner window does not have active document."
: "No outer window available!", nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 358)
; \
359 return err_rval; \
360 } \
361 return outer->method args; \
362 PR_END_MACRO} while (0)
363
364static nsGlobalWindowOuter* GetOuterWindowForForwarding(
365 nsGlobalWindowInner* aInner, ErrorResult& aError) {
366 nsGlobalWindowOuter* outer = aInner->GetOuterWindowInternal();
367 if (MOZ_LIKELY(aInner->HasActiveDocument())(__builtin_expect(!!(aInner->HasActiveDocument()), 1))) {
368 return outer;
369 }
370 if (!outer) {
371 NS_WARNING("No outer window available!")NS_DebugBreak(NS_DEBUG_WARNING, "No outer window available!",
nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 371)
;
372 aError.Throw(NS_ERROR_NOT_INITIALIZED);
373 } else {
374 aError.Throw(NS_ERROR_XPC_SECURITY_MANAGER_VETO);
375 }
376 return nullptr;
377}
378
379#define FORWARD_TO_OUTER_OR_THROW(method, args, rv, err_rval) \
380 PR_BEGIN_MACROdo { \
381 RefPtr<nsGlobalWindowOuter> outer = GetOuterWindowForForwarding(this, rv); \
382 if (MOZ_LIKELY(outer)(__builtin_expect(!!(outer), 1))) { \
383 return outer->method args; \
384 } \
385 return err_rval; \
386 PR_END_MACRO} while (0)
387
388#define FORWARD_TO_OUTER_VOID(method, args) \
389 PR_BEGIN_MACROdo { \
390 RefPtr<nsGlobalWindowOuter> outer = GetOuterWindowInternal(); \
391 if (!HasActiveDocument()) { \
392 NS_WARNING(outer ? "Inner window does not have active document." \NS_DebugBreak(NS_DEBUG_WARNING, outer ? "Inner window does not have active document."
: "No outer window available!", nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 393)
393 : "No outer window available!")NS_DebugBreak(NS_DEBUG_WARNING, outer ? "Inner window does not have active document."
: "No outer window available!", nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 393)
; \
394 return; \
395 } \
396 outer->method args; \
397 return; \
398 PR_END_MACRO} while (0)
399
400#define ENSURE_ACTIVE_DOCUMENT(errorresult, err_rval)do { if ((__builtin_expect(!!(!HasActiveDocument()), 0))) { aError
.Throw(NS_ERROR_XPC_SECURITY_MANAGER_VETO); return err_rval; }
} while (0)
\
401 PR_BEGIN_MACROdo { \
402 if (MOZ_UNLIKELY(!HasActiveDocument())(__builtin_expect(!!(!HasActiveDocument()), 0))) { \
403 aError.Throw(NS_ERROR_XPC_SECURITY_MANAGER_VETO); \
404 return err_rval; \
405 } \
406 PR_END_MACRO} while (0)
407
408#define DOM_TOUCH_LISTENER_ADDED"dom-touch-listener-added" "dom-touch-listener-added"
409#define MEMORY_PRESSURE_OBSERVER_TOPIC"memory-pressure" "memory-pressure"
410#define PERMISSION_CHANGED_TOPIC"perm-changed" "perm-changed"
411
412static LazyLogModule gDOMLeakPRLogInner("DOMLeakInner");
413extern mozilla::LazyLogModule gTimeoutLog;
414
415#ifdef DEBUG1
416static LazyLogModule gDocShellAndDOMWindowLeakLogging(
417 "DocShellAndDOMWindowLeak");
418#endif
419
420static FILE* gDumpFile = nullptr;
421
422mozilla::StaticAutoPtr<nsGlobalWindowInner::InnerWindowByIdTable>
423 nsGlobalWindowInner::sInnerWindowsById;
424
425bool nsGlobalWindowInner::sDragServiceDisabled = false;
426bool nsGlobalWindowInner::sMouseDown = false;
427
428/**
429 * An indirect observer object that means we don't have to implement nsIObserver
430 * on nsGlobalWindow, where any script could see it.
431 */
432class nsGlobalWindowObserver final : public nsIObserver,
433 public nsIInterfaceRequestor,
434 public StorageNotificationObserver {
435 public:
436 explicit nsGlobalWindowObserver(nsGlobalWindowInner* aWindow)
437 : mWindow(aWindow) {}
438 NS_DECL_ISUPPORTSpublic: virtual nsresult QueryInterface(const nsIID& aIID
, void** aInstancePtr) override; virtual MozExternalRefCountType
AddRef(void) override; virtual MozExternalRefCountType Release
(void) override; using HasThreadSafeRefCnt = std::false_type;
protected: nsAutoRefCnt mRefCnt; nsAutoOwningThread _mOwningThread
; public:
439 MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODvirtual nsresult
440 Observe(nsISupports* aSubject, const char* aTopic,
441 const char16_t* aData) override {
442 if (!mWindow) return NS_OK;
443 const RefPtr<nsGlobalWindowInner> win = mWindow;
444 return win->Observe(aSubject, aTopic, aData);
445 }
446 void Forget() { mWindow = nullptr; }
447 NS_IMETHODvirtual nsresult GetInterface(const nsIID& aIID, void** aResult) override {
448 if (mWindow && aIID.Equals(NS_GET_IID(nsIDOMWindow)(nsIDOMWindow::kIID)) && mWindow) {
449 return mWindow->QueryInterface(aIID, aResult);
450 }
451 return NS_NOINTERFACE;
452 }
453
454 void ObserveStorageNotification(StorageEvent* aEvent,
455 const char16_t* aStorageType,
456 bool aPrivateBrowsing) override {
457 if (mWindow) {
458 mWindow->ObserveStorageNotification(aEvent, aStorageType,
459 aPrivateBrowsing);
460 }
461 }
462
463 nsIPrincipal* GetEffectiveCookiePrincipal() const override {
464 return mWindow ? mWindow->GetEffectiveCookiePrincipal() : nullptr;
465 }
466
467 nsIPrincipal* GetEffectiveStoragePrincipal() const override {
468 return mWindow ? mWindow->GetEffectiveStoragePrincipal() : nullptr;
469 }
470
471 bool IsPrivateBrowsing() const override {
472 return mWindow ? mWindow->IsPrivateBrowsing() : false;
473 }
474
475 nsIEventTarget* GetEventTarget() const override {
476 return mWindow ? mWindow->SerialEventTarget() : nullptr;
477 }
478
479 private:
480 ~nsGlobalWindowObserver() = default;
481
482 // This reference is non-owning and safe because it's cleared by
483 // nsGlobalWindowInner::FreeInnerObjects().
484 nsGlobalWindowInner* MOZ_NON_OWNING_REF mWindow;
485};
486
487NS_IMPL_ISUPPORTS(nsGlobalWindowObserver, nsIObserver, nsIInterfaceRequestor)MozExternalRefCountType nsGlobalWindowObserver::AddRef(void) {
static_assert(!std::is_destructible_v<nsGlobalWindowObserver
>, "Reference-counted class " "nsGlobalWindowObserver" " should not have a public destructor. "
"Make this class's destructor non-public"); do { static_assert
( mozilla::detail::AssertionConditionType<decltype(int32_t
(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 487); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 487
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("nsGlobalWindowObserver" != nullptr)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!("nsGlobalWindowObserver" != nullptr))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("\"nsGlobalWindowObserver\" != nullptr"
" (" "Must specify a name" ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 487); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"nsGlobalWindowObserver\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 487); __attribute__((nomerge)) ::abort(); } while (false); }
} while (false); if (!mRefCnt.isThreadSafe) _mOwningThread.AssertOwnership
("nsGlobalWindowObserver" " not thread-safe"); nsrefcnt count
= ++mRefCnt; NS_LogAddRef((this), (count), ("nsGlobalWindowObserver"
), (uint32_t)(sizeof(*this))); return count; } MozExternalRefCountType
nsGlobalWindowObserver::Release(void) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(int32_t(mRefCnt)
> 0)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(int32_t(mRefCnt) > 0))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0" " (" "dup release"
")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp",
487); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 487
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("nsGlobalWindowObserver" != nullptr)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!("nsGlobalWindowObserver" != nullptr))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("\"nsGlobalWindowObserver\" != nullptr"
" (" "Must specify a name" ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 487); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"nsGlobalWindowObserver\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 487); __attribute__((nomerge)) ::abort(); } while (false); }
} while (false); if (!mRefCnt.isThreadSafe) _mOwningThread.AssertOwnership
("nsGlobalWindowObserver" " not thread-safe"); const char* const
nametmp = "nsGlobalWindowObserver"; nsrefcnt count = --mRefCnt
; NS_LogRelease((this), (count), (nametmp)); if (count == 0) {
mRefCnt = 1; delete (this); return 0; } return count; } nsresult
nsGlobalWindowObserver::QueryInterface(const nsIID& aIID
, void** aInstancePtr) { do { if (!(aInstancePtr)) { NS_DebugBreak
(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 487); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE
; static_assert(2 > 0, "Need more arguments to NS_INTERFACE_TABLE"
); static const QITableEntry table[] = { {&mozilla::detail
::kImplementedIID<nsGlobalWindowObserver, nsIObserver>,
int32_t( reinterpret_cast<char*>(static_cast<nsIObserver
*>((nsGlobalWindowObserver*)0x1000)) - reinterpret_cast<
char*>((nsGlobalWindowObserver*)0x1000))}, {&mozilla::
detail::kImplementedIID<nsGlobalWindowObserver, nsIInterfaceRequestor
>, int32_t( reinterpret_cast<char*>(static_cast<nsIInterfaceRequestor
*>((nsGlobalWindowObserver*)0x1000)) - reinterpret_cast<
char*>((nsGlobalWindowObserver*)0x1000))}, {&mozilla::
detail::kImplementedIID<nsGlobalWindowObserver, nsISupports
>, int32_t(reinterpret_cast<char*>(static_cast<nsISupports
*>( static_cast<nsIObserver*>((nsGlobalWindowObserver
*)0x1000))) - reinterpret_cast<char*>((nsGlobalWindowObserver
*)0x1000))}, { nullptr, 0 } } ; static_assert(std::size(table
) > 1, "need at least 1 interface"); rv = NS_TableDrivenQI
(static_cast<void*>(this), aIID, aInstancePtr, table); return
rv; }
488
489class IdleRequestExecutor;
490
491class IdleRequestExecutorTimeoutHandler final : public TimeoutHandler {
492 public:
493 explicit IdleRequestExecutorTimeoutHandler(IdleRequestExecutor* aExecutor)
494 : mExecutor(aExecutor) {}
495
496 NS_DECL_CYCLE_COLLECTING_ISUPPORTS_FINALpublic: virtual nsresult QueryInterface(const nsIID& aIID
, void** aInstancePtr) final; virtual MozExternalRefCountType
AddRef(void) final; virtual MozExternalRefCountType Release(
void) final; using HasThreadSafeRefCnt = std::false_type; protected
: nsCycleCollectingAutoRefCnt mRefCnt; nsAutoOwningThread _mOwningThread
; public: void DeleteCycleCollectable(void); public:
497 NS_DECL_CYCLE_COLLECTION_CLASS(IdleRequestExecutorTimeoutHandler)class cycleCollection : public nsXPCOMCycleCollectionParticipant
{ public: constexpr explicit cycleCollection(Flags aFlags = 0
) : nsXPCOMCycleCollectionParticipant(aFlags) {} private: public
: virtual nsresult TraverseNative(void* p, nsCycleCollectionTraversalCallback
& cb) override; virtual const char* ClassName() override {
return "IdleRequestExecutorTimeoutHandler"; }; virtual void DeleteCycleCollectable
(void* p) override { DowncastCCParticipant<IdleRequestExecutorTimeoutHandler
>(p)->DeleteCycleCollectable(); } static IdleRequestExecutorTimeoutHandler
* Downcast(nsISupports* s) { return static_cast<IdleRequestExecutorTimeoutHandler
*>(static_cast<IdleRequestExecutorTimeoutHandler*>(s
)); } static nsISupports* Upcast(IdleRequestExecutorTimeoutHandler
* p) { return static_cast<nsISupports*>(static_cast<
IdleRequestExecutorTimeoutHandler*>(p)); } virtual void Unlink
(void* p) override; static constexpr nsXPCOMCycleCollectionParticipant
* GetParticipant() { return &IdleRequestExecutorTimeoutHandler
::_cycleCollectorGlobal; } }; clang diagnostic push clang diagnostic
ignored "-Wunnecessary-virtual-specifier" virtual void CheckForRightParticipant
() clang diagnostic pop { nsXPCOMCycleCollectionParticipant*
p; CallQueryInterface(this, &p); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(p == &_cycleCollectorGlobal
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(p == &_cycleCollectorGlobal))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("p == &_cycleCollectorGlobal"
" (" "IdleRequestExecutorTimeoutHandler" " should QI to its own CC participant"
")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp",
497); AnnotateMozCrashReason("MOZ_ASSERT" "(" "p == &_cycleCollectorGlobal"
") (" "IdleRequestExecutorTimeoutHandler" " should QI to its own CC participant"
")"); do { MOZ_CrashSequence(__null, 497); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } static cycleCollection
_cycleCollectorGlobal; clang diagnostic push clang diagnostic
ignored "-Wunnecessary-virtual-specifier" virtual void BaseCycleCollectable
() final{} clang diagnostic pop
498
499 bool Call(const char* /* unused */) override;
500
501 private:
502 ~IdleRequestExecutorTimeoutHandler() override = default;
503 RefPtr<IdleRequestExecutor> mExecutor;
504};
505
506NS_IMPL_CYCLE_COLLECTION(IdleRequestExecutorTimeoutHandler, mExecutor)IdleRequestExecutorTimeoutHandler::cycleCollection IdleRequestExecutorTimeoutHandler
::_cycleCollectorGlobal; void IdleRequestExecutorTimeoutHandler
::cycleCollection::Unlink(void* p) { IdleRequestExecutorTimeoutHandler
* tmp = DowncastCCParticipant<IdleRequestExecutorTimeoutHandler
>(p); ImplCycleCollectionUnlink(tmp->mExecutor); (void)
tmp; } nsresult IdleRequestExecutorTimeoutHandler::cycleCollection
::TraverseNative( void* p, nsCycleCollectionTraversalCallback
& cb) { IdleRequestExecutorTimeoutHandler* tmp = DowncastCCParticipant
<IdleRequestExecutorTimeoutHandler>(p); cb.DescribeRefCountedNode
(tmp->mRefCnt.get(), "IdleRequestExecutorTimeoutHandler");
ImplCycleCollectionTraverse(cb, tmp->mExecutor, "mExecutor"
, 0); (void)tmp; return NS_OK; }
507
508NS_IMPL_CYCLE_COLLECTING_ADDREF(IdleRequestExecutorTimeoutHandler)MozExternalRefCountType IdleRequestExecutorTimeoutHandler::AddRef
(void) { static_assert(!std::is_destructible_v<IdleRequestExecutorTimeoutHandler
>, "Reference-counted class " "IdleRequestExecutorTimeoutHandler"
" should not have a public destructor. " "Make this class's destructor non-public"
); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 508); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 508
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); _mOwningThread.AssertOwnership("IdleRequestExecutorTimeoutHandler"
" not thread-safe"); nsISupports* base = IdleRequestExecutorTimeoutHandler
::cycleCollection::Upcast(this); nsrefcnt count = mRefCnt.incr
(base); NS_LogAddRef((this), (count), ("IdleRequestExecutorTimeoutHandler"
), (uint32_t)(sizeof(*this))); return count; }
509NS_IMPL_CYCLE_COLLECTING_RELEASE(IdleRequestExecutorTimeoutHandler)MozExternalRefCountType IdleRequestExecutorTimeoutHandler::Release
(void) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) > 0))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0"
" (" "dup release" ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 509); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 509
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); _mOwningThread.AssertOwnership("IdleRequestExecutorTimeoutHandler"
" not thread-safe"); nsISupports* base = IdleRequestExecutorTimeoutHandler
::cycleCollection::Upcast(this); nsrefcnt count = mRefCnt.decr
(base); if (count == 0) { NS_CycleCollectableHasRefCntZero();
} NS_LogRelease((this), (count), ("IdleRequestExecutorTimeoutHandler"
)); return count; } void IdleRequestExecutorTimeoutHandler::DeleteCycleCollectable
(void) { delete (this); }
510
511NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(IdleRequestExecutorTimeoutHandler)nsresult IdleRequestExecutorTimeoutHandler::QueryInterface(const
nsIID& aIID, void** aInstancePtr) { do { if (!(aInstancePtr
)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 511); MOZ_PretendNoReturn(); } } while (0); nsISupports* foundInterface
; if (TopThreeWordsEquals( aIID, (nsXPCOMCycleCollectionParticipant
::kIID), (nsCycleCollectionISupports::kIID)) && (LowWordEquals
(aIID, (nsXPCOMCycleCollectionParticipant::kIID)) || LowWordEquals
(aIID, (nsCycleCollectionISupports::kIID)))) { if (LowWordEquals
(aIID, (nsXPCOMCycleCollectionParticipant::kIID))) { *aInstancePtr
= IdleRequestExecutorTimeoutHandler::cycleCollection::GetParticipant
(); return NS_OK; } if (LowWordEquals(aIID, (nsCycleCollectionISupports
::kIID))) { *aInstancePtr = IdleRequestExecutorTimeoutHandler
::cycleCollection::Upcast(this); return NS_OK; } foundInterface
= nullptr; } else
512 NS_INTERFACE_MAP_ENTRY(nsISupports)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsISupports>)) foundInterface = static_cast
<nsISupports*>(this); else
513NS_INTERFACE_MAP_ENDfoundInterface = 0; nsresult status; if (!foundInterface) { do
{ static_assert( mozilla::detail::AssertionConditionType<
decltype(!aIID.Equals((nsISupports::kIID)))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!aIID.Equals((nsISupports::kIID
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!aIID.Equals((nsISupports::kIID))", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 513); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aIID.Equals((nsISupports::kIID))"
")"); do { MOZ_CrashSequence(__null, 513); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); status = NS_NOINTERFACE
; } else { (foundInterface)->AddRef(); status = NS_OK; } *
aInstancePtr = foundInterface; return status; }
514
515class IdleRequestExecutor final : public nsIRunnable,
516 public nsICancelableRunnable,
517 public nsINamed,
518 public nsIIdleRunnable {
519 public:
520 explicit IdleRequestExecutor(nsGlobalWindowInner* aWindow)
521 : mDispatched(false), mDeadline(TimeStamp::Now()), mWindow(aWindow) {
522 MOZ_DIAGNOSTIC_ASSERT(mWindow)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mWindow)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mWindow))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mWindow", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 522); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mWindow"
")"); do { MOZ_CrashSequence(__null, 522); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
523
524 mIdlePeriodLimit = {mDeadline, mWindow->LastIdleRequestHandle()};
525 mDelayedExecutorDispatcher =
526 MakeRefPtr<IdleRequestExecutorTimeoutHandler>(this);
527 }
528
529 NS_DECL_CYCLE_COLLECTING_ISUPPORTS_FINALpublic: virtual nsresult QueryInterface(const nsIID& aIID
, void** aInstancePtr) final; virtual MozExternalRefCountType
AddRef(void) final; virtual MozExternalRefCountType Release(
void) final; using HasThreadSafeRefCnt = std::false_type; protected
: nsCycleCollectingAutoRefCnt mRefCnt; nsAutoOwningThread _mOwningThread
; public: void DeleteCycleCollectable(void); public:
530 NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(IdleRequestExecutor, nsIRunnable)class cycleCollection : public nsXPCOMCycleCollectionParticipant
{ public: constexpr explicit cycleCollection(Flags aFlags = 0
) : nsXPCOMCycleCollectionParticipant(aFlags) {} private: public
: virtual nsresult TraverseNative(void* p, nsCycleCollectionTraversalCallback
& cb) override; virtual const char* ClassName() override {
return "IdleRequestExecutor"; }; virtual void DeleteCycleCollectable
(void* p) override { DowncastCCParticipant<IdleRequestExecutor
>(p)->DeleteCycleCollectable(); } static IdleRequestExecutor
* Downcast(nsISupports* s) { return static_cast<IdleRequestExecutor
*>(static_cast<nsIRunnable*>(s)); } static nsISupports
* Upcast(IdleRequestExecutor* p) { return static_cast<nsISupports
*>(static_cast<nsIRunnable*>(p)); } virtual void Unlink
(void* p) override; static constexpr nsXPCOMCycleCollectionParticipant
* GetParticipant() { return &IdleRequestExecutor::_cycleCollectorGlobal
; } }; clang diagnostic push clang diagnostic ignored "-Wunnecessary-virtual-specifier"
virtual void CheckForRightParticipant() clang diagnostic pop
{ nsXPCOMCycleCollectionParticipant* p; CallQueryInterface(
this, &p); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(p == &_cycleCollectorGlobal)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(p == &_cycleCollectorGlobal
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"p == &_cycleCollectorGlobal" " (" "IdleRequestExecutor" " should QI to its own CC participant"
")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp",
530); AnnotateMozCrashReason("MOZ_ASSERT" "(" "p == &_cycleCollectorGlobal"
") (" "IdleRequestExecutor" " should QI to its own CC participant"
")"); do { MOZ_CrashSequence(__null, 530); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } static cycleCollection
_cycleCollectorGlobal; clang diagnostic push clang diagnostic
ignored "-Wunnecessary-virtual-specifier" virtual void BaseCycleCollectable
() final{} clang diagnostic pop
531
532 NS_DECL_NSIRUNNABLEvirtual nsresult Run(void) override;
533 NS_DECL_NSINAMEDvirtual nsresult GetName(nsACString& aName) override;
534 nsresult Cancel() override;
535 void SetDeadline(TimeStamp aDeadline) override;
536
537 bool IsCancelled() const { return !mWindow || mWindow->IsDying(); }
538 // Checks if aRequest shouldn't execute in the current idle period
539 // since it has been queued from a chained call to
540 // requestIdleCallback from within a running idle callback.
541 bool IneligibleForCurrentIdlePeriod(IdleRequest* aRequest) const {
542 return aRequest->Handle() >= mIdlePeriodLimit.mLastRequestIdInIdlePeriod &&
543 TimeStamp::Now() <= mIdlePeriodLimit.mEndOfIdlePeriod;
544 }
545
546 void MaybeUpdateIdlePeriodLimit();
547
548 // Maybe dispatch the IdleRequestExecutor. MabyeDispatch will
549 // schedule a delayed dispatch if the associated window is in the
550 // background or if given a time to wait until dispatching.
551 void MaybeDispatch(TimeStamp aDelayUntil = TimeStamp());
552 void ScheduleDispatch();
553
554 private:
555 struct IdlePeriodLimit {
556 TimeStamp mEndOfIdlePeriod;
557 uint32_t mLastRequestIdInIdlePeriod;
558 };
559
560 void DelayedDispatch(uint32_t aDelay);
561
562 ~IdleRequestExecutor() override = default;
563
564 bool mDispatched;
565 TimeStamp mDeadline;
566 IdlePeriodLimit mIdlePeriodLimit;
567 RefPtr<nsGlobalWindowInner> mWindow;
568 // The timeout handler responsible for dispatching this executor in
569 // the case of immediate dispatch to the idle queue isn't
570 // desirable. This is used if we've dispatched all idle callbacks
571 // that are allowed to run in the current idle period, or if the
572 // associated window is currently in the background.
573 RefPtr<TimeoutHandler> mDelayedExecutorDispatcher;
574 // If not Nothing() then this value is the handle to the currently
575 // scheduled delayed executor dispatcher. This is needed to be able
576 // to cancel the timeout handler in case of the executor being
577 // cancelled.
578 Maybe<int32_t> mDelayedExecutorHandle;
579};
580
581NS_IMPL_CYCLE_COLLECTION(IdleRequestExecutor, mWindow,IdleRequestExecutor::cycleCollection IdleRequestExecutor::_cycleCollectorGlobal
; void IdleRequestExecutor::cycleCollection::Unlink(void* p) {
IdleRequestExecutor* tmp = DowncastCCParticipant<IdleRequestExecutor
>(p); ImplCycleCollectionUnlink(tmp->mWindow); ImplCycleCollectionUnlink
(tmp->mDelayedExecutorDispatcher); (void)tmp; } nsresult IdleRequestExecutor
::cycleCollection::TraverseNative( void* p, nsCycleCollectionTraversalCallback
& cb) { IdleRequestExecutor* tmp = DowncastCCParticipant<
IdleRequestExecutor>(p); cb.DescribeRefCountedNode(tmp->
mRefCnt.get(), "IdleRequestExecutor"); ImplCycleCollectionTraverse
(cb, tmp->mWindow, "mWindow", 0); ImplCycleCollectionTraverse
(cb, tmp->mDelayedExecutorDispatcher, "mDelayedExecutorDispatcher"
, 0); (void)tmp; return NS_OK; }
582 mDelayedExecutorDispatcher)IdleRequestExecutor::cycleCollection IdleRequestExecutor::_cycleCollectorGlobal
; void IdleRequestExecutor::cycleCollection::Unlink(void* p) {
IdleRequestExecutor* tmp = DowncastCCParticipant<IdleRequestExecutor
>(p); ImplCycleCollectionUnlink(tmp->mWindow); ImplCycleCollectionUnlink
(tmp->mDelayedExecutorDispatcher); (void)tmp; } nsresult IdleRequestExecutor
::cycleCollection::TraverseNative( void* p, nsCycleCollectionTraversalCallback
& cb) { IdleRequestExecutor* tmp = DowncastCCParticipant<
IdleRequestExecutor>(p); cb.DescribeRefCountedNode(tmp->
mRefCnt.get(), "IdleRequestExecutor"); ImplCycleCollectionTraverse
(cb, tmp->mWindow, "mWindow", 0); ImplCycleCollectionTraverse
(cb, tmp->mDelayedExecutorDispatcher, "mDelayedExecutorDispatcher"
, 0); (void)tmp; return NS_OK; }
583
584NS_IMPL_CYCLE_COLLECTING_ADDREF(IdleRequestExecutor)MozExternalRefCountType IdleRequestExecutor::AddRef(void) { static_assert
(!std::is_destructible_v<IdleRequestExecutor>, "Reference-counted class "
"IdleRequestExecutor" " should not have a public destructor. "
"Make this class's destructor non-public"); do { static_assert
( mozilla::detail::AssertionConditionType<decltype(int32_t
(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 584); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 584
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); _mOwningThread.AssertOwnership("IdleRequestExecutor"
" not thread-safe"); nsISupports* base = IdleRequestExecutor
::cycleCollection::Upcast(this); nsrefcnt count = mRefCnt.incr
(base); NS_LogAddRef((this), (count), ("IdleRequestExecutor")
, (uint32_t)(sizeof(*this))); return count; }
585NS_IMPL_CYCLE_COLLECTING_RELEASE(IdleRequestExecutor)MozExternalRefCountType IdleRequestExecutor::Release(void) { do
{ static_assert( mozilla::detail::AssertionConditionType<
decltype(int32_t(mRefCnt) > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) > 0))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0"
" (" "dup release" ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 585); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 585
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); _mOwningThread.AssertOwnership("IdleRequestExecutor"
" not thread-safe"); nsISupports* base = IdleRequestExecutor
::cycleCollection::Upcast(this); nsrefcnt count = mRefCnt.decr
(base); if (count == 0) { NS_CycleCollectableHasRefCntZero();
} NS_LogRelease((this), (count), ("IdleRequestExecutor")); return
count; } void IdleRequestExecutor::DeleteCycleCollectable(void
) { delete (this); }
586
587NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(IdleRequestExecutor)nsresult IdleRequestExecutor::QueryInterface(const nsIID&
aIID, void** aInstancePtr) { do { if (!(aInstancePtr)) { NS_DebugBreak
(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 587); MOZ_PretendNoReturn(); } } while (0); nsISupports* foundInterface
; if (TopThreeWordsEquals( aIID, (nsXPCOMCycleCollectionParticipant
::kIID), (nsCycleCollectionISupports::kIID)) && (LowWordEquals
(aIID, (nsXPCOMCycleCollectionParticipant::kIID)) || LowWordEquals
(aIID, (nsCycleCollectionISupports::kIID)))) { if (LowWordEquals
(aIID, (nsXPCOMCycleCollectionParticipant::kIID))) { *aInstancePtr
= IdleRequestExecutor::cycleCollection::GetParticipant(); return
NS_OK; } if (LowWordEquals(aIID, (nsCycleCollectionISupports
::kIID))) { *aInstancePtr = IdleRequestExecutor::cycleCollection
::Upcast(this); return NS_OK; } foundInterface = nullptr; } else
588 NS_INTERFACE_MAP_ENTRY(nsIRunnable)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIRunnable>)) foundInterface = static_cast
<nsIRunnable*>(this); else
589 NS_INTERFACE_MAP_ENTRY(nsICancelableRunnable)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsICancelableRunnable>)) foundInterface
= static_cast<nsICancelableRunnable*>(this); else
590 NS_INTERFACE_MAP_ENTRY(nsINamed)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsINamed>)) foundInterface = static_cast
<nsINamed*>(this); else
591 NS_INTERFACE_MAP_ENTRY(nsIIdleRunnable)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIIdleRunnable>)) foundInterface
= static_cast<nsIIdleRunnable*>(this); else
592 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIRunnable)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsISupports>)) foundInterface = static_cast
<nsISupports*>(static_cast<nsIRunnable*>(this)); else
593NS_INTERFACE_MAP_ENDfoundInterface = 0; nsresult status; if (!foundInterface) { do
{ static_assert( mozilla::detail::AssertionConditionType<
decltype(!aIID.Equals((nsISupports::kIID)))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!aIID.Equals((nsISupports::kIID
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!aIID.Equals((nsISupports::kIID))", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 593); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aIID.Equals((nsISupports::kIID))"
")"); do { MOZ_CrashSequence(__null, 593); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); status = NS_NOINTERFACE
; } else { (foundInterface)->AddRef(); status = NS_OK; } *
aInstancePtr = foundInterface; return status; }
594
595NS_IMETHODIMPnsresult
596IdleRequestExecutor::GetName(nsACString& aName) {
597 aName.AssignLiteral("IdleRequestExecutor");
598 return NS_OK;
599}
600
601// MOZ_CAN_RUN_SCRIPT_BOUNDARY until nsIRunnable::Run is MOZ_CAN_RUN_SCRIPT.
602// See bug 1535398.
603MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMPnsresult IdleRequestExecutor::Run() {
604 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 604
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 604); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
605
606 mDispatched = false;
607 if (mWindow) {
608 RefPtr<nsGlobalWindowInner> window(mWindow);
609 window->ExecuteIdleRequest(mDeadline);
610 }
611
612 return NS_OK;
613}
614
615nsresult IdleRequestExecutor::Cancel() {
616 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 616
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 616); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
617
618 if (mDelayedExecutorHandle && mWindow) {
619 mWindow->GetTimeoutManager()->ClearTimeout(
620 mDelayedExecutorHandle.value(), Timeout::Reason::eIdleCallbackTimeout);
621 }
622
623 mWindow = nullptr;
624 return NS_OK;
625}
626
627void IdleRequestExecutor::SetDeadline(TimeStamp aDeadline) {
628 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 628
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 628); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
629
630 if (!mWindow) {
631 return;
632 }
633
634 mDeadline = aDeadline;
635}
636
637void IdleRequestExecutor::MaybeUpdateIdlePeriodLimit() {
638 if (TimeStamp::Now() > mIdlePeriodLimit.mEndOfIdlePeriod) {
639 mIdlePeriodLimit = {mDeadline, mWindow->LastIdleRequestHandle()};
640 }
641}
642
643void IdleRequestExecutor::MaybeDispatch(TimeStamp aDelayUntil) {
644 // If we've already dispatched the executor we don't want to do it
645 // again. Also, if we've called IdleRequestExecutor::Cancel mWindow
646 // will be null, which indicates that we shouldn't dispatch this
647 // executor either.
648 if (mDispatched || IsCancelled()) {
649 return;
650 }
651
652 mDispatched = true;
653
654 nsPIDOMWindowOuter* outer = mWindow->GetOuterWindow();
655 if (outer && outer->IsBackground()) {
656 // Set a timeout handler with a timeout of 0 ms to throttle idle
657 // callback requests coming from a backround window using
658 // background timeout throttling.
659 DelayedDispatch(0);
660 return;
661 }
662
663 TimeStamp now = TimeStamp::Now();
664 if (!aDelayUntil || aDelayUntil < now) {
665 ScheduleDispatch();
666 return;
667 }
668
669 TimeDuration delay = aDelayUntil - now;
670 DelayedDispatch(static_cast<uint32_t>(delay.ToMilliseconds()));
671}
672
673void IdleRequestExecutor::ScheduleDispatch() {
674 MOZ_ASSERT(mWindow)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mWindow)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mWindow))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mWindow", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 674); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mWindow" ")"
); do { MOZ_CrashSequence(__null, 674); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
675 mDelayedExecutorHandle = Nothing();
676 RefPtr<IdleRequestExecutor> request = this;
677 NS_DispatchToCurrentThreadQueue(request.forget(), EventQueuePriority::Idle);
678}
679
680void IdleRequestExecutor::DelayedDispatch(uint32_t aDelay) {
681 MOZ_ASSERT(mWindow)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mWindow)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mWindow))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mWindow", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 681); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mWindow" ")"
); do { MOZ_CrashSequence(__null, 681); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
682 MOZ_ASSERT(mDelayedExecutorHandle.isNothing())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mDelayedExecutorHandle.isNothing())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mDelayedExecutorHandle.isNothing
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mDelayedExecutorHandle.isNothing()", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 682); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mDelayedExecutorHandle.isNothing()"
")"); do { MOZ_CrashSequence(__null, 682); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
683 int32_t handle;
684 mWindow->GetTimeoutManager()->SetTimeout(
685 mDelayedExecutorDispatcher, aDelay, false,
686 Timeout::Reason::eIdleCallbackTimeout, &handle);
687 mDelayedExecutorHandle = Some(handle);
688}
689
690bool IdleRequestExecutorTimeoutHandler::Call(const char* /* unused */) {
691 if (!mExecutor->IsCancelled()) {
692 mExecutor->ScheduleDispatch();
693 }
694 return true;
695}
696
697void nsGlobalWindowInner::ScheduleIdleRequestDispatch() {
698 AssertIsOnMainThread();
699
700 if (!mIdleRequestExecutor) {
701 mIdleRequestExecutor = MakeRefPtr<IdleRequestExecutor>(this);
702 }
703
704 mIdleRequestExecutor->MaybeDispatch();
705}
706
707void nsGlobalWindowInner::SuspendIdleRequests() {
708 if (mIdleRequestExecutor) {
709 mIdleRequestExecutor->Cancel();
710 mIdleRequestExecutor = nullptr;
711 }
712}
713
714void nsGlobalWindowInner::ResumeIdleRequests() {
715 MOZ_ASSERT(!mIdleRequestExecutor)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mIdleRequestExecutor)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mIdleRequestExecutor))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("!mIdleRequestExecutor"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 715
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mIdleRequestExecutor"
")"); do { MOZ_CrashSequence(__null, 715); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
716
717 ScheduleIdleRequestDispatch();
718}
719
720void nsGlobalWindowInner::RemoveIdleCallback(
721 mozilla::dom::IdleRequest* aRequest) {
722 AssertIsOnMainThread();
723
724 if (aRequest->HasTimeout()) {
725 mTimeoutManager->ClearTimeout(aRequest->GetTimeoutHandle(),
726 Timeout::Reason::eIdleCallbackTimeout);
727 }
728
729 aRequest->removeFrom(mIdleRequestCallbacks);
730}
731
732void nsGlobalWindowInner::RunIdleRequest(IdleRequest* aRequest,
733 DOMHighResTimeStamp aDeadline,
734 bool aDidTimeout) {
735 AssertIsOnMainThread();
736 // XXXbz Do we still need this RefPtr? MOZ_CAN_RUN_SCRIPT should
737 // guarantee that caller is holding a strong ref on the stack.
738 RefPtr<IdleRequest> request(aRequest);
739 RemoveIdleCallback(request);
740 request->IdleRun(this, aDeadline, aDidTimeout);
741}
742
743void nsGlobalWindowInner::ExecuteIdleRequest(TimeStamp aDeadline) {
744 AssertIsOnMainThread();
745 RefPtr<IdleRequest> request = mIdleRequestCallbacks.getFirst();
746
747 if (!request) {
748 // There are no more idle requests, so stop scheduling idle
749 // request callbacks.
750 return;
751 }
752
753 // If the request that we're trying to execute has been queued
754 // during the current idle period, then dispatch it again at the end
755 // of the idle period.
756 if (mIdleRequestExecutor->IneligibleForCurrentIdlePeriod(request)) {
757 mIdleRequestExecutor->MaybeDispatch(aDeadline);
758 return;
759 }
760
761 DOMHighResTimeStamp deadline = 0.0;
762
763 if (Performance* perf = GetPerformance()) {
764 deadline = perf->GetDOMTiming()->TimeStampToDOMHighRes(aDeadline);
765 }
766
767 mIdleRequestExecutor->MaybeUpdateIdlePeriodLimit();
768 RunIdleRequest(request, deadline, false);
769
770 // Running the idle callback could've suspended the window, in which
771 // case mIdleRequestExecutor will be null.
772 if (mIdleRequestExecutor) {
773 mIdleRequestExecutor->MaybeDispatch();
774 }
775}
776
777class IdleRequestTimeoutHandler final : public TimeoutHandler {
778 public:
779 IdleRequestTimeoutHandler(JSContext* aCx, IdleRequest* aIdleRequest,
780 nsPIDOMWindowInner* aWindow)
781 : TimeoutHandler(aCx), mIdleRequest(aIdleRequest), mWindow(aWindow) {}
782
783 NS_DECL_CYCLE_COLLECTING_ISUPPORTS_FINALpublic: virtual nsresult QueryInterface(const nsIID& aIID
, void** aInstancePtr) final; virtual MozExternalRefCountType
AddRef(void) final; virtual MozExternalRefCountType Release(
void) final; using HasThreadSafeRefCnt = std::false_type; protected
: nsCycleCollectingAutoRefCnt mRefCnt; nsAutoOwningThread _mOwningThread
; public: void DeleteCycleCollectable(void); public:
784 NS_DECL_CYCLE_COLLECTION_CLASS(IdleRequestTimeoutHandler)class cycleCollection : public nsXPCOMCycleCollectionParticipant
{ public: constexpr explicit cycleCollection(Flags aFlags = 0
) : nsXPCOMCycleCollectionParticipant(aFlags) {} private: public
: virtual nsresult TraverseNative(void* p, nsCycleCollectionTraversalCallback
& cb) override; virtual const char* ClassName() override {
return "IdleRequestTimeoutHandler"; }; virtual void DeleteCycleCollectable
(void* p) override { DowncastCCParticipant<IdleRequestTimeoutHandler
>(p)->DeleteCycleCollectable(); } static IdleRequestTimeoutHandler
* Downcast(nsISupports* s) { return static_cast<IdleRequestTimeoutHandler
*>(static_cast<IdleRequestTimeoutHandler*>(s)); } static
nsISupports* Upcast(IdleRequestTimeoutHandler* p) { return static_cast
<nsISupports*>(static_cast<IdleRequestTimeoutHandler
*>(p)); } virtual void Unlink(void* p) override; static constexpr
nsXPCOMCycleCollectionParticipant* GetParticipant() { return
&IdleRequestTimeoutHandler::_cycleCollectorGlobal; } }; clang
diagnostic push clang diagnostic ignored "-Wunnecessary-virtual-specifier"
virtual void CheckForRightParticipant() clang diagnostic pop
{ nsXPCOMCycleCollectionParticipant* p; CallQueryInterface(
this, &p); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(p == &_cycleCollectorGlobal)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(p == &_cycleCollectorGlobal
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"p == &_cycleCollectorGlobal" " (" "IdleRequestTimeoutHandler"
" should QI to its own CC participant" ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 784); AnnotateMozCrashReason("MOZ_ASSERT" "(" "p == &_cycleCollectorGlobal"
") (" "IdleRequestTimeoutHandler" " should QI to its own CC participant"
")"); do { MOZ_CrashSequence(__null, 784); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } static cycleCollection
_cycleCollectorGlobal; clang diagnostic push clang diagnostic
ignored "-Wunnecessary-virtual-specifier" virtual void BaseCycleCollectable
() final{} clang diagnostic pop
785
786 MOZ_CAN_RUN_SCRIPT bool Call(const char* /* unused */) override {
787 RefPtr<nsGlobalWindowInner> window(nsGlobalWindowInner::Cast(mWindow));
788 RefPtr<IdleRequest> request(mIdleRequest);
789 window->RunIdleRequest(request, 0.0, true);
790 return true;
791 }
792
793 private:
794 ~IdleRequestTimeoutHandler() override = default;
795
796 RefPtr<IdleRequest> mIdleRequest;
797 nsCOMPtr<nsPIDOMWindowInner> mWindow;
798};
799
800NS_IMPL_CYCLE_COLLECTION(IdleRequestTimeoutHandler, mIdleRequest, mWindow)IdleRequestTimeoutHandler::cycleCollection IdleRequestTimeoutHandler
::_cycleCollectorGlobal; void IdleRequestTimeoutHandler::cycleCollection
::Unlink(void* p) { IdleRequestTimeoutHandler* tmp = DowncastCCParticipant
<IdleRequestTimeoutHandler>(p); ImplCycleCollectionUnlink
(tmp->mIdleRequest); ImplCycleCollectionUnlink(tmp->mWindow
); (void)tmp; } nsresult IdleRequestTimeoutHandler::cycleCollection
::TraverseNative( void* p, nsCycleCollectionTraversalCallback
& cb) { IdleRequestTimeoutHandler* tmp = DowncastCCParticipant
<IdleRequestTimeoutHandler>(p); cb.DescribeRefCountedNode
(tmp->mRefCnt.get(), "IdleRequestTimeoutHandler"); ImplCycleCollectionTraverse
(cb, tmp->mIdleRequest, "mIdleRequest", 0); ImplCycleCollectionTraverse
(cb, tmp->mWindow, "mWindow", 0); (void)tmp; return NS_OK;
}
801
802NS_IMPL_CYCLE_COLLECTING_ADDREF(IdleRequestTimeoutHandler)MozExternalRefCountType IdleRequestTimeoutHandler::AddRef(void
) { static_assert(!std::is_destructible_v<IdleRequestTimeoutHandler
>, "Reference-counted class " "IdleRequestTimeoutHandler" " should not have a public destructor. "
"Make this class's destructor non-public"); do { static_assert
( mozilla::detail::AssertionConditionType<decltype(int32_t
(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 802); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 802
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); _mOwningThread.AssertOwnership("IdleRequestTimeoutHandler"
" not thread-safe"); nsISupports* base = IdleRequestTimeoutHandler
::cycleCollection::Upcast(this); nsrefcnt count = mRefCnt.incr
(base); NS_LogAddRef((this), (count), ("IdleRequestTimeoutHandler"
), (uint32_t)(sizeof(*this))); return count; }
803NS_IMPL_CYCLE_COLLECTING_RELEASE(IdleRequestTimeoutHandler)MozExternalRefCountType IdleRequestTimeoutHandler::Release(void
) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) > 0))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0"
" (" "dup release" ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 803); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 803
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); _mOwningThread.AssertOwnership("IdleRequestTimeoutHandler"
" not thread-safe"); nsISupports* base = IdleRequestTimeoutHandler
::cycleCollection::Upcast(this); nsrefcnt count = mRefCnt.decr
(base); if (count == 0) { NS_CycleCollectableHasRefCntZero();
} NS_LogRelease((this), (count), ("IdleRequestTimeoutHandler"
)); return count; } void IdleRequestTimeoutHandler::DeleteCycleCollectable
(void) { delete (this); }
804
805NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(IdleRequestTimeoutHandler)nsresult IdleRequestTimeoutHandler::QueryInterface(const nsIID
& aIID, void** aInstancePtr) { do { if (!(aInstancePtr)) {
NS_DebugBreak(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 805); MOZ_PretendNoReturn(); } } while (0); nsISupports* foundInterface
; if (TopThreeWordsEquals( aIID, (nsXPCOMCycleCollectionParticipant
::kIID), (nsCycleCollectionISupports::kIID)) && (LowWordEquals
(aIID, (nsXPCOMCycleCollectionParticipant::kIID)) || LowWordEquals
(aIID, (nsCycleCollectionISupports::kIID)))) { if (LowWordEquals
(aIID, (nsXPCOMCycleCollectionParticipant::kIID))) { *aInstancePtr
= IdleRequestTimeoutHandler::cycleCollection::GetParticipant
(); return NS_OK; } if (LowWordEquals(aIID, (nsCycleCollectionISupports
::kIID))) { *aInstancePtr = IdleRequestTimeoutHandler::cycleCollection
::Upcast(this); return NS_OK; } foundInterface = nullptr; } else
806 NS_INTERFACE_MAP_ENTRY(nsISupports)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsISupports>)) foundInterface = static_cast
<nsISupports*>(this); else
807NS_INTERFACE_MAP_ENDfoundInterface = 0; nsresult status; if (!foundInterface) { do
{ static_assert( mozilla::detail::AssertionConditionType<
decltype(!aIID.Equals((nsISupports::kIID)))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!aIID.Equals((nsISupports::kIID
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!aIID.Equals((nsISupports::kIID))", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 807); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aIID.Equals((nsISupports::kIID))"
")"); do { MOZ_CrashSequence(__null, 807); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); status = NS_NOINTERFACE
; } else { (foundInterface)->AddRef(); status = NS_OK; } *
aInstancePtr = foundInterface; return status; }
808
809uint32_t nsGlobalWindowInner::RequestIdleCallback(
810 JSContext* aCx, IdleRequestCallback& aCallback,
811 const IdleRequestOptions& aOptions, ErrorResult& aError) {
812 AssertIsOnMainThread();
813
814 if (IsDying()) {
815 return 0;
816 }
817
818 uint32_t handle = mIdleRequestCallbackCounter++;
819
820 RefPtr request = MakeRefPtr<IdleRequest>(&aCallback, handle);
821
822 if (aOptions.mTimeout.WasPassed()) {
823 int32_t timeoutHandle;
824 RefPtr handler = MakeRefPtr<IdleRequestTimeoutHandler>(aCx, request, this);
825
826 nsresult rv = mTimeoutManager->SetTimeout(
827 handler, aOptions.mTimeout.Value(), false,
828 Timeout::Reason::eIdleCallbackTimeout, &timeoutHandle);
829
830 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 830)
) {
831 return 0;
832 }
833
834 request->SetTimeoutHandle(timeoutHandle);
835 }
836
837 mIdleRequestCallbacks.insertBack(request);
838
839 if (!IsSuspended()) {
840 ScheduleIdleRequestDispatch();
841 }
842
843 return handle;
844}
845
846void nsGlobalWindowInner::CancelIdleCallback(uint32_t aHandle) {
847 for (IdleRequest* r : mIdleRequestCallbacks) {
848 if (r->Handle() == aHandle) {
849 RemoveIdleCallback(r);
850 break;
851 }
852 }
853}
854
855void nsGlobalWindowInner::DisableIdleCallbackRequests() {
856 if (mIdleRequestExecutor) {
857 mIdleRequestExecutor->Cancel();
858 mIdleRequestExecutor = nullptr;
859 }
860
861 while (!mIdleRequestCallbacks.isEmpty()) {
862 RefPtr<IdleRequest> request = mIdleRequestCallbacks.getFirst();
863 RemoveIdleCallback(request);
864 }
865}
866
867bool nsGlobalWindowInner::IsBackgroundInternal() const {
868 return !mOuterWindow || mOuterWindow->IsBackground();
869}
870
871class PromiseDocumentFlushedResolver final {
872 public:
873 PromiseDocumentFlushedResolver(Promise* aPromise,
874 PromiseDocumentFlushedCallback& aCallback)
875 : mPromise(aPromise), mCallback(&aCallback) {}
876
877 virtual ~PromiseDocumentFlushedResolver() = default;
878
879 void Call() {
880 nsMutationGuard guard;
881 ErrorResult error;
882 JS::Rooted<JS::Value> returnVal(RootingCx());
883 mCallback->Call(&returnVal, error);
884
885 if (error.Failed()) {
886 mPromise->MaybeReject(std::move(error));
887 } else if (guard.Mutated(0)) {
888 // Something within the callback mutated the DOM.
889 mPromise->MaybeRejectWithNoModificationAllowedError(
890 "DOM mutated from promiseDocumentFlushed callbacks");
891 } else {
892 mPromise->MaybeResolve(returnVal);
893 }
894 }
895
896 RefPtr<Promise> mPromise;
897 RefPtr<PromiseDocumentFlushedCallback> mCallback;
898};
899
900//*****************************************************************************
901//*** nsGlobalWindowInner: Object Management
902//*****************************************************************************
903
904nsGlobalWindowInner::nsGlobalWindowInner(nsGlobalWindowOuter* aOuterWindow,
905 WindowGlobalChild* aActor)
906 : nsPIDOMWindowInner(aOuterWindow, aActor),
907 mHasOrientationChangeListeners(false),
908 mWasOffline(false),
909 mHasHadSlowScript(false),
910 mIsChrome(false),
911 mCleanMessageManager(false),
912 mNeedsFocus(true),
913 mFocusByKeyOccurred(false),
914 mDidFireDocElemInserted(false),
915 mHasGamepad(false),
916 mHasXRSession(false),
917 mHasVRDisplayActivateEvents(false),
918 mXRRuntimeDetectionInFlight(false),
919 mXRPermissionRequestInFlight(false),
920 mXRPermissionGranted(false),
921 mWasCurrentInnerWindow(false),
922 mHasSeenGamepadInput(false),
923 mHintedWasLoading(false),
924 mHasOpenedExternalProtocolFrame(false),
925 mScrollMarksOnHScrollbar(false),
926 mStorageAllowedReasonCache(0),
927 mSuspendDepth(0),
928 mFreezeDepth(0),
929#ifdef DEBUG1
930 mSerial(0),
931#endif
932 mFocusMethod(0),
933 mIdleRequestCallbackCounter(1),
934 mIdleRequestExecutor(nullptr),
935 mObservingRefresh(false),
936 mIteratingDocumentFlushedResolvers(false),
937 mCanSkipCCGeneration(0) {
938 mIsInnerWindow = true;
939
940 AssertIsOnMainThread();
941 SetIsOnMainThread();
942 nsLayoutStatics::AddRef();
943
944 // Initialize the PRCList (this).
945 PR_INIT_CLIST(this)do {(this)->next = (this); (this)->prev = (this); } while
(0)
;
946
947 // add this inner window to the outer window list of inners.
948 PR_INSERT_AFTER(this, aOuterWindow)do {(this)->next = (aOuterWindow)->next; (this)->prev
= (aOuterWindow); (aOuterWindow)->next->prev = (this);
(aOuterWindow)->next = (this); } while (0)
;
949
950 mTimeoutManager = MakeUnique<dom::TimeoutManager>(
951 *this, StaticPrefs::dom_timeout_max_idle_defer_ms(),
952 static_cast<nsISerialEventTarget*>(nsPIDOMWindowInner::From(this)
953 ->GetBrowsingContextGroup()
954 ->GetTimerEventQueue()));
955
956 mObserver = MakeRefPtr<nsGlobalWindowObserver>(this);
957 if (nsCOMPtr<nsIObserverService> os = services::GetObserverService()) {
958 // Watch for online/offline status changes so we can fire events. Use
959 // a strong reference.
960 os->AddObserver(mObserver, NS_IOSERVICE_OFFLINE_STATUS_TOPIC"network:offline-status-changed", false);
961 os->AddObserver(mObserver, MEMORY_PRESSURE_OBSERVER_TOPIC"memory-pressure", false);
962 os->AddObserver(mObserver, PERMISSION_CHANGED_TOPIC"perm-changed", false);
963 os->AddObserver(mObserver, "browser-perm-changed", false);
964 os->AddObserver(mObserver, "screen-information-changed", false);
965 os->AddObserver(mObserver, "audio-playback", false);
966 }
967
968 Preferences::AddStrongObserver(mObserver, "intl.accept_languages");
969
970 // Watch for storage notifications so we can fire storage events.
971 RefPtr<StorageNotifierService> sns = StorageNotifierService::GetOrCreate();
972 if (sns) {
973 sns->Register(mObserver);
974 }
975
976 if (XRE_IsContentProcess()) {
977 nsCOMPtr<nsIDocShell> docShell = GetDocShell();
978 if (docShell) {
979 mBrowserChild = docShell->GetBrowserChild();
980 }
981 }
982
983 if (gDumpFile == nullptr) {
984 nsAutoCString fname;
985 Preferences::GetCString("browser.dom.window.dump.file", fname);
986 if (!fname.IsEmpty()) {
987 // If this fails to open, Dump() knows to just go to stdout on null.
988 gDumpFile = fopen(fname.get(), "wb+");
989 } else {
990 gDumpFile = stdoutstdout;
991 }
992 }
993
994#ifdef DEBUG1
995 mSerial = nsContentUtils::InnerOrOuterWindowCreated();
996
997 if (MOZ_LOG_TEST(gDocShellAndDOMWindowLeakLogging, LogLevel::Info)(__builtin_expect(!!(mozilla::detail::log_test(gDocShellAndDOMWindowLeakLogging
, LogLevel::Info)), 0))
) {
998 MOZ_LOG(gDocShellAndDOMWindowLeakLogging, LogLevel::Info,do { const ::mozilla::LogModule* moz_real_module = gDocShellAndDOMWindowLeakLogging
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Info)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Info, "++DOMWINDOW == %d (%p) [pid = %d] [serial = %d] [outer = %p]\n"
, nsContentUtils::GetCurrentInnerOrOuterWindowCount(), static_cast
<void*>(ToCanonicalSupports(this)), getpid(), mSerial, static_cast
<void*>(ToCanonicalSupports(aOuterWindow))); } } while (
0)
999 ("++DOMWINDOW == %d (%p) [pid = %d] [serial = %d] [outer = %p]\n",do { const ::mozilla::LogModule* moz_real_module = gDocShellAndDOMWindowLeakLogging
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Info)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Info, "++DOMWINDOW == %d (%p) [pid = %d] [serial = %d] [outer = %p]\n"
, nsContentUtils::GetCurrentInnerOrOuterWindowCount(), static_cast
<void*>(ToCanonicalSupports(this)), getpid(), mSerial, static_cast
<void*>(ToCanonicalSupports(aOuterWindow))); } } while (
0)
1000 nsContentUtils::GetCurrentInnerOrOuterWindowCount(),do { const ::mozilla::LogModule* moz_real_module = gDocShellAndDOMWindowLeakLogging
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Info)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Info, "++DOMWINDOW == %d (%p) [pid = %d] [serial = %d] [outer = %p]\n"
, nsContentUtils::GetCurrentInnerOrOuterWindowCount(), static_cast
<void*>(ToCanonicalSupports(this)), getpid(), mSerial, static_cast
<void*>(ToCanonicalSupports(aOuterWindow))); } } while (
0)
1001 static_cast<void*>(ToCanonicalSupports(this)), getpid(), mSerial,do { const ::mozilla::LogModule* moz_real_module = gDocShellAndDOMWindowLeakLogging
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Info)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Info, "++DOMWINDOW == %d (%p) [pid = %d] [serial = %d] [outer = %p]\n"
, nsContentUtils::GetCurrentInnerOrOuterWindowCount(), static_cast
<void*>(ToCanonicalSupports(this)), getpid(), mSerial, static_cast
<void*>(ToCanonicalSupports(aOuterWindow))); } } while (
0)
1002 static_cast<void*>(ToCanonicalSupports(aOuterWindow))))do { const ::mozilla::LogModule* moz_real_module = gDocShellAndDOMWindowLeakLogging
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Info)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Info, "++DOMWINDOW == %d (%p) [pid = %d] [serial = %d] [outer = %p]\n"
, nsContentUtils::GetCurrentInnerOrOuterWindowCount(), static_cast
<void*>(ToCanonicalSupports(this)), getpid(), mSerial, static_cast
<void*>(ToCanonicalSupports(aOuterWindow))); } } while (
0)
;
1003
1004 nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
1005 if (obs) {
1006 nsString data;
1007 data.AppendPrintf(
1008 "serial=%d address=0x%" PRIxPTR"l" "x" " type=inner outer=0x%" PRIxPTR"l" "x",
1009 mSerial, reinterpret_cast<uintptr_t>(ToCanonicalSupports(this)),
1010 reinterpret_cast<uintptr_t>(ToCanonicalSupports(aOuterWindow)));
1011 obs->NotifyObservers(nullptr, "debug-domwindow-created", data.get());
1012 }
1013 }
1014#endif
1015
1016 MOZ_LOG(gDOMLeakPRLogInner, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gDOMLeakPRLogInner
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "DOMWINDOW %p created outer=%p", this, aOuterWindow
); } } while (0)
1017 ("DOMWINDOW %p created outer=%p", this, aOuterWindow))do { const ::mozilla::LogModule* moz_real_module = gDOMLeakPRLogInner
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "DOMWINDOW %p created outer=%p", this, aOuterWindow
); } } while (0)
;
1018
1019 // Add ourselves to the inner windows list.
1020 MOZ_ASSERT(sInnerWindowsById, "Inner Windows hash table must be created!")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(sInnerWindowsById)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(sInnerWindowsById))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("sInnerWindowsById"
" (" "Inner Windows hash table must be created!" ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 1020); AnnotateMozCrashReason("MOZ_ASSERT" "(" "sInnerWindowsById"
") (" "Inner Windows hash table must be created!" ")"); do {
MOZ_CrashSequence(__null, 1020); __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
1021 MOZ_ASSERT(!sInnerWindowsById->Contains(mWindowID),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!sInnerWindowsById->Contains(mWindowID))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!sInnerWindowsById->Contains(mWindowID)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("!sInnerWindowsById->Contains(mWindowID)"
" (" "This window shouldn't be in the hash table yet!" ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 1022); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!sInnerWindowsById->Contains(mWindowID)"
") (" "This window shouldn't be in the hash table yet!" ")")
; do { MOZ_CrashSequence(__null, 1022); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1022 "This window shouldn't be in the hash table yet!")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!sInnerWindowsById->Contains(mWindowID))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!sInnerWindowsById->Contains(mWindowID)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("!sInnerWindowsById->Contains(mWindowID)"
" (" "This window shouldn't be in the hash table yet!" ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 1022); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!sInnerWindowsById->Contains(mWindowID)"
") (" "This window shouldn't be in the hash table yet!" ")")
; do { MOZ_CrashSequence(__null, 1022); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1023 // We seem to see crashes in release builds because of null
1024 // |sInnerWindowsById|.
1025 if (sInnerWindowsById) {
1026 sInnerWindowsById->InsertOrUpdate(mWindowID, this);
1027 }
1028}
1029
1030#ifdef DEBUG1
1031
1032/* static */
1033void nsGlobalWindowInner::AssertIsOnMainThread() {
1034 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 1034
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 1034); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1035}
1036
1037#endif // DEBUG
1038
1039/* static */
1040void nsGlobalWindowInner::Init() {
1041 AssertIsOnMainThread();
1042
1043 NS_ASSERTION(gDOMLeakPRLogInner,do { if (!(gDOMLeakPRLogInner)) { NS_DebugBreak(NS_DEBUG_ASSERTION
, "gDOMLeakPRLogInner should have been initialized!", "gDOMLeakPRLogInner"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 1044
); MOZ_PretendNoReturn(); } } while (0)
1044 "gDOMLeakPRLogInner should have been initialized!")do { if (!(gDOMLeakPRLogInner)) { NS_DebugBreak(NS_DEBUG_ASSERTION
, "gDOMLeakPRLogInner should have been initialized!", "gDOMLeakPRLogInner"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 1044
); MOZ_PretendNoReturn(); } } while (0)
;
1045
1046 sInnerWindowsById = new InnerWindowByIdTable();
1047}
1048
1049nsGlobalWindowInner::~nsGlobalWindowInner() {
1050 AssertIsOnMainThread();
1051 MOZ_ASSERT(!mHintedWasLoading)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mHintedWasLoading)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mHintedWasLoading))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("!mHintedWasLoading"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 1051
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mHintedWasLoading"
")"); do { MOZ_CrashSequence(__null, 1051); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1052
1053 if (IsChromeWindow()) {
1054 MOZ_ASSERT(mCleanMessageManager,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mCleanMessageManager)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mCleanMessageManager))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("mCleanMessageManager"
" (" "chrome windows may always disconnect the msg manager" ")"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 1055
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCleanMessageManager"
") (" "chrome windows may always disconnect the msg manager"
")"); do { MOZ_CrashSequence(__null, 1055); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1055 "chrome windows may always disconnect the msg manager")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mCleanMessageManager)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mCleanMessageManager))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("mCleanMessageManager"
" (" "chrome windows may always disconnect the msg manager" ")"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 1055
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCleanMessageManager"
") (" "chrome windows may always disconnect the msg manager"
")"); do { MOZ_CrashSequence(__null, 1055); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1056
1057 DisconnectAndClearGroupMessageManagers();
1058
1059 if (mChromeFields.mMessageManager) {
1060 static_cast<nsFrameMessageManager*>(mChromeFields.mMessageManager.get())
1061 ->Disconnect();
1062 }
1063
1064 mCleanMessageManager = false;
1065 }
1066
1067 // In most cases this should already have been called, but call it again
1068 // here to catch any corner cases.
1069 FreeInnerObjects();
1070
1071 if (sInnerWindowsById) {
1072 sInnerWindowsById->Remove(mWindowID);
1073 }
1074
1075 nsContentUtils::InnerOrOuterWindowDestroyed();
1076
1077#ifdef DEBUG1
1078 if (MOZ_LOG_TEST(gDocShellAndDOMWindowLeakLogging, LogLevel::Info)(__builtin_expect(!!(mozilla::detail::log_test(gDocShellAndDOMWindowLeakLogging
, LogLevel::Info)), 0))
) {
1079 nsAutoCString url;
1080 if (mLastOpenedURI) {
1081 url = mLastOpenedURI->GetSpecOrDefault();
1082
1083 // Data URLs can be very long, so truncate to avoid flooding the log.
1084 const uint32_t maxURLLength = 1000;
1085 if (url.Length() > maxURLLength) {
1086 url.Truncate(maxURLLength);
1087 }
1088 }
1089
1090 nsGlobalWindowOuter* outer = nsGlobalWindowOuter::Cast(mOuterWindow);
1091 MOZ_LOG(do { const ::mozilla::LogModule* moz_real_module = gDocShellAndDOMWindowLeakLogging
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Info)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Info, "--DOMWINDOW == %d (%p) [pid = %d] [serial = %d] [outer = %p] [url = "
"%s]\n", nsContentUtils::GetCurrentInnerOrOuterWindowCount()
, static_cast<void*>(ToCanonicalSupports(this)), getpid
(), mSerial, static_cast<void*>(ToCanonicalSupports(outer
)), url.get()); } } while (0)
1092 gDocShellAndDOMWindowLeakLogging, LogLevel::Info,do { const ::mozilla::LogModule* moz_real_module = gDocShellAndDOMWindowLeakLogging
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Info)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Info, "--DOMWINDOW == %d (%p) [pid = %d] [serial = %d] [outer = %p] [url = "
"%s]\n", nsContentUtils::GetCurrentInnerOrOuterWindowCount()
, static_cast<void*>(ToCanonicalSupports(this)), getpid
(), mSerial, static_cast<void*>(ToCanonicalSupports(outer
)), url.get()); } } while (0)
1093 ("--DOMWINDOW == %d (%p) [pid = %d] [serial = %d] [outer = %p] [url = "do { const ::mozilla::LogModule* moz_real_module = gDocShellAndDOMWindowLeakLogging
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Info)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Info, "--DOMWINDOW == %d (%p) [pid = %d] [serial = %d] [outer = %p] [url = "
"%s]\n", nsContentUtils::GetCurrentInnerOrOuterWindowCount()
, static_cast<void*>(ToCanonicalSupports(this)), getpid
(), mSerial, static_cast<void*>(ToCanonicalSupports(outer
)), url.get()); } } while (0)
1094 "%s]\n",do { const ::mozilla::LogModule* moz_real_module = gDocShellAndDOMWindowLeakLogging
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Info)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Info, "--DOMWINDOW == %d (%p) [pid = %d] [serial = %d] [outer = %p] [url = "
"%s]\n", nsContentUtils::GetCurrentInnerOrOuterWindowCount()
, static_cast<void*>(ToCanonicalSupports(this)), getpid
(), mSerial, static_cast<void*>(ToCanonicalSupports(outer
)), url.get()); } } while (0)
1095 nsContentUtils::GetCurrentInnerOrOuterWindowCount(),do { const ::mozilla::LogModule* moz_real_module = gDocShellAndDOMWindowLeakLogging
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Info)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Info, "--DOMWINDOW == %d (%p) [pid = %d] [serial = %d] [outer = %p] [url = "
"%s]\n", nsContentUtils::GetCurrentInnerOrOuterWindowCount()
, static_cast<void*>(ToCanonicalSupports(this)), getpid
(), mSerial, static_cast<void*>(ToCanonicalSupports(outer
)), url.get()); } } while (0)
1096 static_cast<void*>(ToCanonicalSupports(this)), getpid(), mSerial,do { const ::mozilla::LogModule* moz_real_module = gDocShellAndDOMWindowLeakLogging
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Info)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Info, "--DOMWINDOW == %d (%p) [pid = %d] [serial = %d] [outer = %p] [url = "
"%s]\n", nsContentUtils::GetCurrentInnerOrOuterWindowCount()
, static_cast<void*>(ToCanonicalSupports(this)), getpid
(), mSerial, static_cast<void*>(ToCanonicalSupports(outer
)), url.get()); } } while (0)
1097 static_cast<void*>(ToCanonicalSupports(outer)), url.get()))do { const ::mozilla::LogModule* moz_real_module = gDocShellAndDOMWindowLeakLogging
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Info)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Info, "--DOMWINDOW == %d (%p) [pid = %d] [serial = %d] [outer = %p] [url = "
"%s]\n", nsContentUtils::GetCurrentInnerOrOuterWindowCount()
, static_cast<void*>(ToCanonicalSupports(this)), getpid
(), mSerial, static_cast<void*>(ToCanonicalSupports(outer
)), url.get()); } } while (0)
;
1098
1099 uint32_t serial = mSerial;
1100 NS_DispatchToMainThread(
1101 NS_NewRunnableFunction(
1102 "TestDOMWindowDestroyed",
1103 [serial, url = std::move(url)] {
1104 nsCOMPtr<nsIObserverService> obs =
1105 mozilla::services::GetObserverService();
1106 if (obs) {
1107 nsString data;
1108 data.AppendPrintf("serial=%d type=inner url=%s", serial,
1109 url.get());
1110 obs->NotifyObservers(nullptr, "debug-domwindow-destroyed",
1111 data.get());
1112 }
1113 }),
1114 NS_DISPATCH_FALLIBLEnsIEventTarget::DISPATCH_FALLIBLE);
1115 }
1116#endif
1117 MOZ_LOG(gDOMLeakPRLogInner, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gDOMLeakPRLogInner
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "DOMWINDOW %p destroyed", this); } } while
(0)
1118 ("DOMWINDOW %p destroyed", this))do { const ::mozilla::LogModule* moz_real_module = gDOMLeakPRLogInner
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "DOMWINDOW %p destroyed", this); } } while
(0)
;
1119
1120 // An inner window is destroyed, pull it out of the outer window's
1121 // list if inner windows.
1122
1123 PR_REMOVE_LINK(this)do {(this)->prev->next = (this)->next; (this)->next
->prev = (this)->prev; } while (0)
;
1124
1125 // If our outer window's inner window is this window, null out the
1126 // outer window's reference to this window that's being deleted.
1127 nsGlobalWindowOuter* outer = GetOuterWindowInternal();
1128 if (outer) {
1129 outer->MaybeClearInnerWindow(this);
1130 }
1131
1132 // We don't have to leave the tab group if we are an inner window.
1133
1134 nsCOMPtr<nsIDeviceSensors> ac = do_GetService(NS_DEVICE_SENSORS_CONTRACTID"@mozilla.org/devicesensors;1");
1135 if (ac) ac->RemoveWindowAsListener(this);
1136
1137 nsLayoutStatics::Release();
1138}
1139
1140// static
1141void nsGlobalWindowInner::ShutDown() {
1142 AssertIsOnMainThread();
1143
1144 if (gDumpFile && gDumpFile != stdoutstdout) {
1145 fclose(gDumpFile);
1146 }
1147 gDumpFile = nullptr;
1148
1149 sInnerWindowsById = nullptr;
1150}
1151
1152void nsGlobalWindowInner::FreeInnerObjects() {
1153 if (IsDying()) {
1154 return;
1155 }
1156 StartDying();
1157
1158 ClearHasPointerRawUpdateEventListeners();
1159
1160 if (mDoc && mDoc->GetWindowContext()) {
1161 // The document is about to lose its window, so this is a good time to send
1162 // our page use counters.
1163 //
1164 // (We also do this in Document::SetScriptGlobalObject(nullptr), which
1165 // catches most cases of documents losing their window, but not all.)
1166 mDoc->SendPageUseCounters();
1167 }
1168
1169 // Make sure that this is called before we null out the document and
1170 // other members that the window destroyed observers could
1171 // re-create.
1172 if (auto* reporter = nsWindowMemoryReporter::Get()) {
1173 reporter->ObserveDOMWindowDetached(this);
1174 }
1175
1176 // Kill all of the workers for this window.
1177 CancelWorkersForWindow(*this);
1178
1179 for (RefPtr<mozilla::dom::SharedWorker> pinnedWorker :
1180 mSharedWorkers.ForwardRange()) {
1181 pinnedWorker->Close();
1182 }
1183
1184 if (mTimeoutManager) {
1185 mTimeoutManager->ClearAllTimeouts();
1186 }
1187
1188 DisableIdleCallbackRequests();
1189
1190 mChromeEventHandler = nullptr;
1191
1192 if (mListenerManager) {
1193 mListenerManager->RemoveAllListeners();
1194 mListenerManager->Disconnect();
1195 mListenerManager = nullptr;
1196 }
1197
1198 mHistory = nullptr;
1199
1200 mNavigation = nullptr;
1201
1202 if (mNavigator) {
1203 mNavigator->OnNavigation();
1204 mNavigator->Invalidate();
1205 mNavigator = nullptr;
1206 }
1207
1208 mScreen = nullptr;
1209
1210 if (mDoc) {
1211 // Remember the document's principal, URI, and policyContainer.
1212 mDocumentPrincipal = mDoc->NodePrincipal();
1213 mDocumentCookiePrincipal = mDoc->EffectiveCookiePrincipal();
1214 mDocumentStoragePrincipal = mDoc->EffectiveStoragePrincipal();
1215 mDocumentPartitionedPrincipal = mDoc->PartitionedPrincipal();
1216 mDocumentURI = mDoc->GetDocumentURI();
1217 mDocBaseURI = mDoc->GetDocBaseURI();
1218 mDocumentPolicyContainer = mDoc->GetPolicyContainer();
1219
1220 while (mDoc->EventHandlingSuppressed()) {
1221 mDoc->UnsuppressEventHandlingAndFireEvents(false);
1222 }
1223 }
1224
1225 // Remove our reference to the document and the document principal.
1226 mFocusedElement = nullptr;
1227
1228 // Unregister any remaining media source blob: URLs created by this window.
1229 if (RefPtr<DocGroup> docGroup = GetDocGroup()) {
1230 nsTArray<nsCString> mediaSourceURLs = std::move(mMediaSourceURLs);
1231 for (auto& url : mediaSourceURLs) {
1232 docGroup->UnregisterMediaSourceURL(url, /* aNotifyWindow */ false);
1233 }
1234 }
1235
1236 nsIGlobalObject::UnlinkObjectsInGlobal();
1237
1238 NotifyWindowIDDestroyed("inner-window-destroyed");
1239
1240 for (uint32_t i = 0; i < mAudioContexts.Length(); ++i) {
1241 mAudioContexts[i]->OnWindowDestroy();
1242 }
1243 mAudioContexts.Clear();
1244
1245 for (MediaKeys* mediaKeys : mMediaKeysInstances) {
1246 mediaKeys->OnInnerWindowDestroy();
1247 }
1248 mMediaKeysInstances.Clear();
1249
1250 DisableGamepadUpdates();
1251 mHasGamepad = false;
1252 mGamepads.Clear();
1253 DisableVRUpdates();
1254 mHasXRSession = false;
1255 mHasVRDisplayActivateEvents = false;
1256 mXRRuntimeDetectionInFlight = false;
1257 mXRPermissionRequestInFlight = false;
1258 mXRPermissionGranted = false;
1259 mVRDisplays.Clear();
1260
1261 // This breaks a cycle between the window and the ClientSource object.
1262 mClientSource.reset();
1263
1264 if (mWindowGlobalChild) {
1265 // Remove any remaining listeners.
1266 int64_t nListeners = mWindowGlobalChild->BeforeUnloadListeners();
1267 for (int64_t i = 0; i < nListeners; ++i) {
1268 mWindowGlobalChild->BeforeUnloadRemoved();
1269 }
1270 MOZ_ASSERT(mWindowGlobalChild->BeforeUnloadListeners() == 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mWindowGlobalChild->BeforeUnloadListeners() == 0)
>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(mWindowGlobalChild->BeforeUnloadListeners() == 0)
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("mWindowGlobalChild->BeforeUnloadListeners() == 0"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 1270
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mWindowGlobalChild->BeforeUnloadListeners() == 0"
")"); do { MOZ_CrashSequence(__null, 1270); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1271 }
1272
1273 // If we have any promiseDocumentFlushed callbacks, fire them now so
1274 // that the Promises can resolve.
1275 CallDocumentFlushedResolvers(/* aUntilExhaustion = */ true);
1276
1277 DisconnectGlobalTeardownObservers();
1278
1279#ifdef MOZ_WIDGET_ANDROID
1280 DisableOrientationChangeListener();
1281#endif
1282
1283 if (mObserver) {
1284 if (nsCOMPtr<nsIObserverService> os = services::GetObserverService()) {
1285 os->RemoveObserver(mObserver, NS_IOSERVICE_OFFLINE_STATUS_TOPIC"network:offline-status-changed");
1286 os->RemoveObserver(mObserver, MEMORY_PRESSURE_OBSERVER_TOPIC"memory-pressure");
1287 os->RemoveObserver(mObserver, PERMISSION_CHANGED_TOPIC"perm-changed");
1288 os->RemoveObserver(mObserver, "browser-perm-changed");
1289 os->RemoveObserver(mObserver, "screen-information-changed");
1290 os->RemoveObserver(mObserver, "audio-playback");
1291 }
1292
1293 RefPtr<StorageNotifierService> sns = StorageNotifierService::GetOrCreate();
1294 if (sns) {
1295 sns->Unregister(mObserver);
1296 }
1297
1298 Preferences::RemoveObserver(mObserver, "intl.accept_languages");
1299
1300 // Drop its reference to this dying window, in case for some bogus reason
1301 // the object stays around.
1302 mObserver->Forget();
1303 }
1304
1305 mMenubar = nullptr;
1306 mToolbar = nullptr;
1307 mLocationbar = nullptr;
1308 mPersonalbar = nullptr;
1309 mStatusbar = nullptr;
1310 mScrollbars = nullptr;
1311
1312 mConsole = nullptr;
1313 mCookieStore = nullptr;
1314 mDocumentPiP = nullptr;
1315 mCloseWatcherManager = nullptr;
1316
1317 mPaintWorklet = nullptr;
1318
1319 mExternal = nullptr;
1320
1321 if (mLocalStorage) {
1322 mLocalStorage->Disconnect();
1323 mLocalStorage = nullptr;
1324 }
1325 mSessionStorage = nullptr;
1326 if (mPerformance) {
1327 // Since window is dying, nothing is going to be painted with meaningful
1328 // sizes, so the temp data for LCP and container timing is no longer needed.
1329 // Clearing the container timing records also drops their raw element keys.
1330 auto* perf = static_cast<PerformanceMainThread*>(mPerformance.get());
1331 perf->ClearGeneratedTempDataForLCP();
1332 perf->ClearContainerTimingData();
1333 }
1334 mPerformance = nullptr;
1335
1336 mContentMediaController = nullptr;
1337
1338 if (mWebTaskScheduler) {
1339 mWebTaskScheduler->Disconnect();
1340 mWebTaskScheduler = nullptr;
1341 }
1342
1343 mTrustedTypePolicyFactory = nullptr;
1344
1345 mSharedWorkers.Clear();
1346
1347#ifdef MOZ_WEBSPEECH1
1348 mSpeechSynthesis = nullptr;
1349#endif
1350
1351 mGlean = nullptr;
1352 mGleanPings = nullptr;
1353
1354 mParentTarget = nullptr;
1355
1356 if (mCleanMessageManager) {
1357 MOZ_ASSERT(mIsChrome, "only chrome should have msg manager cleaned")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mIsChrome)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mIsChrome))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mIsChrome" " (" "only chrome should have msg manager cleaned"
")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp",
1357); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mIsChrome" ") ("
"only chrome should have msg manager cleaned" ")"); do { MOZ_CrashSequence
(__null, 1357); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
1358 if (mChromeFields.mMessageManager) {
1359 mChromeFields.mMessageManager->Disconnect();
1360 }
1361 }
1362
1363 if (mWindowGlobalChild && !mWindowGlobalChild->IsClosed()) {
1364 mWindowGlobalChild->Destroy();
1365 }
1366
1367 mIntlUtils = nullptr;
1368
1369 HintIsLoading(false);
1370}
1371
1372//*****************************************************************************
1373// nsGlobalWindowInner::nsISupports
1374//*****************************************************************************
1375
1376// QueryInterface implementation for nsGlobalWindowInner
1377NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsGlobalWindowInner)nsresult nsGlobalWindowInner::QueryInterface(const nsIID&
aIID, void** aInstancePtr) { do { if (!(aInstancePtr)) { NS_DebugBreak
(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 1377); MOZ_PretendNoReturn(); } } while (0); nsISupports* foundInterface
; if (TopThreeWordsEquals( aIID, (nsXPCOMCycleCollectionParticipant
::kIID), (nsCycleCollectionISupports::kIID)) && (LowWordEquals
(aIID, (nsXPCOMCycleCollectionParticipant::kIID)) || LowWordEquals
(aIID, (nsCycleCollectionISupports::kIID)))) { if (LowWordEquals
(aIID, (nsXPCOMCycleCollectionParticipant::kIID))) { *aInstancePtr
= nsGlobalWindowInner::cycleCollection::GetParticipant(); return
NS_OK; } if (LowWordEquals(aIID, (nsCycleCollectionISupports
::kIID))) { *aInstancePtr = nsGlobalWindowInner::cycleCollection
::Upcast(this); return NS_OK; } foundInterface = nullptr; } else
1378 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRYif (aIID.Equals((nsWrapperCache::kIID))) { *aInstancePtr = static_cast
<nsWrapperCache*>(this); return NS_OK; } else
1379 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, EventTarget)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsISupports>)) foundInterface = static_cast
<nsISupports*>(static_cast<EventTarget*>(this)); else
1380 NS_INTERFACE_MAP_ENTRY(nsIDOMWindow)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIDOMWindow>)) foundInterface = static_cast
<nsIDOMWindow*>(this); else
1381 NS_INTERFACE_MAP_ENTRY(nsIGlobalObject)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIGlobalObject>)) foundInterface
= static_cast<nsIGlobalObject*>(this); else
1382 NS_INTERFACE_MAP_ENTRY(nsIScriptGlobalObject)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIScriptGlobalObject>)) foundInterface
= static_cast<nsIScriptGlobalObject*>(this); else
1383 NS_INTERFACE_MAP_ENTRY(nsIScriptObjectPrincipal)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIScriptObjectPrincipal>)) foundInterface
= static_cast<nsIScriptObjectPrincipal*>(this); else
1384 NS_INTERFACE_MAP_ENTRY(mozilla::dom::EventTarget)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, mozilla::dom::EventTarget>)) foundInterface
= static_cast<mozilla::dom::EventTarget*>(this); else
1385 NS_INTERFACE_MAP_ENTRY(nsPIDOMWindowInner)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsPIDOMWindowInner>)) foundInterface
= static_cast<nsPIDOMWindowInner*>(this); else
1386 NS_INTERFACE_MAP_ENTRY(mozIDOMWindow)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, mozIDOMWindow>)) foundInterface =
static_cast<mozIDOMWindow*>(this); else
1387 NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsISupportsWeakReference>)) foundInterface
= static_cast<nsISupportsWeakReference*>(this); else
1388 NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIInterfaceRequestor>)) foundInterface
= static_cast<nsIInterfaceRequestor*>(this); else
1389NS_INTERFACE_MAP_ENDfoundInterface = 0; nsresult status; if (!foundInterface) { do
{ static_assert( mozilla::detail::AssertionConditionType<
decltype(!aIID.Equals((nsISupports::kIID)))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!aIID.Equals((nsISupports::kIID
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!aIID.Equals((nsISupports::kIID))", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 1389); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aIID.Equals((nsISupports::kIID))"
")"); do { MOZ_CrashSequence(__null, 1389); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); status = NS_NOINTERFACE
; } else { (foundInterface)->AddRef(); status = NS_OK; } *
aInstancePtr = foundInterface; return status; }
1390
1391NS_IMPL_CYCLE_COLLECTING_ADDREF(nsGlobalWindowInner)MozExternalRefCountType nsGlobalWindowInner::AddRef(void) { static_assert
(!std::is_destructible_v<nsGlobalWindowInner>, "Reference-counted class "
"nsGlobalWindowInner" " should not have a public destructor. "
"Make this class's destructor non-public"); do { static_assert
( mozilla::detail::AssertionConditionType<decltype(int32_t
(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 1391); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 1391
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); _mOwningThread.AssertOwnership("nsGlobalWindowInner"
" not thread-safe"); nsISupports* base = nsGlobalWindowInner
::cycleCollection::Upcast(this); nsrefcnt count = mRefCnt.incr
(base); NS_LogAddRef((this), (count), ("nsGlobalWindowInner")
, (uint32_t)(sizeof(*this))); return count; }
1392NS_IMPL_CYCLE_COLLECTING_RELEASE(nsGlobalWindowInner)MozExternalRefCountType nsGlobalWindowInner::Release(void) { do
{ static_assert( mozilla::detail::AssertionConditionType<
decltype(int32_t(mRefCnt) > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) > 0))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0"
" (" "dup release" ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 1392); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 1392
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); _mOwningThread.AssertOwnership("nsGlobalWindowInner"
" not thread-safe"); nsISupports* base = nsGlobalWindowInner
::cycleCollection::Upcast(this); nsrefcnt count = mRefCnt.decr
(base); if (count == 0) { NS_CycleCollectableHasRefCntZero();
} NS_LogRelease((this), (count), ("nsGlobalWindowInner")); return
count; } void nsGlobalWindowInner::DeleteCycleCollectable(void
) { delete (this); }
1393
1394NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsGlobalWindowInner)bool nsGlobalWindowInner::cycleCollection::CanSkipReal(void* p
, bool aRemovingAllowed) { nsGlobalWindowInner* tmp = DowncastCCParticipant
<nsGlobalWindowInner>(p);
1395 if (tmp->IsBlackForCC(false)) {
1396 if (nsCCUncollectableMarker::InGeneration(tmp->mCanSkipCCGeneration)) {
1397 return true;
1398 }
1399 tmp->mCanSkipCCGeneration = nsCCUncollectableMarker::sGeneration;
1400 if (EventListenerManager* elm = tmp->GetExistingListenerManager()) {
1401 elm->MarkForCC();
1402 }
1403 if (tmp->mTimeoutManager) {
1404 tmp->mTimeoutManager->UnmarkGrayTimers();
1405 }
1406 return true;
1407 }
1408NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END(void)tmp; return false; }
1409
1410NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(nsGlobalWindowInner)bool nsGlobalWindowInner::cycleCollection::CanSkipInCCReal(void
* p) { nsGlobalWindowInner* tmp = DowncastCCParticipant<nsGlobalWindowInner
>(p);
1411 return tmp->IsBlackForCC(true);
1412NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END(void)tmp; return false; }
1413
1414NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(nsGlobalWindowInner)bool nsGlobalWindowInner::cycleCollection::CanSkipThisReal(void
* p) { nsGlobalWindowInner* tmp = DowncastCCParticipant<nsGlobalWindowInner
>(p);
1415 return tmp->IsBlackForCC(false);
1416NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END(void)tmp; return false; }
1417
1418NS_IMPL_CYCLE_COLLECTION_CLASS(nsGlobalWindowInner)nsGlobalWindowInner::cycleCollection nsGlobalWindowInner::_cycleCollectorGlobal
;
1419
1420NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGlobalWindowInner)nsresult nsGlobalWindowInner::cycleCollection::TraverseNative
( void* p, nsCycleCollectionTraversalCallback& cb) { nsGlobalWindowInner
* tmp = DowncastCCParticipant<nsGlobalWindowInner>(p);
1421 if (MOZ_UNLIKELY(cb.WantDebugInfo())(__builtin_expect(!!(cb.WantDebugInfo()), 0))) {
1422 char name[512];
1423 nsAutoCString uri;
1424 if (tmp->mDoc && tmp->mDoc->GetDocumentURI()) {
1425 uri = tmp->mDoc->GetDocumentURI()->GetSpecOrDefault();
1426 }
1427 SprintfLiteral(name, "nsGlobalWindowInner # %" PRIu64"l" "u" " inner %s",
1428 tmp->mWindowID, uri.get());
1429 cb.DescribeRefCountedNode(tmp->mRefCnt.get(), name);
1430 } else {
1431 NS_IMPL_CYCLE_COLLECTION_DESCRIBE(nsGlobalWindowInner, tmp->mRefCnt.get())cb.DescribeRefCountedNode(tmp->mRefCnt.get(), "nsGlobalWindowInner"
);
1432 }
1433
1434 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNavigation)ImplCycleCollectionTraverse(cb, tmp->mNavigation, "mNavigation"
, 0);
1435
1436 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNavigator)ImplCycleCollectionTraverse(cb, tmp->mNavigator, "mNavigator"
, 0);
1437
1438 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPerformance)ImplCycleCollectionTraverse(cb, tmp->mPerformance, "mPerformance"
, 0);
1439
1440 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWebTaskScheduler)ImplCycleCollectionTraverse(cb, tmp->mWebTaskScheduler, "mWebTaskScheduler"
, 0);
1441
1442 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTrustedTypePolicyFactory)ImplCycleCollectionTraverse(cb, tmp->mTrustedTypePolicyFactory
, "mTrustedTypePolicyFactory", 0);
1443
1444#ifdef MOZ_WEBSPEECH1
1445 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSpeechSynthesis)ImplCycleCollectionTraverse(cb, tmp->mSpeechSynthesis, "mSpeechSynthesis"
, 0);
1446#endif
1447
1448 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGlean)ImplCycleCollectionTraverse(cb, tmp->mGlean, "mGlean", 0);
1449 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGleanPings)ImplCycleCollectionTraverse(cb, tmp->mGleanPings, "mGleanPings"
, 0);
1450
1451 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOuterWindow)ImplCycleCollectionTraverse(cb, tmp->mOuterWindow, "mOuterWindow"
, 0);
1452
1453 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTopInnerWindow)ImplCycleCollectionTraverse(cb, tmp->mTopInnerWindow, "mTopInnerWindow"
, 0);
1454
1455 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mListenerManager)ImplCycleCollectionTraverse(cb, tmp->mListenerManager, "mListenerManager"
, 0);
1456
1457 if (tmp->mTimeoutManager) {
1458 tmp->mTimeoutManager->ForEachUnorderedTimeout([&cb](Timeout* timeout) {
1459 cb.NoteNativeChild(timeout, NS_CYCLE_COLLECTION_PARTICIPANT(Timeout)Timeout::cycleCollection::GetParticipant());
1460 });
1461 }
1462
1463 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLocation)ImplCycleCollectionTraverse(cb, tmp->mLocation, "mLocation"
, 0);
1464 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mHistory)ImplCycleCollectionTraverse(cb, tmp->mHistory, "mHistory",
0);
1465 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCustomElements)ImplCycleCollectionTraverse(cb, tmp->mCustomElements, "mCustomElements"
, 0);
1466 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSharedWorkers)ImplCycleCollectionTraverse(cb, tmp->mSharedWorkers, "mSharedWorkers"
, 0);
1467 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLocalStorage)ImplCycleCollectionTraverse(cb, tmp->mLocalStorage, "mLocalStorage"
, 0);
1468 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSessionStorage)ImplCycleCollectionTraverse(cb, tmp->mSessionStorage, "mSessionStorage"
, 0);
1469 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIndexedDB)ImplCycleCollectionTraverse(cb, tmp->mIndexedDB, "mIndexedDB"
, 0);
1470 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentPrincipal)ImplCycleCollectionTraverse(cb, tmp->mDocumentPrincipal, "mDocumentPrincipal"
, 0);
1471 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentCookiePrincipal)ImplCycleCollectionTraverse(cb, tmp->mDocumentCookiePrincipal
, "mDocumentCookiePrincipal", 0);
1472 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentStoragePrincipal)ImplCycleCollectionTraverse(cb, tmp->mDocumentStoragePrincipal
, "mDocumentStoragePrincipal", 0);
1473 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentPartitionedPrincipal)ImplCycleCollectionTraverse(cb, tmp->mDocumentPartitionedPrincipal
, "mDocumentPartitionedPrincipal", 0);
1474 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentPolicyContainer)ImplCycleCollectionTraverse(cb, tmp->mDocumentPolicyContainer
, "mDocumentPolicyContainer", 0);
1475 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBrowserChild)ImplCycleCollectionTraverse(cb, tmp->mBrowserChild, "mBrowserChild"
, 0);
1476 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDoc)ImplCycleCollectionTraverse(cb, tmp->mDoc, "mDoc", 0);
1477 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWebIdentityHandler)ImplCycleCollectionTraverse(cb, tmp->mWebIdentityHandler, "mWebIdentityHandler"
, 0);
1478
1479 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIdleRequestExecutor)ImplCycleCollectionTraverse(cb, tmp->mIdleRequestExecutor,
"mIdleRequestExecutor", 0);
1480 for (IdleRequest* request : tmp->mIdleRequestCallbacks) {
1481 cb.NoteNativeChild(request, NS_CYCLE_COLLECTION_PARTICIPANT(IdleRequest)IdleRequest::cycleCollection::GetParticipant());
1482 }
1483
1484 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mClientSource)ImplCycleCollectionTraverse(cb, tmp->mClientSource, "mClientSource"
, 0);
1485
1486 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGamepads)ImplCycleCollectionTraverse(cb, tmp->mGamepads, "mGamepads"
, 0);
1487
1488 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCacheStorage)ImplCycleCollectionTraverse(cb, tmp->mCacheStorage, "mCacheStorage"
, 0);
1489 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mVRDisplays)ImplCycleCollectionTraverse(cb, tmp->mVRDisplays, "mVRDisplays"
, 0);
1490
1491 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDebuggerNotificationManager)ImplCycleCollectionTraverse(cb, tmp->mDebuggerNotificationManager
, "mDebuggerNotificationManager", 0);
1492
1493 // Traverse stuff from nsPIDOMWindow
1494 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChromeEventHandler)ImplCycleCollectionTraverse(cb, tmp->mChromeEventHandler, "mChromeEventHandler"
, 0);
1495 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParentTarget)ImplCycleCollectionTraverse(cb, tmp->mParentTarget, "mParentTarget"
, 0);
1496 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFocusedElement)ImplCycleCollectionTraverse(cb, tmp->mFocusedElement, "mFocusedElement"
, 0);
1497 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBrowsingContext)ImplCycleCollectionTraverse(cb, tmp->mBrowsingContext, "mBrowsingContext"
, 0);
1498 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindowGlobalChild)ImplCycleCollectionTraverse(cb, tmp->mWindowGlobalChild, "mWindowGlobalChild"
, 0);
1499 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCloseWatcherManager)ImplCycleCollectionTraverse(cb, tmp->mCloseWatcherManager,
"mCloseWatcherManager", 0);
1500
1501 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMenubar)ImplCycleCollectionTraverse(cb, tmp->mMenubar, "mMenubar",
0);
1502 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mToolbar)ImplCycleCollectionTraverse(cb, tmp->mToolbar, "mToolbar",
0);
1503 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLocationbar)ImplCycleCollectionTraverse(cb, tmp->mLocationbar, "mLocationbar"
, 0);
1504 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPersonalbar)ImplCycleCollectionTraverse(cb, tmp->mPersonalbar, "mPersonalbar"
, 0);
1505 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStatusbar)ImplCycleCollectionTraverse(cb, tmp->mStatusbar, "mStatusbar"
, 0);
1506 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mScrollbars)ImplCycleCollectionTraverse(cb, tmp->mScrollbars, "mScrollbars"
, 0);
1507 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCrypto)ImplCycleCollectionTraverse(cb, tmp->mCrypto, "mCrypto", 0
);
1508 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mConsole)ImplCycleCollectionTraverse(cb, tmp->mConsole, "mConsole",
0);
1509 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCookieStore)ImplCycleCollectionTraverse(cb, tmp->mCookieStore, "mCookieStore"
, 0);
1510 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentPiP)ImplCycleCollectionTraverse(cb, tmp->mDocumentPiP, "mDocumentPiP"
, 0);
1511 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPaintWorklet)ImplCycleCollectionTraverse(cb, tmp->mPaintWorklet, "mPaintWorklet"
, 0);
1512 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mExternal)ImplCycleCollectionTraverse(cb, tmp->mExternal, "mExternal"
, 0);
1513 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIntlUtils)ImplCycleCollectionTraverse(cb, tmp->mIntlUtils, "mIntlUtils"
, 0);
1514 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mVisualViewport)ImplCycleCollectionTraverse(cb, tmp->mVisualViewport, "mVisualViewport"
, 0);
1515 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCurrentPasteDataTransfer)ImplCycleCollectionTraverse(cb, tmp->mCurrentPasteDataTransfer
, "mCurrentPasteDataTransfer", 0);
1516
1517 tmp->TraverseObjectsInGlobal(cb);
1518
1519 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChromeFields.mMessageManager)ImplCycleCollectionTraverse(cb, tmp->mChromeFields.mMessageManager
, "mChromeFields.mMessageManager", 0);
1520 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChromeFields.mGroupMessageManagers)ImplCycleCollectionTraverse(cb, tmp->mChromeFields.mGroupMessageManagers
, "mChromeFields.mGroupMessageManagers", 0);
1521
1522 for (size_t i = 0; i < tmp->mDocumentFlushedResolvers.Length(); i++) {
1523 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentFlushedResolvers[i]->mPromise)ImplCycleCollectionTraverse(cb, tmp->mDocumentFlushedResolvers
[i]->mPromise, "mDocumentFlushedResolvers[i]->mPromise"
, 0);
;
1524 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentFlushedResolvers[i]->mCallback)ImplCycleCollectionTraverse(cb, tmp->mDocumentFlushedResolvers
[i]->mCallback, "mDocumentFlushedResolvers[i]->mCallback"
, 0);
;
1525 }
1526
1527NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END(void)tmp; return NS_OK; }
1528
1529NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGlobalWindowInner)void nsGlobalWindowInner::cycleCollection::Unlink(void* p) { nsGlobalWindowInner
* tmp = DowncastCCParticipant<nsGlobalWindowInner>(p);
1530 NS_IMPL_CYCLE_COLLECTION_UNLINK_WEAK_REFERENCEtmp->ClearWeakReferences();
1531 if (sInnerWindowsById) {
1532 sInnerWindowsById->Remove(tmp->mWindowID);
1533 }
1534
1535 JSObject* wrapper = tmp->GetWrapperPreserveColor();
1536 if (wrapper) {
1537 // Mark our realm as dead, so the JS engine won't hand out our
1538 // global after this point.
1539 JS::SetRealmNonLive(js::GetNonCCWObjectRealm(wrapper));
1540 }
1541
1542 NS_IMPL_CYCLE_COLLECTION_UNLINK(mNavigation)ImplCycleCollectionUnlink(tmp->mNavigation);
1543
1544 NS_IMPL_CYCLE_COLLECTION_UNLINK(mNavigator)ImplCycleCollectionUnlink(tmp->mNavigator);
1545
1546 NS_IMPL_CYCLE_COLLECTION_UNLINK(mPerformance)ImplCycleCollectionUnlink(tmp->mPerformance);
1547
1548 if (tmp->mWebTaskScheduler) {
1549 tmp->mWebTaskScheduler->Disconnect();
1550 NS_IMPL_CYCLE_COLLECTION_UNLINK(mWebTaskScheduler)ImplCycleCollectionUnlink(tmp->mWebTaskScheduler);
1551 }
1552
1553 NS_IMPL_CYCLE_COLLECTION_UNLINK(mTrustedTypePolicyFactory)ImplCycleCollectionUnlink(tmp->mTrustedTypePolicyFactory);
1554
1555#ifdef MOZ_WEBSPEECH1
1556 NS_IMPL_CYCLE_COLLECTION_UNLINK(mSpeechSynthesis)ImplCycleCollectionUnlink(tmp->mSpeechSynthesis);
1557#endif
1558
1559 NS_IMPL_CYCLE_COLLECTION_UNLINK(mGlean)ImplCycleCollectionUnlink(tmp->mGlean);
1560 NS_IMPL_CYCLE_COLLECTION_UNLINK(mGleanPings)ImplCycleCollectionUnlink(tmp->mGleanPings);
1561
1562 if (tmp->mOuterWindow) {
1563 nsGlobalWindowOuter::Cast(tmp->mOuterWindow)->MaybeClearInnerWindow(tmp);
1564 NS_IMPL_CYCLE_COLLECTION_UNLINK(mOuterWindow)ImplCycleCollectionUnlink(tmp->mOuterWindow);
1565 }
1566
1567 if (tmp->mListenerManager) {
1568 tmp->mListenerManager->Disconnect();
1569 NS_IMPL_CYCLE_COLLECTION_UNLINK(mListenerManager)ImplCycleCollectionUnlink(tmp->mListenerManager);
1570 }
1571
1572 // Here the Timeouts list would've been unlinked, but we rely on
1573 // that Timeout objects have been traced and will remove themselves
1574 // while unlinking.
1575
1576 tmp->UpdateTopInnerWindow();
1577 NS_IMPL_CYCLE_COLLECTION_UNLINK(mTopInnerWindow)ImplCycleCollectionUnlink(tmp->mTopInnerWindow);
1578
1579 NS_IMPL_CYCLE_COLLECTION_UNLINK(mLocation)ImplCycleCollectionUnlink(tmp->mLocation);
1580 NS_IMPL_CYCLE_COLLECTION_UNLINK(mHistory)ImplCycleCollectionUnlink(tmp->mHistory);
1581 NS_IMPL_CYCLE_COLLECTION_UNLINK(mNavigation)ImplCycleCollectionUnlink(tmp->mNavigation);
1582 NS_IMPL_CYCLE_COLLECTION_UNLINK(mCustomElements)ImplCycleCollectionUnlink(tmp->mCustomElements);
1583 NS_IMPL_CYCLE_COLLECTION_UNLINK(mSharedWorkers)ImplCycleCollectionUnlink(tmp->mSharedWorkers);
1584 if (tmp->mLocalStorage) {
1585 tmp->mLocalStorage->Disconnect();
1586 NS_IMPL_CYCLE_COLLECTION_UNLINK(mLocalStorage)ImplCycleCollectionUnlink(tmp->mLocalStorage);
1587 }
1588 NS_IMPL_CYCLE_COLLECTION_UNLINK(mSessionStorage)ImplCycleCollectionUnlink(tmp->mSessionStorage);
1589 NS_IMPL_CYCLE_COLLECTION_UNLINK(mIndexedDB)ImplCycleCollectionUnlink(tmp->mIndexedDB);
1590 NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentPrincipal)ImplCycleCollectionUnlink(tmp->mDocumentPrincipal);
1591 NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentCookiePrincipal)ImplCycleCollectionUnlink(tmp->mDocumentCookiePrincipal);
1592 NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentStoragePrincipal)ImplCycleCollectionUnlink(tmp->mDocumentStoragePrincipal);
1593 NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentPartitionedPrincipal)ImplCycleCollectionUnlink(tmp->mDocumentPartitionedPrincipal
);
1594 NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentPolicyContainer)ImplCycleCollectionUnlink(tmp->mDocumentPolicyContainer);
1595 NS_IMPL_CYCLE_COLLECTION_UNLINK(mBrowserChild)ImplCycleCollectionUnlink(tmp->mBrowserChild);
1596 NS_IMPL_CYCLE_COLLECTION_UNLINK(mDoc)ImplCycleCollectionUnlink(tmp->mDoc);
1597 NS_IMPL_CYCLE_COLLECTION_UNLINK(mWebIdentityHandler)ImplCycleCollectionUnlink(tmp->mWebIdentityHandler);
1598
1599 NS_IMPL_CYCLE_COLLECTION_UNLINK(mGamepads)ImplCycleCollectionUnlink(tmp->mGamepads);
1600
1601 NS_IMPL_CYCLE_COLLECTION_UNLINK(mCacheStorage)ImplCycleCollectionUnlink(tmp->mCacheStorage);
1602 NS_IMPL_CYCLE_COLLECTION_UNLINK(mVRDisplays)ImplCycleCollectionUnlink(tmp->mVRDisplays);
1603
1604 NS_IMPL_CYCLE_COLLECTION_UNLINK(mDebuggerNotificationManager)ImplCycleCollectionUnlink(tmp->mDebuggerNotificationManager
);
1605
1606 // Unlink stuff from nsPIDOMWindow
1607 NS_IMPL_CYCLE_COLLECTION_UNLINK(mChromeEventHandler)ImplCycleCollectionUnlink(tmp->mChromeEventHandler);
1608 NS_IMPL_CYCLE_COLLECTION_UNLINK(mParentTarget)ImplCycleCollectionUnlink(tmp->mParentTarget);
1609 NS_IMPL_CYCLE_COLLECTION_UNLINK(mFocusedElement)ImplCycleCollectionUnlink(tmp->mFocusedElement);
1610 NS_IMPL_CYCLE_COLLECTION_UNLINK(mBrowsingContext)ImplCycleCollectionUnlink(tmp->mBrowsingContext);
1611
1612 MOZ_DIAGNOSTIC_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!tmp->mWindowGlobalChild || tmp->mWindowGlobalChild
->IsClosed())>::isValid, "invalid assertion condition")
; if ((__builtin_expect(!!(!(!!(!tmp->mWindowGlobalChild ||
tmp->mWindowGlobalChild->IsClosed()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!tmp->mWindowGlobalChild || tmp->mWindowGlobalChild->IsClosed()"
" (" "How are we unlinking a window before its actor has been destroyed?"
")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp",
1614); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!tmp->mWindowGlobalChild || tmp->mWindowGlobalChild->IsClosed()"
") (" "How are we unlinking a window before its actor has been destroyed?"
")"); do { MOZ_CrashSequence(__null, 1614); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1613 !tmp->mWindowGlobalChild || tmp->mWindowGlobalChild->IsClosed(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!tmp->mWindowGlobalChild || tmp->mWindowGlobalChild
->IsClosed())>::isValid, "invalid assertion condition")
; if ((__builtin_expect(!!(!(!!(!tmp->mWindowGlobalChild ||
tmp->mWindowGlobalChild->IsClosed()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!tmp->mWindowGlobalChild || tmp->mWindowGlobalChild->IsClosed()"
" (" "How are we unlinking a window before its actor has been destroyed?"
")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp",
1614); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!tmp->mWindowGlobalChild || tmp->mWindowGlobalChild->IsClosed()"
") (" "How are we unlinking a window before its actor has been destroyed?"
")"); do { MOZ_CrashSequence(__null, 1614); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1614 "How are we unlinking a window before its actor has been destroyed?")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!tmp->mWindowGlobalChild || tmp->mWindowGlobalChild
->IsClosed())>::isValid, "invalid assertion condition")
; if ((__builtin_expect(!!(!(!!(!tmp->mWindowGlobalChild ||
tmp->mWindowGlobalChild->IsClosed()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!tmp->mWindowGlobalChild || tmp->mWindowGlobalChild->IsClosed()"
" (" "How are we unlinking a window before its actor has been destroyed?"
")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp",
1614); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!tmp->mWindowGlobalChild || tmp->mWindowGlobalChild->IsClosed()"
") (" "How are we unlinking a window before its actor has been destroyed?"
")"); do { MOZ_CrashSequence(__null, 1614); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1615 NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindowGlobalChild)ImplCycleCollectionUnlink(tmp->mWindowGlobalChild);
1616 NS_IMPL_CYCLE_COLLECTION_UNLINK(mCloseWatcherManager)ImplCycleCollectionUnlink(tmp->mCloseWatcherManager);
1617
1618 NS_IMPL_CYCLE_COLLECTION_UNLINK(mMenubar)ImplCycleCollectionUnlink(tmp->mMenubar);
1619 NS_IMPL_CYCLE_COLLECTION_UNLINK(mToolbar)ImplCycleCollectionUnlink(tmp->mToolbar);
1620 NS_IMPL_CYCLE_COLLECTION_UNLINK(mLocationbar)ImplCycleCollectionUnlink(tmp->mLocationbar);
1621 NS_IMPL_CYCLE_COLLECTION_UNLINK(mPersonalbar)ImplCycleCollectionUnlink(tmp->mPersonalbar);
1622 NS_IMPL_CYCLE_COLLECTION_UNLINK(mStatusbar)ImplCycleCollectionUnlink(tmp->mStatusbar);
1623 NS_IMPL_CYCLE_COLLECTION_UNLINK(mScrollbars)ImplCycleCollectionUnlink(tmp->mScrollbars);
1624 NS_IMPL_CYCLE_COLLECTION_UNLINK(mCrypto)ImplCycleCollectionUnlink(tmp->mCrypto);
1625 NS_IMPL_CYCLE_COLLECTION_UNLINK(mConsole)ImplCycleCollectionUnlink(tmp->mConsole);
1626 NS_IMPL_CYCLE_COLLECTION_UNLINK(mCookieStore)ImplCycleCollectionUnlink(tmp->mCookieStore);
1627 NS_IMPL_CYCLE_COLLECTION_UNLINK(mPaintWorklet)ImplCycleCollectionUnlink(tmp->mPaintWorklet);
1628 NS_IMPL_CYCLE_COLLECTION_UNLINK(mExternal)ImplCycleCollectionUnlink(tmp->mExternal);
1629 NS_IMPL_CYCLE_COLLECTION_UNLINK(mIntlUtils)ImplCycleCollectionUnlink(tmp->mIntlUtils);
1630 NS_IMPL_CYCLE_COLLECTION_UNLINK(mVisualViewport)ImplCycleCollectionUnlink(tmp->mVisualViewport);
1631 NS_IMPL_CYCLE_COLLECTION_UNLINK(mCurrentPasteDataTransfer)ImplCycleCollectionUnlink(tmp->mCurrentPasteDataTransfer);
1632
1633 tmp->UnlinkObjectsInGlobal();
1634
1635 NS_IMPL_CYCLE_COLLECTION_UNLINK(mIdleRequestExecutor)ImplCycleCollectionUnlink(tmp->mIdleRequestExecutor);
1636
1637 // Here the IdleRequest list would've been unlinked, but we rely on
1638 // that IdleRequest objects have been traced and will remove
1639 // themselves while unlinking.
1640
1641 NS_IMPL_CYCLE_COLLECTION_UNLINK(mClientSource)ImplCycleCollectionUnlink(tmp->mClientSource);
1642
1643 if (tmp->IsChromeWindow()) {
1644 if (tmp->mChromeFields.mMessageManager) {
1645 static_cast<nsFrameMessageManager*>(
1646 tmp->mChromeFields.mMessageManager.get())
1647 ->Disconnect();
1648 NS_IMPL_CYCLE_COLLECTION_UNLINK(mChromeFields.mMessageManager)ImplCycleCollectionUnlink(tmp->mChromeFields.mMessageManager
);
1649 }
1650 tmp->DisconnectAndClearGroupMessageManagers();
1651 NS_IMPL_CYCLE_COLLECTION_UNLINK(mChromeFields.mGroupMessageManagers)ImplCycleCollectionUnlink(tmp->mChromeFields.mGroupMessageManagers
);
1652 }
1653
1654 for (size_t i = 0; i < tmp->mDocumentFlushedResolvers.Length(); i++) {
1655 NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentFlushedResolvers[i]->mPromise)ImplCycleCollectionUnlink(tmp->mDocumentFlushedResolvers[i
]->mPromise);
;
1656 NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentFlushedResolvers[i]->mCallback)ImplCycleCollectionUnlink(tmp->mDocumentFlushedResolvers[i
]->mCallback);
;
1657 }
1658 tmp->mDocumentFlushedResolvers.Clear();
1659
1660 NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPERtmp->ReleaseWrapper(p);
1661NS_IMPL_CYCLE_COLLECTION_UNLINK_END(void)tmp; }
1662
1663#ifdef DEBUG1
1664void nsGlobalWindowInner::RiskyUnlink() {
1665 NS_CYCLE_COLLECTION_INNERNAME_cycleCollectorGlobal.Unlink(this);
1666}
1667#endif
1668
1669NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsGlobalWindowInner)void nsGlobalWindowInner::cycleCollection::Trace( void* p, const
TraceCallbacks& aCallbacks, void* aClosure) { nsGlobalWindowInner
* tmp = DowncastCCParticipant<nsGlobalWindowInner>(p);
1670 NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPERtmp->TraceWrapper(aCallbacks, aClosure);
1671NS_IMPL_CYCLE_COLLECTION_TRACE_END(void)tmp; }
1672
1673bool nsGlobalWindowInner::IsBlackForCC(bool aTracingNeeded) {
1674 if (!nsCCUncollectableMarker::sGeneration) {
1675 return false;
1676 }
1677
1678 return (nsCCUncollectableMarker::InGeneration(GetMarkedCCGeneration()) ||
1679 HasKnownLiveWrapper()) &&
1680 (!aTracingNeeded || HasNothingToTrace(ToSupports(this)));
1681}
1682
1683//*****************************************************************************
1684// nsGlobalWindowInner::nsIScriptGlobalObject
1685//*****************************************************************************
1686
1687bool nsGlobalWindowInner::ShouldResistFingerprinting(RFPTarget aTarget) const {
1688 if (mDoc) {
1689 return mDoc->ShouldResistFingerprinting(aTarget);
1690 }
1691 return nsContentUtils::ShouldResistFingerprinting(
1692 "If we do not have a document then we do not have any context"
1693 "to make an informed RFP choice, so we fall back to the global pref",
1694 aTarget);
1695}
1696
1697OriginTrials nsGlobalWindowInner::Trials() const {
1698 return OriginTrials::FromWindow(this);
1699}
1700
1701FontFaceSet* nsGlobalWindowInner::GetFonts() {
1702 if (mDoc) {
1703 return mDoc->Fonts();
1704 }
1705 return nullptr;
1706}
1707
1708mozilla::Result<mozilla::ipc::PrincipalInfo, nsresult>
1709nsGlobalWindowInner::GetStorageKey() {
1710 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 1710
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 1710); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1711
1712 nsIPrincipal* principal = GetEffectiveStoragePrincipal();
1713 if (!principal) {
1714 return mozilla::Err(NS_ERROR_FAILURE);
1715 }
1716
1717 mozilla::ipc::PrincipalInfo principalInfo;
1718 nsresult rv = PrincipalToPrincipalInfo(principal, &principalInfo);
1719 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1720 return mozilla::Err(rv);
1721 }
1722
1723 // Block expanded and null principals, let content and system through.
1724 if (principalInfo.type() !=
1725 mozilla::ipc::PrincipalInfo::TContentPrincipalInfo &&
1726 principalInfo.type() !=
1727 mozilla::ipc::PrincipalInfo::TSystemPrincipalInfo) {
1728 return Err(NS_ERROR_DOM_SECURITY_ERR);
1729 }
1730
1731 return std::move(principalInfo);
1732}
1733
1734mozilla::dom::StorageManager* nsGlobalWindowInner::GetStorageManager() {
1735 return Navigator()->Storage();
1736}
1737
1738// https://html.spec.whatwg.org/multipage/web-messaging.html#eligible-for-messaging
1739// * a Window object whose associated Document is fully active
1740bool nsGlobalWindowInner::IsEligibleForMessaging() { return IsFullyActive(); }
1741
1742void nsGlobalWindowInner::ReportToConsole(
1743 uint32_t aErrorFlags, const nsCString& aCategory, PropertiesFile aFile,
1744 const nsCString& aMessageName, const nsTArray<nsString>& aParams,
1745 const mozilla::SourceLocation& aLocation) {
1746 nsContentUtils::ReportToConsole(aErrorFlags, aCategory, mDoc, aFile,
1747 aMessageName.get(), aParams, aLocation);
1748}
1749
1750nsresult nsGlobalWindowInner::EnsureScriptEnvironment() {
1751 // NOTE: We can't use FORWARD_TO_OUTER here because we don't want to fail if
1752 // we're called on an inactive inner window.
1753 nsGlobalWindowOuter* outer = GetOuterWindowInternal();
1754 if (!outer) {
1755 NS_WARNING("No outer window available!")NS_DebugBreak(NS_DEBUG_WARNING, "No outer window available!",
nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 1755)
;
1756 return NS_ERROR_FAILURE;
1757 }
1758 return outer->EnsureScriptEnvironment();
1759}
1760
1761nsIScriptContext* nsGlobalWindowInner::GetScriptContext() {
1762 nsGlobalWindowOuter* outer = GetOuterWindowInternal();
1763 if (!outer) {
1764 return nullptr;
1765 }
1766 return outer->GetScriptContext();
1767}
1768
1769void nsGlobalWindowInner::TraceGlobalJSObject(JSTracer* aTrc) {
1770 TraceWrapper(aTrc, "active window global");
1771}
1772
1773void nsGlobalWindowInner::UpdateAutoplayPermission() {
1774 if (!GetWindowContext()) {
1775 return;
1776 }
1777 uint32_t perm =
1778 media::AutoplayPolicy::GetSiteAutoplayPermission(GetPrincipal());
1779 if (GetWindowContext()->GetAutoplayPermission() == perm) {
1780 return;
1781 }
1782
1783 // Setting autoplay permission on a discarded context has no effect.
1784 (void)GetWindowContext()->SetAutoplayPermission(perm);
1785}
1786
1787void nsGlobalWindowInner::UpdateShortcutsPermission() {
1788 if (!GetWindowContext() ||
1789 !GetWindowContext()->GetBrowsingContext()->IsTop()) {
1790 // We only cache the shortcuts permission on top-level WindowContexts
1791 // since we always check the top-level principal for the permission.
1792 return;
1793 }
1794
1795 uint32_t perm = GetShortcutsPermission(GetPrincipal());
1796
1797 if (GetWindowContext()->GetShortcutsPermission() == perm) {
1798 return;
1799 }
1800
1801 // If the WindowContext is discarded this has no effect.
1802 (void)GetWindowContext()->SetShortcutsPermission(perm);
1803}
1804
1805/* static */
1806uint32_t nsGlobalWindowInner::GetShortcutsPermission(nsIPrincipal* aPrincipal) {
1807 uint32_t perm = nsIPermissionManager::DENY_ACTION;
1808 nsCOMPtr<nsIPermissionManager> permMgr =
1809 mozilla::components::PermissionManager::Service();
1810 if (aPrincipal && permMgr) {
1811 permMgr->TestExactPermissionFromPrincipal(aPrincipal, "shortcuts"_ns,
1812 &perm);
1813 }
1814 return perm;
1815}
1816
1817void nsGlobalWindowInner::UpdatePopupPermission() {
1818 if (!GetWindowContext()) {
1819 return;
1820 }
1821
1822 uint32_t perm = PopupBlocker::GetPopupPermission(GetPrincipal());
1823 if (GetWindowContext()->GetPopupPermission() == perm) {
1824 return;
1825 }
1826
1827 // If the WindowContext is discarded this has no effect.
1828 (void)GetWindowContext()->SetPopupPermission(perm);
1829}
1830
1831void nsGlobalWindowInner::UpdatePermissions() {
1832 if (!GetWindowContext()) {
1833 return;
1834 }
1835
1836 nsCOMPtr<nsIPrincipal> principal = GetPrincipal();
1837 RefPtr<WindowContext> windowContext = GetWindowContext();
1838
1839 WindowContext::Transaction txn;
1840 txn.SetAutoplayPermission(
1841 media::AutoplayPolicy::GetSiteAutoplayPermission(principal));
1842 txn.SetPopupPermission(PopupBlocker::GetPopupPermission(principal));
1843
1844 if (windowContext->IsTop()) {
1845 txn.SetShortcutsPermission(GetShortcutsPermission(principal));
1846 }
1847
1848 // Setting permissions on a discarded WindowContext has no effect
1849 (void)txn.Commit(windowContext);
1850}
1851
1852void nsGlobalWindowInner::InitDocumentDependentState(JSContext* aCx) {
1853 MOZ_ASSERT(mDoc)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mDoc)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(mDoc))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("mDoc", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 1853); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mDoc" ")");
do { MOZ_CrashSequence(__null, 1853); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1854
1855 if (MOZ_LOG_TEST(gDOMLeakPRLogInner, LogLevel::Debug)(__builtin_expect(!!(mozilla::detail::log_test(gDOMLeakPRLogInner
, LogLevel::Debug)), 0))
) {
1856 nsIURI* uri = mDoc->GetDocumentURI();
1857 MOZ_LOG(gDOMLeakPRLogInner, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gDOMLeakPRLogInner
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "DOMWINDOW %p SetNewDocument %s", this, uri
? uri->GetSpecOrDefault().get() : ""); } } while (0)
1858 ("DOMWINDOW %p SetNewDocument %s", this,do { const ::mozilla::LogModule* moz_real_module = gDOMLeakPRLogInner
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "DOMWINDOW %p SetNewDocument %s", this, uri
? uri->GetSpecOrDefault().get() : ""); } } while (0)
1859 uri ? uri->GetSpecOrDefault().get() : ""))do { const ::mozilla::LogModule* moz_real_module = gDOMLeakPRLogInner
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "DOMWINDOW %p SetNewDocument %s", this, uri
? uri->GetSpecOrDefault().get() : ""); } } while (0)
;
1860 }
1861
1862 mFocusedElement = nullptr;
1863 mLocalStorage = nullptr;
1864 mSessionStorage = nullptr;
1865 mPerformance = nullptr;
1866 if (mWebTaskScheduler) {
1867 mWebTaskScheduler->Disconnect();
1868 mWebTaskScheduler = nullptr;
1869 SetWebTaskSchedulingState(nullptr);
1870 }
1871
1872 // This must be called after nullifying the internal objects because here we
1873 // could recreate them, calling the getter methods, and store them into the JS
1874 // slots. If we nullify them after, the slot values and the objects will be
1875 // out of sync.
1876 ClearDocumentDependentSlots(aCx);
1877
1878 if (!mWindowGlobalChild) {
1879 mWindowGlobalChild = WindowGlobalChild::Create(this);
1880 } else {
1881 // If the window global existed before the window, it must've come from the
1882 // AboutBlankInitializer
1883 MOZ_ASSERT(NS_IsAboutBlankAllowQueryAndFragment(GetDocumentURI()),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsAboutBlankAllowQueryAndFragment(GetDocumentURI(
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(NS_IsAboutBlankAllowQueryAndFragment(GetDocumentURI(
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("NS_IsAboutBlankAllowQueryAndFragment(GetDocumentURI())" " ("
"AboutBlankInitializer should only be used with about:blank"
")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp",
1884); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsAboutBlankAllowQueryAndFragment(GetDocumentURI())"
") (" "AboutBlankInitializer should only be used with about:blank"
")"); do { MOZ_CrashSequence(__null, 1884); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1884 "AboutBlankInitializer should only be used with about:blank")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsAboutBlankAllowQueryAndFragment(GetDocumentURI(
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(NS_IsAboutBlankAllowQueryAndFragment(GetDocumentURI(
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("NS_IsAboutBlankAllowQueryAndFragment(GetDocumentURI())" " ("
"AboutBlankInitializer should only be used with about:blank"
")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp",
1884); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsAboutBlankAllowQueryAndFragment(GetDocumentURI())"
") (" "AboutBlankInitializer should only be used with about:blank"
")"); do { MOZ_CrashSequence(__null, 1884); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1885 }
1886 MOZ_ASSERT(!GetWindowContext()->HasBeenUserGestureActivated(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!GetWindowContext()->HasBeenUserGestureActivated(
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!GetWindowContext()->HasBeenUserGestureActivated(
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!GetWindowContext()->HasBeenUserGestureActivated()" " ("
"WindowContext should always not have user gesture activation at "
"this point." ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 1888); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!GetWindowContext()->HasBeenUserGestureActivated()"
") (" "WindowContext should always not have user gesture activation at "
"this point." ")"); do { MOZ_CrashSequence(__null, 1888); __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
1887 "WindowContext should always not have user gesture activation at "do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!GetWindowContext()->HasBeenUserGestureActivated(
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!GetWindowContext()->HasBeenUserGestureActivated(
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!GetWindowContext()->HasBeenUserGestureActivated()" " ("
"WindowContext should always not have user gesture activation at "
"this point." ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 1888); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!GetWindowContext()->HasBeenUserGestureActivated()"
") (" "WindowContext should always not have user gesture activation at "
"this point." ")"); do { MOZ_CrashSequence(__null, 1888); __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
1888 "this point.")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!GetWindowContext()->HasBeenUserGestureActivated(
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!GetWindowContext()->HasBeenUserGestureActivated(
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!GetWindowContext()->HasBeenUserGestureActivated()" " ("
"WindowContext should always not have user gesture activation at "
"this point." ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 1888); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!GetWindowContext()->HasBeenUserGestureActivated()"
") (" "WindowContext should always not have user gesture activation at "
"this point." ")"); do { MOZ_CrashSequence(__null, 1888); __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
;
1889
1890 UpdatePermissions();
1891
1892 RefPtr<PermissionDelegateHandler> permDelegateHandler =
1893 mDoc->GetPermissionDelegateHandler();
1894
1895 if (permDelegateHandler) {
1896 permDelegateHandler->PopulateAllDelegatedPermissions();
1897 }
1898
1899#if defined(MOZ_WIDGET_ANDROID)
1900 // When we insert the new document to the window in the top-level browsing
1901 // context, we should reset the status of the request which is used for the
1902 // previous document.
1903 if (mWindowGlobalChild && GetBrowsingContext() &&
1904 !GetBrowsingContext()->GetParent()) {
1905 // Return value of setting synced field should be checked. See bug 1656492.
1906 (void)GetBrowsingContext()->ResetGVAutoplayRequestStatus();
1907 }
1908#endif
1909
1910#ifdef DEBUG1
1911 mLastOpenedURI = mDoc->GetDocumentURI();
1912#endif
1913}
1914
1915nsresult nsGlobalWindowInner::EnsureClientSource() {
1916 MOZ_DIAGNOSTIC_ASSERT(mDoc)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mDoc)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(mDoc))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("mDoc", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 1916); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mDoc"
")"); do { MOZ_CrashSequence(__null, 1916); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1917
1918 bool newClientSource = false;
1919
1920 // Get the load info for the document if we performed a load. Be careful not
1921 // to look at local URLs, though. Local URLs are those that have a scheme of:
1922 // * about:
1923 // * data:
1924 // * blob:
1925 // We also do an additional check here so that we only treat about:blank
1926 // and about:srcdoc as local URLs. Other internal firefox about: URLs should
1927 // not be treated this way.
1928 nsCOMPtr<nsILoadInfo> loadInfo;
1929 nsCOMPtr<nsIChannel> channel = mDoc->GetChannel();
1930 if (channel) {
1931 nsCOMPtr<nsIURI> uri;
1932 (void)channel->GetURI(getter_AddRefs(uri));
1933
1934 bool ignoreLoadInfo = false;
1935
1936 if (uri->SchemeIs("about")) {
1937 ignoreLoadInfo =
1938 NS_IsAboutBlankAllowQueryAndFragment(uri) || NS_IsAboutSrcdoc(uri);
1939 } else {
1940 // Its not an about: URL, so now check for our other URL types.
1941 ignoreLoadInfo = uri->SchemeIs("data") || uri->SchemeIs("blob");
1942 }
1943
1944 if (!ignoreLoadInfo) {
1945 loadInfo = channel->LoadInfo();
1946 }
1947 }
1948
1949 // Take the initial client source from the docshell immediately. Even if we
1950 // don't end up using it here we should consume it.
1951 UniquePtr<ClientSource> initialClientSource;
1952 nsIDocShell* docshell = GetDocShell();
1953 if (docshell) {
1954 initialClientSource = docshell->TakeInitialClientSource();
1955 }
1956
1957 // Try to get the reserved client from the LoadInfo. A Client is
1958 // reserved at the start of the channel load if there is not an
1959 // initial uncommitted about:blank whose window will be reused. It is also
1960 // created if the channel load encounters a cross-origin redirect.
1961 if (loadInfo) {
1962 UniquePtr<ClientSource> reservedClient =
1963 loadInfo->TakeReservedClientSource();
1964 if (reservedClient) {
1965 mClientSource.reset();
1966 mClientSource = std::move(reservedClient);
1967 newClientSource = true;
1968 }
1969 }
1970
1971 // We don't have a LoadInfo reserved client, but maybe we should
1972 // be inheriting an initial one from the docshell. This means
1973 // that the docshell started the channel load before creating the
1974 // initial about:blank document. This is an optimization, though,
1975 // and it created an initial Client as a placeholder for the document.
1976 // In this case we want to inherit this placeholder Client here.
1977 if (!mClientSource) {
1978 mClientSource = std::move(initialClientSource);
1979 if (mClientSource) {
1980 newClientSource = true;
1981 }
1982 }
1983
1984 nsCOMPtr<nsIPrincipal> foreignPartitionedPrincipal;
1985
1986 nsresult rv = StoragePrincipalHelper::GetPrincipal(
1987 this, StoragePrincipalHelper::eForeignPartitionedPrincipal,
1988 getter_AddRefs(foreignPartitionedPrincipal));
1989 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 1989); return rv; } } while (false)
;
1990
1991 // Verify the final ClientSource principal matches the final document
1992 // principal. The ClientChannelHelper handles things like network
1993 // redirects, but there are other ways the document principal can change.
1994 // For example, if something sets the nsIChannel.owner property, then
1995 // the final channel principal can be anything. Unfortunately there is
1996 // no good way to detect this until after the channel completes loading.
1997 //
1998 // For now we handle this just by reseting the ClientSource. This will
1999 // result in a new ClientSource with the correct principal being created.
2000 // To APIs like ServiceWorker and Clients API it will look like there was
2001 // an initial content page created that was then immediately replaced.
2002 // This is pretty close to what we are actually doing.
2003 if (mClientSource) {
2004 auto principalOrErr = mClientSource->Info().GetPrincipal();
2005 nsCOMPtr<nsIPrincipal> clientPrincipal =
2006 principalOrErr.isOk() ? principalOrErr.unwrap() : nullptr;
2007 if (!clientPrincipal ||
2008 !clientPrincipal->Equals(foreignPartitionedPrincipal)) {
2009 mClientSource.reset();
2010 }
2011 }
2012
2013 // If we don't have a reserved client or an initial client, then create
2014 // one now. This can happen in certain cases where we avoid preallocating
2015 // the client in the docshell. This mainly occurs in situations where
2016 // the principal is not clearly inherited from the parent; e.g. sandboxed
2017 // iframes, window.open(), etc.
2018 //
2019 // We also do this late ClientSource creation if the final document ended
2020 // up with a different principal.
2021 //
2022 // TODO: We may not be marking initial about:blank documents created
2023 // this way as controlled by a service worker properly. The
2024 // controller should be coming from the same place as the inheritted
2025 // principal. We do this in docshell, but as mentioned we aren't
2026 // smart enough to handle all cases yet. For example, a
2027 // window.open() with new URL should inherit the controller from
2028 // the opener, but we probably don't handle that yet.
2029 if (!mClientSource) {
2030 mClientSource = ClientManager::CreateSource(
2031 ClientType::Window, SerialEventTarget(), foreignPartitionedPrincipal);
2032 MOZ_DIAGNOSTIC_ASSERT(mClientSource)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mClientSource)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mClientSource))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("mClientSource",
"/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 2032
); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mClientSource"
")"); do { MOZ_CrashSequence(__null, 2032); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2033 newClientSource = true;
2034
2035 // Note, we don't apply the loadinfo controller below if we create
2036 // the ClientSource here.
2037 }
2038
2039 // The load may have started controlling the Client as well. If
2040 // so, mark it as controlled immediately here. The actor may
2041 // or may not have been notified by the parent side about being
2042 // controlled yet.
2043 //
2044 // Note: We should be careful not to control a client that was created late.
2045 // These clients were not seen by the ServiceWorkerManager when it
2046 // marked the LoadInfo controlled and it won't know about them. Its
2047 // also possible we are creating the client late due to the final
2048 // principal changing and these clients should definitely not be
2049 // controlled by a service worker with a different principal.
2050 else if (loadInfo) {
2051 const Maybe<ServiceWorkerDescriptor> controller = loadInfo->GetController();
2052 if (controller.isSome()) {
2053 mClientSource->SetController(controller.ref());
2054 }
2055
2056 // We also have to handle the case where te initial about:blank is
2057 // controlled due to inheritting the service worker from its parent,
2058 // but the actual nsIChannel load is not covered by any service worker.
2059 // In this case we want the final page to be uncontrolled. There is
2060 // an open spec issue about how exactly this should be handled, but for
2061 // now we just force creation of a new ClientSource to clear the
2062 // controller.
2063 //
2064 // https://github.com/w3c/ServiceWorker/issues/1232
2065 //
2066 else if (mClientSource->GetController().isSome()) {
2067 mClientSource.reset();
2068 mClientSource = ClientManager::CreateSource(
2069 ClientType::Window, SerialEventTarget(), foreignPartitionedPrincipal);
2070 MOZ_DIAGNOSTIC_ASSERT(mClientSource)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mClientSource)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mClientSource))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("mClientSource",
"/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 2070
); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mClientSource"
")"); do { MOZ_CrashSequence(__null, 2070); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2071 newClientSource = true;
2072 }
2073 }
2074
2075 if (mClientSource) {
2076 // Generally the policyContainer is stored within the Client and cached on
2077 // the document. At the time of policyContainer parsing however, the Client
2078 // has not been created yet, hence we store the policyContainer on the
2079 // document and propagate/sync the policyContainer with Client here when we
2080 // create the Client.
2081 mClientSource->SetPolicyContainer(mDoc->GetPolicyContainer());
2082
2083 DocGroup* docGroup = GetDocGroup();
2084 MOZ_DIAGNOSTIC_ASSERT(docGroup)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(docGroup)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(docGroup))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("docGroup", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 2084); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "docGroup"
")"); do { MOZ_CrashSequence(__null, 2084); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2085 mClientSource->SetAgentClusterId(docGroup->AgentClusterId());
2086
2087 if (mWindowGlobalChild) {
2088 mWindowGlobalChild->SendSetClientInfo(mClientSource->Info().ToIPC());
2089 }
2090 }
2091
2092 // Its possible that we got a client just after being frozen in
2093 // the bfcache. In that case freeze the client immediately.
2094 if (newClientSource && IsFrozen()) {
2095 mClientSource->Freeze();
2096 }
2097
2098 return NS_OK;
2099}
2100
2101nsresult nsGlobalWindowInner::ExecutionReady() {
2102 nsresult rv = EnsureClientSource();
2103 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 2103); return rv; } } while (false)
;
2104
2105 rv = mClientSource->WindowExecutionReady(this);
2106 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 2106); return rv; } } while (false)
;
2107
2108 return NS_OK;
2109}
2110
2111void nsGlobalWindowInner::UpdateParentTarget() {
2112 // NOTE: This method is identical to
2113 // nsGlobalWindowOuter::UpdateParentTarget(). IF YOU UPDATE THIS METHOD,
2114 // UPDATE THE OTHER ONE TOO!
2115
2116 // Try to get our frame element's tab child global (its in-process message
2117 // manager). If that fails, fall back to the chrome event handler's tab
2118 // child global, and if it doesn't have one, just use the chrome event
2119 // handler itself.
2120
2121 nsPIDOMWindowOuter* outer = GetOuterWindow();
2122 if (!outer) {
2123 return;
2124 }
2125 nsCOMPtr<Element> frameElement = outer->GetFrameElementInternal();
2126 nsCOMPtr<EventTarget> eventTarget =
2127 nsContentUtils::TryGetBrowserChildGlobal(frameElement);
2128
2129 if (!eventTarget) {
2130 nsGlobalWindowOuter* topWin = GetInProcessScriptableTopInternal();
2131 if (topWin) {
2132 frameElement = topWin->GetFrameElementInternal();
2133 eventTarget = nsContentUtils::TryGetBrowserChildGlobal(frameElement);
2134 }
2135 }
2136
2137 if (!eventTarget) {
2138 eventTarget = nsContentUtils::TryGetBrowserChildGlobal(mChromeEventHandler);
2139 }
2140
2141 if (!eventTarget) {
2142 eventTarget = mChromeEventHandler;
2143 }
2144
2145 mParentTarget = std::move(eventTarget);
2146}
2147
2148EventTarget* nsGlobalWindowInner::GetTargetForDOMEvent() {
2149 return GetOuterWindowInternal();
2150}
2151
2152void nsGlobalWindowInner::GetEventTargetParent(EventChainPreVisitor& aVisitor) {
2153 aVisitor.mCanHandle = true;
2154 aVisitor.mForceContentDispatch = true; // FIXME! Bug 329119
2155 switch (aVisitor.mEvent->mMessage) {
2156 case eResize:
2157 if (aVisitor.mEvent->IsTrusted()) {
2158 // Checking whether the event target is an inner window or not, so we
2159 // can keep the old behavior also in case a child window is handling
2160 // resize.
2161 if (aVisitor.mEvent->mOriginalTarget &&
2162 aVisitor.mEvent->mOriginalTarget->IsInnerWindow()) {
2163 mIsHandlingResizeEvent = true;
2164 }
2165 }
2166 break;
2167 case eMouseDown:
2168 if (aVisitor.mEvent->IsTrusted()) {
2169 sMouseDown = true;
2170 }
2171 break;
2172 case eMouseUp:
2173 case eDragEnd:
2174 if (aVisitor.mEvent->IsTrusted()) {
2175 sMouseDown = false;
2176 if (sDragServiceDisabled) {
2177 nsCOMPtr<nsIDragService> ds =
2178 do_GetService("@mozilla.org/widget/dragservice;1");
2179 if (ds) {
2180 sDragServiceDisabled = false;
2181 ds->Unsuppress();
2182 }
2183 }
2184 }
2185 break;
2186 default:
2187 break;
2188 }
2189
2190 aVisitor.SetParentTarget(GetParentTarget(), true);
2191}
2192
2193// Editor library types for about:blank compat workaround
2194enum class EmptyFrameLibrary {
2195 None,
2196 CKEditor,
2197 GWT,
2198 ZE,
2199};
2200
2201// ckeditor 4 uses UA sniffing to wait for an async load event for its editor
2202// iframe. This patch makes it work by delaying the sync-about:blank's load
2203// event on such frames. See bug 2002481 and:
2204// https://github.com/ckeditor/ckeditor4/blob/c7e59ec199298b6b23f4aa7a7668f18572385bac/plugins/wysiwygarea/plugin.js#L43
2205//
2206// GWT RichTextArea also uses UA sniffing and expects an async `load` event
2207// for its editor iframe. See bug 2020927,
2208// https://github.com/gwtproject/gwt/issues/10292 , and
2209// https://github.com/gwtproject/gwt/blob/4b6a646faf0e9ce579658d78b6acf9fe5c840379/user/src/com/google/gwt/user/client/ui/impl/RichTextAreaImplMozilla.java#L44
2210// .
2211//
2212// Polarion appears to use the GWT Editor too, but with a different class name.
2213//
2214// Old version of ZE appears to have a similar problem. Newer versions don't,
2215// because they have `srcdoc`. See bug 2020668.
2216MOZ_CAN_RUN_SCRIPT static bool IsDeferredLoadEmptyFrame(Element& aEmbedder) {
2217 const nsAttrValue* classes = aEmbedder.GetClasses();
2218 if (!classes) {
2219 return false;
2220 }
2221 EmptyFrameLibrary lib = EmptyFrameLibrary::None;
2222 if (StaticPrefs::dom_about_blank_ckeditor_hack_enabled() &&
2223 classes->Contains(nsGkAtoms::cke_wysiwyg_frame, eCaseMatters)) {
2224 lib = EmptyFrameLibrary::CKEditor;
2225 } else if (StaticPrefs::dom_about_blank_gwt_hack_enabled() &&
2226 classes->Contains(nsGkAtoms::gwt_RichTextArea, eCaseMatters)) {
2227 lib = EmptyFrameLibrary::GWT;
2228 } else if (StaticPrefs::dom_about_blank_polarion_gwt_hack_enabled() &&
2229 classes->Contains(nsGkAtoms::polarion_rte_RichTextArea,
2230 eCaseMatters)) {
2231 lib = EmptyFrameLibrary::GWT;
2232 } else if (StaticPrefs::dom_about_blank_ze_hack_enabled() &&
2233 classes->Contains(nsGkAtoms::ze_area, eCaseMatters)) {
2234 lib = EmptyFrameLibrary::ZE;
2235 }
2236 if (lib == EmptyFrameLibrary::None) {
2237 return false;
2238 }
2239 if (!aEmbedder.IsHTMLElement(nsGkAtoms::iframe)) {
2240 return false;
2241 }
2242 // We only come here if the initial document is reaching its load event.
2243 // That doesn't happen with `srcdoc`, which is an immediate navigation
2244 // to a non-about:blank document. Newer versions of ZE don't need this
2245 // and don't come here, because they have `srcdoc`.
2246 // Note: We can assert on `srcdoc` only after excluding non-iframe
2247 // element type above!
2248 MOZ_ASSERT(!aEmbedder.HasAttr(nsGkAtoms::srcdoc))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!aEmbedder.HasAttr(nsGkAtoms::srcdoc))>::isValid,
"invalid assertion condition"); if ((__builtin_expect(!!(!(!
!(!aEmbedder.HasAttr(nsGkAtoms::srcdoc)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!aEmbedder.HasAttr(nsGkAtoms::srcdoc)"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 2248
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aEmbedder.HasAttr(nsGkAtoms::srcdoc)"
")"); do { MOZ_CrashSequence(__null, 2248); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2249 const auto* src = aEmbedder.GetParsedAttr(nsGkAtoms::src);
2250 // Require empty src for CKEditor 4 and no src for GWT and ZE.
2251 switch (lib) {
2252 case EmptyFrameLibrary::CKEditor:
2253 if (!src || !src->IsEmptyString()) {
2254 return false;
2255 }
2256 break;
2257 default:
2258 if (src) {
2259 return false;
2260 }
2261 break;
2262 }
2263 const char* blocklistPref = "";
Value stored to 'blocklistPref' during its initialization is never read
2264 switch (lib) {
2265 case EmptyFrameLibrary::CKEditor:
2266 blocklistPref = "dom.about-blank-ckeditor-hack.disabled-domains";
2267 break;
2268 case EmptyFrameLibrary::GWT:
2269 blocklistPref = "dom.about-blank-gwt-hack.disabled-domains";
2270 break;
2271 case EmptyFrameLibrary::ZE:
2272 blocklistPref = "dom.about-blank-ze-hack.disabled-domains";
2273 break;
2274 case EmptyFrameLibrary::None:
2275 MOZ_ASSERT_UNREACHABLE()do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "MOZ_ASSERT_UNREACHABLE: "
")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp",
2275); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " ")"); do { MOZ_CrashSequence(__null
, 2275); __attribute__((nomerge)) ::abort(); } while (false);
} } while (false)
;
2276 return false;
2277 }
2278
2279 // Deal with the blocklist here before properties on the global
2280 // (which is potentially observable via JS getters).
2281 if (aEmbedder.NodePrincipal()->IsURIInPrefList(blocklistPref)) {
2282 return false;
2283 }
2284 // Finally, we also look for an identifying property on the embedder's global
2285 // to be extra sure.
2286 RefPtr global = aEmbedder.GetRelevantGlobal();
2287 if (!global || !global->GetGlobalJSObject()) {
2288 return false;
2289 }
2290 AutoJSAPI jsapi;
2291 if (!jsapi.Init(global)) {
2292 return false;
2293 }
2294 if (lib == EmptyFrameLibrary::GWT) {
2295 JS::Rooted<JSObject*> globalObj(jsapi.cx(), global->GetGlobalJSObject());
2296 JS::Rooted<JS::Value> val(jsapi.cx());
2297 if (!JS_GetProperty(jsapi.cx(), globalObj, "__gwt_stylesLoaded", &val)) {
2298 JS_ClearPendingException(jsapi.cx());
2299 return false;
2300 }
2301 if (!val.isObject()) {
2302 return false;
2303 }
2304 aEmbedder.OwnerDoc()->WarnOnceAbout(
2305 DeprecatedOperations::eGWTRichTextAreaCompatHack);
2306 return true;
2307 }
2308 CkEditorProperty property;
2309 JS::Rooted<JS::Value> v(jsapi.cx(),
2310 JS::ObjectValue(*global->GetGlobalJSObject()));
2311 if (!property.Init(jsapi.cx(), v)) {
2312 JS_ClearPendingException(jsapi.cx());
2313 return false;
2314 }
2315 switch (lib) {
2316 case EmptyFrameLibrary::GWT:
2317 case EmptyFrameLibrary::None:
2318 MOZ_ASSERT_UNREACHABLE()do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "MOZ_ASSERT_UNREACHABLE: "
")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp",
2318); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " ")"); do { MOZ_CrashSequence(__null
, 2318); __attribute__((nomerge)) ::abort(); } while (false);
} } while (false)
;
2319 return false;
2320 case EmptyFrameLibrary::ZE:
2321 if (!property.mZE_Init.WasPassed()) {
2322 return false;
2323 }
2324 // No use counter at least for now.
2325 aEmbedder.OwnerDoc()->WarnOnceAbout(
2326 DeprecatedOperations::eOldZECompatHack);
2327 return true;
2328 case EmptyFrameLibrary::CKEditor:
2329 const auto* version = [&]() -> const CkEditorVersion* {
2330 if (property.mCKEDITOR.WasPassed()) {
2331 return &property.mCKEDITOR.Value();
2332 }
2333 if (property.mJEDITOR.WasPassed()) {
2334 return &property.mJEDITOR.Value();
2335 }
2336 return nullptr;
2337 }();
2338 if (!version) {
2339 return false;
2340 }
2341 // The CKEditor source code has "%VERSION%", which may be left in place
2342 // in deployment if a proper build step is missing.
2343 if (!(StringBeginsWith(version->mVersion, u"4."_ns) ||
2344 version->mVersion.EqualsLiteral(u"%VERSION%"))) {
2345 return false;
2346 }
2347 aEmbedder.OwnerDoc()->WarnOnceAbout(
2348 DeprecatedOperations::eCKEditor4CompatHack);
2349 return true;
2350 }
2351 MOZ_ASSERT_UNREACHABLE("Every switch case should have returned.")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "MOZ_ASSERT_UNREACHABLE: "
"Every switch case should have returned." ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 2351); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Every switch case should have returned."
")"); do { MOZ_CrashSequence(__null, 2351); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2352 return false;
2353}
2354
2355MOZ_CAN_RUN_SCRIPT static bool NeedsAsyncLoadEventForInitialDocument(
2356 nsGlobalWindowInner& aInner, Element& aEmbedder) {
2357 if (auto* doc = aInner.GetExtantDoc(); !doc || !doc->IsInitialDocument()) {
2358 return false;
2359 }
2360 return IsDeferredLoadEmptyFrame(aEmbedder);
2361}
2362
2363void nsGlobalWindowInner::FireFrameLoadEvent() {
2364 // If we're not in a content frame, or are at a BrowsingContext tree boundary,
2365 // such as the content-chrome boundary, don't fire the "load" event.
2366 if (GetBrowsingContext()->IsTopContent() ||
2367 GetBrowsingContext()->IsChrome()) {
2368 return;
2369 }
2370
2371 // If embedder is same-process, fire the event on our embedder element.
2372 //
2373 // XXX: Bug 1440212 is looking into potentially changing this behaviour to act
2374 // more like the remote case when in-process.
2375 if (RefPtr<Element> element = GetBrowsingContext()->GetEmbedderElement()) {
2376 if (NeedsAsyncLoadEventForInitialDocument(*this, *element)) {
2377 (new AsyncEventDispatcher(element, eLoad, CanBubble::eNo))
2378 ->PostDOMEvent();
2379 return;
2380 }
2381
2382 nsEventStatus status = nsEventStatus_eIgnore;
2383 WidgetEvent event(/* aIsTrusted = */ true, eLoad);
2384 event.mFlags.mBubbles = false;
2385 event.mFlags.mCancelable = false;
2386
2387 // Most of the time we could get a pres context to pass in here, but not
2388 // always (i.e. if this window is not shown there won't be a pres context
2389 // available). Since we're not firing a GUI event we don't need a pres
2390 // context anyway so we just pass null as the pres context all the time.
2391 EventDispatcher::Dispatch(element, nullptr, &event, nullptr, &status);
2392 return;
2393 }
2394
2395 // We don't have an in-process embedder. Try to get our `BrowserChild` actor
2396 // to send a message to that embedder. We want to double-check that our outer
2397 // window is actually the one at the root of this browserChild though, just in
2398 // case.
2399 RefPtr<BrowserChild> browserChild =
2400 BrowserChild::GetFrom(static_cast<nsPIDOMWindowInner*>(this));
2401 if (browserChild &&
2402 !GetBrowsingContext()->GetParentWindowContext()->IsInProcess()) {
2403 // Double-check that our outer window is actually at the root of this
2404 // `BrowserChild`, in case we're in an odd maybe-unhosted situation like a
2405 // print preview dialog.
2406 nsCOMPtr<nsPIDOMWindowOuter> rootOuter =
2407 do_GetInterface(browserChild->WebNavigation());
2408 if (!rootOuter || rootOuter != GetOuterWindow()) {
2409 return;
2410 }
2411
2412 (void)browserChild->SendMaybeFireEmbedderLoadEvents(
2413 EmbedderElementEventType::LoadEvent);
2414 }
2415}
2416
2417nsresult nsGlobalWindowInner::PostHandleEvent(EventChainPostVisitor& aVisitor) {
2418 // Return early if there is nothing to do.
2419 switch (aVisitor.mEvent->mMessage) {
2420 case eResize:
2421 case eUnload:
2422 case eLoad:
2423 break;
2424 default:
2425 return NS_OK;
2426 }
2427
2428 /* mChromeEventHandler and mContext go dangling in the middle of this
2429 function under some circumstances (events that destroy the window)
2430 without this addref. */
2431 RefPtr<EventTarget> kungFuDeathGrip1(mChromeEventHandler);
2432 (void)kungFuDeathGrip1; // These aren't referred to through the function
2433 nsCOMPtr<nsIScriptContext> kungFuDeathGrip2(GetContextInternal());
2434 (void)kungFuDeathGrip2; // These aren't referred to through the function
2435
2436 if (aVisitor.mEvent->mMessage == eResize) {
2437 mIsHandlingResizeEvent = false;
2438 } else if (aVisitor.mEvent->mMessage == eUnload &&
2439 aVisitor.mEvent->IsTrusted()) {
2440 // If any VR display presentation is active at unload, the next page
2441 // will receive a vrdisplayactive event to indicate that it should
2442 // immediately begin vr presentation. This should occur when navigating
2443 // forwards, navigating backwards, and on page reload.
2444 for (const auto& display : mVRDisplays) {
2445 if (display->IsPresenting()) {
2446 display->StartVRNavigation();
2447 // Save this VR display ID to trigger vrdisplayactivate event
2448 // after the next load event.
2449 nsGlobalWindowOuter* outer = GetOuterWindowInternal();
2450 if (outer) {
2451 outer->SetAutoActivateVRDisplayID(display->DisplayId());
2452 }
2453
2454 // XXX The WebVR 1.1 spec does not define which of multiple VR
2455 // presenting VR displays will be chosen during navigation.
2456 // As the underlying platform VR API's currently only allow a single
2457 // VR display, it is safe to choose the first VR display for now.
2458 break;
2459 }
2460 }
2461 mIsDocumentLoaded = false;
2462 // Tell the parent process that the document is not loaded.
2463 if (mWindowGlobalChild) {
2464 mWindowGlobalChild->SendUpdateDocumentHasLoaded(mIsDocumentLoaded);
2465 mWindowGlobalChild->OnDocumentUnloaded();
2466 }
2467 } else if (aVisitor.mEvent->mMessage == eLoad &&
2468 aVisitor.mEvent->IsTrusted()) {
2469 // This is page load event since load events don't propagate to |window|.
2470 // @see Document::GetEventTargetParent.
2471 mIsDocumentLoaded = true;
2472 // Tell the parent process that the document is loaded.
2473 if (mWindowGlobalChild) {
2474 mWindowGlobalChild->SendUpdateDocumentHasLoaded(mIsDocumentLoaded);
2475 mWindowGlobalChild->OnDocumentLoaded();
2476 }
2477
2478 mTimeoutManager->OnDocumentLoaded();
2479
2480 MOZ_ASSERT(aVisitor.mEvent->IsTrusted())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aVisitor.mEvent->IsTrusted())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aVisitor.mEvent->IsTrusted
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aVisitor.mEvent->IsTrusted()", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 2480); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aVisitor.mEvent->IsTrusted()"
")"); do { MOZ_CrashSequence(__null, 2480); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2481 FireFrameLoadEvent();
2482
2483 if (mVREventObserver) {
2484 mVREventObserver->NotifyAfterLoad();
2485 }
2486
2487 uint32_t autoActivateVRDisplayID = 0;
2488 nsGlobalWindowOuter* outer = GetOuterWindowInternal();
2489 if (outer) {
2490 autoActivateVRDisplayID = outer->GetAutoActivateVRDisplayID();
2491 }
2492 if (autoActivateVRDisplayID) {
2493 DispatchVRDisplayActivate(autoActivateVRDisplayID,
2494 VRDisplayEventReason::Navigation);
2495 }
2496 }
2497
2498 return NS_OK;
2499}
2500
2501nsresult nsGlobalWindowInner::DefineArgumentsProperty(nsIArray* aArguments) {
2502 nsIScriptContext* ctx = GetOuterWindowInternal()->mContext;
2503 NS_ENSURE_TRUE(aArguments && ctx, NS_ERROR_NOT_INITIALIZED)do { if ((__builtin_expect(!!(!(aArguments && ctx)), 0
))) { NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aArguments && ctx"
") failed", nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 2503); return NS_ERROR_NOT_INITIALIZED; } } while (false)
;
2504
2505 JS::Rooted<JSObject*> obj(RootingCx(), GetWrapperPreserveColor());
2506 return ctx->SetProperty(obj, "arguments", aArguments);
2507}
2508
2509//*****************************************************************************
2510// nsGlobalWindowInner::nsIScriptObjectPrincipal
2511//*****************************************************************************
2512
2513nsIPrincipal* nsGlobalWindowInner::GetPrincipal() {
2514 if (mDoc) {
2515 // If we have a document, get the principal from the document
2516 return mDoc->NodePrincipal();
2517 }
2518
2519 if (mDocumentPrincipal) {
2520 return mDocumentPrincipal;
2521 }
2522
2523 // If we don't have a principal and we don't have a document we
2524 // ask the parent window for the principal. This can happen when
2525 // loading a frameset that has a <frame src="javascript:xxx">, in
2526 // that case the global window is used in JS before we've loaded
2527 // a document into the window.
2528
2529 nsCOMPtr<nsIScriptObjectPrincipal> objPrincipal =
2530 do_QueryInterface(GetInProcessParentInternal());
2531
2532 if (objPrincipal) {
2533 return objPrincipal->GetPrincipal();
2534 }
2535
2536 return nullptr;
2537}
2538
2539nsIPrincipal* nsGlobalWindowInner::GetEffectiveCookiePrincipal() {
2540 if (mDoc) {
2541 // If we have a document, get the principal from the document
2542 return mDoc->EffectiveCookiePrincipal();
2543 }
2544
2545 if (mDocumentCookiePrincipal) {
2546 return mDocumentCookiePrincipal;
2547 }
2548
2549 // If we don't have a cookie principal and we don't have a document we ask
2550 // the parent window for the cookie principal.
2551
2552 nsCOMPtr<nsIScriptObjectPrincipal> objPrincipal =
2553 do_QueryInterface(GetInProcessParentInternal());
2554
2555 if (objPrincipal) {
2556 return objPrincipal->GetEffectiveCookiePrincipal();
2557 }
2558
2559 return nullptr;
2560}
2561
2562nsIPrincipal* nsGlobalWindowInner::GetEffectiveStoragePrincipal() {
2563 if (mDoc) {
2564 // If we have a document, get the principal from the document
2565 return mDoc->EffectiveStoragePrincipal();
2566 }
2567
2568 if (mDocumentStoragePrincipal) {
2569 return mDocumentStoragePrincipal;
2570 }
2571
2572 // If we don't have a cookie principal and we don't have a document we ask
2573 // the parent window for the cookie principal.
2574
2575 nsCOMPtr<nsIScriptObjectPrincipal> objPrincipal =
2576 do_QueryInterface(GetInProcessParentInternal());
2577
2578 if (objPrincipal) {
2579 return objPrincipal->GetEffectiveStoragePrincipal();
2580 }
2581
2582 return nullptr;
2583}
2584
2585nsIPrincipal* nsGlobalWindowInner::PartitionedPrincipal() {
2586 if (mDoc) {
2587 // If we have a document, get the principal from the document
2588 return mDoc->PartitionedPrincipal();
2589 }
2590
2591 if (mDocumentPartitionedPrincipal) {
2592 return mDocumentPartitionedPrincipal;
2593 }
2594
2595 // If we don't have a partitioned principal and we don't have a document we
2596 // ask the parent window for the partitioned principal.
2597
2598 nsCOMPtr<nsIScriptObjectPrincipal> objPrincipal =
2599 do_QueryInterface(GetInProcessParentInternal());
2600
2601 if (objPrincipal) {
2602 return objPrincipal->PartitionedPrincipal();
2603 }
2604
2605 return nullptr;
2606}
2607
2608//*****************************************************************************
2609// nsGlobalWindowInner::nsIDOMWindow
2610//*****************************************************************************
2611
2612bool nsPIDOMWindowInner::AddAudioContext(AudioContext* aAudioContext) {
2613 mAudioContexts.AppendElement(aAudioContext);
2614
2615 // Return true if the context should be muted and false if not.
2616 nsIDocShell* docShell = GetDocShell();
2617 return docShell && !docShell->GetAllowMedia() && !aAudioContext->IsOffline();
2618}
2619
2620void nsPIDOMWindowInner::RemoveAudioContext(AudioContext* aAudioContext) {
2621 mAudioContexts.RemoveElement(aAudioContext);
2622}
2623
2624void nsPIDOMWindowInner::MuteAudioContexts() {
2625 for (uint32_t i = 0; i < mAudioContexts.Length(); ++i) {
2626 if (!mAudioContexts[i]->IsOffline()) {
2627 mAudioContexts[i]->Mute();
2628 }
2629 }
2630}
2631
2632void nsPIDOMWindowInner::UnmuteAudioContexts() {
2633 for (uint32_t i = 0; i < mAudioContexts.Length(); ++i) {
2634 if (!mAudioContexts[i]->IsOffline()) {
2635 mAudioContexts[i]->Unmute();
2636 }
2637 }
2638}
2639
2640WindowProxyHolder nsGlobalWindowInner::Window() {
2641 return WindowProxyHolder(GetBrowsingContext());
2642}
2643
2644Navigation* nsPIDOMWindowInner::Navigation() {
2645 if (!mNavigation && Navigation::IsAPIEnabled()) {
2646 mNavigation = MakeRefPtr<mozilla::dom::Navigation>(this);
2647 }
2648
2649 return mNavigation;
2650}
2651
2652Navigator* nsPIDOMWindowInner::Navigator() {
2653 if (!mNavigator) {
2654 mNavigator = MakeRefPtr<mozilla::dom::Navigator>(this);
2655 }
2656
2657 return mNavigator;
2658}
2659
2660MediaDevices* nsPIDOMWindowInner::GetExtantMediaDevices() const {
2661 return mNavigator ? mNavigator->GetExtantMediaDevices() : nullptr;
2662}
2663
2664VisualViewport* nsGlobalWindowInner::VisualViewport() {
2665 if (!mVisualViewport) {
2666 mVisualViewport = MakeRefPtr<mozilla::dom::VisualViewport>(this);
2667 }
2668 return mVisualViewport;
2669}
2670
2671nsScreen* nsGlobalWindowInner::Screen() {
2672 if (!mScreen) {
2673 mScreen = nsScreen::Create(this);
2674 }
2675 return mScreen;
2676}
2677
2678nsHistory* nsGlobalWindowInner::GetHistory(ErrorResult& aError) {
2679 if (!mHistory) {
2680 mHistory = MakeRefPtr<nsHistory>(this);
2681 }
2682 return mHistory;
2683}
2684
2685CustomElementRegistry* nsGlobalWindowInner::CustomElements() {
2686 if (!mCustomElements) {
2687 mCustomElements = MakeRefPtr<CustomElementRegistry>(this);
2688 }
2689
2690 return mCustomElements;
2691}
2692
2693CustomElementRegistry* nsGlobalWindowInner::GetExistingCustomElements() {
2694 return mCustomElements;
2695}
2696
2697Performance* nsPIDOMWindowInner::GetPerformance() {
2698 CreatePerformanceObjectIfNeeded();
2699 return mPerformance;
2700}
2701
2702void nsPIDOMWindowInner::QueuePerformanceNavigationTiming() {
2703 CreatePerformanceObjectIfNeeded();
2704 if (mPerformance) {
2705 mPerformance->QueueNavigationTimingEntry();
2706 }
2707}
2708
2709void nsPIDOMWindowInner::CreatePerformanceObjectIfNeeded() {
2710 if (mPerformance || !mDoc) {
2711 return;
2712 }
2713 RefPtr<nsDOMNavigationTiming> timing = mDoc->GetNavigationTiming();
2714 nsCOMPtr<nsITimedChannel> timedChannel(do_QueryInterface(mDoc->GetChannel()));
2715 if (timing) {
2716 mPerformance = Performance::CreateForMainThread(this, mDoc->NodePrincipal(),
2717 timing, timedChannel);
2718 }
2719}
2720
2721bool nsPIDOMWindowInner::IsSecureContext() const {
2722 return nsGlobalWindowInner::Cast(this)->IsSecureContext();
2723}
2724
2725void nsPIDOMWindowInner::Suspend(bool aIncludeSubWindows) {
2726 nsGlobalWindowInner::Cast(this)->Suspend(aIncludeSubWindows);
2727}
2728
2729void nsPIDOMWindowInner::Resume(bool aIncludeSubWindows) {
2730 nsGlobalWindowInner::Cast(this)->Resume(aIncludeSubWindows);
2731}
2732
2733void nsPIDOMWindowInner::SyncStateFromParentWindow() {
2734 nsGlobalWindowInner::Cast(this)->SyncStateFromParentWindow();
2735}
2736
2737Maybe<ClientInfo> nsPIDOMWindowInner::GetClientInfo() const {
2738 return nsGlobalWindowInner::Cast(this)->GetClientInfo();
2739}
2740
2741Maybe<ClientState> nsPIDOMWindowInner::GetClientState() const {
2742 return nsGlobalWindowInner::Cast(this)->GetClientState();
2743}
2744
2745Maybe<ServiceWorkerDescriptor> nsPIDOMWindowInner::GetController() const {
2746 return nsGlobalWindowInner::Cast(this)->GetController();
2747}
2748
2749ClientSource* nsPIDOMWindowInner::GetClientSource() const {
2750 return nsGlobalWindowInner::Cast(this)->GetClientSource();
2751}
2752
2753void nsPIDOMWindowInner::SetPolicyContainer(
2754 nsIPolicyContainer* aPolicyContainer) {
2755 return nsGlobalWindowInner::Cast(this)->SetPolicyContainer(aPolicyContainer);
2756}
2757
2758void nsPIDOMWindowInner::SetPreloadCsp(nsIContentSecurityPolicy* aPreloadCsp) {
2759 return nsGlobalWindowInner::Cast(this)->SetPreloadCsp(aPreloadCsp);
2760}
2761
2762nsIPolicyContainer* nsPIDOMWindowInner::GetPolicyContainer() {
2763 return nsGlobalWindowInner::Cast(this)->GetPolicyContainer();
2764}
2765
2766void nsPIDOMWindowInner::NoteCalledRegisterForServiceWorkerScope(
2767 const nsACString& aScope) {
2768 nsGlobalWindowInner::Cast(this)->NoteCalledRegisterForServiceWorkerScope(
2769 aScope);
2770}
2771
2772void nsPIDOMWindowInner::NoteDOMContentLoaded() {
2773 nsGlobalWindowInner::Cast(this)->NoteDOMContentLoaded();
2774}
2775
2776bool nsGlobalWindowInner::ShouldReportForServiceWorkerScope(
2777 const nsAString& aScope) {
2778 bool result = false;
2779
2780 nsPIDOMWindowOuter* topOuter = GetInProcessScriptableTop();
2781 NS_ENSURE_TRUE(topOuter, false)do { if ((__builtin_expect(!!(!(topOuter)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "topOuter" ") failed", nullptr
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 2781
); return false; } } while (false)
;
2782
2783 nsGlobalWindowInner* topInner =
2784 nsGlobalWindowInner::Cast(topOuter->GetCurrentInnerWindow());
2785 NS_ENSURE_TRUE(topInner, false)do { if ((__builtin_expect(!!(!(topInner)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "topInner" ") failed", nullptr
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 2785
); return false; } } while (false)
;
2786
2787 topInner->ShouldReportForServiceWorkerScopeInternal(
2788 NS_ConvertUTF16toUTF8(aScope), &result);
2789 return result;
2790}
2791
2792void nsGlobalWindowInner::GetInstallTrigger(
2793 JSContext* aCx, JS::MutableHandle<JSObject*> aResult) {
2794 // Return nullptr, to avoid breaking "typeof InstallTrigger !== 'undefined"
2795 // "UA detection" use case.
2796 //
2797 // A pref ("extensions.InstallTrigger.enabled"), associated to this
2798 // property using the [Pref] extended attribute in Window.webidl, hides the
2799 // entire InstallTrigger property.
2800 //
2801 // See Bug 1754441 for more details about this deprecation.
2802 aResult.set(nullptr);
2803}
2804
2805nsIDOMWindowUtils* nsGlobalWindowInner::GetWindowUtils(ErrorResult& aRv) {
2806 FORWARD_TO_OUTER_OR_THROW(WindowUtils, (), aRv, nullptr);
2807}
2808
2809bool nsGlobalWindowInner::SynthesizeMouseEvent(
2810 const nsAString& aType, float aOffsetX, float aOffsetY,
2811 const SynthesizeMouseEventData& aMouseEventData,
2812 const SynthesizeMouseEventOptions& aOptions,
2813 const Optional<OwningNonNull<VoidFunction>>& aCallback,
2814 ErrorResult& aError) {
2815 nsIDocShell* docShell = GetDocShell();
2816 RefPtr<PresShell> presShell = docShell ? docShell->GetPresShell() : nullptr;
2817 if (!presShell) {
2818 aError.Throw(NS_ERROR_FAILURE);
2819 return false;
2820 }
2821
2822 nsPoint offset;
2823 nsCOMPtr<nsIWidget> widget = nsContentUtils::GetWidget(presShell, &offset);
2824 if (!widget) {
2825 aError.Throw(NS_ERROR_FAILURE);
2826 return false;
2827 }
2828
2829 LayoutDeviceIntPoint refPoint = nsContentUtils::ToWidgetPoint(
2830 CSSPoint(aOffsetX, aOffsetY), offset, presShell->GetPresContext());
2831 auto result = nsContentUtils::SynthesizeMouseEvent(
2832 presShell, widget, aType, refPoint, aMouseEventData, aOptions, aCallback);
2833 if (result.isErr()) {
2834 aError.Throw(result.unwrapErr());
2835 return false;
2836 }
2837
2838 return result.unwrap();
2839}
2840
2841bool nsGlobalWindowInner::SynthesizeTouchEvent(
2842 const nsAString& aType, const nsTArray<SynthesizeTouchEventData>& aTouches,
2843 const int32_t aModifiers, const SynthesizeTouchEventOptions& aOptions,
2844 const Optional<OwningNonNull<VoidFunction>>& aCallback,
2845 mozilla::ErrorResult& aError) {
2846 nsIDocShell* docShell = GetDocShell();
2847 RefPtr<PresShell> presShell = docShell ? docShell->GetPresShell() : nullptr;
2848 if (!presShell) {
2849 aError.Throw(NS_ERROR_FAILURE);
2850 return false;
2851 }
2852
2853 nsPoint offset;
2854 nsCOMPtr<nsIWidget> widget = nsContentUtils::GetWidget(presShell, &offset);
2855 if (!widget) {
2856 aError.Throw(NS_ERROR_FAILURE);
2857 return false;
2858 }
2859
2860 RefPtr<nsPresContext> presContext = mDoc->GetPresContext();
2861 if (!presContext) {
2862 aError.Throw(NS_ERROR_FAILURE);
2863 return false;
2864 }
2865
2866 auto result = nsContentUtils::SynthesizeTouchEvent(
2867 presContext, widget, offset, aType, aTouches, aModifiers, aOptions,
2868 aCallback);
2869 if (result.isErr()) {
2870 aError.Throw(result.unwrapErr());
2871 return false;
2872 }
2873
2874 return result.unwrap();
2875}
2876
2877CallState nsGlobalWindowInner::ShouldReportForServiceWorkerScopeInternal(
2878 const nsACString& aScope, bool* aResultOut) {
2879 MOZ_DIAGNOSTIC_ASSERT(aResultOut)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aResultOut)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aResultOut))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("aResultOut", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 2879); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "aResultOut"
")"); do { MOZ_CrashSequence(__null, 2879); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2880
2881 // First check to see if this window is controlled. If so, then we have
2882 // found a match and are done.
2883 const Maybe<ServiceWorkerDescriptor> swd = GetController();
2884 if (swd.isSome() && swd.ref().Scope() == aScope) {
2885 *aResultOut = true;
2886 return CallState::Stop;
2887 }
2888
2889 // Next, check to see if this window has called
2890 // navigator.serviceWorker.register() for this scope. If so, then treat this
2891 // as a match so console reports appear in the devtools console.
2892 if (mClientSource &&
2893 mClientSource->CalledRegisterForServiceWorkerScope(aScope)) {
2894 *aResultOut = true;
2895 return CallState::Stop;
2896 }
2897
2898 // Finally check the current docshell nsILoadGroup to see if there are any
2899 // outstanding navigation requests. If so, match the scope against the
2900 // channel's URL. We want to show console reports during the FetchEvent
2901 // intercepting the navigation itself.
2902 nsCOMPtr<nsIDocumentLoader> loader(do_QueryInterface(GetDocShell()));
2903 if (loader) {
2904 nsCOMPtr<nsILoadGroup> loadgroup;
2905 (void)loader->GetLoadGroup(getter_AddRefs(loadgroup));
2906 if (loadgroup) {
2907 nsCOMPtr<nsISimpleEnumerator> iter;
2908 (void)loadgroup->GetRequests(getter_AddRefs(iter));
2909 if (iter) {
2910 nsCOMPtr<nsISupports> tmp;
2911 bool hasMore = true;
2912 // Check each network request in the load group.
2913 while (NS_SUCCEEDED(iter->HasMoreElements(&hasMore))((bool)(__builtin_expect(!!(!NS_FAILED_impl(iter->HasMoreElements
(&hasMore))), 1)))
&& hasMore) {
2914 iter->GetNext(getter_AddRefs(tmp));
2915 nsCOMPtr<nsIChannel> loadingChannel(do_QueryInterface(tmp));
2916 // Ignore subresource requests. Logging for a subresource
2917 // FetchEvent should be handled above since the client is
2918 // already controlled.
2919 if (!loadingChannel ||
2920 !nsContentUtils::IsNonSubresourceRequest(loadingChannel)) {
2921 continue;
2922 }
2923 nsCOMPtr<nsIURI> loadingURL;
2924 (void)loadingChannel->GetURI(getter_AddRefs(loadingURL));
2925 if (!loadingURL) {
2926 continue;
2927 }
2928 nsAutoCString loadingSpec;
2929 (void)loadingURL->GetSpec(loadingSpec);
2930 // Perform a simple substring comparison to match the scope
2931 // against the channel URL.
2932 if (StringBeginsWith(loadingSpec, aScope)) {
2933 *aResultOut = true;
2934 return CallState::Stop;
2935 }
2936 }
2937 }
2938 }
2939 }
2940
2941 // The current window doesn't care about this service worker, but maybe
2942 // one of our child frames does.
2943 return CallOnInProcessChildren(
2944 &nsGlobalWindowInner::ShouldReportForServiceWorkerScopeInternal, aScope,
2945 aResultOut);
2946}
2947
2948void nsGlobalWindowInner::NoteCalledRegisterForServiceWorkerScope(
2949 const nsACString& aScope) {
2950 if (!mClientSource) {
2951 return;
2952 }
2953
2954 mClientSource->NoteCalledRegisterForServiceWorkerScope(aScope);
2955}
2956
2957void nsGlobalWindowInner::NoteDOMContentLoaded() {
2958 if (!mClientSource) {
2959 return;
2960 }
2961
2962 mClientSource->NoteDOMContentLoaded();
2963}
2964
2965void nsGlobalWindowInner::UpdateTopInnerWindow() {
2966 if (IsTopInnerWindow() || !mTopInnerWindow) {
2967 return;
2968 }
2969
2970 nsGlobalWindowInner::Cast(mTopInnerWindow)
2971 ->UpdateWebSocketCount(-(int32_t)mNumOfOpenWebSockets);
2972}
2973
2974bool nsGlobalWindowInner::IsInSyncOperation() {
2975 return GetExtantDoc() && GetExtantDoc()->IsInSyncOperation();
2976}
2977
2978bool nsGlobalWindowInner::IsSharedMemoryAllowedInternal(
2979 nsIPrincipal* aPrincipal) const {
2980 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 2980
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 2980); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2981
2982 if (StaticPrefs::
2983 dom_postMessage_sharedArrayBuffer_bypassCOOP_COEP_insecure_enabled()) {
2984 return true;
2985 }
2986
2987 if (ExtensionPolicyService::GetSingleton().IsExtensionProcess()) {
2988 if (auto* basePrincipal = BasePrincipal::Cast(aPrincipal)) {
2989 if (auto* policy = basePrincipal->AddonPolicy()) {
2990 return policy->IsPrivileged();
2991 }
2992 }
2993 }
2994
2995 return CrossOriginIsolated();
2996}
2997
2998bool nsGlobalWindowInner::CrossOriginIsolated() const {
2999 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 2999
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 2999); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3000
3001 RefPtr<BrowsingContext> bc = GetBrowsingContext();
3002 MOZ_DIAGNOSTIC_ASSERT(bc)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(bc)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(bc))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("bc", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 3002); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "bc"
")"); do { MOZ_CrashSequence(__null, 3002); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3003 return bc->CrossOriginIsolated();
3004}
3005
3006bool nsGlobalWindowInner::OriginAgentCluster() const {
3007 if (DocGroup* docGroup = GetDocGroup()) {
3008 return docGroup->IsOriginKeyed();
3009 }
3010 return false;
3011}
3012
3013WindowContext* TopWindowContext(nsPIDOMWindowInner& aWindow) {
3014 WindowContext* wc = aWindow.GetWindowContext();
3015 if (!wc) {
3016 return nullptr;
3017 }
3018
3019 return wc->TopWindowContext();
3020}
3021
3022void nsPIDOMWindowInner::AddPeerConnection() {
3023 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 3023
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 3023); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3024 ++mActivePeerConnections;
3025 if (mActivePeerConnections == 1 && mWindowGlobalChild) {
3026 mWindowGlobalChild->SendUpdateActivePeerConnectionStatus(
3027 /*aIsAdded*/ true);
3028
3029 // We need to present having active peer connections immediately. If we need
3030 // to wait for the parent process to come back with this information we
3031 // might start throttling.
3032 if (WindowContext* top = TopWindowContext(*this)) {
3033 top->TransientSetHasActivePeerConnections();
3034 }
3035 }
3036}
3037
3038void nsPIDOMWindowInner::RemovePeerConnection() {
3039 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 3039
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 3039); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3040 MOZ_ASSERT(mActivePeerConnections > 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mActivePeerConnections > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mActivePeerConnections > 0
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"mActivePeerConnections > 0", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 3040); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mActivePeerConnections > 0"
")"); do { MOZ_CrashSequence(__null, 3040); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3041 --mActivePeerConnections;
3042 if (mActivePeerConnections == 0 && mWindowGlobalChild) {
3043 mWindowGlobalChild->SendUpdateActivePeerConnectionStatus(
3044 /*aIsAdded*/ false);
3045 }
3046}
3047
3048bool nsGlobalWindowInner::HasActivePeerConnections() {
3049 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 3049
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 3049); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3050
3051 WindowContext* topWindowContext = TopWindowContext(*this);
3052 return topWindowContext && topWindowContext->GetHasActivePeerConnections();
3053}
3054
3055void nsPIDOMWindowInner::AddMediaKeysInstance(MediaKeys* aMediaKeys) {
3056 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 3056
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 3056); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3057 mMediaKeysInstances.AppendElement(aMediaKeys);
3058 if (mWindowGlobalChild && mMediaKeysInstances.Length() == 1) {
3059 mWindowGlobalChild->BlockBFCacheFor(BFCacheStatus::CONTAINS_EME_CONTENT);
3060 }
3061}
3062
3063void nsPIDOMWindowInner::RemoveMediaKeysInstance(MediaKeys* aMediaKeys) {
3064 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 3064
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 3064); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3065 mMediaKeysInstances.RemoveElement(aMediaKeys);
3066 if (mWindowGlobalChild && mMediaKeysInstances.IsEmpty()) {
3067 mWindowGlobalChild->UnblockBFCacheFor(BFCacheStatus::CONTAINS_EME_CONTENT);
3068 }
3069}
3070
3071bool nsPIDOMWindowInner::HasActiveMediaKeysInstance() {
3072 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 3072
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 3072); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3073 return !mMediaKeysInstances.IsEmpty();
3074}
3075
3076bool nsGlobalWindowInner::IsPlayingAudio() {
3077 for (uint32_t i = 0; i < mAudioContexts.Length(); i++) {
3078 if (mAudioContexts[i]->IsRunning()) {
3079 return true;
3080 }
3081 }
3082 RefPtr<AudioChannelService> acs = AudioChannelService::Get();
3083 if (!acs) {
3084 return false;
3085 }
3086 auto outer = GetOuterWindow();
3087 if (!outer) {
3088 // We've been unlinked and are about to die. Not a good time to pretend to
3089 // be playing audio.
3090 return false;
3091 }
3092 return acs->IsWindowActive(outer);
3093}
3094
3095bool nsPIDOMWindowInner::IsDocumentLoaded() const { return mIsDocumentLoaded; }
3096
3097mozilla::dom::TimeoutManager* nsGlobalWindowInner::GetTimeoutManager() {
3098 return mTimeoutManager.get();
3099}
3100
3101bool nsGlobalWindowInner::IsRunningTimeout() {
3102 return GetTimeoutManager()->IsRunningTimeout();
3103}
3104
3105void nsPIDOMWindowInner::TryToCacheTopInnerWindow() {
3106 if (mHasTriedToCacheTopInnerWindow) {
3107 return;
3108 }
3109
3110 nsGlobalWindowInner* window = nsGlobalWindowInner::Cast(this);
3111
3112 MOZ_ASSERT(!window->IsDying())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!window->IsDying())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!window->IsDying()))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("!window->IsDying()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 3112
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!window->IsDying()"
")"); do { MOZ_CrashSequence(__null, 3112); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3113
3114 mHasTriedToCacheTopInnerWindow = true;
3115
3116 MOZ_ASSERT(window)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(window)>::isValid, "invalid assertion condition")
; if ((__builtin_expect(!!(!(!!(window))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("window", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 3116); AnnotateMozCrashReason("MOZ_ASSERT" "(" "window" ")"
); do { MOZ_CrashSequence(__null, 3116); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3117
3118 if (nsCOMPtr<nsPIDOMWindowOuter> topOutter =
3119 window->GetInProcessScriptableTop()) {
3120 mTopInnerWindow = topOutter->GetCurrentInnerWindow();
3121 }
3122}
3123
3124void nsGlobalWindowInner::UpdateActiveIndexedDBDatabaseCount(int32_t aDelta) {
3125 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 3125
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 3125); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3126
3127 if (aDelta == 0) {
3128 return;
3129 }
3130
3131 // We count databases but not transactions because only active databases
3132 // could block throttling.
3133 uint32_t& counter = mTopInnerWindow
3134 ? mTopInnerWindow->mNumOfIndexedDBDatabases
3135 : mNumOfIndexedDBDatabases;
3136
3137 counter += aDelta;
3138}
3139
3140bool nsGlobalWindowInner::HasActiveIndexedDBDatabases() const {
3141 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 3141
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 3141); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3142
3143 return mTopInnerWindow ? mTopInnerWindow->mNumOfIndexedDBDatabases > 0
3144 : mNumOfIndexedDBDatabases > 0;
3145}
3146
3147void nsGlobalWindowInner::UpdateWebSocketCount(int32_t aDelta) {
3148 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 3148
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 3148); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3149
3150 if (aDelta == 0) {
3151 return;
3152 }
3153
3154 if (mTopInnerWindow && !IsTopInnerWindow()) {
3155 nsGlobalWindowInner::Cast(mTopInnerWindow)->UpdateWebSocketCount(aDelta);
3156 }
3157
3158 MOZ_DIAGNOSTIC_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aDelta > 0 || ((aDelta + mNumOfOpenWebSockets) <
mNumOfOpenWebSockets))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aDelta > 0 || ((aDelta + mNumOfOpenWebSockets
) < mNumOfOpenWebSockets)))), 0))) { do { } while (false);
MOZ_ReportAssertionFailure("aDelta > 0 || ((aDelta + mNumOfOpenWebSockets) < mNumOfOpenWebSockets)"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 3159
); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "aDelta > 0 || ((aDelta + mNumOfOpenWebSockets) < mNumOfOpenWebSockets)"
")"); do { MOZ_CrashSequence(__null, 3159); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
3159 aDelta > 0 || ((aDelta + mNumOfOpenWebSockets) < mNumOfOpenWebSockets))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aDelta > 0 || ((aDelta + mNumOfOpenWebSockets) <
mNumOfOpenWebSockets))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aDelta > 0 || ((aDelta + mNumOfOpenWebSockets
) < mNumOfOpenWebSockets)))), 0))) { do { } while (false);
MOZ_ReportAssertionFailure("aDelta > 0 || ((aDelta + mNumOfOpenWebSockets) < mNumOfOpenWebSockets)"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 3159
); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "aDelta > 0 || ((aDelta + mNumOfOpenWebSockets) < mNumOfOpenWebSockets)"
")"); do { MOZ_CrashSequence(__null, 3159); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3160
3161 mNumOfOpenWebSockets += aDelta;
3162}
3163
3164bool nsGlobalWindowInner::HasOpenWebSockets() const {
3165 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 3165
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 3165); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3166
3167 return mNumOfOpenWebSockets ||
3168 (mTopInnerWindow && mTopInnerWindow->mNumOfOpenWebSockets);
3169}
3170
3171void nsGlobalWindowInner::AudioPlaybackChanged(bool aIsPlayingAudio) {
3172 AUTO_PROFILER_MARKER_UNTYPED("AudioPlaybackChanged", DOM, {})AutoProfilerUntypedMarker raiiObject3172( "AudioPlaybackChanged"
, ::mozilla::baseprofiler::category::DOM, {})
;
3173 UpdateWorkersPlaybackState(*this, aIsPlayingAudio);
3174}
3175
3176bool nsPIDOMWindowInner::IsCurrentInnerWindow() const {
3177 if (mBrowsingContext && mBrowsingContext->IsInBFCache()) {
3178 return false;
3179 }
3180
3181 if (!mBrowsingContext || mBrowsingContext->IsDiscarded()) {
3182 // If our BrowsingContext has been discarded, we consider ourselves
3183 // still-current if we were current at the time it was discarded.
3184 return mOuterWindow && WasCurrentInnerWindow();
3185 }
3186
3187 nsPIDOMWindowOuter* outer = mBrowsingContext->GetDOMWindow();
3188 return outer && outer->GetCurrentInnerWindow() == this;
3189}
3190
3191bool nsGlobalWindowInner::HasScheduledNormalOrHighPriorityWebTasks() const {
3192 return gNumNormalOrHighPriorityQueuesHaveTaskScheduledMainThread > 0;
3193}
3194
3195bool nsPIDOMWindowInner::IsFullyActive() const {
3196 WindowContext* wc = GetWindowContext();
3197 if (!wc || wc->IsDiscarded() || !wc->IsCurrent()) {
3198 return false;
3199 }
3200 return GetBrowsingContext()->AncestorsAreCurrent();
3201}
3202
3203void nsPIDOMWindowInner::SetAudioCapture(bool aCapture) {
3204 RefPtr<AudioChannelService> service = AudioChannelService::GetOrCreate();
3205 if (service) {
3206 service->SetWindowAudioCaptured(GetOuterWindow(), mWindowID, aCapture);
3207 }
3208}
3209
3210void nsGlobalWindowInner::SetActiveLoadingState(bool aIsLoading) {
3211 MOZ_LOG(do { const ::mozilla::LogModule* moz_real_module = gTimeoutLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, "SetActiveLoadingState innerwindow %p: %d"
, (void*)this, aIsLoading); } } while (0)
3212 gTimeoutLog, mozilla::LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gTimeoutLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, "SetActiveLoadingState innerwindow %p: %d"
, (void*)this, aIsLoading); } } while (0)
3213 ("SetActiveLoadingState innerwindow %p: %d", (void*)this, aIsLoading))do { const ::mozilla::LogModule* moz_real_module = gTimeoutLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, "SetActiveLoadingState innerwindow %p: %d"
, (void*)this, aIsLoading); } } while (0)
;
3214 if (GetBrowsingContext()) {
3215 // Setting loading on a discarded context has no effect.
3216 (void)GetBrowsingContext()->SetLoading(aIsLoading);
3217 }
3218
3219 if (StaticPrefs::dom_timeout_defer_during_load() && !IsChromeWindow()) {
3220 nsIPrincipal* principal = GetPrincipal();
3221 if (!principal || !principal->IsURIInPrefList(
3222 "dom.timeout.defer_during_load.force-disable")) {
3223 mTimeoutManager->SetLoading(aIsLoading);
3224 }
3225 }
3226
3227 HintIsLoading(aIsLoading);
3228}
3229
3230void nsGlobalWindowInner::HintIsLoading(bool aIsLoading) {
3231 // Hint to tell the JS GC to use modified triggers during pageload.
3232 if (mHintedWasLoading != aIsLoading) {
3233 using namespace js::gc;
3234 SetPerformanceHint(danger::GetJSContext(), aIsLoading
3235 ? PerformanceHint::InPageLoad
3236 : PerformanceHint::Normal);
3237 mHintedWasLoading = aIsLoading;
3238 }
3239}
3240
3241// nsISpeechSynthesisGetter
3242
3243#ifdef MOZ_WEBSPEECH1
3244SpeechSynthesis* nsGlobalWindowInner::GetSpeechSynthesis(ErrorResult& aError) {
3245 if (!mSpeechSynthesis) {
3246 mSpeechSynthesis = MakeRefPtr<SpeechSynthesis>(this);
3247 }
3248
3249 return mSpeechSynthesis;
3250}
3251
3252bool nsGlobalWindowInner::HasActiveSpeechSynthesis() {
3253 if (mSpeechSynthesis) {
3254 return !mSpeechSynthesis->HasEmptyQueue();
3255 }
3256
3257 return false;
3258}
3259
3260#endif
3261
3262mozilla::glean::Glean* nsGlobalWindowInner::Glean() {
3263 if (!mGlean) {
3264 mGlean = MakeRefPtr<mozilla::glean::Glean>(this);
3265 }
3266
3267 return mGlean;
3268}
3269
3270mozilla::glean::GleanPings* nsGlobalWindowInner::GleanPings() {
3271 if (!mGleanPings) {
3272 mGleanPings = MakeRefPtr<mozilla::glean::GleanPings>();
3273 }
3274
3275 return mGleanPings;
3276}
3277
3278Nullable<WindowProxyHolder> nsGlobalWindowInner::GetParent(
3279 ErrorResult& aError) {
3280 FORWARD_TO_OUTER_OR_THROW(GetParentOuter, (), aError, nullptr);
3281}
3282
3283/**
3284 * GetInProcessScriptableParent used to be called when a script read
3285 * window.parent. Under Fission, that is now handled by
3286 * BrowsingContext::GetParent, and the result is a WindowProxyHolder rather than
3287 * an actual global window. This method still exists for legacy callers which
3288 * relied on the old logic, and require in-process windows. However, it only
3289 * works correctly when no out-of-process frames exist between this window and
3290 * the top-level window, so it should not be used in new code.
3291 *
3292 * In contrast to GetRealParent, GetInProcessScriptableParent respects <iframe
3293 * mozbrowser> boundaries, so if |this| is contained by an <iframe
3294 * mozbrowser>, we will return |this| as its own parent.
3295 */
3296nsPIDOMWindowOuter* nsGlobalWindowInner::GetInProcessScriptableParent() {
3297 FORWARD_TO_OUTER(GetInProcessScriptableParent, (), nullptr);
3298}
3299
3300/**
3301 * GetInProcessScriptableTop used to be called when a script read window.top.
3302 * Under Fission, that is now handled by BrowsingContext::Top, and the result is
3303 * a WindowProxyHolder rather than an actual global window. This method still
3304 * exists for legacy callers which relied on the old logic, and require
3305 * in-process windows. However, it only works correctly when no out-of-process
3306 * frames exist between this window and the top-level window, so it should not
3307 * be used in new code.
3308 *
3309 * In contrast to GetRealTop, GetInProcessScriptableTop respects <iframe
3310 * mozbrowser> boundaries. If we encounter a window owned by an <iframe
3311 * mozbrowser> while walking up the window hierarchy, we'll stop and return that
3312 * window.
3313 */
3314nsPIDOMWindowOuter* nsGlobalWindowInner::GetInProcessScriptableTop() {
3315 FORWARD_TO_OUTER(GetInProcessScriptableTop, (), nullptr);
3316}
3317
3318void nsGlobalWindowInner::GetContent(JSContext* aCx,
3319 JS::MutableHandle<JSObject*> aRetval,
3320 CallerType aCallerType,
3321 ErrorResult& aError) {
3322 FORWARD_TO_OUTER_OR_THROW(GetContentOuter,
3323 (aCx, aRetval, aCallerType, aError), aError, );
3324}
3325
3326BarProp* nsGlobalWindowInner::GetMenubar(ErrorResult& aError) {
3327 if (!mMenubar) {
3328 mMenubar = MakeRefPtr<MenubarProp>(this);
3329 }
3330
3331 return mMenubar;
3332}
3333
3334BarProp* nsGlobalWindowInner::GetToolbar(ErrorResult& aError) {
3335 if (!mToolbar) {
3336 mToolbar = MakeRefPtr<ToolbarProp>(this);
3337 }
3338
3339 return mToolbar;
3340}
3341
3342BarProp* nsGlobalWindowInner::GetLocationbar(ErrorResult& aError) {
3343 if (!mLocationbar) {
3344 mLocationbar = MakeRefPtr<LocationbarProp>(this);
3345 }
3346 return mLocationbar;
3347}
3348
3349BarProp* nsGlobalWindowInner::GetPersonalbar(ErrorResult& aError) {
3350 if (!mPersonalbar) {
3351 mPersonalbar = MakeRefPtr<PersonalbarProp>(this);
3352 }
3353 return mPersonalbar;
3354}
3355
3356BarProp* nsGlobalWindowInner::GetStatusbar(ErrorResult& aError) {
3357 if (!mStatusbar) {
3358 mStatusbar = MakeRefPtr<StatusbarProp>(this);
3359 }
3360 return mStatusbar;
3361}
3362
3363BarProp* nsGlobalWindowInner::GetScrollbars(ErrorResult& aError) {
3364 if (!mScrollbars) {
3365 mScrollbars = MakeRefPtr<ScrollbarsProp>(this);
3366 }
3367
3368 return mScrollbars;
3369}
3370
3371bool nsGlobalWindowInner::GetClosed(ErrorResult& aError) {
3372 // If we're called from JS (which is the only way we should be getting called
3373 // here) and we reach this point, that means our JS global is the current
3374 // target of the WindowProxy, which means that we are the "current inner"
3375 // of our outer. So if FORWARD_TO_OUTER fails to forward, that means the
3376 // outer is already torn down, which corresponds to the closed state.
3377 FORWARD_TO_OUTER(GetClosedOuter, (), true);
3378}
3379
3380Nullable<WindowProxyHolder> nsGlobalWindowInner::IndexedGetter(
3381 uint32_t aIndex) {
3382 FORWARD_TO_OUTER(IndexedGetterOuter, (aIndex), nullptr);
3383}
3384
3385namespace {
3386
3387struct InterfaceShimEntry {
3388 const char* geckoName;
3389 const char* domName;
3390};
3391
3392} // anonymous namespace
3393
3394// We add shims from Components.interfaces.nsIDOMFoo to window.Foo for each
3395// interface that has interface constants that sites might be getting off
3396// of Ci.
3397const InterfaceShimEntry kInterfaceShimMap[] = {
3398 {"nsIXMLHttpRequest", "XMLHttpRequest"},
3399 {"nsIDOMDOMException", "DOMException"},
3400 {"nsIDOMNode", "Node"},
3401 {"nsIDOMCSSRule", "CSSRule"},
3402 {"nsIDOMEvent", "Event"},
3403 {"nsIDOMNSEvent", "Event"},
3404 {"nsIDOMKeyEvent", "KeyEvent"},
3405 {"nsIDOMMouseEvent", "MouseEvent"},
3406 {"nsIDOMMouseScrollEvent", "MouseScrollEvent"},
3407 {"nsIDOMMutationEvent", "MutationEvent"},
3408 {"nsIDOMUIEvent", "UIEvent"},
3409 {"nsIDOMHTMLMediaElement", "HTMLMediaElement"},
3410 {"nsIDOMRange", "Range"},
3411 // Think about whether Ci.nsINodeFilter can just go away for websites!
3412 {"nsIDOMNodeFilter", "NodeFilter"},
3413 {"nsIDOMXPathResult", "XPathResult"}};
3414
3415bool nsGlobalWindowInner::ResolveComponentsShim(
3416 JSContext* aCx, JS::Handle<JSObject*> aGlobal,
3417 JS::MutableHandle<mozilla::Maybe<JS::PropertyDescriptor>> aDesc) {
3418 // Warn once.
3419 nsCOMPtr<Document> doc = GetExtantDoc();
3420 if (doc) {
3421 doc->WarnOnceAndReportAbout(
3422 DeprecatedOperations::eComponents, /* asError = */
3423 true);
3424 // Keep track of how often this happens.
3425 doc->SetUseCounter(eUseCounter_custom_ComponentsShimResolved);
3426 }
3427
3428 // Create a fake Components object.
3429 AssertSameCompartment(aCx, aGlobal);
3430 JS::Rooted<JSObject*> components(aCx, JS_NewPlainObject(aCx));
3431 if (NS_WARN_IF(!components)NS_warn_if_impl(!components, "!components", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 3431)
) {
3432 return false;
3433 }
3434
3435 // Create a fake interfaces object.
3436 JS::Rooted<JSObject*> interfaces(aCx, JS_NewPlainObject(aCx));
3437 if (NS_WARN_IF(!interfaces)NS_warn_if_impl(!interfaces, "!interfaces", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 3437)
) {
3438 return false;
3439 }
3440 bool ok =
3441 JS_DefineProperty(aCx, components, "interfaces", interfaces,
3442 JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY);
3443 if (NS_WARN_IF(!ok)NS_warn_if_impl(!ok, "!ok", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 3443)
) {
3444 return false;
3445 }
3446
3447 // Define a bunch of shims from the Ci.nsIDOMFoo to window.Foo for DOM
3448 // interfaces with constants.
3449 for (auto entry : kInterfaceShimMap) {
3450 // Grab the names from the table.
3451 const char* geckoName = entry.geckoName;
3452 const char* domName = entry.domName;
3453
3454 // Look up the appopriate interface object on the global.
3455 JS::Rooted<JS::Value> v(aCx, JS::UndefinedValue());
3456 ok = JS_GetProperty(aCx, aGlobal, domName, &v);
3457 if (NS_WARN_IF(!ok)NS_warn_if_impl(!ok, "!ok", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 3457)
) {
3458 return false;
3459 }
3460 if (!v.isObject()) {
3461 NS_WARNING("Unable to find interface object on global")NS_DebugBreak(NS_DEBUG_WARNING, "Unable to find interface object on global"
, nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 3461)
;
3462 continue;
3463 }
3464
3465 // Define the shim on the interfaces object.
3466 ok = JS_DefineProperty(
3467 aCx, interfaces, geckoName, v,
3468 JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY);
3469 if (NS_WARN_IF(!ok)NS_warn_if_impl(!ok, "!ok", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 3469)
) {
3470 return false;
3471 }
3472 }
3473
3474 aDesc.set(mozilla::Some(JS::PropertyDescriptor::Data(
3475 JS::ObjectValue(*components),
3476 {JS::PropertyAttribute::Configurable, JS::PropertyAttribute::Enumerable,
3477 JS::PropertyAttribute::Writable})));
3478 return true;
3479}
3480
3481#ifdef RELEASE_OR_BETA
3482# define USE_CONTROLLERS_SHIM
3483#endif
3484
3485#ifdef USE_CONTROLLERS_SHIM
3486static const JSClass ControllersShimClass = {"Controllers", 0};
3487static const JSClass XULControllersShimClass = {"XULControllers", 0};
3488#endif
3489
3490bool nsGlobalWindowInner::DoResolve(
3491 JSContext* aCx, JS::Handle<JSObject*> aObj, JS::Handle<jsid> aId,
3492 JS::MutableHandle<mozilla::Maybe<JS::PropertyDescriptor>> aDesc) {
3493 // Note: Keep this in sync with MayResolve.
3494
3495 // Note: The infallibleInit call in GlobalResolve depends on this check.
3496 if (!aId.isString()) {
3497 return true;
3498 }
3499
3500 bool found;
3501 if (!WebIDLGlobalNameHash::DefineIfEnabled(aCx, aObj, aId, aDesc, &found)) {
3502 return false;
3503 }
3504
3505 if (found) {
3506 return true;
3507 }
3508
3509 // We support a cut-down Components.interfaces in case websites are
3510 // using Components.interfaces.nsIFoo.CONSTANT_NAME for the ones
3511 // that have constants.
3512 if (StaticPrefs::dom_use_components_shim() &&
3513 aId == XPCJSRuntime::Get()->GetStringID(XPCJSContext::IDX_COMPONENTS)) {
3514 return ResolveComponentsShim(aCx, aObj, aDesc);
3515 }
3516
3517 // We also support a "window.controllers" thing; apparently some
3518 // sites use it for browser-sniffing. See bug 1010577.
3519#ifdef USE_CONTROLLERS_SHIM
3520 // Note: We use |aObj| rather than |this| to get the principal here, because
3521 // this is called during Window setup when the Document isn't necessarily
3522 // hooked up yet.
3523 if ((aId == XPCJSRuntime::Get()->GetStringID(XPCJSContext::IDX_CONTROLLERS) ||
3524 aId == XPCJSRuntime::Get()->GetStringID(
3525 XPCJSContext::IDX_CONTROLLERS_CLASS)) &&
3526 !xpc::IsXrayWrapper(aObj) &&
3527 !nsContentUtils::ObjectPrincipal(aObj)->IsSystemPrincipal()) {
3528 if (GetExtantDoc()) {
3529 GetExtantDoc()->WarnOnceAndReportAbout(
3530 DeprecatedOperations::eWindow_Cc_ontrollers);
3531 }
3532 const JSClass* clazz;
3533 if (aId ==
3534 XPCJSRuntime::Get()->GetStringID(XPCJSContext::IDX_CONTROLLERS)) {
3535 clazz = &XULControllersShimClass;
3536 } else {
3537 clazz = &ControllersShimClass;
3538 }
3539 MOZ_ASSERT(JS_IsGlobalObject(aObj))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(JS_IsGlobalObject(aObj))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(JS_IsGlobalObject(aObj)))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("JS_IsGlobalObject(aObj)"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 3539
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "JS_IsGlobalObject(aObj)"
")"); do { MOZ_CrashSequence(__null, 3539); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3540 JS::Rooted<JSObject*> shim(aCx, JS_NewObject(aCx, clazz));
3541 if (NS_WARN_IF(!shim)NS_warn_if_impl(!shim, "!shim", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 3541)
) {
3542 return false;
3543 }
3544
3545 aDesc.set(mozilla::Some(JS::PropertyDescriptor::Data(
3546 JS::ObjectValue(*shim),
3547 {JS::PropertyAttribute::Configurable, JS::PropertyAttribute::Enumerable,
3548 JS::PropertyAttribute::Writable})));
3549 return true;
3550 }
3551#endif
3552
3553 return true;
3554}
3555
3556/* static */
3557bool nsGlobalWindowInner::MayResolve(jsid aId) {
3558 // Note: This function does not fail and may not have any side-effects.
3559 // Note: Keep this in sync with DoResolve.
3560 if (!aId.isString()) {
3561 return false;
3562 }
3563
3564 if (aId == XPCJSRuntime::Get()->GetStringID(XPCJSContext::IDX_COMPONENTS)) {
3565 return true;
3566 }
3567
3568 if (aId == XPCJSRuntime::Get()->GetStringID(XPCJSContext::IDX_CONTROLLERS) ||
3569 aId == XPCJSRuntime::Get()->GetStringID(
3570 XPCJSContext::IDX_CONTROLLERS_CLASS)) {
3571 // We only resolve .controllers/.Controllers in release builds and on
3572 // non-chrome windows, but let's not worry about any of that stuff.
3573 return true;
3574 }
3575
3576 return WebIDLGlobalNameHash::MayResolve(aId);
3577}
3578
3579void nsGlobalWindowInner::GetOwnPropertyNames(
3580 JSContext* aCx, JS::MutableHandleVector<jsid> aNames, bool aEnumerableOnly,
3581 ErrorResult& aRv) {
3582 if (aEnumerableOnly) {
3583 // The names we would return from here get defined on the window via one of
3584 // two codepaths. The ones coming from the WebIDLGlobalNameHash will end up
3585 // in the DefineConstructor function in BindingUtils, which always defines
3586 // things as non-enumerable. The ones coming from the script namespace
3587 // manager get defined by our resolve hook using FillPropertyDescriptor with
3588 // 0 for the property attributes, so non-enumerable as well.
3589 //
3590 // So in the aEnumerableOnly case we have nothing to do.
3591 return;
3592 }
3593
3594 // "Components" is marked as enumerable but only resolved on demand :-/.
3595 // aNames.AppendElement(u"Components"_ns);
3596
3597 JS::Rooted<JSObject*> wrapper(aCx, GetWrapper());
3598
3599 // There are actually two ways we can get called here: For normal
3600 // enumeration or for Xray enumeration. In the latter case, we want to
3601 // return all possible WebIDL names, because we don't really support
3602 // deleting these names off our Xray; trying to resolve them will just make
3603 // them come back. In the former case, we want to avoid returning deleted
3604 // names. But the JS engine already knows about the non-deleted
3605 // already-resolved names, so we can just return the so-far-unresolved ones.
3606 //
3607 // We can tell which case we're in by whether aCx is in our wrapper's
3608 // compartment. If not, we're in the Xray case.
3609 WebIDLGlobalNameHash::NameType nameType =
3610 js::IsObjectInContextCompartment(wrapper, aCx)
3611 ? WebIDLGlobalNameHash::UnresolvedNamesOnly
3612 : WebIDLGlobalNameHash::AllNames;
3613 if (!WebIDLGlobalNameHash::GetNames(aCx, wrapper, nameType, aNames)) {
3614 aRv.NoteJSContextException(aCx);
3615 }
3616}
3617
3618/* static */
3619bool nsGlobalWindowInner::IsPrivilegedChromeWindow(JSContext*, JSObject* aObj) {
3620 // For now, have to deal with XPConnect objects here.
3621 nsGlobalWindowInner* win = xpc::WindowOrNull(aObj);
3622 return win && win->IsChromeWindow() &&
3623 nsContentUtils::ObjectPrincipal(aObj) ==
3624 nsContentUtils::GetSystemPrincipal();
3625}
3626
3627/* static */
3628bool nsGlobalWindowInner::DeviceSensorsEnabled(JSContext*, JSObject*) {
3629 return Preferences::GetBool("device.sensors.enabled");
3630}
3631
3632Crypto* nsGlobalWindowInner::GetCrypto(ErrorResult& aError) {
3633 if (!mCrypto) {
3634 mCrypto = MakeRefPtr<Crypto>(this);
3635 }
3636 return mCrypto;
3637}
3638
3639nsIControllers* nsGlobalWindowInner::GetControllers(ErrorResult& aError) {
3640 FORWARD_TO_OUTER_OR_THROW(GetControllersOuter, (aError), aError, nullptr);
3641}
3642
3643nsresult nsGlobalWindowInner::GetControllers(nsIControllers** aResult) {
3644 ErrorResult rv;
3645 nsCOMPtr<nsIControllers> controllers = GetControllers(rv);
3646 controllers.forget(aResult);
3647
3648 return rv.StealNSResult();
3649}
3650
3651Nullable<WindowProxyHolder> nsGlobalWindowInner::GetOpenerWindow(
3652 ErrorResult& aError) {
3653 FORWARD_TO_OUTER_OR_THROW(GetOpenerWindowOuter, (), aError, nullptr);
3654}
3655
3656void nsGlobalWindowInner::GetOpener(JSContext* aCx,
3657 JS::MutableHandle<JS::Value> aRetval,
3658 ErrorResult& aError) {
3659 Nullable<WindowProxyHolder> opener = GetOpenerWindow(aError);
3660 if (aError.Failed() || opener.IsNull()) {
3661 aRetval.setNull();
3662 return;
3663 }
3664
3665 if (!ToJSValue(aCx, opener.Value(), aRetval)) {
3666 aError.NoteJSContextException(aCx);
3667 }
3668}
3669
3670void nsGlobalWindowInner::SetOpener(JSContext* aCx,
3671 JS::Handle<JS::Value> aOpener,
3672 ErrorResult& aError) {
3673 if (aOpener.isNull()) {
3674 RefPtr<BrowsingContext> bc(GetBrowsingContext());
3675 if (!bc->IsDiscarded()) {
3676 bc->SetOpener(nullptr);
3677 }
3678 return;
3679 }
3680
3681 // If something other than null is passed, just define aOpener on our inner
3682 // window's JS object, wrapped into the current compartment so that for Xrays
3683 // we define on the Xray expando object, but don't set it on the outer window,
3684 // so that it'll get reset on navigation. This is just like replaceable
3685 // properties, but we're not quite readonly.
3686 RedefineProperty(aCx, "opener", aOpener, aError);
3687}
3688
3689void nsGlobalWindowInner::GetEvent(OwningEventOrUndefined& aRetval) {
3690 if (mEvent) {
3691 aRetval.SetAsEvent() = mEvent;
3692 } else {
3693 aRetval.SetUndefined();
3694 }
3695}
3696
3697void nsGlobalWindowInner::GetStatus(nsAString& aStatus, ErrorResult& aError) {
3698 FORWARD_TO_OUTER_OR_THROW(GetStatusOuter, (aStatus), aError, );
3699}
3700
3701void nsGlobalWindowInner::SetStatus(const nsAString& aStatus,
3702 ErrorResult& aError) {
3703 FORWARD_TO_OUTER_OR_THROW(SetStatusOuter, (aStatus), aError, );
3704}
3705
3706void nsGlobalWindowInner::GetName(nsAString& aName, ErrorResult& aError) {
3707 FORWARD_TO_OUTER_OR_THROW(GetNameOuter, (aName), aError, );
3708}
3709
3710void nsGlobalWindowInner::SetName(const nsAString& aName,
3711 mozilla::ErrorResult& aError) {
3712 FORWARD_TO_OUTER_OR_THROW(SetNameOuter, (aName, aError), aError, );
3713}
3714
3715double nsGlobalWindowInner::GetInnerWidth(CallerType aCallerType,
3716 ErrorResult& aError) {
3717 FORWARD_TO_OUTER_OR_THROW(GetInnerWidthOuter, (aCallerType, aError), aError,
3718 0);
3719}
3720
3721nsresult nsGlobalWindowInner::GetInnerWidth(CallerType aCallerType,
3722 double* aWidth) {
3723 ErrorResult rv;
3724 *aWidth = GetInnerWidth(aCallerType, rv);
3725 return rv.StealNSResult();
3726}
3727
3728double nsGlobalWindowInner::GetInnerHeight(CallerType aCallerType,
3729 ErrorResult& aError) {
3730 FORWARD_TO_OUTER_OR_THROW(GetInnerHeightOuter, (aCallerType, aError), aError,
3731 0);
3732}
3733
3734nsresult nsGlobalWindowInner::GetInnerHeight(CallerType aCallerType,
3735 double* aHeight) {
3736 ErrorResult rv;
3737 *aHeight = GetInnerHeight(aCallerType, rv);
3738 return rv.StealNSResult();
3739}
3740
3741int32_t nsGlobalWindowInner::GetOuterWidth(CallerType aCallerType,
3742 ErrorResult& aError) {
3743 FORWARD_TO_OUTER_OR_THROW(GetOuterWidthOuter, (aCallerType, aError), aError,
3744 0);
3745}
3746
3747int32_t nsGlobalWindowInner::GetOuterHeight(CallerType aCallerType,
3748 ErrorResult& aError) {
3749 FORWARD_TO_OUTER_OR_THROW(GetOuterHeightOuter, (aCallerType, aError), aError,
3750 0);
3751}
3752
3753double nsGlobalWindowInner::ScreenEdgeSlopX() const {
3754 FORWARD_TO_OUTER(ScreenEdgeSlopX, (), 0);
3755}
3756
3757double nsGlobalWindowInner::ScreenEdgeSlopY() const {
3758 FORWARD_TO_OUTER(ScreenEdgeSlopY, (), 0);
3759}
3760
3761int32_t nsGlobalWindowInner::GetScreenX(CallerType aCallerType,
3762 ErrorResult& aError) {
3763 FORWARD_TO_OUTER_OR_THROW(GetScreenXOuter, (aCallerType, aError), aError, 0);
3764}
3765
3766int32_t nsGlobalWindowInner::GetScreenY(CallerType aCallerType,
3767 ErrorResult& aError) {
3768 FORWARD_TO_OUTER_OR_THROW(GetScreenYOuter, (aCallerType, aError), aError, 0);
3769}
3770
3771float nsGlobalWindowInner::GetMozInnerScreenX(CallerType aCallerType,
3772 ErrorResult& aError) {
3773 FORWARD_TO_OUTER_OR_THROW(GetMozInnerScreenXOuter, (aCallerType), aError, 0);
3774}
3775
3776float nsGlobalWindowInner::GetMozInnerScreenY(CallerType aCallerType,
3777 ErrorResult& aError) {
3778 FORWARD_TO_OUTER_OR_THROW(GetMozInnerScreenYOuter, (aCallerType), aError, 0);
3779}
3780
3781static nsPresContext* GetPresContextForRatio(Document* aDoc) {
3782 if (nsPresContext* presContext = aDoc->GetPresContext()) {
3783 return presContext;
3784 }
3785 // We're in an undisplayed subdocument... There's not really an awesome way
3786 // to tell what the right DPI is from here, so we try to walk up our parent
3787 // document chain to the extent that the docs can observe each other.
3788 Document* doc = aDoc;
3789 while (doc->StyleOrLayoutObservablyDependsOnParentDocumentLayout()) {
3790 doc = doc->GetInProcessParentDocument();
3791 if (nsPresContext* presContext = doc->GetPresContext()) {
3792 return presContext;
3793 }
3794 }
3795 return nullptr;
3796}
3797
3798double nsGlobalWindowInner::GetDevicePixelRatio(CallerType aCallerType,
3799 ErrorResult& aError) {
3800 ENSURE_ACTIVE_DOCUMENT(aError, 0.0)do { if ((__builtin_expect(!!(!HasActiveDocument()), 0))) { aError
.Throw(NS_ERROR_XPC_SECURITY_MANAGER_VETO); return 0.0; } } while
(0)
;
3801
3802 RefPtr<nsPresContext> presContext = GetPresContextForRatio(mDoc);
3803 if (NS_WARN_IF(!presContext)NS_warn_if_impl(!presContext, "!presContext", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 3803)
) {
3804 // Still nothing, oh well.
3805 return 1.0;
3806 }
3807
3808 if (nsIGlobalObject::ShouldResistFingerprinting(
3809 aCallerType, RFPTarget::WindowDevicePixelRatio)) {
3810 return nsRFPService::GetDevicePixelRatioAtZoom(presContext->GetFullZoom());
3811 }
3812
3813 if (aCallerType == CallerType::NonSystem) {
3814 float overrideDPPX = presContext->GetOverrideDPPX();
3815 if (overrideDPPX > 0.0f) {
3816 return overrideDPPX;
3817 }
3818 }
3819
3820 return double(AppUnitsPerCSSPixel()) /
3821 double(presContext->AppUnitsPerDevPixel());
3822}
3823
3824double nsGlobalWindowInner::GetDesktopToDeviceScale(ErrorResult& aError) {
3825 ENSURE_ACTIVE_DOCUMENT(aError, 0.0)do { if ((__builtin_expect(!!(!HasActiveDocument()), 0))) { aError
.Throw(NS_ERROR_XPC_SECURITY_MANAGER_VETO); return 0.0; } } while
(0)
;
3826 nsPresContext* presContext = GetPresContextForRatio(mDoc);
3827 if (!presContext) {
3828 return 1.0;
3829 }
3830 return presContext->DeviceContext()->GetDesktopToDeviceScale().scale;
3831}
3832
3833uint32_t nsGlobalWindowInner::RequestAnimationFrame(
3834 FrameRequestCallback& aCallback, ErrorResult& aError) {
3835 if (!mDoc) {
3836 return 0;
3837 }
3838
3839 if (GetWrapperPreserveColor()) {
3840 js::NotifyAnimationActivity(GetWrapperPreserveColor());
3841 }
3842
3843 DebuggerNotificationDispatch(this,
3844 DebuggerNotificationType::RequestAnimationFrame);
3845
3846 uint32_t handle;
3847 aError = mDoc->ScheduleFrameRequestCallback(aCallback, &handle);
3848 return handle;
3849}
3850
3851void nsGlobalWindowInner::CancelAnimationFrame(uint32_t aHandle,
3852 ErrorResult& aError) {
3853 if (!mDoc) {
3854 return;
3855 }
3856
3857 DebuggerNotificationDispatch(this,
3858 DebuggerNotificationType::CancelAnimationFrame);
3859
3860 mDoc->CancelFrameRequestCallback(aHandle);
3861}
3862
3863already_AddRefed<MediaQueryList> nsGlobalWindowInner::MatchMedia(
3864 const nsACString& aMediaQueryList, CallerType aCallerType,
3865 ErrorResult& aError) {
3866 ENSURE_ACTIVE_DOCUMENT(aError, nullptr)do { if ((__builtin_expect(!!(!HasActiveDocument()), 0))) { aError
.Throw(NS_ERROR_XPC_SECURITY_MANAGER_VETO); return nullptr; }
} while (0)
;
3867 return mDoc->MatchMedia(aMediaQueryList, aCallerType);
3868}
3869
3870int32_t nsGlobalWindowInner::GetScrollMinX(ErrorResult& aError) {
3871 FORWARD_TO_OUTER_OR_THROW(GetScrollBoundaryOuter, (eSideLeft), aError, 0);
3872}
3873
3874int32_t nsGlobalWindowInner::GetScrollMinY(ErrorResult& aError) {
3875 FORWARD_TO_OUTER_OR_THROW(GetScrollBoundaryOuter, (eSideTop), aError, 0);
3876}
3877
3878int32_t nsGlobalWindowInner::GetScrollMaxX(ErrorResult& aError) {
3879 FORWARD_TO_OUTER_OR_THROW(GetScrollBoundaryOuter, (eSideRight), aError, 0);
3880}
3881
3882int32_t nsGlobalWindowInner::GetScrollMaxY(ErrorResult& aError) {
3883 FORWARD_TO_OUTER_OR_THROW(GetScrollBoundaryOuter, (eSideBottom), aError, 0);
3884}
3885
3886double nsGlobalWindowInner::GetScrollX(ErrorResult& aError) {
3887 FORWARD_TO_OUTER_OR_THROW(GetScrollXOuter, (), aError, 0);
3888}
3889
3890double nsGlobalWindowInner::GetScrollY(ErrorResult& aError) {
3891 FORWARD_TO_OUTER_OR_THROW(GetScrollYOuter, (), aError, 0);
3892}
3893
3894uint32_t nsGlobalWindowInner::Length() { FORWARD_TO_OUTER(Length, (), 0); }
3895
3896Nullable<WindowProxyHolder> nsGlobalWindowInner::GetTop(
3897 mozilla::ErrorResult& aError) {
3898 FORWARD_TO_OUTER_OR_THROW(GetTopOuter, (), aError, nullptr);
3899}
3900
3901already_AddRefed<BrowsingContext> nsGlobalWindowInner::GetChildWindow(
3902 const nsAString& aName) {
3903 if (GetOuterWindowInternal()) {
3904 return GetOuterWindowInternal()->GetChildWindow(aName);
3905 }
3906 return nullptr;
3907}
3908
3909void nsGlobalWindowInner::RefreshRealmPrincipal() {
3910 JS::SetRealmPrincipals(js::GetNonCCWObjectRealm(GetWrapperPreserveColor()),
3911 nsJSPrincipals::get(mDoc->NodePrincipal()));
3912}
3913
3914void nsGlobalWindowInner::RefreshReduceTimerPrecisionCallerType() {
3915 JS::SetRealmReduceTimerPrecisionCallerType(
3916 js::GetNonCCWObjectRealm(GetWrapperPreserveColor()),
3917 RTPCallerTypeToToken(GetRTPCallerType()));
3918}
3919
3920already_AddRefed<nsIWidget> nsGlobalWindowInner::GetMainWidget() const {
3921 FORWARD_TO_OUTER(GetMainWidget, (), nullptr);
3922}
3923
3924nsIWidget* nsGlobalWindowInner::GetNearestWidget() const {
3925 if (GetOuterWindowInternal()) {
3926 return GetOuterWindowInternal()->GetNearestWidget();
3927 }
3928 return nullptr;
3929}
3930
3931void nsGlobalWindowInner::SetFullScreen(bool aFullscreen,
3932 CallerType aCallerType,
3933 ErrorResult& aError) {
3934 if (aCallerType == CallerType::NonSystem) {
3935 if (Document* doc = GetExtantDoc()) {
3936 doc->WarnOnceAndReportAbout(DeprecatedOperations::eFullscreenAttribute);
3937 }
3938 }
3939 FORWARD_TO_OUTER_OR_THROW(SetFullscreenOuter, (aFullscreen, aError), aError,
3940 /* void */);
3941}
3942
3943bool nsGlobalWindowInner::GetFullScreen(CallerType aCallerType,
3944 ErrorResult& aError) {
3945 if (aCallerType == CallerType::NonSystem) {
3946 if (Document* doc = GetExtantDoc()) {
3947 doc->WarnOnceAndReportAbout(DeprecatedOperations::eFullscreenAttribute);
3948 }
3949 }
3950 FORWARD_TO_OUTER_OR_THROW(GetFullscreenOuter, (), aError, false);
3951}
3952
3953bool nsGlobalWindowInner::GetFullScreen() {
3954 bool fullscreen = GetFullScreen(CallerType::System, IgnoreErrors());
3955 return fullscreen;
3956}
3957
3958void nsGlobalWindowInner::Dump(const nsAString& aStr) {
3959 if (!nsJSUtils::DumpEnabled()) {
3960 return;
3961 }
3962
3963 char* cstr = ToNewUTF8String(aStr);
3964
3965#if defined(XP_MACOSX)
3966 // have to convert \r to \n so that printing to the console works
3967 char *c = cstr, *cEnd = cstr + strlen(cstr);
3968 while (c < cEnd) {
3969 if (*c == '\r') *c = '\n';
3970 c++;
3971 }
3972#endif
3973
3974 if (cstr) {
3975 MOZ_LOG(nsContentUtils::DOMDumpLog(), LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = nsContentUtils
::DOMDumpLog(); if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, LogLevel::Debug)), 0))) { mozilla::detail::
log_print(moz_real_module, LogLevel::Debug, "[Window.Dump] %s"
, cstr); } } while (0)
3976 ("[Window.Dump] %s", cstr))do { const ::mozilla::LogModule* moz_real_module = nsContentUtils
::DOMDumpLog(); if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, LogLevel::Debug)), 0))) { mozilla::detail::
log_print(moz_real_module, LogLevel::Debug, "[Window.Dump] %s"
, cstr); } } while (0)
;
3977#ifdef XP_WIN
3978 PrintToDebugger(cstr);
3979#endif
3980#ifdef ANDROID
3981 __android_log_write(ANDROID_LOG_INFO, "GeckoDump", cstr);
3982#endif
3983 FILE* fp = gDumpFile ? gDumpFile : stdoutstdout;
3984 fputs(cstr, fp);
3985 fflush(fp);
3986 free(cstr);
3987 }
3988}
3989
3990void nsGlobalWindowInner::Alert(nsIPrincipal& aSubjectPrincipal,
3991 ErrorResult& aError) {
3992 Alert(u""_ns, aSubjectPrincipal, aError);
3993}
3994
3995void nsGlobalWindowInner::Alert(const nsAString& aMessage,
3996 nsIPrincipal& aSubjectPrincipal,
3997 ErrorResult& aError) {
3998 FORWARD_TO_OUTER_OR_THROW(AlertOuter, (aMessage, aSubjectPrincipal, aError),
3999 aError, );
4000}
4001
4002bool nsGlobalWindowInner::Confirm(const nsAString& aMessage,
4003 nsIPrincipal& aSubjectPrincipal,
4004 ErrorResult& aError) {
4005 FORWARD_TO_OUTER_OR_THROW(ConfirmOuter, (aMessage, aSubjectPrincipal, aError),
4006 aError, false);
4007}
4008
4009already_AddRefed<Promise> nsGlobalWindowInner::Fetch(
4010 const RequestOrUTF8String& aInput, const RequestInit& aInit,
4011 CallerType aCallerType, ErrorResult& aRv) {
4012 return FetchRequest(this, aInput, aInit, aCallerType, aRv);
4013}
4014
4015void nsGlobalWindowInner::Prompt(const nsAString& aMessage,
4016 const nsAString& aInitial, nsAString& aReturn,
4017 nsIPrincipal& aSubjectPrincipal,
4018 ErrorResult& aError) {
4019 FORWARD_TO_OUTER_OR_THROW(
4020 PromptOuter, (aMessage, aInitial, aReturn, aSubjectPrincipal, aError),
4021 aError, );
4022}
4023
4024void nsGlobalWindowInner::Focus(CallerType aCallerType, ErrorResult& aError) {
4025 FORWARD_TO_OUTER_OR_THROW(FocusOuter,
4026 (aCallerType, /* aFromOtherProcess */ false,
4027 nsFocusManager::GenerateFocusActionId()),
4028 aError, );
4029}
4030
4031nsresult nsGlobalWindowInner::Focus(CallerType aCallerType) {
4032 ErrorResult rv;
4033 Focus(aCallerType, rv);
4034
4035 return rv.StealNSResult();
4036}
4037
4038void nsGlobalWindowInner::Blur(CallerType aCallerType, ErrorResult& aError) {
4039 FORWARD_TO_OUTER_OR_THROW(BlurOuter, (aCallerType), aError, );
4040}
4041
4042void nsGlobalWindowInner::Stop(ErrorResult& aError) {
4043 FORWARD_TO_OUTER_OR_THROW(StopOuter, (aError), aError, );
4044}
4045
4046void nsGlobalWindowInner::Print(ErrorResult& aError) {
4047 FORWARD_TO_OUTER_OR_THROW(PrintOuter, (aError), aError, );
4048}
4049
4050Nullable<WindowProxyHolder> nsGlobalWindowInner::PrintPreview(
4051 nsIPrintSettings* aSettings, nsIWebProgressListener* aListener,
4052 nsIDocShell* aDocShellToCloneInto, ErrorResult& aError) {
4053 FORWARD_TO_OUTER_OR_THROW(
4054 Print,
4055 (aSettings,
4056 /* aRemotePrintJob = */ nullptr, aListener, aDocShellToCloneInto,
4057 nsGlobalWindowOuter::IsPreview::Yes,
4058 nsGlobalWindowOuter::IsForWindowDotPrint::No,
4059 /* aPrintPreviewCallback = */ nullptr, nullptr, aError),
4060 aError, nullptr);
4061}
4062
4063void nsGlobalWindowInner::MoveTo(int32_t aXPos, int32_t aYPos,
4064 CallerType aCallerType, ErrorResult& aError) {
4065 FORWARD_TO_OUTER_OR_THROW(MoveToOuter, (aXPos, aYPos, aCallerType, aError),
4066 aError, );
4067}
4068
4069void nsGlobalWindowInner::MoveBy(int32_t aXDif, int32_t aYDif,
4070 CallerType aCallerType, ErrorResult& aError) {
4071 FORWARD_TO_OUTER_OR_THROW(MoveByOuter, (aXDif, aYDif, aCallerType, aError),
4072 aError, );
4073}
4074
4075void nsGlobalWindowInner::ResizeTo(int32_t aWidth, int32_t aHeight,
4076 CallerType aCallerType,
4077 ErrorResult& aError) {
4078 FORWARD_TO_OUTER_OR_THROW(ResizeToOuter,
4079 (aWidth, aHeight, aCallerType, aError), aError, );
4080}
4081
4082void nsGlobalWindowInner::ResizeBy(int32_t aWidthDif, int32_t aHeightDif,
4083 CallerType aCallerType,
4084 ErrorResult& aError) {
4085 FORWARD_TO_OUTER_OR_THROW(
4086 ResizeByOuter, (aWidthDif, aHeightDif, aCallerType, aError), aError, );
4087}
4088
4089void nsGlobalWindowInner::MoveResize(int32_t aX, int32_t aY, int32_t aWidth,
4090 int32_t aHeight, ErrorResult& aError) {
4091 const auto callerType = CallerType::System; // We're ChromeOnly
4092 FORWARD_TO_OUTER_OR_THROW(
4093 MoveResizeOuter, (aX, aY, aWidth, aHeight, callerType, aError), aError, );
4094}
4095
4096void nsGlobalWindowInner::SizeToContent(
4097 const SizeToContentConstraints& aConstraints, ErrorResult& aError) {
4098 FORWARD_TO_OUTER_OR_THROW(SizeToContentOuter, (aConstraints, aError),
4099 aError, );
4100}
4101
4102already_AddRefed<nsPIWindowRoot> nsGlobalWindowInner::GetTopWindowRoot() {
4103 nsGlobalWindowOuter* outer = GetOuterWindowInternal();
4104 if (!outer) {
4105 return nullptr;
4106 }
4107 return outer->GetTopWindowRoot();
4108}
4109
4110void nsGlobalWindowInner::ScrollTo(double aXScroll, double aYScroll) {
4111 ScrollToOptions options;
4112 options.mLeft.Construct(aXScroll);
4113 options.mTop.Construct(aYScroll);
4114 ScrollTo(options);
4115}
4116
4117void nsGlobalWindowInner::ScrollTo(const ScrollToOptions& aOptions) {
4118 Maybe<double> left;
4119 Maybe<double> top;
4120 if (aOptions.mLeft.WasPassed()) {
4121 left.emplace(ToZeroIfNonfinite(aOptions.mLeft.Value()));
4122 }
4123 if (aOptions.mTop.WasPassed()) {
4124 top.emplace(ToZeroIfNonfinite(aOptions.mTop.Value()));
4125 }
4126
4127 // When scrolling to a non-zero offset, we need to determine whether that
4128 // position is within our scrollable range, so we need updated layout
4129 // information.
4130 if ((top && *top != 0) || (left && *left != 0)) {
4131 FlushPendingNotifications(FlushType::Layout);
4132 }
4133
4134 ScrollContainerFrame* sf = GetScrollContainerFrame();
4135 if (!sf) {
4136 return;
4137 }
4138 CSSPoint scrollPos = sf->GetScrollPositionCSSPixels();
4139 if (left) {
4140 scrollPos.x = *left;
4141 }
4142 if (top) {
4143 scrollPos.y = *top;
4144 }
4145 // Here we calculate what the max pixel value is that we can
4146 // scroll to, we do this by dividing maxint with the pixel to
4147 // twips conversion factor, and subtracting 4, the 4 comes from
4148 // experimenting with this value, anything less makes the view
4149 // code not scroll correctly, I have no idea why. -- jst
4150 //
4151 // FIXME(emilio): This seems like if needed it should be done by the
4152 // scrolling code itself...
4153 const double maxpx = CSSPixel::FromAppUnits(0x7fffffff) - 4;
4154 if (scrollPos.x > maxpx) {
4155 scrollPos.x = maxpx;
4156 }
4157 if (scrollPos.y > maxpx) {
4158 scrollPos.y = maxpx;
4159 }
4160 auto scrollMode = sf->ScrollModeForScrollBehavior(aOptions.mBehavior);
4161 sf->ScrollToCSSPixels(scrollPos, scrollMode);
4162}
4163
4164void nsGlobalWindowInner::ScrollBy(double aXScrollDif, double aYScrollDif) {
4165 ScrollToOptions options;
4166 options.mLeft.Construct(aXScrollDif);
4167 options.mTop.Construct(aYScrollDif);
4168 // It seems like it would make more sense for ScrollBy to use
4169 // SMOOTH mode, but tests seem to depend on the synchronous behaviour.
4170 // Perhaps Web content does too.
4171 ScrollBy(options);
4172}
4173
4174void nsGlobalWindowInner::ScrollBy(const ScrollToOptions& aOptions) {
4175 CSSPoint scrollDelta;
4176 if (aOptions.mLeft.WasPassed()) {
4177 scrollDelta.x = ToZeroIfNonfinite(aOptions.mLeft.Value());
4178 }
4179 if (aOptions.mTop.WasPassed()) {
4180 scrollDelta.y = ToZeroIfNonfinite(aOptions.mTop.Value());
4181 }
4182
4183 if (!scrollDelta.x && !scrollDelta.y) {
4184 return;
4185 }
4186
4187 FlushPendingNotifications(FlushType::Layout);
4188 ScrollContainerFrame* sf = GetScrollContainerFrame();
4189 if (!sf) {
4190 return;
4191 }
4192
4193 auto scrollMode = sf->ScrollModeForScrollBehavior(aOptions.mBehavior);
4194 sf->ScrollByCSSPixels(scrollDelta, scrollMode);
4195}
4196
4197void nsGlobalWindowInner::ScrollByLines(int32_t numLines,
4198 const ScrollOptions& aOptions) {
4199 if (!numLines) {
4200 return;
4201 }
4202 FlushPendingNotifications(FlushType::Layout);
4203 ScrollContainerFrame* sf = GetScrollContainerFrame();
4204 if (!sf) {
4205 return;
4206 }
4207 // It seems like it would make more sense for ScrollByLines to use
4208 // SMOOTH mode, but tests seem to depend on the synchronous behaviour.
4209 // Perhaps Web content does too.
4210 ScrollMode scrollMode = sf->ScrollModeForScrollBehavior(aOptions.mBehavior);
4211 sf->ScrollBy(nsIntPoint(0, numLines), ScrollUnit::LINES, scrollMode);
4212}
4213
4214void nsGlobalWindowInner::ScrollByPages(int32_t numPages,
4215 const ScrollOptions& aOptions) {
4216 if (!numPages) {
4217 return;
4218 }
4219 FlushPendingNotifications(FlushType::Layout);
4220 ScrollContainerFrame* sf = GetScrollContainerFrame();
4221 if (!sf) {
4222 return;
4223 }
4224 // It seems like it would make more sense for ScrollByPages to use
4225 // SMOOTH mode, but tests seem to depend on the synchronous behaviour.
4226 // Perhaps Web content does too.
4227 ScrollMode scrollMode = sf->ScrollModeForScrollBehavior(aOptions.mBehavior);
4228
4229 sf->ScrollBy(nsIntPoint(0, numPages), ScrollUnit::PAGES, scrollMode);
4230}
4231
4232void nsGlobalWindowInner::MozScrollSnap() {
4233 FlushPendingNotifications(FlushType::Layout);
4234 if (ScrollContainerFrame* sf = GetScrollContainerFrame()) {
4235 sf->ScrollSnap();
4236 }
4237}
4238
4239void nsGlobalWindowInner::ClearTimeout(int32_t aHandle) {
4240 DebuggerNotificationDispatch(this, DebuggerNotificationType::ClearTimeout);
4241
4242 if (aHandle > 0) {
4243 mTimeoutManager->ClearTimeout(aHandle, Timeout::Reason::eTimeoutOrInterval);
4244 }
4245}
4246
4247void nsGlobalWindowInner::ClearInterval(int32_t aHandle) {
4248 DebuggerNotificationDispatch(this, DebuggerNotificationType::ClearInterval);
4249
4250 if (aHandle > 0) {
4251 mTimeoutManager->ClearTimeout(aHandle, Timeout::Reason::eTimeoutOrInterval);
4252 }
4253}
4254
4255void nsGlobalWindowInner::SetResizable(bool aResizable) const {
4256 // nop
4257}
4258
4259void nsGlobalWindowInner::CaptureEvents() {
4260 // Intentionally a no-op, as this API is deprecated.
4261}
4262
4263void nsGlobalWindowInner::ReleaseEvents() {
4264 // Intentionally a no-op, as this API is deprecated.
4265}
4266
4267Nullable<WindowProxyHolder> nsGlobalWindowInner::Open(const nsAString& aUrl,
4268 const nsAString& aName,
4269 const nsAString& aOptions,
4270 ErrorResult& aError) {
4271 FORWARD_TO_OUTER_OR_THROW(OpenOuter, (aUrl, aName, aOptions, aError), aError,
4272 nullptr);
4273}
4274
4275Nullable<WindowProxyHolder> nsGlobalWindowInner::OpenDialog(
4276 JSContext* aCx, const nsAString& aUrl, const nsAString& aName,
4277 const nsAString& aOptions, const Sequence<JS::Value>& aExtraArgument,
4278 ErrorResult& aError) {
4279 FORWARD_TO_OUTER_OR_THROW(
4280 OpenDialogOuter, (aCx, aUrl, aName, aOptions, aExtraArgument, aError),
4281 aError, nullptr);
4282}
4283
4284WindowProxyHolder nsGlobalWindowInner::GetFrames(ErrorResult& aError) {
4285 FORWARD_TO_OUTER_OR_THROW(GetFramesOuter, (), aError, Window());
4286}
4287
4288void nsGlobalWindowInner::PostMessageMoz(JSContext* aCx,
4289 JS::Handle<JS::Value> aMessage,
4290 const nsAString& aTargetOrigin,
4291 JS::Handle<JS::Value> aTransfer,
4292 nsIPrincipal& aSubjectPrincipal,
4293 ErrorResult& aError) {
4294 FORWARD_TO_OUTER_OR_THROW(
4295 PostMessageMozOuter,
4296 (aCx, aMessage, aTargetOrigin, aTransfer, aSubjectPrincipal, aError),
4297 aError, );
4298}
4299
4300void nsGlobalWindowInner::PostMessageMoz(JSContext* aCx,
4301 JS::Handle<JS::Value> aMessage,
4302 const nsAString& aTargetOrigin,
4303 const Sequence<JSObject*>& aTransfer,
4304 nsIPrincipal& aSubjectPrincipal,
4305 ErrorResult& aRv) {
4306 JS::Rooted<JS::Value> transferArray(aCx, JS::UndefinedValue());
4307
4308 aRv = nsContentUtils::CreateJSValueFromSequenceOfObject(aCx, aTransfer,
4309 &transferArray);
4310 if (NS_WARN_IF(aRv.Failed())NS_warn_if_impl(aRv.Failed(), "aRv.Failed()", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4310)
) {
4311 return;
4312 }
4313
4314 PostMessageMoz(aCx, aMessage, aTargetOrigin, transferArray, aSubjectPrincipal,
4315 aRv);
4316}
4317
4318void nsGlobalWindowInner::PostMessageMoz(
4319 JSContext* aCx, JS::Handle<JS::Value> aMessage,
4320 const WindowPostMessageOptions& aOptions, nsIPrincipal& aSubjectPrincipal,
4321 ErrorResult& aRv) {
4322 JS::Rooted<JS::Value> transferArray(aCx, JS::UndefinedValue());
4323
4324 aRv = nsContentUtils::CreateJSValueFromSequenceOfObject(
4325 aCx, aOptions.mTransfer, &transferArray);
4326 if (NS_WARN_IF(aRv.Failed())NS_warn_if_impl(aRv.Failed(), "aRv.Failed()", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4326)
) {
4327 return;
4328 }
4329
4330 PostMessageMoz(aCx, aMessage, aOptions.mTargetOrigin, transferArray,
4331 aSubjectPrincipal, aRv);
4332}
4333
4334void nsGlobalWindowInner::Close(CallerType aCallerType, ErrorResult& aError) {
4335 FORWARD_TO_OUTER_OR_THROW(CloseOuter, (aCallerType == CallerType::System),
4336 aError, );
4337}
4338
4339nsresult nsGlobalWindowInner::Close() {
4340 FORWARD_TO_OUTER(Close, (), NS_ERROR_UNEXPECTED);
4341}
4342
4343bool nsGlobalWindowInner::IsInModalState() {
4344 FORWARD_TO_OUTER(IsInModalState, (), false);
4345}
4346
4347void nsGlobalWindowInner::NotifyWindowIDDestroyed(const char* aTopic) {
4348 RefPtr runnable = MakeRefPtr<WindowDestroyedEvent>(this, mWindowID, aTopic);
4349 Dispatch(runnable.forget());
4350}
4351
4352Element* nsGlobalWindowInner::GetFrameElement(nsIPrincipal& aSubjectPrincipal,
4353 ErrorResult& aError) {
4354 FORWARD_TO_OUTER_OR_THROW(GetFrameElement, (aSubjectPrincipal), aError,
4355 nullptr);
4356}
4357
4358Element* nsGlobalWindowInner::GetRealFrameElement(ErrorResult& aError) {
4359 FORWARD_TO_OUTER_OR_THROW(GetFrameElement, (), aError, nullptr);
4360}
4361
4362void nsGlobalWindowInner::UpdateCommands(const nsAString& anAction) {
4363 if (GetOuterWindowInternal()) {
4364 GetOuterWindowInternal()->UpdateCommands(anAction);
4365 }
4366}
4367
4368Selection* nsGlobalWindowInner::GetSelection(ErrorResult& aError) {
4369 FORWARD_TO_OUTER_OR_THROW(GetSelectionOuter, (), aError, nullptr);
4370}
4371
4372WebTaskScheduler* nsGlobalWindowInner::Scheduler() {
4373 if (!mWebTaskScheduler) {
4374 mWebTaskScheduler = WebTaskScheduler::CreateForMainThread(this);
4375 }
4376 MOZ_ASSERT(mWebTaskScheduler)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mWebTaskScheduler)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mWebTaskScheduler))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("mWebTaskScheduler"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 4376
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mWebTaskScheduler"
")"); do { MOZ_CrashSequence(__null, 4376); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4377 return mWebTaskScheduler;
4378}
4379
4380bool nsGlobalWindowInner::Find(const nsAString& aString, bool aCaseSensitive,
4381 bool aBackwards, bool aWrapAround,
4382 bool aWholeWord, bool aSearchInFrames,
4383 bool aShowDialog, ErrorResult& aError) {
4384 FORWARD_TO_OUTER_OR_THROW(FindOuter,
4385 (aString, aCaseSensitive, aBackwards, aWrapAround,
4386 aWholeWord, aSearchInFrames, aShowDialog, aError),
4387 aError, false);
4388}
4389
4390void nsGlobalWindowInner::GetOrigin(nsAString& aOrigin) {
4391 nsContentUtils::GetWebExposedOriginSerialization(GetPrincipal(), aOrigin);
4392}
4393
4394// See also AutoJSAPI::ReportException
4395void nsGlobalWindowInner::ReportError(JSContext* aCx,
4396 JS::Handle<JS::Value> aError,
4397 CallerType aCallerType,
4398 ErrorResult& aRv) {
4399 if (MOZ_UNLIKELY(!HasActiveDocument())(__builtin_expect(!!(!HasActiveDocument()), 0))) {
4400 return aRv.Throw(NS_ERROR_XPC_SECURITY_MANAGER_VETO);
4401 }
4402
4403 JS::ErrorReportBuilder jsReport(aCx);
4404 JS::ExceptionStack exnStack(aCx, aError, nullptr);
4405 if (!jsReport.init(aCx, exnStack, JS::ErrorReportBuilder::NoSideEffects)) {
4406 return aRv.NoteJSContextException(aCx);
4407 }
4408
4409 RefPtr xpcReport = MakeRefPtr<xpc::ErrorReport>();
4410 bool isChrome = aCallerType == CallerType::System;
4411 xpcReport->Init(jsReport.report(), jsReport.toStringResult().c_str(),
4412 isChrome, WindowID());
4413
4414 JS::RootingContext* rcx = JS::RootingContext::get(aCx);
4415 DispatchScriptErrorEvent(this, rcx, xpcReport, exnStack.exception(),
4416 exnStack.stack());
4417}
4418
4419void nsGlobalWindowInner::Atob(const nsAString& aAsciiBase64String,
4420 nsAString& aBinaryData, ErrorResult& aError) {
4421 aError = nsContentUtils::Atob(aAsciiBase64String, aBinaryData);
4422}
4423
4424void nsGlobalWindowInner::Btoa(const nsAString& aBinaryData,
4425 nsAString& aAsciiBase64String,
4426 ErrorResult& aError) {
4427 aError = nsContentUtils::Btoa(aBinaryData, aAsciiBase64String);
4428}
4429
4430//*****************************************************************************
4431// EventTarget
4432//*****************************************************************************
4433
4434bool nsGlobalWindowInner::DispatchEvent(Event& aEvent, CallerType aCallerType,
4435 ErrorResult& aRv) {
4436 if (!IsCurrentInnerWindow()) {
4437 NS_WARNING(NS_DebugBreak(NS_DEBUG_WARNING, "DispatchEvent called on non-current inner window, dropping. "
"Please check the window in the caller instead.", nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4439)
4438 "DispatchEvent called on non-current inner window, dropping. "NS_DebugBreak(NS_DEBUG_WARNING, "DispatchEvent called on non-current inner window, dropping. "
"Please check the window in the caller instead.", nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4439)
4439 "Please check the window in the caller instead.")NS_DebugBreak(NS_DEBUG_WARNING, "DispatchEvent called on non-current inner window, dropping. "
"Please check the window in the caller instead.", nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4439)
;
4440 aRv.Throw(NS_ERROR_FAILURE);
4441 return false;
4442 }
4443
4444 if (!mDoc) {
4445 aRv.Throw(NS_ERROR_FAILURE);
4446 return false;
4447 }
4448
4449 // Obtain a presentation shell
4450 RefPtr<nsPresContext> presContext = mDoc->GetPresContext();
4451
4452 nsEventStatus status = nsEventStatus_eIgnore;
4453 nsresult rv = EventDispatcher::DispatchDOMEvent(this, nullptr, &aEvent,
4454 presContext, &status);
4455 bool retval = !aEvent.DefaultPrevented(aCallerType);
4456 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
4457 aRv.Throw(rv);
4458 }
4459 return retval;
4460}
4461
4462mozilla::Maybe<mozilla::dom::EventCallbackDebuggerNotificationType>
4463nsGlobalWindowInner::GetDebuggerNotificationType() const {
4464 return mozilla::Some(
4465 mozilla::dom::EventCallbackDebuggerNotificationType::Global);
4466}
4467
4468bool nsGlobalWindowInner::ComputeDefaultWantsUntrusted(ErrorResult& aRv) {
4469 return !nsContentUtils::IsChromeDoc(mDoc);
4470}
4471
4472EventListenerManager* nsGlobalWindowInner::GetOrCreateListenerManager() {
4473 if (!mListenerManager) {
4474 mListenerManager =
4475 MakeRefPtr<EventListenerManager>(static_cast<EventTarget*>(this));
4476 }
4477
4478 return mListenerManager;
4479}
4480
4481EventListenerManager* nsGlobalWindowInner::GetExistingListenerManager() const {
4482 return mListenerManager;
4483}
4484
4485mozilla::dom::DebuggerNotificationManager*
4486nsGlobalWindowInner::GetOrCreateDebuggerNotificationManager() {
4487 if (!mDebuggerNotificationManager) {
4488 mDebuggerNotificationManager =
4489 MakeRefPtr<DebuggerNotificationManager>(this);
4490 }
4491
4492 return mDebuggerNotificationManager;
4493}
4494
4495mozilla::dom::DebuggerNotificationManager*
4496nsGlobalWindowInner::GetExistingDebuggerNotificationManager() {
4497 return mDebuggerNotificationManager;
4498}
4499
4500//*****************************************************************************
4501// nsGlobalWindowInner::nsPIDOMWindow
4502//*****************************************************************************
4503
4504Location* nsGlobalWindowInner::Location() {
4505 if (!mLocation) {
4506 mLocation = MakeRefPtr<dom::Location>(this);
4507 }
4508
4509 return mLocation;
4510}
4511
4512void nsGlobalWindowInner::MaybeUpdateTouchState() {
4513 if (mMayHaveTouchEventListener) {
4514 nsCOMPtr<nsIObserverService> observerService =
4515 services::GetObserverService();
4516
4517 if (observerService) {
4518 observerService->NotifyObservers(static_cast<nsIDOMWindow*>(this),
4519 DOM_TOUCH_LISTENER_ADDED"dom-touch-listener-added", nullptr);
4520 }
4521 }
4522}
4523
4524void nsGlobalWindowInner::EnableGamepadUpdates() {
4525 if (mHasGamepad) {
4526 RefPtr<GamepadManager> gamepadManager(GamepadManager::GetService());
4527 if (gamepadManager) {
4528 gamepadManager->AddListener(this);
4529 }
4530 }
4531}
4532
4533void nsGlobalWindowInner::DisableGamepadUpdates() {
4534 if (mHasGamepad) {
4535 RefPtr<GamepadManager> gamepadManager(GamepadManager::GetService());
4536 if (gamepadManager) {
4537 gamepadManager->RemoveListener(this);
4538 }
4539 }
4540}
4541
4542void nsGlobalWindowInner::EnableVRUpdates() {
4543 // We need to create a VREventObserver before we can either detect XR runtimes
4544 // or start an XR session
4545 if (!mVREventObserver && (mHasXRSession || mXRRuntimeDetectionInFlight)) {
4546 // Assert that we are not creating the observer while IsDying() as
4547 // that would result in a leak. VREventObserver holds a RefPtr to
4548 // this nsGlobalWindowInner and would prevent it from being deallocated.
4549 MOZ_ASSERT(!IsDying(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!IsDying())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!IsDying()))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("!IsDying()" " (" "Creating a VREventObserver for an nsGlobalWindow that is "
"dying would cause it to leak." ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4551); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!IsDying()"
") (" "Creating a VREventObserver for an nsGlobalWindow that is "
"dying would cause it to leak." ")"); do { MOZ_CrashSequence
(__null, 4551); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
4550 "Creating a VREventObserver for an nsGlobalWindow that is "do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!IsDying())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!IsDying()))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("!IsDying()" " (" "Creating a VREventObserver for an nsGlobalWindow that is "
"dying would cause it to leak." ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4551); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!IsDying()"
") (" "Creating a VREventObserver for an nsGlobalWindow that is "
"dying would cause it to leak." ")"); do { MOZ_CrashSequence
(__null, 4551); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
4551 "dying would cause it to leak.")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!IsDying())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!IsDying()))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("!IsDying()" " (" "Creating a VREventObserver for an nsGlobalWindow that is "
"dying would cause it to leak." ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4551); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!IsDying()"
") (" "Creating a VREventObserver for an nsGlobalWindow that is "
"dying would cause it to leak." ")"); do { MOZ_CrashSequence
(__null, 4551); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4552 mVREventObserver = MakeRefPtr<VREventObserver>(this);
4553 }
4554 // If the content has an XR session, then we need to tell
4555 // VREventObserver that there is VR activity.
4556 if (mHasXRSession) {
4557 nsPIDOMWindowOuter* outer = GetOuterWindow();
4558 if (outer && !outer->IsBackground()) {
4559 StartVRActivity();
4560 }
4561 }
4562}
4563
4564void nsGlobalWindowInner::DisableVRUpdates() {
4565 if (mVREventObserver) {
4566 mVREventObserver->DisconnectFromOwner();
4567 mVREventObserver = nullptr;
4568 }
4569}
4570
4571void nsGlobalWindowInner::StartVRActivity() {
4572 /**
4573 * If the content has an XR session, tell
4574 * the VREventObserver that the window is accessing
4575 * VR devices.
4576 *
4577 * It's possible to have a VREventObserver without
4578 * and XR session, if we are using it to get updates
4579 * about XR runtime enumeration. In this case,
4580 * we would not tell the VREventObserver that
4581 * we are accessing VR devices.
4582 */
4583 if (mVREventObserver && mHasXRSession) {
4584 mVREventObserver->StartActivity();
4585 }
4586}
4587
4588void nsGlobalWindowInner::StopVRActivity() {
4589 /**
4590 * If the content has an XR session, tell
4591 * the VReventObserver that the window is no longer
4592 * accessing VR devices. This does not stop the
4593 * XR session itself, which may be resumed with
4594 * EnableVRUpdates.
4595 * It's possible to have a VREventObserver without
4596 * and XR session, if we are using it to get updates
4597 * about XR runtime enumeration. In this case,
4598 * we would not tell the VREventObserver that
4599 * we ending an activity that accesses VR devices.
4600 */
4601 if (mVREventObserver && mHasXRSession) {
4602 mVREventObserver->StopActivity();
4603 }
4604}
4605
4606void nsGlobalWindowInner::SetFocusedElement(Element* aElement,
4607 uint32_t aFocusMethod,
4608 bool aNeedsFocus) {
4609 if (aElement && aElement->GetComposedDoc() != mDoc) {
4610 NS_WARNING("Trying to set focus to a node from a wrong document")NS_DebugBreak(NS_DEBUG_WARNING, "Trying to set focus to a node from a wrong document"
, nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4610)
;
4611 return;
4612 }
4613
4614 if (IsDying()) {
4615 NS_ASSERTION(!aElement, "Trying to focus cleaned up window!")do { if (!(!aElement)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "Trying to focus cleaned up window!"
, "!aElement", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4615); MOZ_PretendNoReturn(); } } while (0)
;
4616 aElement = nullptr;
4617 aNeedsFocus = false;
4618 }
4619 if (mFocusedElement != aElement) {
4620 mFocusedElement = aElement;
4621 // TODO: Maybe this should be set on refocus too?
4622 mFocusMethod = aFocusMethod & nsIFocusManager::METHOD_MASK;
4623 }
4624
4625 if (mFocusedElement) {
4626 // if a node was focused by a keypress, turn on focus rings for the
4627 // window.
4628 if (mFocusMethod & nsIFocusManager::FLAG_BYKEY) {
4629 mUnknownFocusMethodShouldShowOutline = true;
4630 mFocusByKeyOccurred = true;
4631 } else if (nsFocusManager::GetFocusMoveActionCause(mFocusMethod) !=
4632 widget::InputContextAction::CAUSE_UNKNOWN) {
4633 mUnknownFocusMethodShouldShowOutline = false;
4634 } else if (aFocusMethod & nsIFocusManager::FLAG_NOSHOWRING) {
4635 // If we get focused via script, and script has explicitly opted out of
4636 // outlines via FLAG_NOSHOWRING, we don't want to make a refocus start
4637 // showing outlines.
4638 mUnknownFocusMethodShouldShowOutline = false;
4639 }
4640 }
4641
4642 if (aNeedsFocus) {
4643 mNeedsFocus = aNeedsFocus;
4644 }
4645}
4646
4647uint32_t nsGlobalWindowInner::GetFocusMethod() { return mFocusMethod; }
4648
4649bool nsGlobalWindowInner::ShouldShowFocusRing() {
4650 if (mFocusByKeyOccurred &&
4651 StaticPrefs::browser_display_always_show_rings_after_key_focus()) {
4652 return true;
4653 }
4654 return StaticPrefs::browser_display_show_focus_rings();
4655}
4656
4657bool nsGlobalWindowInner::TakeFocus(bool aFocus, uint32_t aFocusMethod) {
4658 if (IsDying()) {
4659 return false;
4660 }
4661
4662 if (aFocus) {
4663 mFocusMethod = aFocusMethod & nsIFocusManager::METHOD_MASK;
4664 }
4665
4666 // if mNeedsFocus is true, then the document has not yet received a
4667 // document-level focus event. If there is a root content node, then return
4668 // true to tell the calling focus manager that a focus event is expected. If
4669 // there is no root content node, the document hasn't loaded enough yet, or
4670 // there isn't one and there is no point in firing a focus event.
4671 if (aFocus && mNeedsFocus && mDoc && mDoc->GetRootElement()) {
4672 mNeedsFocus = false;
4673 return true;
4674 }
4675
4676 mNeedsFocus = false;
4677 return false;
4678}
4679
4680void nsGlobalWindowInner::SetReadyForFocus() {
4681 bool oldNeedsFocus = mNeedsFocus;
4682 mNeedsFocus = false;
4683
4684 if (RefPtr<nsFocusManager> fm = nsFocusManager::GetFocusManager()) {
4685 nsCOMPtr<nsPIDOMWindowOuter> outerWindow = GetOuterWindow();
4686 fm->WindowShown(outerWindow, oldNeedsFocus);
4687 }
4688}
4689
4690void nsGlobalWindowInner::PageHidden(bool aIsEnteringBFCacheInParent) {
4691 // the window is being hidden, so tell the focus manager that the frame is
4692 // no longer valid. Use the persisted field to determine if the document
4693 // is being destroyed.
4694
4695 if (RefPtr<nsFocusManager> fm = nsFocusManager::GetFocusManager()) {
4696 nsCOMPtr<nsPIDOMWindowOuter> outerWindow = GetOuterWindow();
4697 fm->WindowHidden(outerWindow, nsFocusManager::GenerateFocusActionId(),
4698 aIsEnteringBFCacheInParent);
4699 }
4700
4701 mNeedsFocus = true;
4702}
4703
4704class HashchangeCallback : public Runnable {
4705 public:
4706 HashchangeCallback(const nsAString& aOldURL, const nsAString& aNewURL,
4707 nsGlobalWindowInner* aWindow)
4708 : mozilla::Runnable("HashchangeCallback"), mWindow(aWindow) {
4709 MOZ_ASSERT(mWindow)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mWindow)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mWindow))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mWindow", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4709); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mWindow" ")"
); do { MOZ_CrashSequence(__null, 4709); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4710 mOldURL.Assign(aOldURL);
4711 mNewURL.Assign(aNewURL);
4712 }
4713
4714 NS_IMETHODvirtual nsresult Run() override {
4715 MOZ_ASSERT(NS_IsMainThread(), "Should be called on the main thread.")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
" (" "Should be called on the main thread." ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4715); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Should be called on the main thread." ")"); do { MOZ_CrashSequence
(__null, 4715); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4716 return mWindow->FireHashchange(mOldURL, mNewURL);
4717 }
4718
4719 private:
4720 nsString mOldURL;
4721 nsString mNewURL;
4722 RefPtr<nsGlobalWindowInner> mWindow;
4723};
4724
4725nsresult nsGlobalWindowInner::DispatchAsyncHashchange(nsIURI* aOldURI,
4726 nsIURI* aNewURI) {
4727 // Make sure that aOldURI and aNewURI are identical up to the '#', and that
4728 // their hashes are different.
4729 bool equal = false;
4730 NS_ENSURE_STATE(NS_SUCCEEDED(aOldURI->EqualsExceptRef(aNewURI, &equal)) &&do { if ((__builtin_expect(!!(!(((bool)(__builtin_expect(!!(!
NS_FAILED_impl(aOldURI->EqualsExceptRef(aNewURI, &equal
))), 1))) && equal)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(aOldURI->EqualsExceptRef(aNewURI, &equal))), 1))) && equal"
") failed", nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4731); return NS_ERROR_UNEXPECTED; } } while (false)
4731 equal)do { if ((__builtin_expect(!!(!(((bool)(__builtin_expect(!!(!
NS_FAILED_impl(aOldURI->EqualsExceptRef(aNewURI, &equal
))), 1))) && equal)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(aOldURI->EqualsExceptRef(aNewURI, &equal))), 1))) && equal"
") failed", nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4731); return NS_ERROR_UNEXPECTED; } } while (false)
;
4732 nsAutoCString oldHash, newHash;
4733 bool oldHasHash, newHasHash;
4734 NS_ENSURE_STATE(NS_SUCCEEDED(aOldURI->GetRef(oldHash)) &&do { if ((__builtin_expect(!!(!(((bool)(__builtin_expect(!!(!
NS_FAILED_impl(aOldURI->GetRef(oldHash))), 1))) &&
((bool)(__builtin_expect(!!(!NS_FAILED_impl(aNewURI->GetRef
(newHash))), 1))) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl
(aOldURI->GetHasRef(&oldHasHash))), 1))) && ((
bool)(__builtin_expect(!!(!NS_FAILED_impl(aNewURI->GetHasRef
(&newHasHash))), 1))) && (oldHasHash != newHasHash
|| !oldHash.Equals(newHash)))), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(aOldURI->GetRef(oldHash))), 1))) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl(aNewURI->GetRef(newHash))), 1))) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl(aOldURI->GetHasRef(&oldHasHash))), 1))) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl(aNewURI->GetHasRef(&newHasHash))), 1))) && (oldHasHash != newHasHash || !oldHash.Equals(newHash))"
") failed", nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4738); return NS_ERROR_UNEXPECTED; } } while (false)
4735 NS_SUCCEEDED(aNewURI->GetRef(newHash)) &&do { if ((__builtin_expect(!!(!(((bool)(__builtin_expect(!!(!
NS_FAILED_impl(aOldURI->GetRef(oldHash))), 1))) &&
((bool)(__builtin_expect(!!(!NS_FAILED_impl(aNewURI->GetRef
(newHash))), 1))) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl
(aOldURI->GetHasRef(&oldHasHash))), 1))) && ((
bool)(__builtin_expect(!!(!NS_FAILED_impl(aNewURI->GetHasRef
(&newHasHash))), 1))) && (oldHasHash != newHasHash
|| !oldHash.Equals(newHash)))), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(aOldURI->GetRef(oldHash))), 1))) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl(aNewURI->GetRef(newHash))), 1))) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl(aOldURI->GetHasRef(&oldHasHash))), 1))) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl(aNewURI->GetHasRef(&newHasHash))), 1))) && (oldHasHash != newHasHash || !oldHash.Equals(newHash))"
") failed", nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4738); return NS_ERROR_UNEXPECTED; } } while (false)
4736 NS_SUCCEEDED(aOldURI->GetHasRef(&oldHasHash)) &&do { if ((__builtin_expect(!!(!(((bool)(__builtin_expect(!!(!
NS_FAILED_impl(aOldURI->GetRef(oldHash))), 1))) &&
((bool)(__builtin_expect(!!(!NS_FAILED_impl(aNewURI->GetRef
(newHash))), 1))) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl
(aOldURI->GetHasRef(&oldHasHash))), 1))) && ((
bool)(__builtin_expect(!!(!NS_FAILED_impl(aNewURI->GetHasRef
(&newHasHash))), 1))) && (oldHasHash != newHasHash
|| !oldHash.Equals(newHash)))), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(aOldURI->GetRef(oldHash))), 1))) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl(aNewURI->GetRef(newHash))), 1))) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl(aOldURI->GetHasRef(&oldHasHash))), 1))) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl(aNewURI->GetHasRef(&newHasHash))), 1))) && (oldHasHash != newHasHash || !oldHash.Equals(newHash))"
") failed", nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4738); return NS_ERROR_UNEXPECTED; } } while (false)
4737 NS_SUCCEEDED(aNewURI->GetHasRef(&newHasHash)) &&do { if ((__builtin_expect(!!(!(((bool)(__builtin_expect(!!(!
NS_FAILED_impl(aOldURI->GetRef(oldHash))), 1))) &&
((bool)(__builtin_expect(!!(!NS_FAILED_impl(aNewURI->GetRef
(newHash))), 1))) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl
(aOldURI->GetHasRef(&oldHasHash))), 1))) && ((
bool)(__builtin_expect(!!(!NS_FAILED_impl(aNewURI->GetHasRef
(&newHasHash))), 1))) && (oldHasHash != newHasHash
|| !oldHash.Equals(newHash)))), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(aOldURI->GetRef(oldHash))), 1))) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl(aNewURI->GetRef(newHash))), 1))) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl(aOldURI->GetHasRef(&oldHasHash))), 1))) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl(aNewURI->GetHasRef(&newHasHash))), 1))) && (oldHasHash != newHasHash || !oldHash.Equals(newHash))"
") failed", nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4738); return NS_ERROR_UNEXPECTED; } } while (false)
4738 (oldHasHash != newHasHash || !oldHash.Equals(newHash)))do { if ((__builtin_expect(!!(!(((bool)(__builtin_expect(!!(!
NS_FAILED_impl(aOldURI->GetRef(oldHash))), 1))) &&
((bool)(__builtin_expect(!!(!NS_FAILED_impl(aNewURI->GetRef
(newHash))), 1))) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl
(aOldURI->GetHasRef(&oldHasHash))), 1))) && ((
bool)(__builtin_expect(!!(!NS_FAILED_impl(aNewURI->GetHasRef
(&newHasHash))), 1))) && (oldHasHash != newHasHash
|| !oldHash.Equals(newHash)))), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(aOldURI->GetRef(oldHash))), 1))) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl(aNewURI->GetRef(newHash))), 1))) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl(aOldURI->GetHasRef(&oldHasHash))), 1))) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl(aNewURI->GetHasRef(&newHasHash))), 1))) && (oldHasHash != newHasHash || !oldHash.Equals(newHash))"
") failed", nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4738); return NS_ERROR_UNEXPECTED; } } while (false)
;
4739
4740 nsAutoCString oldSpec, newSpec;
4741 nsresult rv = aOldURI->GetSpec(oldSpec);
4742 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4742); return rv; } } while (false)
;
4743 rv = aNewURI->GetSpec(newSpec);
4744 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4744); return rv; } } while (false)
;
4745
4746 NS_ConvertUTF8toUTF16 oldWideSpec(oldSpec);
4747 NS_ConvertUTF8toUTF16 newWideSpec(newSpec);
4748
4749 RefPtr callback =
4750 MakeRefPtr<HashchangeCallback>(oldWideSpec, newWideSpec, this);
4751 return Dispatch(callback.forget());
4752}
4753
4754nsresult nsGlobalWindowInner::FireHashchange(const nsAString& aOldURL,
4755 const nsAString& aNewURL) {
4756 // Don't do anything if the window is frozen.
4757 if (IsFrozen()) {
4758 return NS_OK;
4759 }
4760
4761 // Get a presentation shell for use in creating the hashchange event.
4762 NS_ENSURE_STATE(IsCurrentInnerWindow())do { if ((__builtin_expect(!!(!(IsCurrentInnerWindow())), 0))
) { NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "IsCurrentInnerWindow()"
") failed", nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4762); return NS_ERROR_UNEXPECTED; } } while (false)
;
4763
4764 HashChangeEventInit init;
4765 init.mNewURL = aNewURL;
4766 init.mOldURL = aOldURL;
4767
4768 RefPtr<HashChangeEvent> event =
4769 HashChangeEvent::Constructor(this, u"hashchange"_ns, init);
4770
4771 event->SetTrusted(true);
4772
4773 ErrorResult rv;
4774 DispatchEvent(*event, rv);
4775 return rv.StealNSResult();
4776}
4777
4778nsresult nsGlobalWindowInner::DispatchSyncPopState() {
4779 NS_ASSERTION(nsContentUtils::IsSafeToRunScript(),do { if (!(nsContentUtils::IsSafeToRunScript())) { NS_DebugBreak
(NS_DEBUG_ASSERTION, "Must be safe to run script here.", "nsContentUtils::IsSafeToRunScript()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 4780
); MOZ_PretendNoReturn(); } } while (0)
4780 "Must be safe to run script here.")do { if (!(nsContentUtils::IsSafeToRunScript())) { NS_DebugBreak
(NS_DEBUG_ASSERTION, "Must be safe to run script here.", "nsContentUtils::IsSafeToRunScript()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 4780
); MOZ_PretendNoReturn(); } } while (0)
;
4781
4782 // Bail if the window is frozen.
4783 if (IsFrozen()) {
4784 return NS_OK;
4785 }
4786
4787 AutoJSAPI jsapi;
4788 bool result = jsapi.Init(this);
4789 NS_ENSURE_TRUE(result, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(result)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "result" ") failed", nullptr
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 4789
); return NS_ERROR_FAILURE; } } while (false)
;
4790
4791 JSContext* cx = jsapi.cx();
4792
4793 // Get the document's pending state object -- it contains the data we're
4794 // going to send along with the popstate event. The object is serialized
4795 // using structured clone.
4796 JS::Rooted<JS::Value> stateJSValue(cx);
4797 nsresult rv = mDoc->GetStateObject(&stateJSValue);
4798 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4798); return rv; } } while (false)
;
4799
4800 if (!JS_WrapValue(cx, &stateJSValue)) {
4801 return NS_ERROR_OUT_OF_MEMORY;
4802 }
4803
4804 RootedDictionary<PopStateEventInit> init(cx);
4805 init.mState = stateJSValue;
4806
4807 RefPtr<PopStateEvent> event =
4808 PopStateEvent::Constructor(this, u"popstate"_ns, init);
4809 event->SetTrusted(true);
4810 event->SetTarget(this);
4811
4812 ErrorResult err;
4813 DispatchEvent(*event, err);
4814 return err.StealNSResult();
4815}
4816
4817already_AddRefed<nsDOMCSSDeclaration> nsGlobalWindowInner::GetComputedStyle(
4818 Element& aElt, const nsAString& aPseudoElt, ErrorResult& aError) {
4819 return GetComputedStyleHelper(aElt, aPseudoElt, false, aError);
4820}
4821
4822already_AddRefed<nsDOMCSSDeclaration>
4823nsGlobalWindowInner::GetDefaultComputedStyle(Element& aElt,
4824 const nsAString& aPseudoElt,
4825 ErrorResult& aError) {
4826 return GetComputedStyleHelper(aElt, aPseudoElt, true, aError);
4827}
4828
4829already_AddRefed<nsDOMCSSDeclaration>
4830nsGlobalWindowInner::GetComputedStyleHelper(Element& aElt,
4831 const nsAString& aPseudoElt,
4832 bool aDefaultStylesOnly,
4833 ErrorResult& aError) {
4834 FORWARD_TO_OUTER_OR_THROW(GetComputedStyleHelperOuter,
4835 (aElt, aPseudoElt, aDefaultStylesOnly, aError),
4836 aError, nullptr);
4837}
4838
4839Storage* nsGlobalWindowInner::GetSessionStorage(ErrorResult& aError) {
4840 nsIPrincipal* principal = GetPrincipal();
4841 nsIPrincipal* storagePrincipal = GetEffectiveStoragePrincipal();
4842 BrowsingContext* browsingContext = GetBrowsingContext();
4843
4844 if (!principal || !storagePrincipal || !browsingContext ||
4845 !Storage::StoragePrefIsEnabled()) {
4846 return nullptr;
4847 }
4848
4849 if (mSessionStorage) {
4850 MOZ_LOG(gDOMLeakPRLogInner, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gDOMLeakPRLogInner
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsGlobalWindowInner %p has %p sessionStorage"
, this, mSessionStorage.get()); } } while (0)
4851 ("nsGlobalWindowInner %p has %p sessionStorage", this,do { const ::mozilla::LogModule* moz_real_module = gDOMLeakPRLogInner
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsGlobalWindowInner %p has %p sessionStorage"
, this, mSessionStorage.get()); } } while (0)
4852 mSessionStorage.get()))do { const ::mozilla::LogModule* moz_real_module = gDOMLeakPRLogInner
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsGlobalWindowInner %p has %p sessionStorage"
, this, mSessionStorage.get()); } } while (0)
;
4853 bool canAccess =
4854 principal->Subsumes(mSessionStorage->Principal()) &&
4855 storagePrincipal->Subsumes(mSessionStorage->StoragePrincipal());
4856 if (!canAccess) {
4857 mSessionStorage = nullptr;
4858 }
4859 }
4860
4861 if (!mSessionStorage) {
4862 nsString documentURI;
4863 if (mDoc) {
4864 aError = mDoc->GetDocumentURI(documentURI);
4865 if (NS_WARN_IF(aError.Failed())NS_warn_if_impl(aError.Failed(), "aError.Failed()", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4865)
) {
4866 return nullptr;
4867 }
4868 }
4869
4870 if (!mDoc) {
4871 aError.Throw(NS_ERROR_FAILURE);
4872 return nullptr;
4873 }
4874
4875 // If the document's sandboxed origin flag is set, then accessing
4876 // sessionStorage is prohibited.
4877 if (mDoc->GetSandboxFlags() & SANDBOXED_ORIGIN) {
4878 aError.ThrowSecurityError(
4879 "Forbidden in a sandboxed document without the 'allow-same-origin' "
4880 "flag.");
4881 return nullptr;
4882 }
4883
4884 uint32_t rejectedReason = 0;
4885 StorageAccess access = StorageAllowedForWindow(this, &rejectedReason);
4886
4887 // SessionStorage is an ephemeral per-tab per-origin storage that only lives
4888 // as long as the tab is open, although it may survive browser restarts
4889 // thanks to the session store. So we interpret storage access differently
4890 // than we would for persistent per-origin storage like LocalStorage and so
4891 // it may be okay to provide SessionStorage even when we receive a value of
4892 // eDeny.
4893 //
4894 // ContentBlocking::ShouldAllowAccessFor will return false for 3 main
4895 // reasons.
4896 //
4897 // 1. Cookies are entirely blocked due to a per-origin permission
4898 // (nsICookiePermission::ACCESS_DENY for the top-level principal or this
4899 // window's principal) or the very broad BEHAVIOR_REJECT. This will return
4900 // eDeny with a reason of STATE_COOKIES_BLOCKED_BY_PERMISSION or
4901 // STATE_COOKIES_BLOCKED_ALL.
4902 //
4903 // 2. Third-party cookies are limited via BEHAVIOR_REJECT_FOREIGN and
4904 // BEHAVIOR_LIMIT_FOREIGN and this is a third-party window. This will return
4905 // eDeny with a reason of STATE_COOKIES_BLOCKED_FOREIGN.
4906 //
4907 // 3. Tracking protection (BEHAVIOR_REJECT_TRACKER and
4908 // BEHAVIOR_PARTITION_FOREIGN) is in effect and
4909 // IsThirdPartyTrackingResourceWindow() returned true and there wasn't a
4910 // permission that allows it. This will return ePartitionTrackersOrDeny with
4911 // a reason of STATE_COOKIES_BLOCKED_TRACKER or
4912 // STATE_COOKIES_BLOCKED_SOCIALTRACKER.
4913 // TODO(Bug 2039931): case 3 is out of date.
4914 //
4915 // In the 1st case, the user has explicitly indicated that they don't want
4916 // to allow any storage to the origin or all origins and so we throw an
4917 // error and deny access to SessionStorage. In the 2nd case, a legacy
4918 // decision reasoned that there's no harm in providing SessionStorage
4919 // because the information is not durable and cannot escape the current tab.
4920 // The rationale is similar for the 3rd case.
4921 if (access == StorageAccess::eDeny &&
4922 rejectedReason !=
4923 nsIWebProgressListener::STATE_COOKIES_BLOCKED_FOREIGN) {
4924 aError.Throw(NS_ERROR_DOM_SECURITY_ERR);
4925 return nullptr;
4926 }
4927
4928 const RefPtr<SessionStorageManager> storageManager =
4929 browsingContext->GetSessionStorageManager();
4930 if (!storageManager) {
4931 aError.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
4932 return nullptr;
4933 }
4934
4935 RefPtr<Storage> storage;
4936 aError = storageManager->CreateStorage(this, principal, storagePrincipal,
4937 documentURI, IsPrivateBrowsing(),
4938 getter_AddRefs(storage));
4939 if (aError.Failed()) {
4940 return nullptr;
4941 }
4942
4943 mSessionStorage = storage;
4944 MOZ_ASSERT(mSessionStorage)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mSessionStorage)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mSessionStorage))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("mSessionStorage"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 4944
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mSessionStorage" ")"
); do { MOZ_CrashSequence(__null, 4944); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4945
4946 MOZ_LOG(gDOMLeakPRLogInner, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gDOMLeakPRLogInner
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsGlobalWindowInner %p tried to get a new sessionStorage %p"
, this, mSessionStorage.get()); } } while (0)
4947 ("nsGlobalWindowInner %p tried to get a new sessionStorage %p",do { const ::mozilla::LogModule* moz_real_module = gDOMLeakPRLogInner
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsGlobalWindowInner %p tried to get a new sessionStorage %p"
, this, mSessionStorage.get()); } } while (0)
4948 this, mSessionStorage.get()))do { const ::mozilla::LogModule* moz_real_module = gDOMLeakPRLogInner
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsGlobalWindowInner %p tried to get a new sessionStorage %p"
, this, mSessionStorage.get()); } } while (0)
;
4949
4950 if (!mSessionStorage) {
4951 aError.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
4952 return nullptr;
4953 }
4954 }
4955
4956 MOZ_LOG(gDOMLeakPRLogInner, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gDOMLeakPRLogInner
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsGlobalWindowInner %p returns %p sessionStorage"
, this, mSessionStorage.get()); } } while (0)
4957 ("nsGlobalWindowInner %p returns %p sessionStorage", this,do { const ::mozilla::LogModule* moz_real_module = gDOMLeakPRLogInner
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsGlobalWindowInner %p returns %p sessionStorage"
, this, mSessionStorage.get()); } } while (0)
4958 mSessionStorage.get()))do { const ::mozilla::LogModule* moz_real_module = gDOMLeakPRLogInner
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsGlobalWindowInner %p returns %p sessionStorage"
, this, mSessionStorage.get()); } } while (0)
;
4959
4960 return mSessionStorage;
4961}
4962
4963Storage* nsGlobalWindowInner::GetLocalStorage(ErrorResult& aError) {
4964 if (!Storage::StoragePrefIsEnabled()) {
4965 return nullptr;
4966 }
4967
4968 // If the document's sandboxed origin flag is set, then accessing localStorage
4969 // is prohibited.
4970 if (mDoc && mDoc->GetSandboxFlags() & SANDBOXED_ORIGIN) {
4971 aError.ThrowSecurityError(
4972 "Forbidden in a sandboxed document without the 'allow-same-origin' "
4973 "flag.");
4974 return nullptr;
4975 }
4976
4977 // LocalStorage needs to be exposed in every context except for sandboxes and
4978 // NullPrincipals (data: URLs, for instance). But we need to keep data
4979 // separate in some scenarios: private-browsing and partitioned trackers.
4980 // In private-browsing, LocalStorage keeps data in memory, and it shares
4981 // StorageEvents just with other origins in the same private-browsing
4982 // environment.
4983 // For Partitioned Trackers, we expose a partitioned LocalStorage, which
4984 // doesn't share data with other contexts, and it's just in memory.
4985 // Partitioned localStorage is available only for trackers listed in the
4986 // privacy.restrict3rdpartystorage.partitionedHosts pref. See
4987 // nsContentUtils::IsURIInPrefList to know the syntax for the pref value.
4988 // This is a temporary web-compatibility hack.
4989
4990 StorageAccess access = StorageAllowedForWindow(this);
4991
4992 // We allow partitioned localStorage only to some hosts.
4993 bool isolated = false;
4994 if (ShouldPartitionStorage(access)) {
4995 if (!mDoc) {
4996 access = StorageAccess::eDeny;
4997 } else if (!StoragePartitioningEnabled(access, mDoc->CookieJarSettings())) {
4998 static const char* kPrefName =
4999 "privacy.restrict3rdpartystorage.partitionedHosts";
5000
5001 bool isInList = false;
5002 mDoc->NodePrincipal()->IsURIInPrefList(kPrefName, &isInList);
5003 if (!isInList) {
5004 access = StorageAccess::eDeny;
5005 } else {
5006 isolated = true;
5007 }
5008 }
5009 }
5010
5011 if (access == StorageAccess::eDeny) {
5012 aError.Throw(NS_ERROR_DOM_SECURITY_ERR);
5013 return nullptr;
5014 }
5015
5016 nsCOMPtr<nsICookieJarSettings> cookieJarSettings;
5017 if (mDoc) {
5018 cookieJarSettings = mDoc->CookieJarSettings();
5019 } else {
5020 cookieJarSettings = net::CookieJarSettings::GetBlockingAll(
5021 ShouldResistFingerprinting(RFPTarget::IsAlwaysEnabledForPrecompute));
5022 }
5023
5024 // Note that this behavior is observable: if we grant storage permission to a
5025 // tracker, we pass from the partitioned LocalStorage (or a partitioned cookie
5026 // jar) to the 'normal' one. The previous data is lost and the 2
5027 // window.localStorage objects, before and after the permission granted, will
5028 // be different.
5029 if (mLocalStorage) {
5030 if ((mLocalStorage->Type() == (isolated ? Storage::ePartitionedLocalStorage
5031 : Storage::eLocalStorage)) &&
5032 (mLocalStorage->StoragePrincipal() == GetEffectiveStoragePrincipal())) {
5033 return mLocalStorage;
5034 }
5035
5036 // storage needs change
5037 mLocalStorage = nullptr;
5038 }
5039
5040 MOZ_ASSERT(!mLocalStorage)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mLocalStorage)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mLocalStorage))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!mLocalStorage"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5040
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mLocalStorage" ")"
); do { MOZ_CrashSequence(__null, 5040); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5041
5042 if (!isolated) {
5043 RefPtr<Storage> storage;
5044
5045 if (NextGenLocalStorageEnabled()) {
5046 aError = LSObject::CreateForWindow(this, getter_AddRefs(storage));
5047 } else {
5048 nsresult rv;
5049 nsCOMPtr<nsIDOMStorageManager> storageManager =
5050 do_GetService("@mozilla.org/dom/localStorage-manager;1", &rv);
5051 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5052 aError.Throw(rv);
5053 return nullptr;
5054 }
5055
5056 nsString documentURI;
5057 if (mDoc) {
5058 aError = mDoc->GetDocumentURI(documentURI);
5059 if (NS_WARN_IF(aError.Failed())NS_warn_if_impl(aError.Failed(), "aError.Failed()", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 5059)
) {
5060 return nullptr;
5061 }
5062 }
5063
5064 nsIPrincipal* principal = GetPrincipal();
5065 if (!principal) {
5066 aError.Throw(NS_ERROR_DOM_SECURITY_ERR);
5067 return nullptr;
5068 }
5069
5070 nsIPrincipal* storagePrincipal = GetEffectiveStoragePrincipal();
5071 if (!storagePrincipal) {
5072 aError.Throw(NS_ERROR_DOM_SECURITY_ERR);
5073 return nullptr;
5074 }
5075
5076 aError = storageManager->CreateStorage(this, principal, storagePrincipal,
5077 documentURI, IsPrivateBrowsing(),
5078 getter_AddRefs(storage));
5079 }
5080
5081 if (aError.Failed()) {
5082 return nullptr;
5083 }
5084
5085 mLocalStorage = storage;
5086 } else {
5087 nsresult rv;
5088 nsCOMPtr<nsIDOMSessionStorageManager> storageManager =
5089 do_GetService("@mozilla.org/dom/sessionStorage-manager;1", &rv);
5090 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5091 aError.Throw(rv);
5092 return nullptr;
5093 }
5094
5095 nsIPrincipal* principal = GetPrincipal();
5096 if (!principal) {
5097 aError.Throw(NS_ERROR_DOM_SECURITY_ERR);
5098 return nullptr;
5099 }
5100
5101 nsIPrincipal* storagePrincipal = GetEffectiveStoragePrincipal();
5102 if (!storagePrincipal) {
5103 aError.Throw(NS_ERROR_DOM_SECURITY_ERR);
5104 return nullptr;
5105 }
5106
5107 RefPtr<SessionStorageCache> cache;
5108 if (isolated) {
5109 cache = MakeRefPtr<SessionStorageCache>();
5110 } else {
5111 // This will clone the session storage if it exists.
5112 rv = storageManager->GetSessionStorageCache(principal, storagePrincipal,
5113 &cache);
5114 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5115 aError.Throw(rv);
5116 return nullptr;
5117 }
5118 }
5119
5120 mLocalStorage = MakeRefPtr<PartitionedLocalStorage>(
5121 this, principal, storagePrincipal, cache);
5122 }
5123
5124 MOZ_ASSERT(mLocalStorage)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mLocalStorage)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mLocalStorage))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("mLocalStorage",
"/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5124
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLocalStorage" ")"
); do { MOZ_CrashSequence(__null, 5124); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5125 MOZ_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mLocalStorage->Type() == (isolated ? Storage::ePartitionedLocalStorage
: Storage::eLocalStorage))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mLocalStorage->Type() == (
isolated ? Storage::ePartitionedLocalStorage : Storage::eLocalStorage
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mLocalStorage->Type() == (isolated ? Storage::ePartitionedLocalStorage : Storage::eLocalStorage)"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5127
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLocalStorage->Type() == (isolated ? Storage::ePartitionedLocalStorage : Storage::eLocalStorage)"
")"); do { MOZ_CrashSequence(__null, 5127); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
5126 mLocalStorage->Type() ==do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mLocalStorage->Type() == (isolated ? Storage::ePartitionedLocalStorage
: Storage::eLocalStorage))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mLocalStorage->Type() == (
isolated ? Storage::ePartitionedLocalStorage : Storage::eLocalStorage
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mLocalStorage->Type() == (isolated ? Storage::ePartitionedLocalStorage : Storage::eLocalStorage)"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5127
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLocalStorage->Type() == (isolated ? Storage::ePartitionedLocalStorage : Storage::eLocalStorage)"
")"); do { MOZ_CrashSequence(__null, 5127); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
5127 (isolated ? Storage::ePartitionedLocalStorage : Storage::eLocalStorage))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mLocalStorage->Type() == (isolated ? Storage::ePartitionedLocalStorage
: Storage::eLocalStorage))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mLocalStorage->Type() == (
isolated ? Storage::ePartitionedLocalStorage : Storage::eLocalStorage
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mLocalStorage->Type() == (isolated ? Storage::ePartitionedLocalStorage : Storage::eLocalStorage)"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5127
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLocalStorage->Type() == (isolated ? Storage::ePartitionedLocalStorage : Storage::eLocalStorage)"
")"); do { MOZ_CrashSequence(__null, 5127); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5128 return mLocalStorage;
5129}
5130
5131IDBFactory* nsGlobalWindowInner::GetIndexedDB(JSContext* aCx,
5132 ErrorResult& aError) {
5133 if (!mIndexedDB) {
5134 // This may keep mIndexedDB null without setting an error.
5135 auto res = IDBFactory::CreateForWindow(this);
5136 if (res.isErr()) {
5137 aError = res.unwrapErr();
5138 } else {
5139 mIndexedDB = res.unwrap();
5140 }
5141 }
5142
5143 return mIndexedDB;
5144}
5145
5146//*****************************************************************************
5147// nsGlobalWindowInner::nsIInterfaceRequestor
5148//*****************************************************************************
5149
5150NS_IMETHODIMPnsresult
5151nsGlobalWindowInner::GetInterface(const nsIID& aIID, void** aSink) {
5152 nsGlobalWindowOuter* outer = GetOuterWindowInternal();
5153 NS_ENSURE_TRUE(outer, NS_ERROR_NOT_INITIALIZED)do { if ((__builtin_expect(!!(!(outer)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "outer" ") failed", nullptr
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5153
); return NS_ERROR_NOT_INITIALIZED; } } while (false)
;
5154
5155 nsresult rv = outer->GetInterfaceInternal(aIID, aSink);
5156 if (rv == NS_ERROR_NO_INTERFACE) {
5157 return QueryInterface(aIID, aSink);
5158 }
5159 return rv;
5160}
5161
5162void nsGlobalWindowInner::GetInterface(JSContext* aCx,
5163 JS::Handle<JS::Value> aIID,
5164 JS::MutableHandle<JS::Value> aRetval,
5165 ErrorResult& aError) {
5166 dom::GetInterface(aCx, this, aIID, aRetval, aError);
5167}
5168
5169already_AddRefed<CacheStorage> nsGlobalWindowInner::GetCaches(
5170 ErrorResult& aRv) {
5171 if (!mCacheStorage) {
5172 bool forceTrustedOrigin =
5173 GetBrowsingContext() &&
5174 GetBrowsingContext()->Top()->GetServiceWorkersTestingEnabled();
5175 mCacheStorage = CacheStorage::CreateOnMainThread(
5176 cache::DEFAULT_NAMESPACE, this, GetEffectiveStoragePrincipal(),
5177 forceTrustedOrigin, aRv);
5178 }
5179
5180 RefPtr<CacheStorage> ref = mCacheStorage;
5181 return ref.forget();
5182}
5183
5184void nsGlobalWindowInner::FireOfflineStatusEventIfChanged() {
5185 if (!IsCurrentInnerWindow()) return;
5186
5187 bool isOffline =
5188 NS_IsOffline() ||
5189 (GetBrowsingContext() && GetBrowsingContext()->Top()->GetForceOffline());
5190
5191 // Don't fire an event if the status hasn't changed
5192 if (mWasOffline == isOffline) {
5193 return;
5194 }
5195
5196 if (ShouldResistFingerprinting(RFPTarget::NetworkConnection)) {
5197 // We always report online=true when resistFingerprinting is enabled.
5198 return;
5199 }
5200
5201 mWasOffline = !mWasOffline;
5202
5203 nsAutoString name;
5204 if (mWasOffline) {
5205 name.AssignLiteral("offline");
5206 } else {
5207 name.AssignLiteral("online");
5208 }
5209 nsContentUtils::DispatchTrustedEvent(this, this, name, CanBubble::eNo,
5210 Cancelable::eNo);
5211}
5212
5213nsGlobalWindowInner::SlowScriptResponse
5214nsGlobalWindowInner::ShowSlowScriptDialog(JSContext* aCx,
5215 const nsString& aAddonId,
5216 const double aDuration) {
5217 nsresult rv;
5218
5219 if (Preferences::GetBool("dom.always_stop_slow_scripts")) {
5220 return KillSlowScript;
5221 }
5222
5223 // If it isn't safe to run script, then it isn't safe to bring up the prompt
5224 // (since that spins the event loop). In that (rare) case, we just kill the
5225 // script and report a warning.
5226 if (!nsContentUtils::IsSafeToRunScript()) {
5227 JS::WarnASCII(aCx, "A long running script was terminated");
5228 return KillSlowScript;
5229 }
5230
5231 // If our document is not active, just kill the script: we've been unloaded
5232 if (!HasActiveDocument()) {
5233 return KillSlowScript;
5234 }
5235
5236 // Check if we should offer the option to debug
5237 JS::AutoFilename filename;
5238 uint32_t lineno;
5239 // Computing the line number can be very expensive (see bug 1330231 for
5240 // example), and we don't use the line number anywhere except than in the
5241 // parent process, so we avoid computing it elsewhere. This gives us most of
5242 // the wins we are interested in, since the source of the slowness here is
5243 // minified scripts which is more common in Web content that is loaded in the
5244 // content process.
5245 uint32_t* linenop = XRE_IsParentProcess() ? &lineno : nullptr;
5246 bool hasFrame = JS::DescribeScriptedCaller(&filename, aCx, linenop);
5247
5248 // Record the slow script event if we haven't done so already for this inner
5249 // window (which represents a particular page to the user).
5250 if (!mHasHadSlowScript) {
5251 glean::dom::slow_script_page_count.Add(1);
5252 }
5253 mHasHadSlowScript = true;
5254
5255 // Override the cursor to something that we're sure the user can see.
5256 SetCursor("auto"_ns, IgnoreErrors());
5257
5258 if (XRE_IsContentProcess() && ProcessHangMonitor::Get()) {
5259 ProcessHangMonitor::SlowScriptAction action;
5260 RefPtr<ProcessHangMonitor> monitor = ProcessHangMonitor::Get();
5261 nsIDocShell* docShell = GetDocShell();
5262 nsCOMPtr<nsIBrowserChild> child =
5263 docShell ? docShell->GetBrowserChild() : nullptr;
5264 action =
5265 monitor->NotifySlowScript(child, filename.get(), aAddonId, aDuration);
5266 if (action == ProcessHangMonitor::Terminate) {
5267 return KillSlowScript;
5268 }
5269
5270 if (action == ProcessHangMonitor::StartDebugger) {
5271 // Spin a nested event loop so that the debugger in the parent can fetch
5272 // any information it needs. Once the debugger has started, return to the
5273 // script.
5274 RefPtr<nsGlobalWindowOuter> outer = GetOuterWindowInternal();
5275 outer->EnterModalState();
5276 SpinEventLoopUntil("nsGlobalWindowInner::ShowSlowScriptDialog"_ns, [&]() {
5277 return monitor->IsDebuggerStartupComplete() ||
5278 AppShutdown::IsShutdownImpending();
5279 });
5280 outer->LeaveModalState();
5281 return (AppShutdown::IsShutdownImpending()) ? KillSlowScript
5282 : ContinueSlowScript;
5283 }
5284
5285 return ContinueSlowScriptAndKeepNotifying;
5286 }
5287
5288 // Reached only on non-e10s - once per slow script dialog.
5289 // On e10s - we probe once at ProcessHangsMonitor.sys.mjs
5290 glean::dom::slow_script_notice_count.Add(1);
5291
5292 // Get the nsIPrompt interface from the docshell
5293 nsCOMPtr<nsIDocShell> ds = GetDocShell();
5294 NS_ENSURE_TRUE(ds, KillSlowScript)do { if ((__builtin_expect(!!(!(ds)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "ds" ") failed", nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 5294); return KillSlowScript; } } while (false)
;
5295 nsCOMPtr<nsIPrompt> prompt = do_GetInterface(ds);
5296 NS_ENSURE_TRUE(prompt, KillSlowScript)do { if ((__builtin_expect(!!(!(prompt)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "prompt" ") failed", nullptr
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5296
); return KillSlowScript; } } while (false)
;
5297
5298 // Prioritize the SlowScriptDebug interface over JSD1.
5299 nsCOMPtr<nsISlowScriptDebugCallback> debugCallback;
5300
5301 if (hasFrame) {
5302 const char* debugCID = "@mozilla.org/dom/slow-script-debug;1";
5303 nsCOMPtr<nsISlowScriptDebug> debugService = do_GetService(debugCID, &rv);
5304 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
5305 debugService->GetActivationHandler(getter_AddRefs(debugCallback));
5306 }
5307 }
5308
5309 bool failed = false;
5310 auto getString = [&](const char* name, PropertiesFile propFile =
5311 PropertiesFile::DOM_PROPERTIES) {
5312 nsAutoString result;
5313 nsresult rv = nsContentUtils::GetLocalizedString(propFile, name, result);
5314
5315 // GetStringFromName can return NS_OK and still give nullptr string
5316 failed = failed || NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || result.IsEmpty();
5317 return result;
5318 };
5319
5320 bool isAddonScript = !aAddonId.IsEmpty();
5321 bool showDebugButton = debugCallback && !isAddonScript;
5322
5323 // Get localizable strings
5324
5325 nsAutoString title, checkboxMsg, debugButton, msg;
5326 if (isAddonScript) {
5327 title = getString("KillAddonScriptTitle");
5328 checkboxMsg = getString("KillAddonScriptGlobalMessage");
5329
5330 auto appName =
5331 getString("brandShortName", PropertiesFile::BRAND_PROPERTIES);
5332
5333 nsCOMPtr<nsIAddonPolicyService> aps =
5334 do_GetService("@mozilla.org/addons/policy-service;1");
5335 nsString addonName;
5336 if (!aps || NS_FAILED(aps->GetExtensionName(aAddonId, addonName))((bool)(__builtin_expect(!!(NS_FAILED_impl(aps->GetExtensionName
(aAddonId, addonName))), 0)))
) {
5337 addonName = aAddonId;
5338 }
5339
5340 rv = nsContentUtils::FormatLocalizedString(
5341 msg, PropertiesFile::DOM_PROPERTIES, "KillAddonScriptMessage",
5342 addonName, appName);
5343
5344 failed = failed || NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)));
5345 } else {
5346 title = getString("KillScriptTitle");
5347 checkboxMsg = getString("DontAskAgain");
5348
5349 if (showDebugButton) {
5350 debugButton = getString("DebugScriptButton");
5351 msg = getString("KillScriptWithDebugMessage");
5352 } else {
5353 msg = getString("KillScriptMessage");
5354 }
5355 }
5356
5357 auto stopButton = getString("StopScriptButton");
5358 auto waitButton = getString("WaitForScriptButton");
5359
5360 if (failed) {
5361 NS_ERROR("Failed to get localized strings.")do { NS_DebugBreak(NS_DEBUG_ASSERTION, "Failed to get localized strings."
, "Error", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 5361); MOZ_PretendNoReturn(); } while (0)
;
5362 return ContinueSlowScript;
5363 }
5364
5365 // Append file and line number information, if available
5366 if (filename.get()) {
5367 nsAutoString scriptLocation;
5368 // We want to drop the middle part of too-long locations. We'll
5369 // define "too-long" as longer than 60 UTF-16 code units. Just
5370 // have to be a bit careful about unpaired surrogates.
5371 NS_ConvertUTF8toUTF16 filenameUTF16(filename.get());
5372 if (filenameUTF16.Length() > 60) {
5373 // XXXbz Do we need to insert any bidi overrides here?
5374 size_t cutStart = 30;
5375 size_t cutLength = filenameUTF16.Length() - 60;
5376 MOZ_ASSERT(cutLength > 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(cutLength > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(cutLength > 0))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("cutLength > 0"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5376
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "cutLength > 0"
")"); do { MOZ_CrashSequence(__null, 5376); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5377 if (IsLowSurrogate(filenameUTF16[cutStart])) {
5378 // Don't truncate before the low surrogate, in case it's preceded by a
5379 // high surrogate and forms a single Unicode character. Instead, just
5380 // include the low surrogate.
5381 ++cutStart;
5382 --cutLength;
5383 }
5384 if (IsLowSurrogate(filenameUTF16[cutStart + cutLength])) {
5385 // Likewise, don't drop a trailing low surrogate here. We want to
5386 // increase cutLength, since it might be 0 already so we can't very well
5387 // decrease it.
5388 ++cutLength;
5389 }
5390
5391 // Insert U+2026 HORIZONTAL ELLIPSIS
5392 filenameUTF16.ReplaceLiteral(cutStart, cutLength, u"\x2026");
5393 }
5394 rv = nsContentUtils::FormatLocalizedString(
5395 scriptLocation, PropertiesFile::DOM_PROPERTIES, "KillScriptLocation",
5396 filenameUTF16);
5397
5398 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
5399 msg.AppendLiteral("\n\n");
5400 msg.Append(scriptLocation);
5401 msg.Append(':');
5402 msg.AppendInt(lineno);
5403 }
5404 }
5405
5406 uint32_t buttonFlags = nsIPrompt::BUTTON_POS_1_DEFAULT +
5407 (nsIPrompt::BUTTON_TITLE_IS_STRING *
5408 (nsIPrompt::BUTTON_POS_0 + nsIPrompt::BUTTON_POS_1));
5409
5410 // Add a third button if necessary.
5411 if (showDebugButton)
5412 buttonFlags += nsIPrompt::BUTTON_TITLE_IS_STRING * nsIPrompt::BUTTON_POS_2;
5413
5414 bool checkboxValue = false;
5415 int32_t buttonPressed = 0; // In case the user exits dialog by clicking X.
5416 {
5417 // Null out the operation callback while we're re-entering JS here.
5418 AutoDisableJSInterruptCallback disabler(aCx);
5419
5420 // Open the dialog.
5421 rv = prompt->ConfirmEx(
5422 title.get(), msg.get(), buttonFlags, waitButton.get(), stopButton.get(),
5423 debugButton.get(), checkboxMsg.get(), &checkboxValue, &buttonPressed);
5424 }
5425
5426 if (buttonPressed == 0) {
5427 if (checkboxValue && !isAddonScript && NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))))
5428 return AlwaysContinueSlowScript;
5429 return ContinueSlowScript;
5430 }
5431
5432 if (buttonPressed == 2) {
5433 MOZ_RELEASE_ASSERT(debugCallback)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(debugCallback)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(debugCallback))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("debugCallback",
"/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5433
); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "debugCallback"
")"); do { MOZ_CrashSequence(__null, 5433); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5434
5435 rv = debugCallback->HandleSlowScriptDebug(this);
5436 return NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) ? ContinueSlowScript : KillSlowScript;
5437 }
5438
5439 JS_ClearPendingException(aCx);
5440
5441 return KillSlowScript;
5442}
5443
5444nsresult nsGlobalWindowInner::Observe(nsISupports* aSubject, const char* aTopic,
5445 const char16_t* aData) {
5446 if (!nsCRT::strcmp(aTopic, "audio-playback")) {
5447 if (ToSupports(GetOuterWindow()) != aSubject) {
5448 return NS_OK;
5449 }
5450 AUTO_PROFILER_MARKER_UNTYPED("audio-playback", DOM, {})AutoProfilerUntypedMarker raiiObject5450( "audio-playback", ::
mozilla::baseprofiler::category::DOM, {})
;
5451
5452 nsGlobalWindowOuter* outer =
5453 nsGlobalWindowOuter::Cast(nsPIDOMWindowOuter::From(GetOuterWindow())
5454 ->GetInProcessScriptableTop());
5455 nsGlobalWindowInner* topInnerWindow =
5456 outer ? nsGlobalWindowInner::Cast(outer->GetCurrentInnerWindow())
5457 : nullptr;
5458
5459 if (topInnerWindow) {
5460 const bool isPlayingAudio{IsPlayingAudio()};
5461 topInnerWindow->AudioPlaybackChanged(isPlayingAudio);
5462 topInnerWindow->CallOnInProcessDescendants(
5463 &nsGlobalWindowInner::AudioPlaybackChanged, isPlayingAudio);
5464 }
5465
5466 return NS_OK;
5467 }
5468
5469 if (!nsCRT::strcmp(aTopic, NS_IOSERVICE_OFFLINE_STATUS_TOPIC"network:offline-status-changed")) {
5470 if (!IsFrozen()) {
5471 // Fires an offline status event if the offline status has changed
5472 FireOfflineStatusEventIfChanged();
5473 }
5474 return NS_OK;
5475 }
5476
5477 if (!nsCRT::strcmp(aTopic, MEMORY_PRESSURE_OBSERVER_TOPIC"memory-pressure")) {
5478 if (mPerformance) {
5479 mPerformance->MemoryPressure();
5480 }
5481 RemoveReportRecords();
5482 return NS_OK;
5483 }
5484
5485 if (!nsCRT::strcmp(aTopic, PERMISSION_CHANGED_TOPIC"perm-changed") ||
5486 !nsCRT::strcmp(aTopic, "browser-perm-changed")) {
5487 bool isBrowserPerm = !nsCRT::strcmp(aTopic, "browser-perm-changed");
5488
5489 nsCOMPtr<nsIPermission> perm(do_QueryInterface(aSubject));
5490 if (!perm) {
5491 // Bulk browser permission clear — subject is an nsISupportsPRUint64
5492 // carrying the browserId. Only process if this window belongs to that
5493 // tab.
5494 if (isBrowserPerm) {
5495 nsCOMPtr<nsISupportsPRUint64> wrapper = do_QueryInterface(aSubject);
5496 if (wrapper) {
5497 uint64_t clearedBrowserId = 0;
5498 wrapper->GetData(&clearedBrowserId);
5499 if (clearedBrowserId) {
5500 RefPtr<BrowsingContext> bc = GetBrowsingContext();
5501 if (!bc || bc->Top()->BrowserId() != clearedBrowserId) {
5502 return NS_OK;
5503 }
5504 }
5505 }
5506 }
5507 UpdatePermissions();
5508 if (mDoc) {
5509 RefPtr<PermissionDelegateHandler> permDelegateHandler =
5510 mDoc->GetPermissionDelegateHandler();
5511 if (permDelegateHandler) {
5512 permDelegateHandler->PopulateAllDelegatedPermissions();
5513 }
5514 }
5515 return NS_OK;
5516 }
5517
5518 if (isBrowserPerm) {
5519 uint64_t permBrowserId = 0;
5520 perm->GetBrowserId(&permBrowserId);
5521 if (!permBrowserId) {
5522 return NS_OK;
5523 }
5524 RefPtr<BrowsingContext> bc = GetBrowsingContext();
5525 if (!bc || bc->Top()->BrowserId() != permBrowserId) {
5526 return NS_OK;
5527 }
5528 }
5529
5530 nsAutoCString type;
5531 perm->GetType(type);
5532 if (type == "autoplay-media"_ns) {
5533 UpdateAutoplayPermission();
5534 } else if (type == "shortcuts"_ns) {
5535 UpdateShortcutsPermission();
5536 } else if (type == "popup"_ns) {
5537 UpdatePopupPermission();
5538 }
5539
5540 if (!mDoc) {
5541 return NS_OK;
5542 }
5543
5544 RefPtr<PermissionDelegateHandler> permDelegateHandler =
5545 mDoc->GetPermissionDelegateHandler();
5546
5547 if (permDelegateHandler) {
5548 permDelegateHandler->UpdateDelegatedPermission(type);
5549 }
5550
5551 return NS_OK;
5552 }
5553
5554 if (!nsCRT::strcmp(aTopic, "screen-information-changed")) {
5555 if (mScreen) {
5556 if (RefPtr<ScreenOrientation> orientation =
5557 mScreen->GetOrientationIfExists()) {
5558 orientation->MaybeChanged();
5559 }
5560 }
5561 if (mHasOrientationChangeListeners) {
5562 int32_t oldAngle = mOrientationAngle;
5563 mOrientationAngle = Orientation(CallerType::System);
5564 if (mOrientationAngle != oldAngle && IsCurrentInnerWindow()) {
5565 nsCOMPtr<nsPIDOMWindowOuter> outer = GetOuterWindow();
5566 outer->DispatchCustomEvent(u"orientationchange"_ns);
5567 }
5568 }
5569 return NS_OK;
5570 }
5571
5572 if (!nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID"nsPref:changed")) {
5573 MOZ_ASSERT(!NS_strcmp(aData, u"intl.accept_languages"))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!NS_strcmp(aData, u"intl.accept_languages"))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!NS_strcmp(aData, u"intl.accept_languages")))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("!NS_strcmp(aData, u\"intl.accept_languages\")"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5573
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!NS_strcmp(aData, u\"intl.accept_languages\")"
")"); do { MOZ_CrashSequence(__null, 5573); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5574
5575 // The user preferred languages have changed, we need to fire an event on
5576 // Window object and invalidate the cache for navigator.languages. It is
5577 // done for every change which can be a waste of cycles but those should be
5578 // fairly rare.
5579 // We MUST invalidate navigator.languages before sending the event in the
5580 // very likely situation where an event handler will try to read its value.
5581
5582 if (mNavigator) {
5583 Navigator_Binding::ClearCachedLanguageValue(mNavigator);
5584 Navigator_Binding::ClearCachedLanguagesValue(mNavigator);
5585 }
5586
5587 // The event has to be dispatched only to the current inner window.
5588 if (!IsCurrentInnerWindow()) {
5589 return NS_OK;
5590 }
5591
5592 RefPtr<Event> event = NS_NewDOMEvent(this, nullptr, nullptr);
5593 event->InitEvent(u"languagechange"_ns, false, false);
5594 event->SetTrusted(true);
5595
5596 ErrorResult rv;
5597 DispatchEvent(*event, rv);
5598 return rv.StealNSResult();
5599 }
5600
5601 NS_WARNING(nsPrintfCString("unrecognized topic %s", aTopic).get())NS_DebugBreak(NS_DEBUG_WARNING, nsPrintfCString("unrecognized topic %s"
, aTopic).get(), nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 5601)
;
5602 return NS_ERROR_FAILURE;
5603}
5604
5605void nsGlobalWindowInner::ObserveStorageNotification(
5606 StorageEvent* aEvent, const char16_t* aStorageType, bool aPrivateBrowsing) {
5607 MOZ_ASSERT(aEvent)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aEvent)>::isValid, "invalid assertion condition")
; if ((__builtin_expect(!!(!(!!(aEvent))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aEvent", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 5607); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aEvent" ")"
); do { MOZ_CrashSequence(__null, 5607); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5608
5609 // The private browsing check must be done here again because this window
5610 // could have changed its state before the notification check and now. This
5611 // happens in case this window did have a docShell at that time.
5612 if (aPrivateBrowsing != IsPrivateBrowsing()) {
5613 return;
5614 }
5615
5616 // LocalStorage can only exist on an inner window, and we don't want to
5617 // generate events on frozen or otherwise-navigated-away from windows.
5618 // (Actually, this code used to try and buffer events for frozen windows,
5619 // but it never worked, so we've removed it. See bug 1285898.)
5620 if (!IsCurrentInnerWindow() || IsFrozen()) {
5621 return;
5622 }
5623
5624 nsIPrincipal* principal = GetPrincipal();
5625 if (!principal) {
5626 return;
5627 }
5628
5629 bool fireMozStorageChanged = false;
5630 nsAutoString eventType;
5631 eventType.AssignLiteral("storage");
5632
5633 if (!NS_strcmp(aStorageType, u"sessionStorage")) {
5634 RefPtr<Storage> changingStorage = aEvent->GetStorageArea();
5635 MOZ_ASSERT(changingStorage)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(changingStorage)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(changingStorage))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("changingStorage"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5635
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "changingStorage" ")"
); do { MOZ_CrashSequence(__null, 5635); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5636
5637 bool check = false;
5638
5639 if (const RefPtr<SessionStorageManager> storageManager =
5640 GetBrowsingContext()->GetSessionStorageManager()) {
5641 nsresult rv = storageManager->CheckStorage(GetEffectiveStoragePrincipal(),
5642 changingStorage, &check);
5643 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5644 return;
5645 }
5646 }
5647
5648 if (!check) {
5649 // This storage event is not coming from our storage or is coming
5650 // from a different docshell, i.e. it is a clone, ignore this event.
5651 return;
5652 }
5653
5654 MOZ_LOG(do { const ::mozilla::LogModule* moz_real_module = gDOMLeakPRLogInner
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsGlobalWindowInner %p with sessionStorage %p passing event from %p"
, this, mSessionStorage.get(), changingStorage.get()); } } while
(0)
5655 gDOMLeakPRLogInner, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gDOMLeakPRLogInner
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsGlobalWindowInner %p with sessionStorage %p passing event from %p"
, this, mSessionStorage.get(), changingStorage.get()); } } while
(0)
5656 ("nsGlobalWindowInner %p with sessionStorage %p passing event from %p",do { const ::mozilla::LogModule* moz_real_module = gDOMLeakPRLogInner
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsGlobalWindowInner %p with sessionStorage %p passing event from %p"
, this, mSessionStorage.get(), changingStorage.get()); } } while
(0)
5657 this, mSessionStorage.get(), changingStorage.get()))do { const ::mozilla::LogModule* moz_real_module = gDOMLeakPRLogInner
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsGlobalWindowInner %p with sessionStorage %p passing event from %p"
, this, mSessionStorage.get(), changingStorage.get()); } } while
(0)
;
5658
5659 fireMozStorageChanged = mSessionStorage == changingStorage;
5660 if (fireMozStorageChanged) {
5661 eventType.AssignLiteral("MozSessionStorageChanged");
5662 }
5663 }
5664
5665 else {
5666 MOZ_ASSERT(!NS_strcmp(aStorageType, u"localStorage"))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!NS_strcmp(aStorageType, u"localStorage"))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!NS_strcmp(aStorageType, u"localStorage")))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("!NS_strcmp(aStorageType, u\"localStorage\")"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5666
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!NS_strcmp(aStorageType, u\"localStorage\")"
")"); do { MOZ_CrashSequence(__null, 5666); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5667
5668 nsIPrincipal* storagePrincipal = GetEffectiveStoragePrincipal();
5669 if (!storagePrincipal) {
5670 return;
5671 }
5672
5673 MOZ_DIAGNOSTIC_ASSERT(StorageUtils::PrincipalsEqual(aEvent->GetPrincipal(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(StorageUtils::PrincipalsEqual(aEvent->GetPrincipal
(), storagePrincipal))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(StorageUtils::PrincipalsEqual
(aEvent->GetPrincipal(), storagePrincipal)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("StorageUtils::PrincipalsEqual(aEvent->GetPrincipal(), storagePrincipal)"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5674
); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "StorageUtils::PrincipalsEqual(aEvent->GetPrincipal(), storagePrincipal)"
")"); do { MOZ_CrashSequence(__null, 5674); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
5674 storagePrincipal))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(StorageUtils::PrincipalsEqual(aEvent->GetPrincipal
(), storagePrincipal))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(StorageUtils::PrincipalsEqual
(aEvent->GetPrincipal(), storagePrincipal)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("StorageUtils::PrincipalsEqual(aEvent->GetPrincipal(), storagePrincipal)"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5674
); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "StorageUtils::PrincipalsEqual(aEvent->GetPrincipal(), storagePrincipal)"
")"); do { MOZ_CrashSequence(__null, 5674); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5675
5676 fireMozStorageChanged =
5677 mLocalStorage && mLocalStorage == aEvent->GetStorageArea();
5678
5679 if (fireMozStorageChanged) {
5680 eventType.AssignLiteral("MozLocalStorageChanged");
5681 }
5682 }
5683
5684 // Clone the storage event included in the observer notification. We want
5685 // to dispatch clones rather than the original event.
5686 IgnoredErrorResult error;
5687 RefPtr<StorageEvent> clonedEvent =
5688 CloneStorageEvent(eventType, aEvent, error);
5689 if (error.Failed() || !clonedEvent) {
5690 return;
5691 }
5692
5693 clonedEvent->SetTrusted(true);
5694
5695 if (fireMozStorageChanged) {
5696 WidgetEvent* internalEvent = clonedEvent->WidgetEventPtr();
5697 internalEvent->mFlags.mOnlyChromeDispatch = true;
5698 }
5699
5700 DispatchEvent(*clonedEvent);
5701}
5702
5703already_AddRefed<StorageEvent> nsGlobalWindowInner::CloneStorageEvent(
5704 const nsAString& aType, const RefPtr<StorageEvent>& aEvent,
5705 ErrorResult& aRv) {
5706 StorageEventInit dict;
5707
5708 dict.mBubbles = aEvent->Bubbles();
5709 dict.mCancelable = aEvent->Cancelable();
5710 aEvent->GetKey(dict.mKey);
5711 aEvent->GetOldValue(dict.mOldValue);
5712 aEvent->GetNewValue(dict.mNewValue);
5713 aEvent->GetUrl(dict.mUrl);
5714
5715 RefPtr<Storage> storageArea = aEvent->GetStorageArea();
5716
5717 RefPtr<Storage> storage;
5718
5719 // If null, this is a localStorage event received by IPC.
5720 if (!storageArea) {
5721 storage = GetLocalStorage(aRv);
5722 if (!NextGenLocalStorageEnabled()) {
5723 if (aRv.Failed() || !storage) {
5724 return nullptr;
5725 }
5726
5727 if (storage->Type() == Storage::eLocalStorage) {
5728 RefPtr<LocalStorage> localStorage =
5729 static_cast<LocalStorage*>(storage.get());
5730
5731 // We must apply the current change to the 'local' localStorage.
5732 localStorage->ApplyEvent(aEvent);
5733 }
5734 }
5735 } else if (storageArea->Type() == Storage::eSessionStorage) {
5736 storage = GetSessionStorage(aRv);
5737 } else {
5738 MOZ_ASSERT(storageArea->Type() == Storage::eLocalStorage)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(storageArea->Type() == Storage::eLocalStorage)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(storageArea->Type() == Storage::eLocalStorage))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("storageArea->Type() == Storage::eLocalStorage"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5738
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "storageArea->Type() == Storage::eLocalStorage"
")"); do { MOZ_CrashSequence(__null, 5738); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5739 storage = GetLocalStorage(aRv);
5740 }
5741
5742 if (aRv.Failed() || !storage) {
5743 return nullptr;
5744 }
5745
5746 if (storage->Type() == Storage::ePartitionedLocalStorage) {
5747 // This error message is not exposed.
5748 aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
5749 return nullptr;
5750 }
5751
5752 MOZ_ASSERT(storage)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(storage)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(storage))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("storage", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 5752); AnnotateMozCrashReason("MOZ_ASSERT" "(" "storage" ")"
); do { MOZ_CrashSequence(__null, 5752); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5753 MOZ_ASSERT_IF(storageArea, storage->IsForkOf(storageArea))do { if (storageArea) { do { static_assert( mozilla::detail::
AssertionConditionType<decltype(storage->IsForkOf(storageArea
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(storage->IsForkOf(storageArea)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("storage->IsForkOf(storageArea)"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5753
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "storage->IsForkOf(storageArea)"
")"); do { MOZ_CrashSequence(__null, 5753); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
5754
5755 dict.mStorageArea = storage;
5756
5757 RefPtr<StorageEvent> event = StorageEvent::Constructor(this, aType, dict);
5758 return event.forget();
5759}
5760
5761void nsGlobalWindowInner::Suspend(bool aIncludeSubWindows) {
5762 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5762
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 5762); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5763
5764 // We can only safely suspend windows that are the current inner window. If
5765 // its not the current inner, then we are in one of two different cases.
5766 // Either we are in the bfcache or we are doomed window that is going away.
5767 // When a window becomes inactive we purposely avoid placing already suspended
5768 // windows into the bfcache. It only expects windows suspended due to the
5769 // Freeze() method which occurs while the window is still the current inner.
5770 // So we must not call Suspend() on bfcache windows at this point or this
5771 // invariant will be broken. If the window is doomed there is no point in
5772 // suspending it since it will soon be gone.
5773 if (!IsCurrentInnerWindow()) {
5774 return;
5775 }
5776
5777 // All in-process descendants are also suspended. This ensure mSuspendDepth
5778 // is set properly and the timers are properly canceled for each in-process
5779 // descendant.
5780 if (aIncludeSubWindows) {
5781 CallOnInProcessDescendants(&nsGlobalWindowInner::Suspend, false);
5782 }
5783
5784 mSuspendDepth += 1;
5785 if (mSuspendDepth != 1) {
5786 return;
5787 }
5788
5789 if (mWindowGlobalChild) {
5790 mWindowGlobalChild->BlockBFCacheFor(BFCacheStatus::SUSPENDED);
5791 }
5792
5793 nsCOMPtr<nsIDeviceSensors> ac = do_GetService(NS_DEVICE_SENSORS_CONTRACTID"@mozilla.org/devicesensors;1");
5794 if (ac) {
5795 for (uint32_t i = 0; i < mEnabledSensors.Length(); i++)
5796 ac->RemoveWindowListener(mEnabledSensors[i], this);
5797 }
5798 DisableGamepadUpdates();
5799 DisableVRUpdates();
5800
5801 SuspendWorkersForWindow(*this);
5802
5803 for (RefPtr<mozilla::dom::SharedWorker> pinnedWorker :
5804 mSharedWorkers.ForwardRange()) {
5805 pinnedWorker->Suspend();
5806 }
5807
5808 SuspendIdleRequests();
5809
5810 mTimeoutManager->Suspend();
5811
5812 // Suspend all of the AudioContexts for this window
5813 for (uint32_t i = 0; i < mAudioContexts.Length(); ++i) {
5814 mAudioContexts[i]->SuspendFromChrome();
5815 }
5816}
5817
5818void nsGlobalWindowInner::Resume(bool aIncludeSubWindows) {
5819 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5819
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 5819); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5820
5821 // We can only safely resume a window if its the current inner window. If
5822 // its not the current inner, then we are in one of two different cases.
5823 // Either we are in the bfcache or we are doomed window that is going away.
5824 // If a window is suspended when it becomes inactive we purposely do not
5825 // put it in the bfcache, so Resume should never be needed in that case.
5826 // If the window is doomed then there is no point in resuming it.
5827 if (!IsCurrentInnerWindow()) {
5828 return;
5829 }
5830
5831 // Resume all in-process descendants. This restores timers recursively
5832 // canceled in Suspend() and ensures all in-process descendants have the
5833 // correct mSuspendDepth.
5834 if (aIncludeSubWindows) {
5835 CallOnInProcessDescendants(&nsGlobalWindowInner::Resume, false);
5836 }
5837
5838 if (mSuspendDepth == 0) {
5839 // Ignore if the window is not suspended.
5840 return;
5841 }
5842
5843 mSuspendDepth -= 1;
5844
5845 if (mSuspendDepth != 0) {
5846 return;
5847 }
5848
5849 // We should not be able to resume a frozen window. It must be Thaw()'d
5850 // first.
5851 MOZ_ASSERT(mFreezeDepth == 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mFreezeDepth == 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mFreezeDepth == 0))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("mFreezeDepth == 0"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5851
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mFreezeDepth == 0"
")"); do { MOZ_CrashSequence(__null, 5851); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5852
5853 nsCOMPtr<nsIDeviceSensors> ac = do_GetService(NS_DEVICE_SENSORS_CONTRACTID"@mozilla.org/devicesensors;1");
5854 if (ac) {
5855 for (uint32_t i = 0; i < mEnabledSensors.Length(); i++)
5856 ac->AddWindowListener(mEnabledSensors[i], this);
5857 }
5858 EnableGamepadUpdates();
5859 EnableVRUpdates();
5860
5861 // Resume all of the AudioContexts for this window
5862 for (uint32_t i = 0; i < mAudioContexts.Length(); ++i) {
5863 mAudioContexts[i]->ResumeFromChrome();
5864 }
5865
5866 if (RefPtr<MediaDevices> devices = GetExtantMediaDevices()) {
5867 devices->WindowResumed();
5868 }
5869
5870 mTimeoutManager->Resume();
5871
5872 ResumeIdleRequests();
5873
5874 // Resume all of the workers for this window. We must do this
5875 // after timeouts since workers may have queued events that can trigger
5876 // a setTimeout().
5877 ResumeWorkersForWindow(*this);
5878
5879 for (RefPtr<mozilla::dom::SharedWorker> pinnedWorker :
5880 mSharedWorkers.ForwardRange()) {
5881 pinnedWorker->Resume();
5882 }
5883
5884 if (mWindowGlobalChild) {
5885 mWindowGlobalChild->UnblockBFCacheFor(BFCacheStatus::SUSPENDED);
5886 }
5887}
5888
5889bool nsGlobalWindowInner::IsSuspended() const {
5890 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5890
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 5890); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5891 return mSuspendDepth != 0;
5892}
5893
5894void nsGlobalWindowInner::Freeze(bool aIncludeSubWindows) {
5895 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5895
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 5895); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5896 Suspend(aIncludeSubWindows);
5897 FreezeInternal(aIncludeSubWindows);
5898}
5899
5900void nsGlobalWindowInner::FreezeInternal(bool aIncludeSubWindows) {
5901 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5901
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 5901); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5902 MOZ_DIAGNOSTIC_ASSERT(IsCurrentInnerWindow())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(IsCurrentInnerWindow())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsCurrentInnerWindow()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("IsCurrentInnerWindow()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5902
); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "IsCurrentInnerWindow()"
")"); do { MOZ_CrashSequence(__null, 5902); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5903 MOZ_DIAGNOSTIC_ASSERT(IsSuspended())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(IsSuspended())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsSuspended()))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("IsSuspended()",
"/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5903
); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "IsSuspended()"
")"); do { MOZ_CrashSequence(__null, 5903); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5904
5905 HintIsLoading(false);
5906
5907 if (aIncludeSubWindows) {
5908 CallOnInProcessChildren(&nsGlobalWindowInner::FreezeInternal,
5909 aIncludeSubWindows);
5910 }
5911
5912 mFreezeDepth += 1;
5913 MOZ_ASSERT(mSuspendDepth >= mFreezeDepth)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mSuspendDepth >= mFreezeDepth)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mSuspendDepth >= mFreezeDepth
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"mSuspendDepth >= mFreezeDepth", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 5913); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mSuspendDepth >= mFreezeDepth"
")"); do { MOZ_CrashSequence(__null, 5913); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5914 if (mFreezeDepth != 1) {
5915 return;
5916 }
5917
5918 FreezeWorkersForWindow(*this);
5919
5920 for (RefPtr<mozilla::dom::SharedWorker> pinnedWorker :
5921 mSharedWorkers.ForwardRange()) {
5922 pinnedWorker->Freeze();
5923 }
5924
5925 mTimeoutManager->Freeze();
5926 if (mClientSource) {
5927 mClientSource->Freeze();
5928 }
5929
5930 NotifyGlobalFrozen();
5931}
5932
5933void nsGlobalWindowInner::Thaw(bool aIncludeSubWindows) {
5934 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5934
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 5934); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5935 ThawInternal(aIncludeSubWindows);
5936 Resume(aIncludeSubWindows);
5937}
5938
5939void nsGlobalWindowInner::ThawInternal(bool aIncludeSubWindows) {
5940 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5940
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 5940); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5941 MOZ_DIAGNOSTIC_ASSERT(IsCurrentInnerWindow())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(IsCurrentInnerWindow())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsCurrentInnerWindow()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("IsCurrentInnerWindow()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5941
); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "IsCurrentInnerWindow()"
")"); do { MOZ_CrashSequence(__null, 5941); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5942 MOZ_DIAGNOSTIC_ASSERT(IsSuspended())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(IsSuspended())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsSuspended()))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("IsSuspended()",
"/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5942
); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "IsSuspended()"
")"); do { MOZ_CrashSequence(__null, 5942); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5943
5944 if (aIncludeSubWindows) {
5945 CallOnInProcessChildren(&nsGlobalWindowInner::ThawInternal,
5946 aIncludeSubWindows);
5947 }
5948
5949 MOZ_ASSERT(mFreezeDepth != 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mFreezeDepth != 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mFreezeDepth != 0))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("mFreezeDepth != 0"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5949
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mFreezeDepth != 0"
")"); do { MOZ_CrashSequence(__null, 5949); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5950 mFreezeDepth -= 1;
5951 MOZ_ASSERT(mSuspendDepth >= mFreezeDepth)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mSuspendDepth >= mFreezeDepth)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mSuspendDepth >= mFreezeDepth
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"mSuspendDepth >= mFreezeDepth", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 5951); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mSuspendDepth >= mFreezeDepth"
")"); do { MOZ_CrashSequence(__null, 5951); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5952 if (mFreezeDepth != 0) {
5953 return;
5954 }
5955
5956 if (mClientSource) {
5957 mClientSource->Thaw();
5958 }
5959 mTimeoutManager->Thaw();
5960
5961 ThawWorkersForWindow(*this);
5962
5963 for (RefPtr<mozilla::dom::SharedWorker> pinnedWorker :
5964 mSharedWorkers.ForwardRange()) {
5965 pinnedWorker->Thaw();
5966 }
5967
5968 NotifyGlobalThawed();
5969}
5970
5971bool nsGlobalWindowInner::IsFrozen() const {
5972 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5972
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 5972); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5973 bool frozen = mFreezeDepth != 0;
5974 MOZ_ASSERT_IF(frozen, IsSuspended())do { if (frozen) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(IsSuspended())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsSuspended()))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("IsSuspended()",
"/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5974
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsSuspended()" ")"
); do { MOZ_CrashSequence(__null, 5974); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
5975 return frozen;
5976}
5977
5978void nsGlobalWindowInner::SyncStateFromParentWindow() {
5979 // This method should only be called on an inner window that has been
5980 // assigned to an outer window already.
5981 MOZ_ASSERT(IsCurrentInnerWindow())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(IsCurrentInnerWindow())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsCurrentInnerWindow()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("IsCurrentInnerWindow()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5981
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsCurrentInnerWindow()"
")"); do { MOZ_CrashSequence(__null, 5981); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5982 nsPIDOMWindowOuter* outer = GetOuterWindow();
5983 MOZ_ASSERT(outer)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(outer)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(outer))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("outer", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 5983); AnnotateMozCrashReason("MOZ_ASSERT" "(" "outer" ")")
; do { MOZ_CrashSequence(__null, 5983); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5984
5985 // Attempt to find our parent windows.
5986 nsCOMPtr<Element> frame = outer->GetFrameElementInternal();
5987 nsPIDOMWindowOuter* parentOuter =
5988 frame ? frame->OwnerDoc()->GetWindow() : nullptr;
5989 nsGlobalWindowInner* parentInner =
5990 parentOuter
5991 ? nsGlobalWindowInner::Cast(parentOuter->GetCurrentInnerWindow())
5992 : nullptr;
5993
5994 // If our outer is in a modal state, but our parent is not in a modal
5995 // state, then we must apply the suspend directly. If our parent is
5996 // in a modal state then we should get the suspend automatically
5997 // via the parentSuspendDepth application below.
5998 if ((!parentInner || !parentInner->IsInModalState()) && IsInModalState()) {
5999 Suspend();
6000 }
6001
6002 uint32_t parentFreezeDepth = parentInner ? parentInner->mFreezeDepth : 0;
6003 uint32_t parentSuspendDepth = parentInner ? parentInner->mSuspendDepth : 0;
6004
6005 // Since every Freeze() calls Suspend(), the suspend count must
6006 // be equal or greater to the freeze count.
6007 MOZ_ASSERT(parentFreezeDepth <= parentSuspendDepth)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(parentFreezeDepth <= parentSuspendDepth)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(parentFreezeDepth <= parentSuspendDepth))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("parentFreezeDepth <= parentSuspendDepth"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6007
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "parentFreezeDepth <= parentSuspendDepth"
")"); do { MOZ_CrashSequence(__null, 6007); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6008
6009 // First apply the Freeze() calls.
6010 for (uint32_t i = 0; i < parentFreezeDepth; ++i) {
6011 Freeze();
6012 }
6013
6014 // Now apply only the number of Suspend() calls to reach the target
6015 // suspend count after applying the Freeze() calls.
6016 for (uint32_t i = 0; i < (parentSuspendDepth - parentFreezeDepth); ++i) {
6017 Suspend();
6018 }
6019}
6020
6021void nsGlobalWindowInner::UpdateBackgroundState() {
6022 if (RefPtr<MediaDevices> devices = GetExtantMediaDevices()) {
6023 devices->BackgroundStateChanged();
6024 }
6025 mTimeoutManager->UpdateBackgroundState();
6026
6027 UpdateWorkersBackgroundState(*this, IsBackgroundInternal());
6028}
6029
6030template <typename Method, typename... Args>
6031CallState nsGlobalWindowInner::CallOnInProcessDescendantsInternal(
6032 BrowsingContext* aBrowsingContext, bool aChildOnly, Method aMethod,
6033 Args&&... aArgs) {
6034 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6034
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 6034); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6035 MOZ_ASSERT(aBrowsingContext)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aBrowsingContext)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aBrowsingContext))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("aBrowsingContext"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6035
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aBrowsingContext"
")"); do { MOZ_CrashSequence(__null, 6035); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6036
6037 CallState state = CallState::Continue;
6038 for (const RefPtr<BrowsingContext>& bc : aBrowsingContext->Children()) {
6039 if (nsCOMPtr<nsPIDOMWindowOuter> pWin = bc->GetDOMWindow()) {
6040 auto* win = nsGlobalWindowOuter::Cast(pWin);
6041 if (nsGlobalWindowInner* inner =
6042 nsGlobalWindowInner::Cast(win->GetCurrentInnerWindow())) {
6043 // Call the descendant method using our helper CallDescendant() template
6044 // method. This allows us to handle both void returning methods and
6045 // methods that return CallState explicitly. For void returning methods
6046 // we assume CallState::Continue.
6047 using returnType = decltype((inner->*aMethod)(aArgs...));
6048 state = CallDescendant<returnType>(inner, aMethod, aArgs...);
6049
6050 if (state == CallState::Stop) {
6051 return state;
6052 }
6053 }
6054 }
6055
6056 if (!aChildOnly) {
6057 state = CallOnInProcessDescendantsInternal(bc.get(), aChildOnly, aMethod,
6058 aArgs...);
6059 if (state == CallState::Stop) {
6060 return state;
6061 }
6062 }
6063 }
6064
6065 return state;
6066}
6067
6068nsIURI* nsGlobalWindowInner::GetBaseURI() const { return GetDocBaseURI(); }
6069
6070Maybe<ClientInfo> nsGlobalWindowInner::GetClientInfo() const {
6071 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6071
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 6071); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6072 if (mDoc && mDoc->IsStaticDocument()) {
6073 if (Maybe<ClientInfo> info = mDoc->GetOriginalDocument()->GetClientInfo()) {
6074 return info;
6075 }
6076 }
6077
6078 Maybe<ClientInfo> clientInfo;
6079 if (mClientSource) {
6080 clientInfo.emplace(mClientSource->Info());
6081 }
6082 return clientInfo;
6083}
6084
6085Maybe<ClientState> nsGlobalWindowInner::GetClientState() const {
6086 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6086
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 6086); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6087 if (mDoc && mDoc->IsStaticDocument()) {
6088 if (Maybe<ClientState> state =
6089 mDoc->GetOriginalDocument()->GetClientState()) {
6090 return state;
6091 }
6092 }
6093
6094 Maybe<ClientState> clientState;
6095 if (mClientSource) {
6096 Result<ClientState, ErrorResult> res = mClientSource->SnapshotState();
6097 if (res.isOk()) {
6098 clientState.emplace(res.unwrap());
6099 } else {
6100 res.unwrapErr().SuppressException();
6101 }
6102 }
6103 return clientState;
6104}
6105
6106Maybe<ServiceWorkerDescriptor> nsGlobalWindowInner::GetController() const {
6107 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6107
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 6107); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6108 if (mDoc && mDoc->IsStaticDocument()) {
6109 if (Maybe<ServiceWorkerDescriptor> controller =
6110 mDoc->GetOriginalDocument()->GetController()) {
6111 return controller;
6112 }
6113 }
6114
6115 Maybe<ServiceWorkerDescriptor> controller;
6116 if (mClientSource) {
6117 controller = mClientSource->GetController();
6118 }
6119 return controller;
6120}
6121
6122void nsGlobalWindowInner::SetPolicyContainer(
6123 nsIPolicyContainer* aPolicyContainer) {
6124 if (!mClientSource) {
6125 return;
6126 }
6127 mClientSource->SetPolicyContainer(aPolicyContainer);
6128 // Also cache the PolicyContainer within the document
6129 mDoc->SetPolicyContainer(aPolicyContainer);
6130
6131 if (mWindowGlobalChild) {
6132 mWindowGlobalChild->SendSetClientInfo(mClientSource->Info().ToIPC());
6133 }
6134}
6135
6136nsIPolicyContainer* nsGlobalWindowInner::GetPolicyContainer() {
6137 if (mDoc) {
6138 return mDoc->GetPolicyContainer();
6139 }
6140
6141 // If the window is partially torn down and has its document nulled out,
6142 // we query the policy container we snapshot in FreeInnerObjects.
6143 if (mDocumentPolicyContainer) {
6144 return mDocumentPolicyContainer;
6145 }
6146 return nullptr;
6147}
6148
6149void nsGlobalWindowInner::SetPreloadCsp(nsIContentSecurityPolicy* aPreloadCsp) {
6150 if (!mClientSource) {
6151 return;
6152 }
6153 mClientSource->SetPreloadCsp(aPreloadCsp);
6154 // Also cache the preload CSP within the document
6155 mDoc->SetPreloadCsp(aPreloadCsp);
6156
6157 if (mWindowGlobalChild) {
6158 mWindowGlobalChild->SendSetClientInfo(mClientSource->Info().ToIPC());
6159 }
6160}
6161
6162already_AddRefed<ServiceWorkerContainer>
6163nsGlobalWindowInner::GetServiceWorkerContainer() {
6164 return Navigator()->ServiceWorker();
6165}
6166
6167RefPtr<ServiceWorker> nsGlobalWindowInner::GetOrCreateServiceWorker(
6168 const ServiceWorkerDescriptor& aDescriptor) {
6169 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6169
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 6169); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6170 RefPtr<ServiceWorker> ref;
6171 ForEachGlobalTeardownObserver(
6172 [&](GlobalTeardownObserver* aObserver, bool* aDoneOut) {
6173 RefPtr<ServiceWorker> sw = do_QueryObject(aObserver);
6174 if (!sw || !sw->Descriptor().Matches(aDescriptor)) {
6175 return;
6176 }
6177
6178 ref = std::move(sw);
6179 *aDoneOut = true;
6180 });
6181
6182 if (!ref) {
6183 ref = ServiceWorker::Create(this, aDescriptor);
6184 }
6185
6186 return ref;
6187}
6188
6189RefPtr<mozilla::dom::ServiceWorkerRegistration>
6190nsGlobalWindowInner::GetServiceWorkerRegistration(
6191 const mozilla::dom::ServiceWorkerRegistrationDescriptor& aDescriptor)
6192 const {
6193 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6193
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 6193); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6194 RefPtr<ServiceWorkerRegistration> ref;
6195 ForEachGlobalTeardownObserver(
6196 [&](GlobalTeardownObserver* aObserver, bool* aDoneOut) {
6197 RefPtr<ServiceWorkerRegistration> swr = do_QueryObject(aObserver);
6198 if (!swr || !swr->MatchesDescriptor(aDescriptor)) {
6199 return;
6200 }
6201
6202 ref = std::move(swr);
6203 *aDoneOut = true;
6204 });
6205 return ref;
6206}
6207
6208RefPtr<ServiceWorkerRegistration>
6209nsGlobalWindowInner::GetOrCreateServiceWorkerRegistration(
6210 const ServiceWorkerRegistrationDescriptor& aDescriptor) {
6211 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6211
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 6211); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6212 RefPtr<ServiceWorkerRegistration> ref =
6213 GetServiceWorkerRegistration(aDescriptor);
6214 if (!ref) {
6215 ref = ServiceWorkerRegistration::CreateForMainThread(this, aDescriptor);
6216 }
6217 return ref;
6218}
6219
6220StorageAccess nsGlobalWindowInner::GetStorageAccess() {
6221 return StorageAllowedForWindow(this);
6222}
6223
6224nsICookieJarSettings* nsGlobalWindowInner::GetCookieJarSettings() {
6225 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6225
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 6225); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6226 if (mDoc) {
6227 return mDoc->CookieJarSettings();
6228 }
6229 return nullptr;
6230}
6231
6232nsresult nsGlobalWindowInner::FireDelayedDOMEvents(bool aIncludeSubWindows) {
6233 // Fires an offline status event if the offline status has changed
6234 FireOfflineStatusEventIfChanged();
6235
6236 if (mCookieStore) {
6237 mCookieStore->FireDelayedDOMEvents();
6238 }
6239
6240 if (!aIncludeSubWindows) {
6241 return NS_OK;
6242 }
6243
6244 nsCOMPtr<nsIDocShell> docShell = GetDocShell();
6245 if (docShell) {
6246 int32_t childCount = 0;
6247 docShell->GetInProcessChildCount(&childCount);
6248
6249 // Take a copy of the current children so that modifications to
6250 // the child list don't affect to the iteration.
6251 AutoTArray<nsCOMPtr<nsIDocShellTreeItem>, 8> children;
6252 for (int32_t i = 0; i < childCount; ++i) {
6253 nsCOMPtr<nsIDocShellTreeItem> childShell;
6254 docShell->GetInProcessChildAt(i, getter_AddRefs(childShell));
6255 if (childShell) {
6256 children.AppendElement(childShell);
6257 }
6258 }
6259
6260 for (const nsCOMPtr<nsIDocShellTreeItem>& childShell : children) {
6261 if (const RefPtr<nsGlobalWindowOuter> win =
6262 nsGlobalWindowOuter::Cast(childShell->GetWindow())) {
6263 win->FireDelayedDOMEvents(true);
6264 }
6265 }
6266 }
6267
6268 return NS_OK;
6269}
6270
6271//*****************************************************************************
6272// nsGlobalWindowInner: Window Control Functions
6273//*****************************************************************************
6274
6275nsPIDOMWindowOuter* nsGlobalWindowInner::GetInProcessParentInternal() {
6276 nsGlobalWindowOuter* outer = GetOuterWindowInternal();
6277 if (!outer) {
6278 // No outer window available!
6279 return nullptr;
6280 }
6281 return outer->GetInProcessParentInternal();
6282}
6283
6284nsIPrincipal* nsGlobalWindowInner::GetTopLevelAntiTrackingPrincipal() {
6285 nsPIDOMWindowOuter* outerWindow = GetOuterWindowInternal();
6286 if (!outerWindow) {
6287 return nullptr;
6288 }
6289
6290 nsPIDOMWindowOuter* topLevelOuterWindow =
6291 GetBrowsingContext()->Top()->GetDOMWindow();
6292 if (!topLevelOuterWindow) {
6293 return nullptr;
6294 }
6295
6296 bool stopAtOurLevel =
6297 mDoc && mDoc->CookieJarSettings()->GetCookieBehavior() ==
6298 nsICookieService::BEHAVIOR_REJECT_TRACKER;
6299
6300 if (stopAtOurLevel && topLevelOuterWindow == outerWindow) {
6301 return nullptr;
6302 }
6303
6304 nsPIDOMWindowInner* topLevelInnerWindow =
6305 topLevelOuterWindow->GetCurrentInnerWindow();
6306 if (NS_WARN_IF(!topLevelInnerWindow)NS_warn_if_impl(!topLevelInnerWindow, "!topLevelInnerWindow",
"/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6306
)
) {
6307 return nullptr;
6308 }
6309
6310 nsIPrincipal* topLevelPrincipal =
6311 nsGlobalWindowInner::Cast(topLevelInnerWindow)->GetPrincipal();
6312 if (NS_WARN_IF(!topLevelPrincipal)NS_warn_if_impl(!topLevelPrincipal, "!topLevelPrincipal", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 6312)
) {
6313 return nullptr;
6314 }
6315
6316 return topLevelPrincipal;
6317}
6318
6319nsIPrincipal* nsGlobalWindowInner::GetClientPrincipal() {
6320 return mClientSource ? mClientSource->GetPrincipal() : nullptr;
6321}
6322
6323bool nsGlobalWindowInner::IsInFullScreenTransition() {
6324 if (!mIsChrome) {
6325 return false;
6326 }
6327
6328 nsGlobalWindowOuter* outerWindow = GetOuterWindowInternal();
6329 if (!outerWindow) {
6330 return false;
6331 }
6332
6333 return outerWindow->mIsInFullScreenTransition;
6334}
6335
6336//*****************************************************************************
6337// nsGlobalWindowInner: Timeout Functions
6338//*****************************************************************************
6339
6340class WindowScriptTimeoutHandler final : public ScriptTimeoutHandler {
6341 public:
6342 NS_DECL_ISUPPORTS_INHERITEDpublic: virtual nsresult QueryInterface(const nsIID& aIID
, void** aInstancePtr) override; virtual MozExternalRefCountType
AddRef(void) override; virtual MozExternalRefCountType Release
(void) override;
6343 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(WindowScriptTimeoutHandler,class cycleCollection : public ScriptTimeoutHandler::cycleCollection
{ public: constexpr explicit cycleCollection(Flags aFlags = 0
) : ScriptTimeoutHandler::cycleCollection(aFlags) {} private:
public: virtual nsresult TraverseNative(void* p, nsCycleCollectionTraversalCallback
& cb) override; virtual const char* ClassName() override {
return "WindowScriptTimeoutHandler"; }; static WindowScriptTimeoutHandler
* Downcast(nsISupports* s) { return static_cast<WindowScriptTimeoutHandler
*>(static_cast<ScriptTimeoutHandler*>( ScriptTimeoutHandler
::cycleCollection::Downcast(s))); } virtual void Unlink(void*
p) override; static constexpr nsXPCOMCycleCollectionParticipant
* GetParticipant() { return &WindowScriptTimeoutHandler::
_cycleCollectorGlobal; } }; clang diagnostic push clang diagnostic
ignored "-Wunnecessary-virtual-specifier" virtual void CheckForRightParticipant
() override clang diagnostic pop { nsXPCOMCycleCollectionParticipant
* p; CallQueryInterface(this, &p); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(p == &_cycleCollectorGlobal
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(p == &_cycleCollectorGlobal))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("p == &_cycleCollectorGlobal"
" (" "WindowScriptTimeoutHandler" " should QI to its own CC participant"
")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp",
6344); AnnotateMozCrashReason("MOZ_ASSERT" "(" "p == &_cycleCollectorGlobal"
") (" "WindowScriptTimeoutHandler" " should QI to its own CC participant"
")"); do { MOZ_CrashSequence(__null, 6344); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } static cycleCollection
_cycleCollectorGlobal;
6344 ScriptTimeoutHandler)class cycleCollection : public ScriptTimeoutHandler::cycleCollection
{ public: constexpr explicit cycleCollection(Flags aFlags = 0
) : ScriptTimeoutHandler::cycleCollection(aFlags) {} private:
public: virtual nsresult TraverseNative(void* p, nsCycleCollectionTraversalCallback
& cb) override; virtual const char* ClassName() override {
return "WindowScriptTimeoutHandler"; }; static WindowScriptTimeoutHandler
* Downcast(nsISupports* s) { return static_cast<WindowScriptTimeoutHandler
*>(static_cast<ScriptTimeoutHandler*>( ScriptTimeoutHandler
::cycleCollection::Downcast(s))); } virtual void Unlink(void*
p) override; static constexpr nsXPCOMCycleCollectionParticipant
* GetParticipant() { return &WindowScriptTimeoutHandler::
_cycleCollectorGlobal; } }; clang diagnostic push clang diagnostic
ignored "-Wunnecessary-virtual-specifier" virtual void CheckForRightParticipant
() override clang diagnostic pop { nsXPCOMCycleCollectionParticipant
* p; CallQueryInterface(this, &p); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(p == &_cycleCollectorGlobal
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(p == &_cycleCollectorGlobal))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("p == &_cycleCollectorGlobal"
" (" "WindowScriptTimeoutHandler" " should QI to its own CC participant"
")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp",
6344); AnnotateMozCrashReason("MOZ_ASSERT" "(" "p == &_cycleCollectorGlobal"
") (" "WindowScriptTimeoutHandler" " should QI to its own CC participant"
")"); do { MOZ_CrashSequence(__null, 6344); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } static cycleCollection
_cycleCollectorGlobal;
6345
6346 WindowScriptTimeoutHandler(JSContext* aCx, nsIGlobalObject* aGlobal,
6347 const nsAString& aExpression)
6348 : ScriptTimeoutHandler(aCx, aGlobal, aExpression),
6349 mInitiatingScriptFetchInfo(
6350 ScriptLoader::GetActiveScriptFetchInfo(aCx)) {}
6351
6352 MOZ_CAN_RUN_SCRIPT virtual bool Call(const char* aExecutionReason) override;
6353
6354 private:
6355 virtual ~WindowScriptTimeoutHandler() = default;
6356
6357 // Initiating script's referrer info for use when evaluating mExpr on the main
6358 // thread.
6359 RefPtr<JS::loader::ScriptFetchInfo> mInitiatingScriptFetchInfo;
6360};
6361
6362NS_IMPL_CYCLE_COLLECTION_INHERITED(WindowScriptTimeoutHandler,WindowScriptTimeoutHandler::cycleCollection WindowScriptTimeoutHandler
::_cycleCollectorGlobal; void WindowScriptTimeoutHandler::cycleCollection
::Unlink(void* p) { WindowScriptTimeoutHandler* tmp = DowncastCCParticipant
<WindowScriptTimeoutHandler>(p); nsISupports* s = static_cast
<nsISupports*>(p); ScriptTimeoutHandler::cycleCollection
::Unlink(s); ImplCycleCollectionUnlink(tmp->mInitiatingScriptFetchInfo
); (void)tmp; } nsresult WindowScriptTimeoutHandler::cycleCollection
::TraverseNative( void* p, nsCycleCollectionTraversalCallback
& cb) { WindowScriptTimeoutHandler* tmp = DowncastCCParticipant
<WindowScriptTimeoutHandler>(p); nsISupports* s = static_cast
<nsISupports*>(p); if (ScriptTimeoutHandler::cycleCollection
::TraverseNative(s, cb) == NS_SUCCESS_INTERRUPTED_TRAVERSE) {
return NS_SUCCESS_INTERRUPTED_TRAVERSE; } ImplCycleCollectionTraverse
(cb, tmp->mInitiatingScriptFetchInfo, "mInitiatingScriptFetchInfo"
, 0); (void)tmp; return NS_OK; }
6363 ScriptTimeoutHandler,WindowScriptTimeoutHandler::cycleCollection WindowScriptTimeoutHandler
::_cycleCollectorGlobal; void WindowScriptTimeoutHandler::cycleCollection
::Unlink(void* p) { WindowScriptTimeoutHandler* tmp = DowncastCCParticipant
<WindowScriptTimeoutHandler>(p); nsISupports* s = static_cast
<nsISupports*>(p); ScriptTimeoutHandler::cycleCollection
::Unlink(s); ImplCycleCollectionUnlink(tmp->mInitiatingScriptFetchInfo
); (void)tmp; } nsresult WindowScriptTimeoutHandler::cycleCollection
::TraverseNative( void* p, nsCycleCollectionTraversalCallback
& cb) { WindowScriptTimeoutHandler* tmp = DowncastCCParticipant
<WindowScriptTimeoutHandler>(p); nsISupports* s = static_cast
<nsISupports*>(p); if (ScriptTimeoutHandler::cycleCollection
::TraverseNative(s, cb) == NS_SUCCESS_INTERRUPTED_TRAVERSE) {
return NS_SUCCESS_INTERRUPTED_TRAVERSE; } ImplCycleCollectionTraverse
(cb, tmp->mInitiatingScriptFetchInfo, "mInitiatingScriptFetchInfo"
, 0); (void)tmp; return NS_OK; }
6364 mInitiatingScriptFetchInfo)WindowScriptTimeoutHandler::cycleCollection WindowScriptTimeoutHandler
::_cycleCollectorGlobal; void WindowScriptTimeoutHandler::cycleCollection
::Unlink(void* p) { WindowScriptTimeoutHandler* tmp = DowncastCCParticipant
<WindowScriptTimeoutHandler>(p); nsISupports* s = static_cast
<nsISupports*>(p); ScriptTimeoutHandler::cycleCollection
::Unlink(s); ImplCycleCollectionUnlink(tmp->mInitiatingScriptFetchInfo
); (void)tmp; } nsresult WindowScriptTimeoutHandler::cycleCollection
::TraverseNative( void* p, nsCycleCollectionTraversalCallback
& cb) { WindowScriptTimeoutHandler* tmp = DowncastCCParticipant
<WindowScriptTimeoutHandler>(p); nsISupports* s = static_cast
<nsISupports*>(p); if (ScriptTimeoutHandler::cycleCollection
::TraverseNative(s, cb) == NS_SUCCESS_INTERRUPTED_TRAVERSE) {
return NS_SUCCESS_INTERRUPTED_TRAVERSE; } ImplCycleCollectionTraverse
(cb, tmp->mInitiatingScriptFetchInfo, "mInitiatingScriptFetchInfo"
, 0); (void)tmp; return NS_OK; }
6365
6366NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WindowScriptTimeoutHandler)nsresult WindowScriptTimeoutHandler::QueryInterface(const nsIID
& aIID, void** aInstancePtr) { do { if (!(aInstancePtr)) {
NS_DebugBreak(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 6366); MOZ_PretendNoReturn(); } } while (0); nsISupports* foundInterface
; if (TopThreeWordsEquals( aIID, (nsXPCOMCycleCollectionParticipant
::kIID), (nsCycleCollectionISupports::kIID)) && (LowWordEquals
(aIID, (nsXPCOMCycleCollectionParticipant::kIID)) || LowWordEquals
(aIID, (nsCycleCollectionISupports::kIID)))) { if (LowWordEquals
(aIID, (nsXPCOMCycleCollectionParticipant::kIID))) { *aInstancePtr
= WindowScriptTimeoutHandler::cycleCollection::GetParticipant
(); return NS_OK; } if (LowWordEquals(aIID, (nsCycleCollectionISupports
::kIID))) { *aInstancePtr = WindowScriptTimeoutHandler::cycleCollection
::Upcast(this); return NS_OK; } foundInterface = nullptr; } else
6367NS_INTERFACE_MAP_END_INHERITING(ScriptTimeoutHandler)foundInterface = 0; nsresult status; if (!foundInterface) status
= ScriptTimeoutHandler::QueryInterface(aIID, (void**)&foundInterface
); else { (foundInterface)->AddRef(); status = NS_OK; } *aInstancePtr
= foundInterface; return status; }
6368
6369NS_IMPL_ADDREF_INHERITED(WindowScriptTimeoutHandler, ScriptTimeoutHandler)MozExternalRefCountType WindowScriptTimeoutHandler::AddRef(void
) { static_assert(!std::is_destructible_v<WindowScriptTimeoutHandler
>, "Reference-counted class " "WindowScriptTimeoutHandler"
" should not have a public destructor. " "Make this class's destructor non-public"
); nsrefcnt r = ScriptTimeoutHandler::AddRef(); if constexpr (
::mozilla::detail::ShouldLogInheritedRefcnt<WindowScriptTimeoutHandler
>) { NS_LogAddRef((this), (r), ("WindowScriptTimeoutHandler"
), (uint32_t)(sizeof(*this))); } return r; }
6370NS_IMPL_RELEASE_INHERITED(WindowScriptTimeoutHandler, ScriptTimeoutHandler)MozExternalRefCountType WindowScriptTimeoutHandler::Release(void
) { nsrefcnt r = ScriptTimeoutHandler::Release(); if constexpr
(::mozilla::detail::ShouldLogInheritedRefcnt<WindowScriptTimeoutHandler
>) { NS_LogRelease((this), (r), ("WindowScriptTimeoutHandler"
)); } return r; }
6371
6372bool WindowScriptTimeoutHandler::Call(const char* aExecutionReason) {
6373 // New script entry point required, due to the "Create a script" sub-step
6374 // of
6375 // http://www.whatwg.org/specs/web-apps/current-work/#timer-initialisation-steps
6376 nsAutoMicroTask mt;
6377 AutoEntryScript aes(mGlobal, aExecutionReason, true);
6378 JS::CompileOptions options(aes.cx());
6379 options.setFileAndLine(mCaller.FileName().get(), mCaller.mLine);
6380 options.setNoScriptRval(true);
6381 options.setIntroductionType("domTimer");
6382 JS::Rooted<JSObject*> global(aes.cx(), mGlobal->GetGlobalJSObject());
6383 {
6384 if (MOZ_UNLIKELY(!xpc::Scriptability::Get(global).Allowed())(__builtin_expect(!!(!xpc::Scriptability::Get(global).Allowed
()), 0))
) {
6385 return true;
6386 }
6387
6388 IgnoredErrorResult erv;
6389 mozilla::AutoProfilerLabel autoProfilerLabel("JSExecutionContext",
6390 /* dynamicStr */ nullptr,
6391 JS::ProfilingCategoryPair::JS);
6392 JSAutoRealm autoRealm(aes.cx(), global);
6393 RefPtr<JS::Stencil> stencil;
6394 JS::Rooted<JSScript*> script(aes.cx());
6395 Compile(aes.cx(), options, mExpr, stencil, erv);
6396 if (stencil) {
6397 JS::InstantiateOptions instantiateOptions(options);
6398 MOZ_ASSERT(!instantiateOptions.deferDebugMetadata)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!instantiateOptions.deferDebugMetadata)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!instantiateOptions.deferDebugMetadata))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!instantiateOptions.deferDebugMetadata"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6398
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!instantiateOptions.deferDebugMetadata"
")"); do { MOZ_CrashSequence(__null, 6398); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6399 script.set(JS::InstantiateGlobalStencil(aes.cx(), instantiateOptions,
6400 stencil, /* storage */ nullptr));
6401 if (!script) {
6402 erv.NoteJSContextException(aes.cx());
6403 }
6404 }
6405
6406 if (script) {
6407 MOZ_ASSERT(!erv.Failed())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!erv.Failed())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!erv.Failed()))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("!erv.Failed()",
"/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6407
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!erv.Failed()" ")"
); do { MOZ_CrashSequence(__null, 6407); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6408 if (mInitiatingScriptFetchInfo) {
6409 mInitiatingScriptFetchInfo->AssociateWithScript(script);
6410 }
6411
6412 if (!JS_ExecuteScript(aes.cx(), script)) {
6413 erv.NoteJSContextException(aes.cx());
6414 }
6415 }
6416
6417 if (erv.IsUncatchableException()) {
6418 return false;
6419 }
6420 }
6421
6422 return true;
6423};
6424
6425nsGlobalWindowInner* nsGlobalWindowInner::InnerForSetTimeoutOrInterval(
6426 ErrorResult& aError) {
6427 nsGlobalWindowOuter* outer = GetOuterWindowInternal();
6428 nsPIDOMWindowInner* currentInner =
6429 outer ? outer->GetCurrentInnerWindow() : this;
6430
6431 // If forwardTo is not the window with an active document then we want the
6432 // call to setTimeout/Interval to be a noop, so return null but don't set an
6433 // error.
6434 return HasActiveDocument() ? nsGlobalWindowInner::Cast(currentInner)
6435 : nullptr;
6436}
6437
6438int32_t nsGlobalWindowInner::SetTimeout(
6439 JSContext* aCx, const FunctionOrTrustedScriptOrString& aHandler,
6440 int32_t aTimeout, const Sequence<JS::Value>& aArguments,
6441 nsIPrincipal* aSubjectPrincipal, ErrorResult& aError) {
6442 return SetTimeoutOrInterval(aCx, aHandler, aTimeout, aArguments, false,
6443 aSubjectPrincipal, aError);
6444}
6445
6446int32_t nsGlobalWindowInner::SetInterval(
6447 JSContext* aCx, const FunctionOrTrustedScriptOrString& aHandler,
6448 const int32_t aTimeout, const Sequence<JS::Value>& aArguments,
6449 nsIPrincipal* aSubjectPrincipal, ErrorResult& aError) {
6450 return SetTimeoutOrInterval(aCx, aHandler, aTimeout, aArguments, true,
6451 aSubjectPrincipal, aError);
6452}
6453
6454int32_t nsGlobalWindowInner::SetTimeoutOrInterval(
6455 JSContext* aCx, const FunctionOrTrustedScriptOrString& aHandler,
6456 int32_t aTimeout, const Sequence<JS::Value>& aArguments, bool aIsInterval,
6457 nsIPrincipal* aSubjectPrincipal, ErrorResult& aError) {
6458 nsGlobalWindowInner* inner = InnerForSetTimeoutOrInterval(aError);
6459 if (!inner) {
6460 return -1;
6461 }
6462
6463 if (inner != this) {
6464 RefPtr<nsGlobalWindowInner> innerRef(inner);
6465 return innerRef->SetTimeoutOrInterval(aCx, aHandler, aTimeout, aArguments,
6466 aIsInterval, aSubjectPrincipal,
6467 aError);
6468 }
6469
6470 DebuggerNotificationDispatch(
6471 this, aIsInterval ? DebuggerNotificationType::SetInterval
6472 : DebuggerNotificationType::SetTimeout);
6473
6474 if (!GetContextInternal() || !HasJSGlobal()) {
6475 // This window was already closed, or never properly initialized,
6476 // don't let a timer be scheduled on such a window.
6477 return 0;
6478 }
6479
6480 if (aHandler.IsFunction()) {
6481 nsTArray<JS::Heap<JS::Value>> args;
6482 if (!args.AppendElements(aArguments, fallible)) {
6483 aError.Throw(NS_ERROR_OUT_OF_MEMORY);
6484 return 0;
6485 }
6486
6487 RefPtr handler = MakeRefPtr<CallbackTimeoutHandler>(
6488 aCx, this, &aHandler.GetAsFunction(), std::move(args));
6489
6490 int32_t result;
6491 aError = mTimeoutManager->SetTimeout(handler, aTimeout, aIsInterval,
6492 Timeout::Reason::eTimeoutOrInterval,
6493 &result);
6494 return result;
6495 }
6496
6497 constexpr nsLiteralString sinkSetTimeout = u"Window setTimeout"_ns;
6498 constexpr nsLiteralString sinkSetInterval = u"Window setInterval"_ns;
6499 Maybe<nsAutoString> compliantStringHolder;
6500 nsCOMPtr<nsIGlobalObject> pinnedGlobal = this;
6501 const nsAString* compliantString =
6502 TrustedTypeUtils::GetTrustedTypesCompliantString(
6503 aHandler, aIsInterval ? sinkSetInterval : sinkSetTimeout,
6504 kTrustedTypesOnlySinkGroup, *pinnedGlobal, aSubjectPrincipal,
6505 compliantStringHolder, aError);
6506 if (aError.Failed()) {
6507 return 0;
6508 }
6509
6510 bool allowEval = false;
6511 aError =
6512 CSPEvalChecker::CheckForWindow(aCx, this, *compliantString, &allowEval);
6513 if (NS_WARN_IF(aError.Failed())NS_warn_if_impl(aError.Failed(), "aError.Failed()", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 6513)
|| !allowEval) {
6514 return 0;
6515 }
6516 RefPtr handler =
6517 MakeRefPtr<WindowScriptTimeoutHandler>(aCx, this, *compliantString);
6518 int32_t result;
6519 aError =
6520 mTimeoutManager->SetTimeout(handler, aTimeout, aIsInterval,
6521 Timeout::Reason::eTimeoutOrInterval, &result);
6522 return result;
6523}
6524
6525static const char* GetTimeoutReasonString(Timeout* aTimeout) {
6526 switch (aTimeout->mReason) {
6527 case Timeout::Reason::eTimeoutOrInterval:
6528 if (aTimeout->mIsInterval) {
6529 return "setInterval handler";
6530 }
6531 return "setTimeout handler";
6532 case Timeout::Reason::eIdleCallbackTimeout:
6533 return "setIdleCallback handler (timed out)";
6534 case Timeout::Reason::eAbortSignalTimeout:
6535 return "AbortSignal timeout";
6536 case Timeout::Reason::eDelayedWebTaskTimeout:
6537 return "delayedWebTaskCallback handler (timed out)";
6538 case Timeout::Reason::eJSTimeout:
6539 return "JavaScript TimeoutJob (timed out)";
6540 default:
6541 MOZ_CRASH("Unexpected enum value")do { do { } while (false); MOZ_ReportCrash("" "Unexpected enum value"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6541
); AnnotateMozCrashReason("MOZ_CRASH(" "Unexpected enum value"
")"); do { MOZ_CrashSequence(__null, 6541); __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
6542 return "";
6543 }
6544 MOZ_CRASH("Unexpected enum value")do { do { } while (false); MOZ_ReportCrash("" "Unexpected enum value"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6544
); AnnotateMozCrashReason("MOZ_CRASH(" "Unexpected enum value"
")"); do { MOZ_CrashSequence(__null, 6544); __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
6545 return "";
6546}
6547
6548bool nsGlobalWindowInner::RunTimeoutHandler(Timeout* aTimeout) {
6549 // Hold on to the timeout in case mExpr or mFunObj releases its
6550 // doc.
6551 // XXXbz Our caller guarantees it'll hold on to the timeout (because
6552 // we're MOZ_CAN_RUN_SCRIPT), so we can probably stop doing that...
6553 RefPtr<Timeout> timeout = aTimeout;
6554 Timeout* last_running_timeout = mTimeoutManager->BeginRunningTimeout(timeout);
6555 timeout->mRunning = true;
6556
6557 // Push this timeout's popup control state, which should only be
6558 // enabled the first time a timeout fires that was created while
6559 // popups were enabled and with a delay less than
6560 // "dom.disable_open_click_delay".
6561 AutoPopupStatePusherAutoPopupStatePusherInternal popupStatePusher(timeout->mPopupState);
6562
6563 // Clear the timeout's popup state, if any, to prevent interval
6564 // timeouts from repeatedly opening poups.
6565 timeout->mPopupState = PopupBlocker::openAbused;
6566
6567 uint32_t nestingLevel = mTimeoutManager->GetNestingLevelForWindow();
6568 mTimeoutManager->SetNestingLevelForWindow(timeout->mNestingLevel);
6569
6570 const char* reason = GetTimeoutReasonString(timeout);
6571
6572 nsCString str;
6573 if (profiler_thread_is_being_profiled_for_markers()) {
6574 TimeDuration originalInterval = timeout->When() - timeout->SubmitTime();
6575 str.Append(reason);
6576 str.Append(" with interval ");
6577 str.AppendInt(int(originalInterval.ToMilliseconds()));
6578 str.Append("ms: ");
6579 nsCString handlerDescription;
6580 timeout->mScriptHandler->GetDescription(handlerDescription);
6581 str.Append(handlerDescription);
6582 }
6583 AUTO_PROFILER_MARKER_TEXT("setTimeout callback", DOM,AutoProfilerTextMarker raiiObject6587( "setTimeout callback",
::mozilla::baseprofiler::category::DOM, MarkerOptions(MarkerStack
::TakeBacktrace( timeout->TakeProfilerBacktrace()), MarkerInnerWindowId
(mWindowID)), str)
6584 MarkerOptions(MarkerStack::TakeBacktrace(AutoProfilerTextMarker raiiObject6587( "setTimeout callback",
::mozilla::baseprofiler::category::DOM, MarkerOptions(MarkerStack
::TakeBacktrace( timeout->TakeProfilerBacktrace()), MarkerInnerWindowId
(mWindowID)), str)
6585 timeout->TakeProfilerBacktrace()),AutoProfilerTextMarker raiiObject6587( "setTimeout callback",
::mozilla::baseprofiler::category::DOM, MarkerOptions(MarkerStack
::TakeBacktrace( timeout->TakeProfilerBacktrace()), MarkerInnerWindowId
(mWindowID)), str)
6586 MarkerInnerWindowId(mWindowID)),AutoProfilerTextMarker raiiObject6587( "setTimeout callback",
::mozilla::baseprofiler::category::DOM, MarkerOptions(MarkerStack
::TakeBacktrace( timeout->TakeProfilerBacktrace()), MarkerInnerWindowId
(mWindowID)), str)
6587 str)AutoProfilerTextMarker raiiObject6587( "setTimeout callback",
::mozilla::baseprofiler::category::DOM, MarkerOptions(MarkerStack
::TakeBacktrace( timeout->TakeProfilerBacktrace()), MarkerInnerWindowId
(mWindowID)), str)
;
6588
6589 bool abortIntervalHandler;
6590 {
6591 RefPtr<TimeoutHandler> handler(timeout->mScriptHandler);
6592
6593 CallbackDebuggerNotificationGuard guard(
6594 this, timeout->mIsInterval
6595 ? DebuggerNotificationType::SetIntervalCallback
6596 : DebuggerNotificationType::SetTimeoutCallback);
6597 abortIntervalHandler = !handler->Call(reason);
6598 }
6599
6600 // If we received an uncatchable exception, do not schedule the timeout again.
6601 // This allows the slow script dialog to break easy DoS attacks like
6602 // setInterval(function() { while(1); }, 100);
6603 if (abortIntervalHandler) {
6604 // If it wasn't an interval timer to begin with, this does nothing. If it
6605 // was, we'll treat it as a timeout that we just ran and discard it when
6606 // we return.
6607 timeout->mIsInterval = false;
6608 }
6609
6610 // We ignore any failures from calling EvaluateString() on the context or
6611 // Call() on a Function here since we're in a loop
6612 // where we're likely to be running timeouts whose OS timers
6613 // didn't fire in time and we don't want to not fire those timers
6614 // now just because execution of one timer failed. We can't
6615 // propagate the error to anyone who cares about it from this
6616 // point anyway, and the script context should have already reported
6617 // the script error in the usual way - so we just drop it.
6618
6619 mTimeoutManager->SetNestingLevelForWindow(nestingLevel);
6620
6621 mTimeoutManager->EndRunningTimeout(last_running_timeout);
6622 timeout->mRunning = false;
6623
6624 return timeout->mCleared;
6625}
6626
6627//*****************************************************************************
6628// nsGlobalWindowInner: Helper Functions
6629//*****************************************************************************
6630
6631already_AddRefed<nsIDocShellTreeOwner> nsGlobalWindowInner::GetTreeOwner() {
6632 FORWARD_TO_OUTER(GetTreeOwner, (), nullptr);
6633}
6634
6635already_AddRefed<nsIWebBrowserChrome>
6636nsGlobalWindowInner::GetWebBrowserChrome() {
6637 nsCOMPtr<nsIDocShellTreeOwner> treeOwner = GetTreeOwner();
6638
6639 nsCOMPtr<nsIWebBrowserChrome> browserChrome = do_GetInterface(treeOwner);
6640 return browserChrome.forget();
6641}
6642
6643ScrollContainerFrame* nsGlobalWindowInner::GetScrollContainerFrame() {
6644 FORWARD_TO_OUTER(GetScrollContainerFrame, (), nullptr);
6645}
6646
6647bool nsGlobalWindowInner::IsPrivateBrowsing() {
6648 nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(GetDocShell());
6649 return loadContext && loadContext->UsePrivateBrowsing();
6650}
6651
6652void nsGlobalWindowInner::FlushPendingNotifications(FlushType aType) {
6653 if (mDoc) {
6654 mDoc->FlushPendingNotifications(aType);
6655 }
6656}
6657
6658void nsGlobalWindowInner::EnableDeviceSensor(uint32_t aType) {
6659 bool alreadyEnabled = false;
6660 for (uint32_t i = 0; i < mEnabledSensors.Length(); i++) {
6661 if (mEnabledSensors[i] == aType) {
6662 alreadyEnabled = true;
6663 break;
6664 }
6665 }
6666
6667 mEnabledSensors.AppendElement(aType);
6668
6669 if (alreadyEnabled) {
6670 return;
6671 }
6672
6673 nsCOMPtr<nsIDeviceSensors> ac = do_GetService(NS_DEVICE_SENSORS_CONTRACTID"@mozilla.org/devicesensors;1");
6674 if (ac) {
6675 ac->AddWindowListener(aType, this);
6676 }
6677}
6678
6679void nsGlobalWindowInner::DisableDeviceSensor(uint32_t aType) {
6680 int32_t doomedElement = -1;
6681 int32_t listenerCount = 0;
6682 for (uint32_t i = 0; i < mEnabledSensors.Length(); i++) {
6683 if (mEnabledSensors[i] == aType) {
6684 doomedElement = i;
6685 listenerCount++;
6686 }
6687 }
6688
6689 if (doomedElement == -1) {
6690 return;
6691 }
6692
6693 mEnabledSensors.RemoveElementAt(doomedElement);
6694
6695 if (listenerCount > 1) {
6696 return;
6697 }
6698
6699 nsCOMPtr<nsIDeviceSensors> ac = do_GetService(NS_DEVICE_SENSORS_CONTRACTID"@mozilla.org/devicesensors;1");
6700 if (ac) {
6701 ac->RemoveWindowListener(aType, this);
6702 }
6703}
6704
6705#if defined(MOZ_WIDGET_ANDROID)
6706void nsGlobalWindowInner::EnableOrientationChangeListener() {
6707 if (!ShouldResistFingerprinting(RFPTarget::ScreenOrientation)) {
6708 mHasOrientationChangeListeners = true;
6709 mOrientationAngle = Orientation(CallerType::System);
6710 }
6711}
6712
6713void nsGlobalWindowInner::DisableOrientationChangeListener() {
6714 mHasOrientationChangeListeners = false;
6715}
6716#endif
6717
6718void nsGlobalWindowInner::SetHasGamepadEventListener(
6719 bool aHasGamepad /* = true*/) {
6720 mHasGamepad = aHasGamepad;
6721 if (aHasGamepad) {
6722 EnableGamepadUpdates();
6723 }
6724}
6725
6726void nsGlobalWindowInner::NotifyDetectXRRuntimesCompleted() {
6727 if (!mXRRuntimeDetectionInFlight) {
6728 return;
6729 }
6730 mXRRuntimeDetectionInFlight = false;
6731 if (mXRPermissionRequestInFlight) {
6732 return;
6733 }
6734 gfx::VRManagerChild* vm = gfx::VRManagerChild::Get();
6735 bool supported = vm->RuntimeSupportsVR();
6736 if (!supported) {
6737 // A VR runtime was not installed; we can suppress
6738 // the permission prompt
6739 OnXRPermissionRequestCancel();
6740 return;
6741 }
6742 // A VR runtime was found. Display a permission prompt before
6743 // allowing it to be accessed.
6744 // Connect to the VRManager in order to receive the runtime
6745 // detection results.
6746 mXRPermissionRequestInFlight = true;
6747 RefPtr request = MakeRefPtr<XRPermissionRequest>(this, WindowID());
6748 (void)NS_WARN_IF(NS_FAILED(request->Start()))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(request
->Start())), 0))), "NS_FAILED(request->Start())", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 6748)
;
6749}
6750
6751void nsGlobalWindowInner::RequestXRPermission() {
6752 if (IsDying()) {
6753 // Do not proceed if the window is dying, as that will result
6754 // in leaks of objects that get re-allocated after FreeInnerObjects
6755 // has been called, including mVREventObserver.
6756 return;
6757 }
6758 if (mXRPermissionGranted) {
6759 // Don't prompt redundantly once permission to
6760 // access XR devices has been granted.
6761 OnXRPermissionRequestAllow();
6762 return;
6763 }
6764 if (mXRRuntimeDetectionInFlight || mXRPermissionRequestInFlight) {
6765 // Don't allow multiple simultaneous permissions requests;
6766 return;
6767 }
6768 // Before displaying a permission prompt, detect
6769 // if there is any VR runtime installed.
6770 gfx::VRManagerChild* vm = gfx::VRManagerChild::Get();
6771 mXRRuntimeDetectionInFlight = true;
6772 EnableVRUpdates();
6773 vm->DetectRuntimes();
6774}
6775
6776void nsGlobalWindowInner::OnXRPermissionRequestAllow() {
6777 mXRPermissionRequestInFlight = false;
6778 if (IsDying()) {
6779 // The window may have started dying while the permission request
6780 // is in flight.
6781 // Do not proceed if the window is dying, as that will result
6782 // in leaks of objects that get re-allocated after FreeInnerObjects
6783 // has been called, including mNavigator.
6784 return;
6785 }
6786 mXRPermissionGranted = true;
6787
6788 NotifyHasXRSession();
6789
6790 dom::Navigator* nav = Navigator();
6791 MOZ_ASSERT(nav != nullptr)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(nav != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(nav != nullptr))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("nav != nullptr"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6791
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "nav != nullptr" ")"
); do { MOZ_CrashSequence(__null, 6791); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6792 nav->OnXRPermissionRequestAllow();
6793}
6794
6795void nsGlobalWindowInner::OnXRPermissionRequestCancel() {
6796 mXRPermissionRequestInFlight = false;
6797 if (IsDying()) {
6798 // The window may have started dying while the permission request
6799 // is in flight.
6800 // Do not proceed if the window is dying, as that will result
6801 // in leaks of objects that get re-allocated after FreeInnerObjects
6802 // has been called, including mNavigator.
6803 return;
6804 }
6805 dom::Navigator* nav = Navigator();
6806 MOZ_ASSERT(nav != nullptr)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(nav != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(nav != nullptr))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("nav != nullptr"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6806
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "nav != nullptr" ")"
); do { MOZ_CrashSequence(__null, 6806); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6807 nav->OnXRPermissionRequestCancel();
6808}
6809
6810void nsGlobalWindowInner::EventListenerAdded(nsAtom* aType) {
6811 if (aType == nsGkAtoms::onvrdisplayactivate ||
6812 aType == nsGkAtoms::onvrdisplayconnect ||
6813 aType == nsGkAtoms::onvrdisplaydeactivate ||
6814 aType == nsGkAtoms::onvrdisplaydisconnect ||
6815 aType == nsGkAtoms::onvrdisplaypresentchange) {
6816 RequestXRPermission();
6817 }
6818
6819 if (aType == nsGkAtoms::onvrdisplayactivate) {
6820 mHasVRDisplayActivateEvents = true;
6821 }
6822
6823 if (aType == nsGkAtoms::onunload && mWindowGlobalChild) {
6824 if (++mUnloadOrBeforeUnloadListenerCount == 1) {
6825 mWindowGlobalChild->BlockBFCacheFor(BFCacheStatus::UNLOAD_LISTENER);
6826 }
6827 }
6828
6829 if (aType == nsGkAtoms::onbeforeunload && mWindowGlobalChild) {
6830 if (!StaticPrefs::
6831 docshell_shistory_bfcache_ship_allow_beforeunload_listeners()) {
6832 if (++mUnloadOrBeforeUnloadListenerCount == 1) {
6833 mWindowGlobalChild->BlockBFCacheFor(
6834 BFCacheStatus::BEFOREUNLOAD_LISTENER);
6835 }
6836 }
6837 if (!mDoc || !(mDoc->GetSandboxFlags() & SANDBOXED_MODALS)) {
6838 mWindowGlobalChild->BeforeUnloadAdded();
6839 MOZ_ASSERT(mWindowGlobalChild->BeforeUnloadListeners() > 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mWindowGlobalChild->BeforeUnloadListeners() > 0
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(mWindowGlobalChild->BeforeUnloadListeners() > 0
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"mWindowGlobalChild->BeforeUnloadListeners() > 0", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 6839); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mWindowGlobalChild->BeforeUnloadListeners() > 0"
")"); do { MOZ_CrashSequence(__null, 6839); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6840 }
6841 }
6842
6843 // We need to initialize localStorage in order to receive notifications.
6844 if (aType == nsGkAtoms::onstorage) {
6845 ErrorResult rv;
6846 GetLocalStorage(rv);
6847 rv.SuppressException();
6848
6849 if (NextGenLocalStorageEnabled() && mLocalStorage &&
6850 mLocalStorage->Type() == Storage::eLocalStorage) {
6851 auto object = static_cast<LSObject*>(mLocalStorage.get());
6852
6853 (void)NS_WARN_IF(NS_FAILED(object->EnsureObserver()))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(object
->EnsureObserver())), 0))), "NS_FAILED(object->EnsureObserver())"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6853
)
;
6854 }
6855 }
6856}
6857
6858void nsGlobalWindowInner::EventListenerRemoved(nsAtom* aType) {
6859 if (aType == nsGkAtoms::onunload && mWindowGlobalChild) {
6860 MOZ_ASSERT(mUnloadOrBeforeUnloadListenerCount > 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mUnloadOrBeforeUnloadListenerCount > 0)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(mUnloadOrBeforeUnloadListenerCount > 0))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("mUnloadOrBeforeUnloadListenerCount > 0"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6860
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mUnloadOrBeforeUnloadListenerCount > 0"
")"); do { MOZ_CrashSequence(__null, 6860); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6861 if (--mUnloadOrBeforeUnloadListenerCount == 0) {
6862 mWindowGlobalChild->UnblockBFCacheFor(BFCacheStatus::UNLOAD_LISTENER);
6863 }
6864 }
6865
6866 if (aType == nsGkAtoms::onbeforeunload && mWindowGlobalChild) {
6867 if (!StaticPrefs::
6868 docshell_shistory_bfcache_ship_allow_beforeunload_listeners()) {
6869 if (--mUnloadOrBeforeUnloadListenerCount == 0) {
6870 mWindowGlobalChild->UnblockBFCacheFor(
6871 BFCacheStatus::BEFOREUNLOAD_LISTENER);
6872 }
6873 }
6874 if (!mDoc || !(mDoc->GetSandboxFlags() & SANDBOXED_MODALS)) {
6875 mWindowGlobalChild->BeforeUnloadRemoved();
6876 MOZ_ASSERT(mWindowGlobalChild->BeforeUnloadListeners() >= 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mWindowGlobalChild->BeforeUnloadListeners() >=
0)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(mWindowGlobalChild->BeforeUnloadListeners() >=
0))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mWindowGlobalChild->BeforeUnloadListeners() >= 0", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 6876); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mWindowGlobalChild->BeforeUnloadListeners() >= 0"
")"); do { MOZ_CrashSequence(__null, 6876); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6877 }
6878 }
6879
6880 if (aType == nsGkAtoms::onstorage) {
6881 if (NextGenLocalStorageEnabled() && mLocalStorage &&
6882 mLocalStorage->Type() == Storage::eLocalStorage &&
6883 // The remove event is fired even if this isn't the last listener, so
6884 // only remove if there are no other listeners left.
6885 mListenerManager &&
6886 !mListenerManager->HasListenersFor(nsGkAtoms::onstorage)) {
6887 auto object = static_cast<LSObject*>(mLocalStorage.get());
6888
6889 object->DropObserver();
6890 }
6891 }
6892}
6893
6894void nsGlobalWindowInner::NotifyHasXRSession() {
6895 if (IsDying()) {
6896 // Do not proceed if the window is dying, as that will result
6897 // in leaks of objects that get re-allocated after FreeInnerObjects
6898 // has been called, including mVREventObserver.
6899 return;
6900 }
6901 if (mWindowGlobalChild && !mHasXRSession) {
6902 mWindowGlobalChild->BlockBFCacheFor(BFCacheStatus::HAS_USED_VR);
6903 }
6904 mHasXRSession = true;
6905 EnableVRUpdates();
6906}
6907
6908bool nsGlobalWindowInner::HasUsedVR() const {
6909 // Returns true only if content has enumerated and activated
6910 // XR devices. Detection of XR runtimes without activation
6911 // will not cause true to be returned.
6912 return mHasXRSession;
6913}
6914
6915bool nsGlobalWindowInner::IsVRContentDetected() const {
6916 // Returns true only if the content will respond to
6917 // the VRDisplayActivate event.
6918 return mHasVRDisplayActivateEvents;
6919}
6920
6921bool nsGlobalWindowInner::IsVRContentPresenting() const {
6922 for (const auto& display : mVRDisplays) {
6923 if (display->IsAnyPresenting(gfx::kVRGroupAll)) {
6924 return true;
6925 }
6926 }
6927 return false;
6928}
6929
6930void nsGlobalWindowInner::AddSizeOfIncludingThis(
6931 nsWindowSizes& aWindowSizes) const {
6932 aWindowSizes.mDOMSizes.mDOMOtherSize +=
6933 aWindowSizes.mState.mMallocSizeOf(this);
6934 aWindowSizes.mDOMSizes.mDOMOtherSize +=
6935 nsIGlobalObject::ShallowSizeOfExcludingThis(
6936 aWindowSizes.mState.mMallocSizeOf);
6937
6938 EventListenerManager* elm = GetExistingListenerManager();
6939 if (elm) {
6940 aWindowSizes.mDOMSizes.mDOMOtherSize +=
6941 elm->SizeOfIncludingThis(aWindowSizes.mState.mMallocSizeOf);
6942 aWindowSizes.mDOMEventListenersCount += elm->ListenerCount();
6943 }
6944 if (mDoc) {
6945 // Multiple global windows can share a document. So only measure the
6946 // document if it (a) doesn't have a global window, or (b) it's the
6947 // primary document for the window.
6948 if (!mDoc->GetInnerWindow() || mDoc->GetInnerWindow() == this) {
6949 mDoc->DocAddSizeOfIncludingThis(aWindowSizes);
6950 }
6951 }
6952
6953 if (mNavigation) {
6954 aWindowSizes.mDOMSizes.mDOMOtherSize +=
6955 aWindowSizes.mState.mMallocSizeOf(mNavigation.get());
6956 }
6957 if (mNavigator) {
6958 aWindowSizes.mDOMSizes.mDOMOtherSize +=
6959 mNavigator->SizeOfIncludingThis(aWindowSizes.mState.mMallocSizeOf);
6960 }
6961
6962 ForEachGlobalTeardownObserver([&](GlobalTeardownObserver* et,
6963 bool* aDoneOut) {
6964 if (nsCOMPtr<nsISizeOfEventTarget> iSizeOf = do_QueryObject(et)) {
6965 aWindowSizes.mDOMSizes.mDOMEventTargetsSize +=
6966 iSizeOf->SizeOfEventTargetIncludingThis(
6967 aWindowSizes.mState.mMallocSizeOf);
6968 }
6969 if (nsCOMPtr<DOMEventTargetHelper> helper = do_QueryObject(et)) {
6970 if (EventListenerManager* elm = helper->GetExistingListenerManager()) {
6971 aWindowSizes.mDOMEventListenersCount += elm->ListenerCount();
6972 }
6973 }
6974 ++aWindowSizes.mDOMEventTargetsCount;
6975 });
6976
6977 if (mPerformance) {
6978 aWindowSizes.mDOMSizes.mDOMPerformanceUserEntries =
6979 mPerformance->SizeOfUserEntries(aWindowSizes.mState.mMallocSizeOf);
6980 aWindowSizes.mDOMSizes.mDOMPerformanceResourceEntries =
6981 mPerformance->SizeOfResourceEntries(aWindowSizes.mState.mMallocSizeOf);
6982 aWindowSizes.mDOMSizes.mDOMPerformanceEventEntries =
6983 mPerformance->SizeOfEventEntries(aWindowSizes.mState.mMallocSizeOf);
6984 }
6985
6986 aWindowSizes.mMediaSourceURLsCount = mMediaSourceURLs.Length();
6987}
6988
6989void nsGlobalWindowInner::RegisterDataDocumentForMemoryReporting(
6990 Document* aDocument) {
6991 aDocument->SetAddedToMemoryReportAsDataDocument();
6992 mDataDocumentsForMemoryReporting.AppendElement(aDocument);
6993}
6994
6995void nsGlobalWindowInner::UnregisterDataDocumentForMemoryReporting(
6996 Document* aDocument) {
6997 DebugOnly<bool> found =
6998 mDataDocumentsForMemoryReporting.RemoveElement(aDocument);
6999 MOZ_ASSERT(found)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(found)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(found))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("found", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 6999); AnnotateMozCrashReason("MOZ_ASSERT" "(" "found" ")")
; do { MOZ_CrashSequence(__null, 6999); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7000}
7001
7002void nsGlobalWindowInner::CollectDOMSizesForDataDocuments(
7003 nsWindowSizes& aSize) const {
7004 for (Document* doc : mDataDocumentsForMemoryReporting) {
7005 if (doc) {
7006 doc->DocAddSizeOfIncludingThis(aSize);
7007 }
7008 }
7009}
7010
7011void nsGlobalWindowInner::AddGamepad(GamepadHandle aHandle, Gamepad* aGamepad) {
7012 // Create the index we will present to content based on which indices are
7013 // already taken, as required by the spec.
7014 // https://w3c.github.io/gamepad/gamepad.html#widl-Gamepad-index
7015 int index = 0;
7016 while (mGamepadIndexSet.Contains(index)) {
7017 ++index;
7018 }
7019 mGamepadIndexSet.Put(index);
7020 aGamepad->SetIndex(index);
7021 mGamepads.InsertOrUpdate(aHandle, RefPtr{aGamepad});
7022}
7023
7024void nsGlobalWindowInner::RemoveGamepad(GamepadHandle aHandle) {
7025 RefPtr<Gamepad> gamepad;
7026 if (!mGamepads.Get(aHandle, getter_AddRefs(gamepad))) {
7027 return;
7028 }
7029 // Free up the index we were using so it can be reused
7030 mGamepadIndexSet.Remove(gamepad->Index());
7031 mGamepads.Remove(aHandle);
7032}
7033
7034void nsGlobalWindowInner::GetGamepads(nsTArray<RefPtr<Gamepad>>& aGamepads) {
7035 aGamepads.Clear();
7036
7037 // navigator.getGamepads() always returns an empty array when
7038 // privacy.resistFingerprinting is true.
7039 if (ShouldResistFingerprinting(RFPTarget::Gamepad)) {
7040 return;
7041 }
7042
7043 // mGamepads.Count() may not be sufficient, but it's not harmful.
7044 aGamepads.SetCapacity(mGamepads.Count());
7045 for (const auto& entry : mGamepads) {
7046 Gamepad* gamepad = entry.GetWeak();
7047 aGamepads.EnsureLengthAtLeast(gamepad->Index() + 1);
7048 aGamepads[gamepad->Index()] = gamepad;
7049 }
7050}
7051
7052already_AddRefed<mozilla::dom::Promise> nsGlobalWindowInner::RequestAllGamepads(
7053 ErrorResult& aRv) {
7054 RefPtr<GamepadManager> gamepadManager(GamepadManager::GetService());
7055
7056 if (!gamepadManager) {
7057 aRv.Throw(NS_ERROR_UNEXPECTED);
7058 return nullptr;
7059 }
7060
7061 return gamepadManager->RequestAllGamepads(this, aRv);
7062}
7063
7064already_AddRefed<Gamepad> nsGlobalWindowInner::GetGamepad(
7065 GamepadHandle aHandle) {
7066 RefPtr<Gamepad> gamepad;
7067
7068 if (mGamepads.Get(aHandle, getter_AddRefs(gamepad))) {
7069 return gamepad.forget();
7070 }
7071
7072 return nullptr;
7073}
7074
7075void nsGlobalWindowInner::SetHasSeenGamepadInput(bool aHasSeen) {
7076 mHasSeenGamepadInput = aHasSeen;
7077}
7078
7079bool nsGlobalWindowInner::HasSeenGamepadInput() { return mHasSeenGamepadInput; }
7080
7081void nsGlobalWindowInner::SyncGamepadState() {
7082 if (mHasSeenGamepadInput) {
7083 RefPtr<GamepadManager> gamepadManager(GamepadManager::GetService());
7084 for (const auto& entry : mGamepads) {
7085 gamepadManager->SyncGamepadState(entry.GetKey(), this, entry.GetWeak());
7086 }
7087 }
7088}
7089
7090void nsGlobalWindowInner::StopGamepadHaptics() {
7091 if (mHasSeenGamepadInput) {
7092 RefPtr<GamepadManager> gamepadManager(GamepadManager::GetService());
7093 gamepadManager->StopHaptics();
7094 }
7095}
7096
7097bool nsGlobalWindowInner::UpdateVRDisplays(
7098 nsTArray<RefPtr<mozilla::dom::VRDisplay>>& aDevices) {
7099 VRDisplay::UpdateVRDisplays(mVRDisplays, this);
7100 aDevices = mVRDisplays.Clone();
7101 return true;
7102}
7103
7104void nsGlobalWindowInner::NotifyActiveVRDisplaysChanged() {
7105 if (mNavigator) {
7106 mNavigator->NotifyActiveVRDisplaysChanged();
7107 }
7108}
7109
7110void nsGlobalWindowInner::NotifyPresentationGenerationChanged(
7111 uint32_t aDisplayID) {
7112 for (const auto& display : mVRDisplays) {
7113 if (display->DisplayId() == aDisplayID) {
7114 display->OnPresentationGenerationChanged();
7115 }
7116 }
7117}
7118
7119void nsGlobalWindowInner::DispatchVRDisplayActivate(
7120 uint32_t aDisplayID, mozilla::dom::VRDisplayEventReason aReason) {
7121 // Ensure that our list of displays is up to date
7122 VRDisplay::UpdateVRDisplays(mVRDisplays, this);
7123
7124 // Search for the display identified with aDisplayID and fire the
7125 // event if found.
7126 for (const auto& display : mVRDisplays) {
7127 if (display->DisplayId() == aDisplayID) {
7128 if (aReason != VRDisplayEventReason::Navigation &&
7129 display->IsAnyPresenting(gfx::kVRGroupContent)) {
7130 // We only want to trigger this event if nobody is presenting to the
7131 // display already or when a page is loaded by navigating away
7132 // from a page with an active VR Presentation.
7133 continue;
7134 }
7135
7136 VRDisplayEventInit init;
7137 init.mBubbles = false;
7138 init.mCancelable = false;
7139 init.mDisplay = display;
7140 init.mReason.Construct(aReason);
7141
7142 RefPtr<VRDisplayEvent> event =
7143 VRDisplayEvent::Constructor(this, u"vrdisplayactivate"_ns, init);
7144 // vrdisplayactivate is a trusted event, allowing VRDisplay.requestPresent
7145 // to be used in response to link traversal, user request (chrome UX), and
7146 // HMD mounting detection sensors.
7147 event->SetTrusted(true);
7148 // VRDisplay.requestPresent normally requires a user gesture; however, an
7149 // exception is made to allow it to be called in response to
7150 // vrdisplayactivate during VR link traversal.
7151 display->StartHandlingVRNavigationEvent();
7152 DispatchEvent(*event);
7153 display->StopHandlingVRNavigationEvent();
7154 // Once we dispatch the event, we must not access any members as an event
7155 // listener can do anything, including closing windows.
7156 return;
7157 }
7158 }
7159}
7160
7161void nsGlobalWindowInner::DispatchVRDisplayDeactivate(
7162 uint32_t aDisplayID, mozilla::dom::VRDisplayEventReason aReason) {
7163 // Ensure that our list of displays is up to date
7164 VRDisplay::UpdateVRDisplays(mVRDisplays, this);
7165
7166 // Search for the display identified with aDisplayID and fire the
7167 // event if found.
7168 for (const auto& display : mVRDisplays) {
7169 if (display->DisplayId() == aDisplayID && display->IsPresenting()) {
7170 // We only want to trigger this event to content that is presenting to
7171 // the display already.
7172
7173 VRDisplayEventInit init;
7174 init.mBubbles = false;
7175 init.mCancelable = false;
7176 init.mDisplay = display;
7177 init.mReason.Construct(aReason);
7178
7179 RefPtr<VRDisplayEvent> event =
7180 VRDisplayEvent::Constructor(this, u"vrdisplaydeactivate"_ns, init);
7181 event->SetTrusted(true);
7182 DispatchEvent(*event);
7183 // Once we dispatch the event, we must not access any members as an event
7184 // listener can do anything, including closing windows.
7185 return;
7186 }
7187 }
7188}
7189
7190void nsGlobalWindowInner::DispatchVRDisplayConnect(uint32_t aDisplayID) {
7191 // Ensure that our list of displays is up to date
7192 VRDisplay::UpdateVRDisplays(mVRDisplays, this);
7193
7194 // Search for the display identified with aDisplayID and fire the
7195 // event if found.
7196 for (const auto& display : mVRDisplays) {
7197 if (display->DisplayId() == aDisplayID) {
7198 // Fire event even if not presenting to the display.
7199 VRDisplayEventInit init;
7200 init.mBubbles = false;
7201 init.mCancelable = false;
7202 init.mDisplay = display;
7203 // VRDisplayEvent.reason is not set for vrdisplayconnect
7204
7205 RefPtr<VRDisplayEvent> event =
7206 VRDisplayEvent::Constructor(this, u"vrdisplayconnect"_ns, init);
7207 event->SetTrusted(true);
7208 DispatchEvent(*event);
7209 // Once we dispatch the event, we must not access any members as an event
7210 // listener can do anything, including closing windows.
7211 return;
7212 }
7213 }
7214}
7215
7216void nsGlobalWindowInner::DispatchVRDisplayDisconnect(uint32_t aDisplayID) {
7217 // Ensure that our list of displays is up to date
7218 VRDisplay::UpdateVRDisplays(mVRDisplays, this);
7219
7220 // Search for the display identified with aDisplayID and fire the
7221 // event if found.
7222 for (const auto& display : mVRDisplays) {
7223 if (display->DisplayId() == aDisplayID) {
7224 // Fire event even if not presenting to the display.
7225 VRDisplayEventInit init;
7226 init.mBubbles = false;
7227 init.mCancelable = false;
7228 init.mDisplay = display;
7229 // VRDisplayEvent.reason is not set for vrdisplaydisconnect
7230
7231 RefPtr<VRDisplayEvent> event =
7232 VRDisplayEvent::Constructor(this, u"vrdisplaydisconnect"_ns, init);
7233 event->SetTrusted(true);
7234 DispatchEvent(*event);
7235 // Once we dispatch the event, we must not access any members as an event
7236 // listener can do anything, including closing windows.
7237 return;
7238 }
7239 }
7240}
7241
7242void nsGlobalWindowInner::DispatchVRDisplayPresentChange(uint32_t aDisplayID) {
7243 // Ensure that our list of displays is up to date
7244 VRDisplay::UpdateVRDisplays(mVRDisplays, this);
7245
7246 // Search for the display identified with aDisplayID and fire the
7247 // event if found.
7248 for (const auto& display : mVRDisplays) {
7249 if (display->DisplayId() == aDisplayID) {
7250 // Fire event even if not presenting to the display.
7251 VRDisplayEventInit init;
7252 init.mBubbles = false;
7253 init.mCancelable = false;
7254 init.mDisplay = display;
7255 // VRDisplayEvent.reason is not set for vrdisplaypresentchange
7256 RefPtr<VRDisplayEvent> event =
7257 VRDisplayEvent::Constructor(this, u"vrdisplaypresentchange"_ns, init);
7258 event->SetTrusted(true);
7259 DispatchEvent(*event);
7260 // Once we dispatch the event, we must not access any members as an event
7261 // listener can do anything, including closing windows.
7262 return;
7263 }
7264 }
7265}
7266
7267enum WindowState {
7268 // These constants need to match the constants in Window.webidl
7269 STATE_MAXIMIZED = 1,
7270 STATE_MINIMIZED = 2,
7271 STATE_NORMAL = 3,
7272 STATE_FULLSCREEN = 4
7273};
7274
7275uint16_t nsGlobalWindowInner::WindowState() {
7276 nsCOMPtr<nsIWidget> widget = GetMainWidget();
7277
7278 int32_t mode = widget ? widget->SizeMode() : 0;
7279
7280 switch (mode) {
7281 case nsSizeMode_Minimized:
7282 return STATE_MINIMIZED;
7283 case nsSizeMode_Maximized:
7284 return STATE_MAXIMIZED;
7285 case nsSizeMode_Fullscreen:
7286 return STATE_FULLSCREEN;
7287 case nsSizeMode_Normal:
7288 return STATE_NORMAL;
7289 default:
7290 NS_WARNING("Illegal window state for this chrome window")NS_DebugBreak(NS_DEBUG_WARNING, "Illegal window state for this chrome window"
, nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 7290)
;
7291 break;
7292 }
7293
7294 return STATE_NORMAL;
7295}
7296
7297bool nsGlobalWindowInner::IsFullyOccluded() {
7298 nsCOMPtr<nsIWidget> widget = GetMainWidget();
7299 return widget && widget->IsFullyOccluded();
7300}
7301
7302void nsGlobalWindowInner::Maximize() {
7303 if (nsCOMPtr<nsIWidget> widget = GetMainWidget()) {
7304 widget->SetSizeMode(nsSizeMode_Maximized);
7305 }
7306}
7307
7308void nsGlobalWindowInner::Minimize() {
7309 if (nsCOMPtr<nsIWidget> widget = GetMainWidget()) {
7310 widget->SetSizeMode(nsSizeMode_Minimized);
7311 }
7312}
7313
7314void nsGlobalWindowInner::Restore() {
7315 if (nsCOMPtr<nsIWidget> widget = GetMainWidget()) {
7316 widget->SetSizeMode(nsSizeMode_Normal);
7317 }
7318}
7319
7320void nsGlobalWindowInner::GetWorkspaceID(nsAString& workspaceID) {
7321 workspaceID.Truncate();
7322 if (nsCOMPtr<nsIWidget> widget = GetMainWidget()) {
7323 return widget->GetWorkspaceID(workspaceID);
7324 }
7325}
7326
7327void nsGlobalWindowInner::MoveToWorkspace(const nsAString& workspaceID) {
7328 if (nsCOMPtr<nsIWidget> widget = GetMainWidget()) {
7329 widget->MoveToWorkspace(workspaceID);
7330 }
7331}
7332
7333bool nsGlobalWindowInner::IsCloaked() const {
7334 if (nsCOMPtr<nsIWidget> widget = GetMainWidget()) {
7335 return widget->IsCloaked();
7336 }
7337 // Assume that it is not, since most windows are not cloaked.
7338 return false;
7339}
7340
7341void nsGlobalWindowInner::GetAttention(ErrorResult& aResult) {
7342 return GetAttentionWithCycleCount(-1, aResult);
7343}
7344
7345void nsGlobalWindowInner::GetAttentionWithCycleCount(int32_t aCycleCount,
7346 ErrorResult& aError) {
7347 nsCOMPtr<nsIWidget> widget = GetMainWidget();
7348
7349 if (widget) {
7350 aError = widget->GetAttention(aCycleCount);
7351 }
7352}
7353
7354already_AddRefed<Promise> nsGlobalWindowInner::PromiseDocumentFlushed(
7355 PromiseDocumentFlushedCallback& aCallback, ErrorResult& aError) {
7356 MOZ_RELEASE_ASSERT(IsChromeWindow())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(IsChromeWindow())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsChromeWindow()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("IsChromeWindow()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 7356
); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "IsChromeWindow()"
")"); do { MOZ_CrashSequence(__null, 7356); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7357
7358 if (!IsCurrentInnerWindow()) {
7359 aError.ThrowInvalidStateError("Not the current inner window");
7360 return nullptr;
7361 }
7362 if (!mDoc) {
7363 aError.ThrowInvalidStateError("No document");
7364 return nullptr;
7365 }
7366
7367 if (mIteratingDocumentFlushedResolvers) {
7368 aError.ThrowInvalidStateError("Already iterating through resolvers");
7369 return nullptr;
7370 }
7371
7372 PresShell* presShell = mDoc->GetPresShell();
7373 if (!presShell) {
7374 aError.ThrowInvalidStateError("No pres shell");
7375 return nullptr;
7376 }
7377
7378 // We need to associate the lifetime of the Promise to the lifetime
7379 // of the caller's global. That way, if the window we're observing
7380 // refresh driver ticks on goes away before our observer is fired,
7381 // we can still resolve the Promise.
7382 nsIGlobalObject* global = GetIncumbentGlobal();
7383 if (!global) {
7384 aError.ThrowInvalidStateError("No incumbent global");
7385 return nullptr;
7386 }
7387
7388 RefPtr<Promise> resultPromise = Promise::Create(global, aError);
7389 if (aError.Failed()) {
7390 return nullptr;
7391 }
7392
7393 auto flushResolver =
7394 MakeUnique<PromiseDocumentFlushedResolver>(resultPromise, aCallback);
7395
7396 if (!presShell->NeedStyleFlush() && !presShell->NeedLayoutFlush()) {
7397 flushResolver->Call();
7398 return resultPromise.forget();
7399 }
7400
7401 if (!TryToObserveRefresh()) {
7402 aError.ThrowInvalidStateError("Couldn't observe refresh");
7403 return nullptr;
7404 }
7405
7406 mDocumentFlushedResolvers.AppendElement(std::move(flushResolver));
7407 return resultPromise.forget();
7408}
7409
7410bool nsGlobalWindowInner::TryToObserveRefresh() {
7411 if (mObservingRefresh) {
7412 return true;
7413 }
7414
7415 if (!mDoc) {
7416 return false;
7417 }
7418
7419 nsPresContext* pc = mDoc->GetPresContext();
7420 if (!pc) {
7421 return false;
7422 }
7423
7424 mObservingRefresh = true;
7425 auto observer = MakeRefPtr<ManagedPostRefreshObserver>(
7426 pc, [win = RefPtr{this}](bool aWasCanceled) {
7427 if (win->MaybeCallDocumentFlushedResolvers(
7428 /* aUntilExhaustion = */ aWasCanceled)) {
7429 return ManagedPostRefreshObserver::Unregister::No;
7430 }
7431 win->mObservingRefresh = false;
7432 return ManagedPostRefreshObserver::Unregister::Yes;
7433 });
7434 pc->RegisterManagedPostRefreshObserver(observer.get());
7435 return mObservingRefresh;
7436}
7437
7438void nsGlobalWindowInner::CallDocumentFlushedResolvers(bool aUntilExhaustion) {
7439 while (true) {
7440 {
7441 // To coalesce MicroTask checkpoints inside callback call, enclose the
7442 // inner loop with nsAutoMicroTask, and perform a MicroTask checkpoint
7443 // after the loop.
7444 nsAutoMicroTask mt;
7445
7446 mIteratingDocumentFlushedResolvers = true;
7447
7448 auto resolvers = std::move(mDocumentFlushedResolvers);
7449 for (const auto& resolver : resolvers) {
7450 resolver->Call();
7451 }
7452
7453 mIteratingDocumentFlushedResolvers = false;
7454 }
7455
7456 // Leaving nsAutoMicroTask above will perform MicroTask checkpoint, and
7457 // Promise callbacks there may create mDocumentFlushedResolvers items.
7458
7459 // If there's no new resolvers, or we're not exhausting the queue, there's
7460 // nothing to do (we'll keep observing if there's any new observer).
7461 //
7462 // Otherwise, keep looping to call all promises. This case can happen while
7463 // destroying the window. This violates the constraint that the
7464 // promiseDocumentFlushed callback only ever run when no flush is needed,
7465 // but it's necessary to resolve the Promise returned by that.
7466 if (!aUntilExhaustion || mDocumentFlushedResolvers.IsEmpty()) {
7467 break;
7468 }
7469 }
7470}
7471
7472bool nsGlobalWindowInner::MaybeCallDocumentFlushedResolvers(
7473 bool aUntilExhaustion) {
7474 MOZ_ASSERT(mDoc)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mDoc)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(mDoc))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("mDoc", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 7474); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mDoc" ")");
do { MOZ_CrashSequence(__null, 7474); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7475
7476 PresShell* presShell = mDoc->GetPresShell();
7477 if (!presShell || aUntilExhaustion) {
7478 CallDocumentFlushedResolvers(/* aUntilExhaustion = */ true);
7479 return false;
7480 }
7481
7482 if (presShell->NeedStyleFlush() || presShell->NeedLayoutFlush()) {
7483 // By the time our observer fired, something has already invalidated
7484 // style or layout - or perhaps we're still in the middle of a flush that
7485 // was interrupted. In either case, we'll wait until the next refresh driver
7486 // tick instead and try again.
7487 return true;
7488 }
7489
7490 CallDocumentFlushedResolvers(/* aUntilExhaustion = */ false);
7491 return !mDocumentFlushedResolvers.IsEmpty();
7492}
7493
7494already_AddRefed<nsWindowRoot> nsGlobalWindowInner::GetWindowRoot(
7495 mozilla::ErrorResult& aError) {
7496 FORWARD_TO_OUTER_OR_THROW(GetWindowRootOuter, (), aError, nullptr);
7497}
7498
7499void nsGlobalWindowInner::SetCursor(const nsACString& aCursor,
7500 ErrorResult& aError) {
7501 FORWARD_TO_OUTER_OR_THROW(SetCursorOuter, (aCursor, aError), aError, );
7502}
7503
7504nsIBrowserDOMWindow* nsGlobalWindowInner::GetBrowserDOMWindow(
7505 ErrorResult& aError) {
7506 FORWARD_TO_OUTER_OR_THROW(GetBrowserDOMWindow, (), aError, nullptr);
7507}
7508
7509void nsGlobalWindowInner::SetBrowserDOMWindow(
7510 nsIBrowserDOMWindow* aBrowserWindow, ErrorResult& aError) {
7511 FORWARD_TO_OUTER_OR_THROW(SetBrowserDOMWindowOuter, (aBrowserWindow),
7512 aError, );
7513}
7514
7515void nsGlobalWindowInner::NotifyDefaultButtonLoaded(Element& aDefaultButton,
7516 ErrorResult& aError) {
7517 // Don't snap to a disabled button.
7518 nsCOMPtr<nsIDOMXULControlElement> xulControl = aDefaultButton.AsXULControl();
7519 if (!xulControl) {
7520 aError.Throw(NS_ERROR_FAILURE);
7521 return;
7522 }
7523 bool disabled;
7524 aError = xulControl->GetDisabled(&disabled);
7525 if (aError.Failed() || disabled) {
7526 return;
7527 }
7528
7529 // Get the button rect in screen coordinates.
7530 nsIFrame* frame = aDefaultButton.GetPrimaryFrame();
7531 if (!frame) {
7532 aError.Throw(NS_ERROR_FAILURE);
7533 return;
7534 }
7535 LayoutDeviceIntRect buttonRect = LayoutDeviceIntRect::FromAppUnitsToNearest(
7536 frame->GetScreenRectInAppUnits(),
7537 frame->PresContext()->AppUnitsPerDevPixel());
7538
7539 // Get the widget rect in screen coordinates.
7540 nsIWidget* widget = GetNearestWidget();
7541 if (!widget) {
7542 aError.Throw(NS_ERROR_FAILURE);
7543 return;
7544 }
7545 LayoutDeviceIntRect widgetRect = widget->GetScreenBounds();
7546
7547 // Convert the buttonRect coordinates from screen to the widget.
7548 buttonRect -= widgetRect.TopLeft();
7549 nsresult rv = widget->OnDefaultButtonLoaded(buttonRect);
7550 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) && rv != NS_ERROR_NOT_IMPLEMENTED) {
7551 aError.Throw(rv);
7552 }
7553}
7554
7555ChromeMessageBroadcaster* nsGlobalWindowInner::MessageManager() {
7556 MOZ_ASSERT(IsChromeWindow())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(IsChromeWindow())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsChromeWindow()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("IsChromeWindow()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 7556
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsChromeWindow()"
")"); do { MOZ_CrashSequence(__null, 7556); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7557 if (!mChromeFields.mMessageManager) {
7558 RefPtr<ChromeMessageBroadcaster> globalMM =
7559 nsFrameMessageManager::GetGlobalMessageManager();
7560 mChromeFields.mMessageManager =
7561 MakeRefPtr<ChromeMessageBroadcaster>(globalMM);
7562 }
7563 return mChromeFields.mMessageManager;
7564}
7565
7566ChromeMessageBroadcaster* nsGlobalWindowInner::GetGroupMessageManager(
7567 const nsAString& aGroup) {
7568 MOZ_ASSERT(IsChromeWindow())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(IsChromeWindow())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsChromeWindow()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("IsChromeWindow()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 7568
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsChromeWindow()"
")"); do { MOZ_CrashSequence(__null, 7568); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7569
7570 return mChromeFields.mGroupMessageManagers
7571 .LookupOrInsertWith(
7572 aGroup,
7573 [&] {
7574 return MakeAndAddRef<ChromeMessageBroadcaster>(MessageManager());
7575 })
7576 .get();
7577}
7578
7579void nsGlobalWindowInner::InitWasOffline() { mWasOffline = NS_IsOffline(); }
7580
7581int16_t nsGlobalWindowInner::Orientation(CallerType aCallerType) {
7582 // GetOrientationAngle() returns 0, 90, 180 or 270.
7583 // window.orientation returns -90, 0, 90 or 180.
7584 uint16_t screenAngle = Screen()->GetOrientationAngle();
7585 if (nsIGlobalObject::ShouldResistFingerprinting(
7586 aCallerType, RFPTarget::ScreenOrientation)) {
7587 CSSIntSize size = mBrowsingContext->TopInnerSizeSpoofedForRFP();
7588 screenAngle = nsRFPService::ViewportSizeToAngle(size.width, size.height);
7589 }
7590 int16_t angle = AssertedCast<int16_t>(screenAngle);
7591 return angle <= 180 ? angle : angle - 360;
7592}
7593
7594already_AddRefed<Console> nsGlobalWindowInner::GetConsole(JSContext* aCx,
7595 ErrorResult& aRv) {
7596 if (!mConsole) {
7597 mConsole = Console::Create(aCx, this, aRv);
7598 if (NS_WARN_IF(aRv.Failed())NS_warn_if_impl(aRv.Failed(), "aRv.Failed()", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 7598)
) {
7599 return nullptr;
7600 }
7601 }
7602
7603 RefPtr<Console> console = mConsole;
7604 return console.forget();
7605}
7606
7607already_AddRefed<CookieStore> nsGlobalWindowInner::CookieStore() {
7608 if (!mCookieStore) {
7609 mCookieStore = CookieStore::Create(this);
7610 }
7611
7612 return do_AddRef(mCookieStore);
7613}
7614
7615DocumentPictureInPicture* nsGlobalWindowInner::DocumentPictureInPicture() {
7616 if (!mDocumentPiP) {
7617 mDocumentPiP = MakeRefPtr<class DocumentPictureInPicture>(this);
7618 }
7619
7620 return mDocumentPiP;
7621}
7622
7623bool nsGlobalWindowInner::IsSecureContext() const {
7624 JS::Realm* realm = js::GetNonCCWObjectRealm(GetWrapperPreserveColor());
7625 return JS::GetIsSecureContext(realm);
7626}
7627
7628External* nsGlobalWindowInner::External() {
7629 if (!mExternal) {
7630 mExternal = MakeRefPtr<dom::External>(ToSupports(this));
7631 }
7632
7633 return mExternal;
7634}
7635
7636void nsGlobalWindowInner::ClearDocumentDependentSlots(JSContext* aCx) {
7637 // If JSAPI OOMs here, there is basically nothing we can do to recover safely.
7638 if (!Window_Binding::ClearCachedDocumentValue(aCx, this) ||
7639 !Window_Binding::ClearCachedPerformanceValue(aCx, this)) {
7640 MOZ_CRASH("Unhandlable OOM while clearing document dependent slots.")do { do { } while (false); MOZ_ReportCrash("" "Unhandlable OOM while clearing document dependent slots."
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 7640
); AnnotateMozCrashReason("MOZ_CRASH(" "Unhandlable OOM while clearing document dependent slots."
")"); do { MOZ_CrashSequence(__null, 7640); __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
7641 }
7642}
7643
7644/* static */
7645JSObject* nsGlobalWindowInner::CreateNamedPropertiesObject(
7646 JSContext* aCx, JS::Handle<JSObject*> aProto) {
7647 return WindowNamedPropertiesHandler::Create(aCx, aProto);
7648}
7649
7650void nsGlobalWindowInner::RedefineProperty(JSContext* aCx,
7651 const char* aPropName,
7652 JS::Handle<JS::Value> aValue,
7653 ErrorResult& aError) {
7654 JS::Rooted<JSObject*> thisObj(aCx, GetWrapperPreserveColor());
7655 if (!thisObj) {
7656 aError.Throw(NS_ERROR_UNEXPECTED);
7657 return;
7658 }
7659
7660 if (!JS_WrapObject(aCx, &thisObj) ||
7661 !JS_DefineProperty(aCx, thisObj, aPropName, aValue, JSPROP_ENUMERATE)) {
7662 aError.Throw(NS_ERROR_FAILURE);
7663 }
7664}
7665
7666void nsGlobalWindowInner::FireOnNewGlobalObject() {
7667 // AutoEntryScript required to invoke debugger hook, which is a
7668 // Gecko-specific concept at present.
7669 AutoEntryScript aes(this, "nsGlobalWindowInner report new global");
7670 JS::Rooted<JSObject*> global(aes.cx(), GetWrapper());
7671 JS_FireOnNewGlobalObject(aes.cx(), global);
7672}
7673
7674#if defined(_WINDOWS_) && !defined(MOZ_WRAPPED_WINDOWS_H)
7675# pragma message( \
7676 "wrapper failure reason: " MOZ_WINDOWS_WRAPPER_DISABLED_REASON)
7677# error "Never include unwrapped windows.h in this file!"
7678#endif
7679
7680already_AddRefed<Promise> nsGlobalWindowInner::CreateImageBitmap(
7681 const ImageBitmapSource& aImage, const ImageBitmapOptions& aOptions,
7682 ErrorResult& aRv) {
7683 return ImageBitmap::Create(this, aImage, Nothing(), aOptions, aRv);
7684}
7685
7686already_AddRefed<Promise> nsGlobalWindowInner::CreateImageBitmap(
7687 const ImageBitmapSource& aImage, int32_t aSx, int32_t aSy, int32_t aSw,
7688 int32_t aSh, const ImageBitmapOptions& aOptions, ErrorResult& aRv) {
7689 return ImageBitmap::Create(
7690 this, aImage, Some(gfx::IntRect(aSx, aSy, aSw, aSh)), aOptions, aRv);
7691}
7692
7693// https://html.spec.whatwg.org/#structured-cloning
7694void nsGlobalWindowInner::StructuredClone(
7695 JSContext* aCx, JS::Handle<JS::Value> aValue,
7696 const StructuredSerializeOptions& aOptions,
7697 JS::MutableHandle<JS::Value> aRetval, ErrorResult& aError) {
7698 nsContentUtils::StructuredClone(aCx, this, aValue, aOptions, aRetval, aError);
7699}
7700
7701nsresult nsGlobalWindowInner::Dispatch(
7702 already_AddRefed<nsIRunnable> aRunnable) const {
7703 MOZ_RELEASE_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 7703
); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 7703); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7704 return NS_DispatchToCurrentThread(std::move(aRunnable));
7705}
7706
7707nsISerialEventTarget* nsGlobalWindowInner::SerialEventTarget() const {
7708 MOZ_RELEASE_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 7708
); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 7708); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7709 return GetMainThreadSerialEventTarget();
7710}
7711
7712Worklet* nsGlobalWindowInner::GetPaintWorklet(ErrorResult& aRv) {
7713 if (!mPaintWorklet) {
7714 nsIPrincipal* principal = GetPrincipal();
7715 if (!principal) {
7716 aRv.Throw(NS_ERROR_FAILURE);
7717 return nullptr;
7718 }
7719
7720 mPaintWorklet = PaintWorkletImpl::CreateWorklet(this, principal);
7721 }
7722
7723 return mPaintWorklet;
7724}
7725
7726void nsGlobalWindowInner::GetWebExposedLocales(nsTArray<nsString>& aLocales) {
7727 MOZ_ASSERT(mozilla::intl::LocaleService::GetInstance())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mozilla::intl::LocaleService::GetInstance())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(mozilla::intl::LocaleService::GetInstance()))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("mozilla::intl::LocaleService::GetInstance()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 7727
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mozilla::intl::LocaleService::GetInstance()"
")"); do { MOZ_CrashSequence(__null, 7727); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7728
7729 AutoTArray<nsCString, 10> rpLocales;
7730 mozilla::intl::LocaleService::GetInstance()->GetWebExposedLocales(rpLocales);
7731
7732 for (const auto& loc : rpLocales) {
7733 aLocales.AppendElement(NS_ConvertUTF8toUTF16(loc));
7734 }
7735}
7736
7737IntlUtils* nsGlobalWindowInner::GetIntlUtils(ErrorResult& aError) {
7738 if (!mIntlUtils) {
7739 mIntlUtils = MakeRefPtr<IntlUtils>(this);
7740 }
7741
7742 return mIntlUtils;
7743}
7744
7745void nsGlobalWindowInner::StoreSharedWorker(SharedWorker* aSharedWorker) {
7746 MOZ_ASSERT(aSharedWorker)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aSharedWorker)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aSharedWorker))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("aSharedWorker",
"/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 7746
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aSharedWorker" ")"
); do { MOZ_CrashSequence(__null, 7746); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7747 MOZ_ASSERT(!mSharedWorkers.Contains(aSharedWorker))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mSharedWorkers.Contains(aSharedWorker))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!mSharedWorkers.Contains(aSharedWorker)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!mSharedWorkers.Contains(aSharedWorker)"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 7747
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mSharedWorkers.Contains(aSharedWorker)"
")"); do { MOZ_CrashSequence(__null, 7747); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7748
7749 mSharedWorkers.AppendElement(aSharedWorker);
7750}
7751
7752void nsGlobalWindowInner::ForgetSharedWorker(SharedWorker* aSharedWorker) {
7753 MOZ_ASSERT(aSharedWorker)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aSharedWorker)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aSharedWorker))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("aSharedWorker",
"/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 7753
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aSharedWorker" ")"
); do { MOZ_CrashSequence(__null, 7753); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7754 MOZ_ASSERT(mSharedWorkers.Contains(aSharedWorker))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mSharedWorkers.Contains(aSharedWorker))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(mSharedWorkers.Contains(aSharedWorker)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mSharedWorkers.Contains(aSharedWorker)"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 7754
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mSharedWorkers.Contains(aSharedWorker)"
")"); do { MOZ_CrashSequence(__null, 7754); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7755
7756 mSharedWorkers.RemoveElement(aSharedWorker);
7757}
7758
7759void nsGlobalWindowInner::UpdateSharedWorkersLanguageOverride(
7760 const nsCString& aLanguageOverride) {
7761 nsTArray<nsString> resolvedLanguages;
7762 Navigator::GetAcceptLanguages(resolvedLanguages, aLanguageOverride.IsEmpty()
7763 ? nullptr
7764 : &aLanguageOverride);
7765
7766 for (RefPtr<mozilla::dom::SharedWorker> pinnedWorker :
7767 mSharedWorkers.ForwardRange()) {
7768 pinnedWorker->UpdateLanguageOverride(aLanguageOverride, resolvedLanguages);
7769 }
7770}
7771
7772void nsGlobalWindowInner::UpdateSharedWorkerTimezoneOverride(
7773 const nsAString& aTimezoneOverride) {
7774 for (RefPtr<SharedWorker> pinnedWorker : mSharedWorkers.ForwardRange()) {
7775 pinnedWorker->UpdateTimezoneOverride(aTimezoneOverride);
7776 }
7777}
7778
7779RefPtr<GenericPromise> nsGlobalWindowInner::StorageAccessPermissionChanged(
7780 bool aGranted) {
7781 // Invalidate cached StorageAllowed field so that calls to GetLocalStorage
7782 // give us the updated localStorage object.
7783 ClearStorageAllowedCache();
7784
7785 // Just reset the active cookie and storage principals
7786 nsCOMPtr<nsICookieJarSettings> cjs;
7787 if (mDoc) {
7788 cjs = mDoc->CookieJarSettings();
7789 }
7790 StorageAccess storageAccess = StorageAllowedForWindow(this);
7791 if (ShouldPartitionStorage(storageAccess) &&
7792 StoragePartitioningEnabled(storageAccess, cjs)) {
7793 if (mDoc) {
7794 mDoc->ClearActiveCookieAndStoragePrincipals();
7795 }
7796 // When storage access is granted the content process needs to request the
7797 // updated cookie list from the parent process. Otherwise the site won't
7798 // have access to unpartitioned cookies via document.cookie without a
7799 // reload.
7800 if (aGranted) {
7801 nsIChannel* channel = mDoc->GetChannel();
7802 if (channel) {
7803 // The promise resolves when the updated cookie list has been received
7804 // from the parent.
7805 return ContentChild::UpdateCookieStatus(channel);
7806 }
7807 }
7808 }
7809
7810 PropagateStorageAccessPermissionGrantedToWorkers(*this);
7811
7812 // If we have a partitioned localStorage, it's time to replace it with a real
7813 // one in order to receive notifications.
7814
7815 if (mLocalStorage) {
7816 IgnoredErrorResult error;
7817 GetLocalStorage(error);
7818 if (NS_WARN_IF(error.Failed())NS_warn_if_impl(error.Failed(), "error.Failed()", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 7818)
) {
7819 return MozPromise<bool, nsresult, true>::CreateAndReject(
7820 error.StealNSResult(), __func__);
7821 }
7822
7823 MOZ_ASSERT(mLocalStorage &&do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mLocalStorage && mLocalStorage->Type() ==
Storage::eLocalStorage)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mLocalStorage && mLocalStorage
->Type() == Storage::eLocalStorage))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mLocalStorage && mLocalStorage->Type() == Storage::eLocalStorage"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 7824
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLocalStorage && mLocalStorage->Type() == Storage::eLocalStorage"
")"); do { MOZ_CrashSequence(__null, 7824); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
7824 mLocalStorage->Type() == Storage::eLocalStorage)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mLocalStorage && mLocalStorage->Type() ==
Storage::eLocalStorage)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mLocalStorage && mLocalStorage
->Type() == Storage::eLocalStorage))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mLocalStorage && mLocalStorage->Type() == Storage::eLocalStorage"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 7824
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLocalStorage && mLocalStorage->Type() == Storage::eLocalStorage"
")"); do { MOZ_CrashSequence(__null, 7824); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7825
7826 if (NextGenLocalStorageEnabled() && mListenerManager &&
7827 mListenerManager->HasListenersFor(nsGkAtoms::onstorage)) {
7828 auto object = static_cast<LSObject*>(mLocalStorage.get());
7829
7830 object->EnsureObserver();
7831 }
7832 }
7833
7834 // Reset the IndexedDB factory.
7835 mIndexedDB = nullptr;
7836
7837 // Reset DOM Cache
7838 mCacheStorage = nullptr;
7839
7840 // Reset the active cookie and storage principals
7841 if (mDoc) {
7842 mDoc->ClearActiveCookieAndStoragePrincipals();
7843 if (mWindowGlobalChild) {
7844 // Clearing the cookie principal might make us end up with a new effective
7845 // storage principal on the child side than on the parent side, which
7846 // means that we need to sync it. See bug 1705359.
7847 mWindowGlobalChild->SendUpdatePrincipalPartitioning(
7848 !mDoc->UseRegularPrincipal());
7849 }
7850 }
7851
7852 // When storage access is granted the content process needs to request the
7853 // updated cookie list from the parent process. Otherwise the site won't have
7854 // access to unpartitioned cookies via document.cookie without a reload.
7855 if (aGranted) {
7856 nsIChannel* channel = mDoc->GetChannel();
7857 if (channel) {
7858 // The promise resolves when the updated cookie list has been received
7859 // from the parent.
7860 return ContentChild::UpdateCookieStatus(channel);
7861 }
7862 }
7863 return MozPromise<bool, nsresult, true>::CreateAndResolve(true, __func__);
7864}
7865
7866ContentMediaController* nsGlobalWindowInner::GetContentMediaController() {
7867 if (mContentMediaController) {
7868 return mContentMediaController;
7869 }
7870 if (!mBrowsingContext) {
7871 return nullptr;
7872 }
7873
7874 mContentMediaController =
7875 MakeRefPtr<ContentMediaController>(mBrowsingContext->Id());
7876 return mContentMediaController;
7877}
7878
7879void nsGlobalWindowInner::SetScrollMarks(const nsTArray<uint32_t>& aScrollMarks,
7880 bool aOnHScrollbar) {
7881 mScrollMarks.Assign(aScrollMarks);
7882 mScrollMarksOnHScrollbar = aOnHScrollbar;
7883
7884 // Mark the scrollbar for repainting.
7885 if (mDoc) {
7886 PresShell* presShell = mDoc->GetPresShell();
7887 if (presShell) {
7888 ScrollContainerFrame* sf = presShell->GetRootScrollContainerFrame();
7889 if (sf) {
7890 sf->InvalidateScrollbars();
7891 }
7892 }
7893 }
7894}
7895
7896/* static */
7897already_AddRefed<nsGlobalWindowInner> nsGlobalWindowInner::Create(
7898 nsGlobalWindowOuter* aOuterWindow, bool aIsChrome,
7899 WindowGlobalChild* aActor) {
7900 RefPtr<nsGlobalWindowInner> window =
7901 new nsGlobalWindowInner(aOuterWindow, aActor);
7902 if (aIsChrome) {
7903 window->mIsChrome = true;
7904 window->mCleanMessageManager = true;
7905 }
7906
7907 if (aActor) {
7908 aActor->InitWindowGlobal(window);
7909 }
7910
7911 window->InitWasOffline();
7912 return window.forget();
7913}
7914
7915JS::loader::ModuleLoaderBase* nsGlobalWindowInner::GetModuleLoader(
7916 JSContext* aCx) {
7917 Document* document = GetDocument();
7918 if (!document) {
7919 return nullptr;
7920 }
7921
7922 ScriptLoader* loader = document->GetScriptLoader();
7923 if (!loader) {
7924 return nullptr;
7925 }
7926
7927 return loader->GetModuleLoader();
7928}
7929
7930void nsGlobalWindowInner::SetCurrentPasteDataTransfer(
7931 DataTransfer* aDataTransfer) {
7932 MOZ_ASSERT_IF(aDataTransfer, aDataTransfer->GetEventMessage() == ePaste)do { if (aDataTransfer) { do { static_assert( mozilla::detail
::AssertionConditionType<decltype(aDataTransfer->GetEventMessage
() == ePaste)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(aDataTransfer->GetEventMessage
() == ePaste))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aDataTransfer->GetEventMessage() == ePaste", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 7932); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aDataTransfer->GetEventMessage() == ePaste"
")"); do { MOZ_CrashSequence(__null, 7932); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
7933 MOZ_ASSERT_IF(aDataTransfer, aDataTransfer->ClipboardType() ==do { if (aDataTransfer) { do { static_assert( mozilla::detail
::AssertionConditionType<decltype(aDataTransfer->ClipboardType
() == Some(nsIClipboard::kGlobalClipboard))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aDataTransfer->ClipboardType
() == Some(nsIClipboard::kGlobalClipboard)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aDataTransfer->ClipboardType() == Some(nsIClipboard::kGlobalClipboard)"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 7934
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aDataTransfer->ClipboardType() == Some(nsIClipboard::kGlobalClipboard)"
")"); do { MOZ_CrashSequence(__null, 7934); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
7934 Some(nsIClipboard::kGlobalClipboard))do { if (aDataTransfer) { do { static_assert( mozilla::detail
::AssertionConditionType<decltype(aDataTransfer->ClipboardType
() == Some(nsIClipboard::kGlobalClipboard))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aDataTransfer->ClipboardType
() == Some(nsIClipboard::kGlobalClipboard)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aDataTransfer->ClipboardType() == Some(nsIClipboard::kGlobalClipboard)"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 7934
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aDataTransfer->ClipboardType() == Some(nsIClipboard::kGlobalClipboard)"
")"); do { MOZ_CrashSequence(__null, 7934); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
7935 MOZ_ASSERT_IF(aDataTransfer, aDataTransfer->GetClipboardDataSnapshot())do { if (aDataTransfer) { do { static_assert( mozilla::detail
::AssertionConditionType<decltype(aDataTransfer->GetClipboardDataSnapshot
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(aDataTransfer->GetClipboardDataSnapshot()))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("aDataTransfer->GetClipboardDataSnapshot()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 7935
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aDataTransfer->GetClipboardDataSnapshot()"
")"); do { MOZ_CrashSequence(__null, 7935); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
7936 mCurrentPasteDataTransfer = aDataTransfer;
7937}
7938
7939DataTransfer* nsGlobalWindowInner::GetCurrentPasteDataTransfer() const {
7940 return mCurrentPasteDataTransfer;
7941}
7942
7943TrustedTypePolicyFactory* nsGlobalWindowInner::TrustedTypes() {
7944 if (!mTrustedTypePolicyFactory) {
7945 mTrustedTypePolicyFactory = MakeRefPtr<TrustedTypePolicyFactory>(this);
7946 }
7947
7948 return mTrustedTypePolicyFactory;
7949}
7950
7951void nsGlobalWindowInner::NoteMediaSourceURL(const nsACString& aURL) {
7952 MOZ_ASSERT(!IsDying(), "MediaSourceURL will never be cleaned up")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!IsDying())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!IsDying()))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("!IsDying()" " (" "MediaSourceURL will never be cleaned up"
")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp",
7952); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!IsDying()" ") ("
"MediaSourceURL will never be cleaned up" ")"); do { MOZ_CrashSequence
(__null, 7952); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
7953 mMediaSourceURLs.InsertElementSorted(aURL);
7954}
7955
7956void nsGlobalWindowInner::UnnoteMediaSourceURL(const nsACString& aURL) {
7957 DebugOnly<bool> found = mMediaSourceURLs.RemoveElementSorted(aURL);
7958 MOZ_ASSERT(found, "MediaSourceURL should have been noted")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(found)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(found))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("found" " (" "MediaSourceURL should have been noted"
")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp",
7958); AnnotateMozCrashReason("MOZ_ASSERT" "(" "found" ") ("
"MediaSourceURL should have been noted" ")"); do { MOZ_CrashSequence
(__null, 7958); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
7959}
7960
7961void nsPIDOMWindowInner::MaybeSetHasPointerRawUpdateEventListeners() {
7962 if (HasPointerRawUpdateEventListeners() || !IsSecureContext()) {
7963 return;
7964 }
7965 mMayHavePointerRawUpdateEventListener = true;
7966 if (BrowserChild* const browserChild = BrowserChild::GetFrom(this)) {
7967 browserChild->OnPointerRawUpdateEventListenerAdded(this);
7968 }
7969}
7970
7971void nsPIDOMWindowInner::ClearHasPointerRawUpdateEventListeners() {
7972 if (!HasPointerRawUpdateEventListeners()) {
7973 return;
7974 }
7975 mMayHavePointerRawUpdateEventListener = false;
7976 if (BrowserChild* const browserChild = BrowserChild::GetFrom(this)) {
7977 browserChild->OnPointerRawUpdateEventListenerRemoved(this);
7978 }
7979}
7980
7981nsIURI* nsPIDOMWindowInner::GetDocumentURI() const {
7982 return mDoc ? mDoc->GetDocumentURI() : mDocumentURI.get();
7983}
7984
7985nsIURI* nsPIDOMWindowInner::GetDocBaseURI() const {
7986 return mDoc ? mDoc->GetDocBaseURI() : mDocBaseURI.get();
7987}
7988
7989mozilla::dom::WindowContext* nsPIDOMWindowInner::GetWindowContext() const {
7990 return mWindowGlobalChild ? mWindowGlobalChild->WindowContext() : nullptr;
7991}
7992
7993bool nsPIDOMWindowInner::RemoveFromBFCacheSync() {
7994 if (Document* doc = GetExtantDoc()) {
7995 return doc->RemoveFromBFCacheSync();
7996 }
7997 return false;
7998}
7999
8000void nsPIDOMWindowInner::MaybeCreateDoc() {
8001 // XXX: Forward to outer?
8002 MOZ_ASSERT(!mDoc)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mDoc)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(!mDoc))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("!mDoc", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 8002); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mDoc" ")")
; do { MOZ_CrashSequence(__null, 8002); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8003 if (nsIDocShell* docShell = GetDocShell()) {
8004 // Note that |document| here is the same thing as our mDoc, but we
8005 // don't have to explicitly set the member variable because the docshell
8006 // has already called SetNewDocument().
8007 nsCOMPtr<Document> document = docShell->GetDocument();
8008 (void)document;
8009 }
8010}
8011
8012mozilla::dom::DocGroup* nsPIDOMWindowInner::GetDocGroup() const {
8013 Document* doc = GetExtantDoc();
8014 if (doc) {
8015 return doc->GetDocGroup();
8016 }
8017 return nullptr;
8018}
8019
8020mozilla::dom::BrowsingContextGroup*
8021nsPIDOMWindowInner::GetBrowsingContextGroup() const {
8022 return mBrowsingContext ? mBrowsingContext->Group() : nullptr;
8023}
8024
8025nsIGlobalObject* nsPIDOMWindowInner::AsGlobal() {
8026 return nsGlobalWindowInner::Cast(this);
8027}
8028
8029const nsIGlobalObject* nsPIDOMWindowInner::AsGlobal() const {
8030 return nsGlobalWindowInner::Cast(this);
8031}
8032
8033RefPtr<GenericPromise>
8034nsPIDOMWindowInner::SaveStorageAccessPermissionGranted() {
8035 WindowContext* wc = GetWindowContext();
8036 if (wc) {
8037 (void)wc->SetUsingStorageAccess(true);
8038 }
8039
8040 return nsGlobalWindowInner::Cast(this)->StorageAccessPermissionChanged(true);
8041}
8042
8043RefPtr<GenericPromise>
8044nsPIDOMWindowInner::SaveStorageAccessPermissionRevoked() {
8045 WindowContext* wc = GetWindowContext();
8046 if (wc) {
8047 (void)wc->SetUsingStorageAccess(false);
8048 }
8049
8050 return nsGlobalWindowInner::Cast(this)->StorageAccessPermissionChanged(false);
8051}
8052
8053bool nsPIDOMWindowInner::UsingStorageAccess() {
8054 WindowContext* wc = GetWindowContext();
8055 if (!wc) {
8056 return false;
8057 }
8058
8059 return wc->GetUsingStorageAccess();
8060}
8061
8062WebIdentityHandler* nsPIDOMWindowInner::GetOrCreateWebIdentityHandler() {
8063 if (mWebIdentityHandler) {
8064 return mWebIdentityHandler;
8065 }
8066 mWebIdentityHandler = MakeRefPtr<WebIdentityHandler>(this);
8067 bool success = mWebIdentityHandler->MaybeCreateActor();
8068 if (!success) {
8069 mWebIdentityHandler = nullptr;
8070 }
8071 return mWebIdentityHandler;
8072}
8073
8074CloseWatcherManager* nsPIDOMWindowInner::EnsureCloseWatcherManager() {
8075 if (!mCloseWatcherManager) {
8076 mCloseWatcherManager = MakeRefPtr<CloseWatcherManager>();
8077 }
8078 return mCloseWatcherManager;
8079}
8080
8081void nsPIDOMWindowInner::NotifyCloseWatcherAdded() {
8082 MOZ_ASSERT(mCloseWatcherManager && !mCloseWatcherManager->IsEmpty())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mCloseWatcherManager && !mCloseWatcherManager
->IsEmpty())>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(mCloseWatcherManager &&
!mCloseWatcherManager->IsEmpty()))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("mCloseWatcherManager && !mCloseWatcherManager->IsEmpty()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 8082
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCloseWatcherManager && !mCloseWatcherManager->IsEmpty()"
")"); do { MOZ_CrashSequence(__null, 8082); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8083 if (WindowContext* top = TopWindowContext(*this)) {
8084 (void)top->SetHasActiveCloseWatcher(true);
8085 }
8086}
8087
8088void nsPIDOMWindowInner::NotifyCloseWatcherRemoved() {
8089 MOZ_ASSERT(mCloseWatcherManager)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mCloseWatcherManager)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mCloseWatcherManager))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("mCloseWatcherManager"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 8089
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCloseWatcherManager"
")"); do { MOZ_CrashSequence(__null, 8089); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8090 if (WindowContext* top = TopWindowContext(*this)) {
8091 (void)top->SetHasActiveCloseWatcher(!mCloseWatcherManager->IsEmpty());
8092 }
8093}
8094
8095nsPIDOMWindowInner::nsPIDOMWindowInner(nsPIDOMWindowOuter* aOuterWindow,
8096 WindowGlobalChild* aActor)
8097 : mOuterWindow(aOuterWindow), mWindowGlobalChild(aActor) {
8098 MOZ_ASSERT(aOuterWindow)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aOuterWindow)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aOuterWindow))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("aOuterWindow", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 8098); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aOuterWindow"
")"); do { MOZ_CrashSequence(__null, 8098); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8099 mBrowsingContext = aOuterWindow->GetBrowsingContext();
8100
8101 if (mWindowGlobalChild) {
8102 mWindowID = aActor->InnerWindowId();
8103
8104 MOZ_ASSERT(mWindowGlobalChild->BrowsingContext() == mBrowsingContext)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mWindowGlobalChild->BrowsingContext() == mBrowsingContext
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(mWindowGlobalChild->BrowsingContext() == mBrowsingContext
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"mWindowGlobalChild->BrowsingContext() == mBrowsingContext"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 8104
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mWindowGlobalChild->BrowsingContext() == mBrowsingContext"
")"); do { MOZ_CrashSequence(__null, 8104); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8105 } else {
8106 mWindowID = nsContentUtils::GenerateWindowId();
8107 }
8108}
8109
8110nsPIDOMWindowInner::~nsPIDOMWindowInner() = default;
8111
8112#undef FORWARD_TO_OUTER
8113#undef FORWARD_TO_OUTER_OR_THROW
8114#undef FORWARD_TO_OUTER_VOID