| File: | root/firefox-clang/dom/base/nsGlobalWindowInner.cpp |
| Warning: | line 5408, column 7 1st function call argument is an uninitialized value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 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/PushManager.h" | |||
| 156 | #include "mozilla/dom/RootedDictionary.h" | |||
| 157 | #include "mozilla/dom/ScriptLoader.h" | |||
| 158 | #include "mozilla/dom/ScriptSettings.h" | |||
| 159 | #include "mozilla/dom/ServiceWorker.h" | |||
| 160 | #include "mozilla/dom/ServiceWorkerDescriptor.h" | |||
| 161 | #include "mozilla/dom/ServiceWorkerRegistration.h" | |||
| 162 | #include "mozilla/dom/SessionStorageManager.h" | |||
| 163 | #include "mozilla/dom/SharedWorker.h" | |||
| 164 | #include "mozilla/dom/Storage.h" | |||
| 165 | #include "mozilla/dom/StorageEvent.h" | |||
| 166 | #include "mozilla/dom/StorageEventBinding.h" | |||
| 167 | #include "mozilla/dom/StorageNotifierService.h" | |||
| 168 | #include "mozilla/dom/StorageUtils.h" | |||
| 169 | #include "mozilla/dom/TabMessageTypes.h" | |||
| 170 | #include "mozilla/dom/Timeout.h" | |||
| 171 | #include "mozilla/dom/TimeoutHandler.h" | |||
| 172 | #include "mozilla/dom/TimeoutManager.h" | |||
| 173 | #include "mozilla/dom/ToJSValue.h" | |||
| 174 | #include "mozilla/dom/TrustedTypePolicyFactory.h" | |||
| 175 | #include "mozilla/dom/TrustedTypeUtils.h" | |||
| 176 | #include "mozilla/dom/TrustedTypesConstants.h" | |||
| 177 | #include "mozilla/dom/VRDisplay.h" | |||
| 178 | #include "mozilla/dom/VRDisplayEvent.h" | |||
| 179 | #include "mozilla/dom/VRDisplayEventBinding.h" | |||
| 180 | #include "mozilla/dom/VREventObserver.h" | |||
| 181 | #include "mozilla/dom/VisualViewport.h" | |||
| 182 | #include "mozilla/dom/WebCompatBinding.h" | |||
| 183 | #include "mozilla/dom/WebIDLGlobalNameHash.h" | |||
| 184 | #include "mozilla/dom/WebIdentityHandler.h" | |||
| 185 | #include "mozilla/dom/WebTaskSchedulerMainThread.h" | |||
| 186 | #include "mozilla/dom/WindowBinding.h" | |||
| 187 | #include "mozilla/dom/WindowContext.h" | |||
| 188 | #include "mozilla/dom/WindowGlobalChild.h" | |||
| 189 | #include "mozilla/dom/WindowOrWorkerGlobalScopeBinding.h" | |||
| 190 | #include "mozilla/dom/WindowProxyHolder.h" | |||
| 191 | #include "mozilla/dom/WorkerCommon.h" | |||
| 192 | #include "mozilla/dom/Worklet.h" | |||
| 193 | #include "mozilla/dom/XRPermissionRequest.h" | |||
| 194 | #include "mozilla/dom/cache/CacheStorage.h" | |||
| 195 | #include "mozilla/dom/cache/Types.h" | |||
| 196 | #include "mozilla/extensions/WebExtensionPolicy.h" | |||
| 197 | #include "mozilla/fallible.h" | |||
| 198 | #include "mozilla/gfx/BasePoint.h" | |||
| 199 | #include "mozilla/gfx/BaseRect.h" | |||
| 200 | #include "mozilla/gfx/BaseSize.h" | |||
| 201 | #include "mozilla/gfx/Rect.h" | |||
| 202 | #include "mozilla/gfx/Types.h" | |||
| 203 | #include "mozilla/glean/DomMetrics.h" | |||
| 204 | #include "mozilla/glean/bindings/Glean.h" | |||
| 205 | #include "mozilla/glean/bindings/GleanPings.h" | |||
| 206 | #include "mozilla/intl/LocaleService.h" | |||
| 207 | #include "mozilla/ipc/BackgroundUtils.h" | |||
| 208 | #include "mozilla/ipc/PBackgroundSharedTypes.h" | |||
| 209 | #include "mozilla/net/CookieJarSettings.h" | |||
| 210 | #include "nsAtom.h" | |||
| 211 | #include "nsBaseHashtable.h" | |||
| 212 | #include "nsCCUncollectableMarker.h" | |||
| 213 | #include "nsCOMPtr.h" | |||
| 214 | #include "nsCRT.h" | |||
| 215 | #include "nsCRTGlue.h" | |||
| 216 | #include "nsCanvasFrame.h" | |||
| 217 | #include "nsCheapSets.h" | |||
| 218 | #include "nsContentUtils.h" | |||
| 219 | #include "nsCoord.h" | |||
| 220 | #include "nsCycleCollectionNoteChild.h" | |||
| 221 | #include "nsCycleCollectionTraversalCallback.h" | |||
| 222 | #include "nsDOMNavigationTiming.h" | |||
| 223 | #include "nsDebug.h" | |||
| 224 | #include "nsDeviceContext.h" | |||
| 225 | #include "nsDocShell.h" | |||
| 226 | #include "nsFocusManager.h" | |||
| 227 | #include "nsFrameMessageManager.h" | |||
| 228 | #include "nsGkAtoms.h" | |||
| 229 | #include "nsGlobalWindowOuter.h" | |||
| 230 | #include "nsHashKeys.h" | |||
| 231 | #include "nsHistory.h" | |||
| 232 | #include "nsIAddonPolicyService.h" | |||
| 233 | #include "nsIArray.h" | |||
| 234 | #include "nsIBrowserChild.h" | |||
| 235 | #include "nsICancelableRunnable.h" | |||
| 236 | #include "nsIChannel.h" | |||
| 237 | #include "nsIClipboard.h" | |||
| 238 | #include "nsIContentSecurityPolicy.h" | |||
| 239 | #include "nsIControllers.h" | |||
| 240 | #include "nsICookieJarSettings.h" | |||
| 241 | #include "nsICookieService.h" | |||
| 242 | #include "nsID.h" | |||
| 243 | #include "nsIDOMStorageManager.h" | |||
| 244 | #include "nsIDOMXULControlElement.h" | |||
| 245 | #include "nsIDeviceSensors.h" | |||
| 246 | #include "nsIDocShell.h" | |||
| 247 | #include "nsIDocShellTreeItem.h" | |||
| 248 | #include "nsIDocShellTreeOwner.h" | |||
| 249 | #include "nsIDocumentLoader.h" | |||
| 250 | #include "nsIDragService.h" | |||
| 251 | #include "nsIFocusManager.h" | |||
| 252 | #include "nsIFrame.h" | |||
| 253 | #include "nsIGlobalObject.h" | |||
| 254 | #include "nsIIOService.h" | |||
| 255 | #include "nsIIdleRunnable.h" | |||
| 256 | #include "nsIInterfaceRequestorUtils.h" | |||
| 257 | #include "nsILoadContext.h" | |||
| 258 | #include "nsILoadGroup.h" | |||
| 259 | #include "nsILoadInfo.h" | |||
| 260 | #include "nsINamed.h" | |||
| 261 | #include "nsINode.h" | |||
| 262 | #include "nsIObserver.h" | |||
| 263 | #include "nsIObserverService.h" | |||
| 264 | #include "nsIPermission.h" | |||
| 265 | #include "nsIPermissionManager.h" | |||
| 266 | #include "nsIPrefBranch.h" | |||
| 267 | #include "nsIPrincipal.h" | |||
| 268 | #include "nsIPrintSettings.h" | |||
| 269 | #include "nsIPrompt.h" | |||
| 270 | #include "nsIRunnable.h" | |||
| 271 | #include "nsIScreen.h" | |||
| 272 | #include "nsIScreenManager.h" | |||
| 273 | #include "nsIScriptContext.h" | |||
| 274 | #include "nsIScriptGlobalObject.h" | |||
| 275 | #include "nsIScriptObjectPrincipal.h" | |||
| 276 | #include "nsISerialEventTarget.h" | |||
| 277 | #include "nsISimpleEnumerator.h" | |||
| 278 | #include "nsISizeOfEventTarget.h" | |||
| 279 | #include "nsISupportsPrimitives.h" | |||
| 280 | #include "nsISupportsUtils.h" | |||
| 281 | #include "nsIThread.h" | |||
| 282 | #include "nsITimedChannel.h" | |||
| 283 | #include "nsIURI.h" | |||
| 284 | #include "nsIWeakReference.h" | |||
| 285 | #include "nsIWebBrowserChrome.h" | |||
| 286 | #include "nsIWebNavigation.h" | |||
| 287 | #include "nsIWebProgressListener.h" | |||
| 288 | #include "nsIWidget.h" | |||
| 289 | #include "nsIWidgetListener.h" | |||
| 290 | #include "nsIXULRuntime.h" | |||
| 291 | #include "nsJSPrincipals.h" | |||
| 292 | #include "nsJSUtils.h" | |||
| 293 | #include "nsLayoutStatics.h" | |||
| 294 | #include "nsLiteralString.h" | |||
| 295 | #include "nsNetUtil.h" | |||
| 296 | #include "nsPIDOMWindow.h" | |||
| 297 | #include "nsPIDOMWindowInlines.h" | |||
| 298 | #include "nsPIWindowRoot.h" | |||
| 299 | #include "nsPoint.h" | |||
| 300 | #include "nsPresContext.h" | |||
| 301 | #include "nsQueryObject.h" | |||
| 302 | #include "nsSandboxFlags.h" | |||
| 303 | #include "nsScreen.h" | |||
| 304 | #include "nsServiceManagerUtils.h" | |||
| 305 | #include "nsString.h" | |||
| 306 | #include "nsStringFlags.h" | |||
| 307 | #include "nsStringFwd.h" | |||
| 308 | #include "nsTArray.h" | |||
| 309 | #include "nsTLiteralString.h" | |||
| 310 | #include "nsTObserverArray.h" | |||
| 311 | #include "nsTStringRepr.h" | |||
| 312 | #include "nsThread.h" | |||
| 313 | #include "nsThreadManager.h" | |||
| 314 | #include "nsThreadUtils.h" | |||
| 315 | #include "nsWeakReference.h" | |||
| 316 | #include "nsWindowMemoryReporter.h" | |||
| 317 | #include "nsWindowSizes.h" | |||
| 318 | #include "nsWrapperCache.h" | |||
| 319 | #include "nsWrapperCacheInlines.h" | |||
| 320 | #include "nsXULAppAPI.h" | |||
| 321 | #include "nsrootidl.h" | |||
| 322 | #include "prclist.h" | |||
| 323 | #include "prtypes.h" | |||
| 324 | #include "xpcprivate.h" | |||
| 325 | #include "xpcpublic.h" | |||
| 326 | ||||
| 327 | #ifdef MOZ_WEBSPEECH1 | |||
| 328 | # include "mozilla/dom/SpeechSynthesis.h" | |||
| 329 | #endif | |||
| 330 | ||||
| 331 | #ifdef ANDROID | |||
| 332 | # include <android/log.h> | |||
| 333 | #endif | |||
| 334 | ||||
| 335 | #ifdef XP_WIN | |||
| 336 | # include <process.h> | |||
| 337 | ||||
| 338 | # include "mozilla/Debug.h" | |||
| 339 | # define getpid _getpid | |||
| 340 | #else | |||
| 341 | # include <unistd.h> // for getpid() | |||
| 342 | #endif | |||
| 343 | ||||
| 344 | using namespace mozilla; | |||
| 345 | using namespace mozilla::dom; | |||
| 346 | using namespace mozilla::dom::ipc; | |||
| 347 | using mozilla::TimeDuration; | |||
| 348 | using mozilla::TimeStamp; | |||
| 349 | using mozilla::dom::GamepadHandle; | |||
| 350 | using mozilla::dom::cache::CacheStorage; | |||
| 351 | ||||
| 352 | #define FORWARD_TO_OUTER(method, args, err_rval) \ | |||
| 353 | PR_BEGIN_MACROdo { \ | |||
| 354 | RefPtr<nsGlobalWindowOuter> outer = GetOuterWindowInternal(); \ | |||
| 355 | if (!HasActiveDocument()) { \ | |||
| 356 | 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" , 357) | |||
| 357 | : "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" , 357); \ | |||
| 358 | return err_rval; \ | |||
| 359 | } \ | |||
| 360 | return outer->method args; \ | |||
| 361 | PR_END_MACRO} while (0) | |||
| 362 | ||||
| 363 | static nsGlobalWindowOuter* GetOuterWindowForForwarding( | |||
| 364 | nsGlobalWindowInner* aInner, ErrorResult& aError) { | |||
| 365 | nsGlobalWindowOuter* outer = aInner->GetOuterWindowInternal(); | |||
| 366 | if (MOZ_LIKELY(aInner->HasActiveDocument())(__builtin_expect(!!(aInner->HasActiveDocument()), 1))) { | |||
| 367 | return outer; | |||
| 368 | } | |||
| 369 | if (!outer) { | |||
| 370 | NS_WARNING("No outer window available!")NS_DebugBreak(NS_DEBUG_WARNING, "No outer window available!", nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp" , 370); | |||
| 371 | aError.Throw(NS_ERROR_NOT_INITIALIZED); | |||
| 372 | } else { | |||
| 373 | aError.Throw(NS_ERROR_XPC_SECURITY_MANAGER_VETO); | |||
| 374 | } | |||
| 375 | return nullptr; | |||
| 376 | } | |||
| 377 | ||||
| 378 | #define FORWARD_TO_OUTER_OR_THROW(method, args, rv, err_rval) \ | |||
| 379 | PR_BEGIN_MACROdo { \ | |||
| 380 | RefPtr<nsGlobalWindowOuter> outer = GetOuterWindowForForwarding(this, rv); \ | |||
| 381 | if (MOZ_LIKELY(outer)(__builtin_expect(!!(outer), 1))) { \ | |||
| 382 | return outer->method args; \ | |||
| 383 | } \ | |||
| 384 | return err_rval; \ | |||
| 385 | PR_END_MACRO} while (0) | |||
| 386 | ||||
| 387 | #define FORWARD_TO_OUTER_VOID(method, args) \ | |||
| 388 | PR_BEGIN_MACROdo { \ | |||
| 389 | RefPtr<nsGlobalWindowOuter> outer = GetOuterWindowInternal(); \ | |||
| 390 | if (!HasActiveDocument()) { \ | |||
| 391 | 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" , 392) | |||
| 392 | : "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" , 392); \ | |||
| 393 | return; \ | |||
| 394 | } \ | |||
| 395 | outer->method args; \ | |||
| 396 | return; \ | |||
| 397 | PR_END_MACRO} while (0) | |||
| 398 | ||||
| 399 | #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) \ | |||
| 400 | PR_BEGIN_MACROdo { \ | |||
| 401 | if (MOZ_UNLIKELY(!HasActiveDocument())(__builtin_expect(!!(!HasActiveDocument()), 0))) { \ | |||
| 402 | aError.Throw(NS_ERROR_XPC_SECURITY_MANAGER_VETO); \ | |||
| 403 | return err_rval; \ | |||
| 404 | } \ | |||
| 405 | PR_END_MACRO} while (0) | |||
| 406 | ||||
| 407 | #define DOM_TOUCH_LISTENER_ADDED"dom-touch-listener-added" "dom-touch-listener-added" | |||
| 408 | #define MEMORY_PRESSURE_OBSERVER_TOPIC"memory-pressure" "memory-pressure" | |||
| 409 | #define PERMISSION_CHANGED_TOPIC"perm-changed" "perm-changed" | |||
| 410 | ||||
| 411 | static LazyLogModule gDOMLeakPRLogInner("DOMLeakInner"); | |||
| 412 | extern mozilla::LazyLogModule gTimeoutLog; | |||
| 413 | ||||
| 414 | #ifdef DEBUG1 | |||
| 415 | static LazyLogModule gDocShellAndDOMWindowLeakLogging( | |||
| 416 | "DocShellAndDOMWindowLeak"); | |||
| 417 | #endif | |||
| 418 | ||||
| 419 | static FILE* gDumpFile = nullptr; | |||
| 420 | ||||
| 421 | mozilla::StaticAutoPtr<nsGlobalWindowInner::InnerWindowByIdTable> | |||
| 422 | nsGlobalWindowInner::sInnerWindowsById; | |||
| 423 | ||||
| 424 | bool nsGlobalWindowInner::sDragServiceDisabled = false; | |||
| 425 | bool nsGlobalWindowInner::sMouseDown = false; | |||
| 426 | ||||
| 427 | /** | |||
| 428 | * An indirect observer object that means we don't have to implement nsIObserver | |||
| 429 | * on nsGlobalWindow, where any script could see it. | |||
| 430 | */ | |||
| 431 | class nsGlobalWindowObserver final : public nsIObserver, | |||
| 432 | public nsIInterfaceRequestor, | |||
| 433 | public StorageNotificationObserver { | |||
| 434 | public: | |||
| 435 | explicit nsGlobalWindowObserver(nsGlobalWindowInner* aWindow) | |||
| 436 | : mWindow(aWindow) {} | |||
| 437 | 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: | |||
| 438 | MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODvirtual nsresult | |||
| 439 | Observe(nsISupports* aSubject, const char* aTopic, | |||
| 440 | const char16_t* aData) override { | |||
| 441 | if (!mWindow) return NS_OK; | |||
| 442 | const RefPtr<nsGlobalWindowInner> win = mWindow; | |||
| 443 | return win->Observe(aSubject, aTopic, aData); | |||
| 444 | } | |||
| 445 | void Forget() { mWindow = nullptr; } | |||
| 446 | NS_IMETHODvirtual nsresult GetInterface(const nsIID& aIID, void** aResult) override { | |||
| 447 | if (mWindow && aIID.Equals(NS_GET_IID(nsIDOMWindow)(nsIDOMWindow::kIID)) && mWindow) { | |||
| 448 | return mWindow->QueryInterface(aIID, aResult); | |||
| 449 | } | |||
| 450 | return NS_NOINTERFACE; | |||
| 451 | } | |||
| 452 | ||||
| 453 | void ObserveStorageNotification(StorageEvent* aEvent, | |||
| 454 | const char16_t* aStorageType, | |||
| 455 | bool aPrivateBrowsing) override { | |||
| 456 | if (mWindow) { | |||
| 457 | mWindow->ObserveStorageNotification(aEvent, aStorageType, | |||
| 458 | aPrivateBrowsing); | |||
| 459 | } | |||
| 460 | } | |||
| 461 | ||||
| 462 | nsIPrincipal* GetEffectiveCookiePrincipal() const override { | |||
| 463 | return mWindow ? mWindow->GetEffectiveCookiePrincipal() : nullptr; | |||
| 464 | } | |||
| 465 | ||||
| 466 | nsIPrincipal* GetEffectiveStoragePrincipal() const override { | |||
| 467 | return mWindow ? mWindow->GetEffectiveStoragePrincipal() : nullptr; | |||
| 468 | } | |||
| 469 | ||||
| 470 | bool IsPrivateBrowsing() const override { | |||
| 471 | return mWindow ? mWindow->IsPrivateBrowsing() : false; | |||
| 472 | } | |||
| 473 | ||||
| 474 | nsIEventTarget* GetEventTarget() const override { | |||
| 475 | return mWindow ? mWindow->SerialEventTarget() : nullptr; | |||
| 476 | } | |||
| 477 | ||||
| 478 | private: | |||
| 479 | ~nsGlobalWindowObserver() = default; | |||
| 480 | ||||
| 481 | // This reference is non-owning and safe because it's cleared by | |||
| 482 | // nsGlobalWindowInner::FreeInnerObjects(). | |||
| 483 | nsGlobalWindowInner* MOZ_NON_OWNING_REF mWindow; | |||
| 484 | }; | |||
| 485 | ||||
| 486 | NS_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" , 486); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0" ") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 486 ); __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" , 486); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"nsGlobalWindowObserver\" != nullptr" ") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null , 486); __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", 486); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0" ") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 486 ); __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" , 486); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"nsGlobalWindowObserver\" != nullptr" ") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null , 486); __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" , 486); 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; } | |||
| 487 | ||||
| 488 | class IdleRequestExecutor; | |||
| 489 | ||||
| 490 | class IdleRequestExecutorTimeoutHandler final : public TimeoutHandler { | |||
| 491 | public: | |||
| 492 | explicit IdleRequestExecutorTimeoutHandler(IdleRequestExecutor* aExecutor) | |||
| 493 | : mExecutor(aExecutor) {} | |||
| 494 | ||||
| 495 | 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: | |||
| 496 | 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", 496); AnnotateMozCrashReason("MOZ_ASSERT" "(" "p == &_cycleCollectorGlobal" ") (" "IdleRequestExecutorTimeoutHandler" " should QI to its own CC participant" ")"); do { MOZ_CrashSequence(__null, 496); __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 | |||
| 497 | ||||
| 498 | bool Call(const char* /* unused */) override; | |||
| 499 | ||||
| 500 | private: | |||
| 501 | ~IdleRequestExecutorTimeoutHandler() override = default; | |||
| 502 | RefPtr<IdleRequestExecutor> mExecutor; | |||
| 503 | }; | |||
| 504 | ||||
| 505 | NS_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; } | |||
| 506 | ||||
| 507 | NS_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" , 507); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0" ") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 507 ); __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; } | |||
| 508 | NS_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" , 508); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0" ") (" "dup release" ")"); 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.decr (base); if (count == 0) { NS_CycleCollectableHasRefCntZero(); } NS_LogRelease((this), (count), ("IdleRequestExecutorTimeoutHandler" )); return count; } void IdleRequestExecutorTimeoutHandler::DeleteCycleCollectable (void) { delete (this); } | |||
| 509 | ||||
| 510 | NS_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" , 510); 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 | |||
| 511 | NS_INTERFACE_MAP_ENTRY(nsISupports)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t <decltype(*this)>, nsISupports>)) foundInterface = static_cast <nsISupports*>(this); else | |||
| 512 | NS_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" , 512); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aIID.Equals((nsISupports::kIID))" ")"); do { MOZ_CrashSequence(__null, 512); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); status = NS_NOINTERFACE ; } else { (foundInterface)->AddRef(); status = NS_OK; } * aInstancePtr = foundInterface; return status; } | |||
| 513 | ||||
| 514 | class IdleRequestExecutor final : public nsIRunnable, | |||
| 515 | public nsICancelableRunnable, | |||
| 516 | public nsINamed, | |||
| 517 | public nsIIdleRunnable { | |||
| 518 | public: | |||
| 519 | explicit IdleRequestExecutor(nsGlobalWindowInner* aWindow) | |||
| 520 | : mDispatched(false), mDeadline(TimeStamp::Now()), mWindow(aWindow) { | |||
| 521 | 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" , 521); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mWindow" ")"); do { MOZ_CrashSequence(__null, 521); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 522 | ||||
| 523 | mIdlePeriodLimit = {mDeadline, mWindow->LastIdleRequestHandle()}; | |||
| 524 | mDelayedExecutorDispatcher = | |||
| 525 | MakeRefPtr<IdleRequestExecutorTimeoutHandler>(this); | |||
| 526 | } | |||
| 527 | ||||
| 528 | 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: | |||
| 529 | 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", 529); AnnotateMozCrashReason("MOZ_ASSERT" "(" "p == &_cycleCollectorGlobal" ") (" "IdleRequestExecutor" " should QI to its own CC participant" ")"); do { MOZ_CrashSequence(__null, 529); __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 | |||
| 530 | ||||
| 531 | NS_DECL_NSIRUNNABLEvirtual nsresult Run(void) override; | |||
| 532 | NS_DECL_NSINAMEDvirtual nsresult GetName(nsACString& aName) override; | |||
| 533 | nsresult Cancel() override; | |||
| 534 | void SetDeadline(TimeStamp aDeadline) override; | |||
| 535 | ||||
| 536 | bool IsCancelled() const { return !mWindow || mWindow->IsDying(); } | |||
| 537 | // Checks if aRequest shouldn't execute in the current idle period | |||
| 538 | // since it has been queued from a chained call to | |||
| 539 | // requestIdleCallback from within a running idle callback. | |||
| 540 | bool IneligibleForCurrentIdlePeriod(IdleRequest* aRequest) const { | |||
| 541 | return aRequest->Handle() >= mIdlePeriodLimit.mLastRequestIdInIdlePeriod && | |||
| 542 | TimeStamp::Now() <= mIdlePeriodLimit.mEndOfIdlePeriod; | |||
| 543 | } | |||
| 544 | ||||
| 545 | void MaybeUpdateIdlePeriodLimit(); | |||
| 546 | ||||
| 547 | // Maybe dispatch the IdleRequestExecutor. MabyeDispatch will | |||
| 548 | // schedule a delayed dispatch if the associated window is in the | |||
| 549 | // background or if given a time to wait until dispatching. | |||
| 550 | void MaybeDispatch(TimeStamp aDelayUntil = TimeStamp()); | |||
| 551 | void ScheduleDispatch(); | |||
| 552 | ||||
| 553 | private: | |||
| 554 | struct IdlePeriodLimit { | |||
| 555 | TimeStamp mEndOfIdlePeriod; | |||
| 556 | uint32_t mLastRequestIdInIdlePeriod; | |||
| 557 | }; | |||
| 558 | ||||
| 559 | void DelayedDispatch(uint32_t aDelay); | |||
| 560 | ||||
| 561 | ~IdleRequestExecutor() override = default; | |||
| 562 | ||||
| 563 | bool mDispatched; | |||
| 564 | TimeStamp mDeadline; | |||
| 565 | IdlePeriodLimit mIdlePeriodLimit; | |||
| 566 | RefPtr<nsGlobalWindowInner> mWindow; | |||
| 567 | // The timeout handler responsible for dispatching this executor in | |||
| 568 | // the case of immediate dispatch to the idle queue isn't | |||
| 569 | // desirable. This is used if we've dispatched all idle callbacks | |||
| 570 | // that are allowed to run in the current idle period, or if the | |||
| 571 | // associated window is currently in the background. | |||
| 572 | RefPtr<TimeoutHandler> mDelayedExecutorDispatcher; | |||
| 573 | // If not Nothing() then this value is the handle to the currently | |||
| 574 | // scheduled delayed executor dispatcher. This is needed to be able | |||
| 575 | // to cancel the timeout handler in case of the executor being | |||
| 576 | // cancelled. | |||
| 577 | Maybe<int32_t> mDelayedExecutorHandle; | |||
| 578 | }; | |||
| 579 | ||||
| 580 | NS_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; } | |||
| 581 | 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; } | |||
| 582 | ||||
| 583 | NS_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" , 583); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0" ") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 583 ); __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; } | |||
| 584 | NS_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" , 584); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0" ") (" "dup release" ")"); 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.decr (base); if (count == 0) { NS_CycleCollectableHasRefCntZero(); } NS_LogRelease((this), (count), ("IdleRequestExecutor")); return count; } void IdleRequestExecutor::DeleteCycleCollectable(void ) { delete (this); } | |||
| 585 | ||||
| 586 | NS_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" , 586); 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 | |||
| 587 | NS_INTERFACE_MAP_ENTRY(nsIRunnable)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t <decltype(*this)>, nsIRunnable>)) foundInterface = static_cast <nsIRunnable*>(this); else | |||
| 588 | NS_INTERFACE_MAP_ENTRY(nsICancelableRunnable)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t <decltype(*this)>, nsICancelableRunnable>)) foundInterface = static_cast<nsICancelableRunnable*>(this); else | |||
| 589 | NS_INTERFACE_MAP_ENTRY(nsINamed)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t <decltype(*this)>, nsINamed>)) foundInterface = static_cast <nsINamed*>(this); else | |||
| 590 | NS_INTERFACE_MAP_ENTRY(nsIIdleRunnable)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t <decltype(*this)>, nsIIdleRunnable>)) foundInterface = static_cast<nsIIdleRunnable*>(this); else | |||
| 591 | 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 | |||
| 592 | NS_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" , 592); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aIID.Equals((nsISupports::kIID))" ")"); do { MOZ_CrashSequence(__null, 592); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); status = NS_NOINTERFACE ; } else { (foundInterface)->AddRef(); status = NS_OK; } * aInstancePtr = foundInterface; return status; } | |||
| 593 | ||||
| 594 | NS_IMETHODIMPnsresult | |||
| 595 | IdleRequestExecutor::GetName(nsACString& aName) { | |||
| 596 | aName.AssignLiteral("IdleRequestExecutor"); | |||
| 597 | return NS_OK; | |||
| 598 | } | |||
| 599 | ||||
| 600 | // MOZ_CAN_RUN_SCRIPT_BOUNDARY until nsIRunnable::Run is MOZ_CAN_RUN_SCRIPT. | |||
| 601 | // See bug 1535398. | |||
| 602 | MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMPnsresult IdleRequestExecutor::Run() { | |||
| 603 | 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", 603 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence(__null, 603); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 604 | ||||
| 605 | mDispatched = false; | |||
| 606 | if (mWindow) { | |||
| 607 | RefPtr<nsGlobalWindowInner> window(mWindow); | |||
| 608 | window->ExecuteIdleRequest(mDeadline); | |||
| 609 | } | |||
| 610 | ||||
| 611 | return NS_OK; | |||
| 612 | } | |||
| 613 | ||||
| 614 | nsresult IdleRequestExecutor::Cancel() { | |||
| 615 | 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", 615 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence(__null, 615); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 616 | ||||
| 617 | if (mDelayedExecutorHandle && mWindow) { | |||
| 618 | mWindow->GetTimeoutManager()->ClearTimeout( | |||
| 619 | mDelayedExecutorHandle.value(), Timeout::Reason::eIdleCallbackTimeout); | |||
| 620 | } | |||
| 621 | ||||
| 622 | mWindow = nullptr; | |||
| 623 | return NS_OK; | |||
| 624 | } | |||
| 625 | ||||
| 626 | void IdleRequestExecutor::SetDeadline(TimeStamp aDeadline) { | |||
| 627 | 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", 627 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence(__null, 627); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 628 | ||||
| 629 | if (!mWindow) { | |||
| 630 | return; | |||
| 631 | } | |||
| 632 | ||||
| 633 | mDeadline = aDeadline; | |||
| 634 | } | |||
| 635 | ||||
| 636 | void IdleRequestExecutor::MaybeUpdateIdlePeriodLimit() { | |||
| 637 | if (TimeStamp::Now() > mIdlePeriodLimit.mEndOfIdlePeriod) { | |||
| 638 | mIdlePeriodLimit = {mDeadline, mWindow->LastIdleRequestHandle()}; | |||
| 639 | } | |||
| 640 | } | |||
| 641 | ||||
| 642 | void IdleRequestExecutor::MaybeDispatch(TimeStamp aDelayUntil) { | |||
| 643 | // If we've already dispatched the executor we don't want to do it | |||
| 644 | // again. Also, if we've called IdleRequestExecutor::Cancel mWindow | |||
| 645 | // will be null, which indicates that we shouldn't dispatch this | |||
| 646 | // executor either. | |||
| 647 | if (mDispatched || IsCancelled()) { | |||
| 648 | return; | |||
| 649 | } | |||
| 650 | ||||
| 651 | mDispatched = true; | |||
| 652 | ||||
| 653 | nsPIDOMWindowOuter* outer = mWindow->GetOuterWindow(); | |||
| 654 | if (outer && outer->IsBackground()) { | |||
| 655 | // Set a timeout handler with a timeout of 0 ms to throttle idle | |||
| 656 | // callback requests coming from a backround window using | |||
| 657 | // background timeout throttling. | |||
| 658 | DelayedDispatch(0); | |||
| 659 | return; | |||
| 660 | } | |||
| 661 | ||||
| 662 | TimeStamp now = TimeStamp::Now(); | |||
| 663 | if (!aDelayUntil || aDelayUntil < now) { | |||
| 664 | ScheduleDispatch(); | |||
| 665 | return; | |||
| 666 | } | |||
| 667 | ||||
| 668 | TimeDuration delay = aDelayUntil - now; | |||
| 669 | DelayedDispatch(static_cast<uint32_t>(delay.ToMilliseconds())); | |||
| 670 | } | |||
| 671 | ||||
| 672 | void IdleRequestExecutor::ScheduleDispatch() { | |||
| 673 | 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" , 673); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mWindow" ")" ); do { MOZ_CrashSequence(__null, 673); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 674 | mDelayedExecutorHandle = Nothing(); | |||
| 675 | RefPtr<IdleRequestExecutor> request = this; | |||
| 676 | NS_DispatchToCurrentThreadQueue(request.forget(), EventQueuePriority::Idle); | |||
| 677 | } | |||
| 678 | ||||
| 679 | void IdleRequestExecutor::DelayedDispatch(uint32_t aDelay) { | |||
| 680 | 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" , 680); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mWindow" ")" ); do { MOZ_CrashSequence(__null, 680); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 681 | 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" , 681); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mDelayedExecutorHandle.isNothing()" ")"); do { MOZ_CrashSequence(__null, 681); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 682 | int32_t handle; | |||
| 683 | mWindow->GetTimeoutManager()->SetTimeout( | |||
| 684 | mDelayedExecutorDispatcher, aDelay, false, | |||
| 685 | Timeout::Reason::eIdleCallbackTimeout, &handle); | |||
| 686 | mDelayedExecutorHandle = Some(handle); | |||
| 687 | } | |||
| 688 | ||||
| 689 | bool IdleRequestExecutorTimeoutHandler::Call(const char* /* unused */) { | |||
| 690 | if (!mExecutor->IsCancelled()) { | |||
| 691 | mExecutor->ScheduleDispatch(); | |||
| 692 | } | |||
| 693 | return true; | |||
| 694 | } | |||
| 695 | ||||
| 696 | void nsGlobalWindowInner::ScheduleIdleRequestDispatch() { | |||
| 697 | AssertIsOnMainThread(); | |||
| 698 | ||||
| 699 | if (!mIdleRequestExecutor) { | |||
| 700 | mIdleRequestExecutor = MakeRefPtr<IdleRequestExecutor>(this); | |||
| 701 | } | |||
| 702 | ||||
| 703 | mIdleRequestExecutor->MaybeDispatch(); | |||
| 704 | } | |||
| 705 | ||||
| 706 | void nsGlobalWindowInner::SuspendIdleRequests() { | |||
| 707 | if (mIdleRequestExecutor) { | |||
| 708 | mIdleRequestExecutor->Cancel(); | |||
| 709 | mIdleRequestExecutor = nullptr; | |||
| 710 | } | |||
| 711 | } | |||
| 712 | ||||
| 713 | void nsGlobalWindowInner::ResumeIdleRequests() { | |||
| 714 | 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", 714 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mIdleRequestExecutor" ")"); do { MOZ_CrashSequence(__null, 714); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 715 | ||||
| 716 | ScheduleIdleRequestDispatch(); | |||
| 717 | } | |||
| 718 | ||||
| 719 | void nsGlobalWindowInner::RemoveIdleCallback( | |||
| 720 | mozilla::dom::IdleRequest* aRequest) { | |||
| 721 | AssertIsOnMainThread(); | |||
| 722 | ||||
| 723 | if (aRequest->HasTimeout()) { | |||
| 724 | mTimeoutManager->ClearTimeout(aRequest->GetTimeoutHandle(), | |||
| 725 | Timeout::Reason::eIdleCallbackTimeout); | |||
| 726 | } | |||
| 727 | ||||
| 728 | aRequest->RemoveFromList(); | |||
| 729 | } | |||
| 730 | ||||
| 731 | void nsGlobalWindowInner::RunIdleRequest(IdleRequest* aRequest, | |||
| 732 | DOMHighResTimeStamp aDeadline, | |||
| 733 | bool aDidTimeout) { | |||
| 734 | AssertIsOnMainThread(); | |||
| 735 | // XXXbz Do we still need this RefPtr? MOZ_CAN_RUN_SCRIPT should | |||
| 736 | // guarantee that caller is holding a strong ref on the stack. | |||
| 737 | RefPtr<IdleRequest> request(aRequest); | |||
| 738 | RemoveIdleCallback(request); | |||
| 739 | request->IdleRun(this, aDeadline, aDidTimeout); | |||
| 740 | } | |||
| 741 | ||||
| 742 | void nsGlobalWindowInner::ExecuteIdleRequest(TimeStamp aDeadline) { | |||
| 743 | AssertIsOnMainThread(); | |||
| 744 | RefPtr<IdleRequest> request = mIdleRequestCallbacks.getFirst(); | |||
| 745 | ||||
| 746 | if (!request) { | |||
| 747 | // There are no more idle requests, so stop scheduling idle | |||
| 748 | // request callbacks. | |||
| 749 | return; | |||
| 750 | } | |||
| 751 | ||||
| 752 | // If the request that we're trying to execute has been queued | |||
| 753 | // during the current idle period, then dispatch it again at the end | |||
| 754 | // of the idle period. | |||
| 755 | if (mIdleRequestExecutor->IneligibleForCurrentIdlePeriod(request)) { | |||
| 756 | mIdleRequestExecutor->MaybeDispatch(aDeadline); | |||
| 757 | return; | |||
| 758 | } | |||
| 759 | ||||
| 760 | DOMHighResTimeStamp deadline = 0.0; | |||
| 761 | ||||
| 762 | if (Performance* perf = GetPerformance()) { | |||
| 763 | deadline = perf->GetDOMTiming()->TimeStampToDOMHighRes(aDeadline); | |||
| 764 | } | |||
| 765 | ||||
| 766 | mIdleRequestExecutor->MaybeUpdateIdlePeriodLimit(); | |||
| 767 | RunIdleRequest(request, deadline, false); | |||
| 768 | ||||
| 769 | // Running the idle callback could've suspended the window, in which | |||
| 770 | // case mIdleRequestExecutor will be null. | |||
| 771 | if (mIdleRequestExecutor) { | |||
| 772 | mIdleRequestExecutor->MaybeDispatch(); | |||
| 773 | } | |||
| 774 | } | |||
| 775 | ||||
| 776 | class IdleRequestTimeoutHandler final : public TimeoutHandler { | |||
| 777 | public: | |||
| 778 | IdleRequestTimeoutHandler(JSContext* aCx, IdleRequest* aIdleRequest, | |||
| 779 | nsPIDOMWindowInner* aWindow) | |||
| 780 | : TimeoutHandler(aCx), mIdleRequest(aIdleRequest), mWindow(aWindow) {} | |||
| 781 | ||||
| 782 | 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: | |||
| 783 | 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" , 783); AnnotateMozCrashReason("MOZ_ASSERT" "(" "p == &_cycleCollectorGlobal" ") (" "IdleRequestTimeoutHandler" " should QI to its own CC participant" ")"); do { MOZ_CrashSequence(__null, 783); __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 | |||
| 784 | ||||
| 785 | MOZ_CAN_RUN_SCRIPT bool Call(const char* /* unused */) override { | |||
| 786 | RefPtr<nsGlobalWindowInner> window(nsGlobalWindowInner::Cast(mWindow)); | |||
| 787 | RefPtr<IdleRequest> request(mIdleRequest); | |||
| 788 | window->RunIdleRequest(request, 0.0, true); | |||
| 789 | return true; | |||
| 790 | } | |||
| 791 | ||||
| 792 | private: | |||
| 793 | ~IdleRequestTimeoutHandler() override = default; | |||
| 794 | ||||
| 795 | RefPtr<IdleRequest> mIdleRequest; | |||
| 796 | nsCOMPtr<nsPIDOMWindowInner> mWindow; | |||
| 797 | }; | |||
| 798 | ||||
| 799 | NS_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; } | |||
| 800 | ||||
| 801 | NS_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" , 801); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0" ") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 801 ); __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; } | |||
| 802 | NS_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" , 802); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0" ") (" "dup release" ")"); 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.decr (base); if (count == 0) { NS_CycleCollectableHasRefCntZero(); } NS_LogRelease((this), (count), ("IdleRequestTimeoutHandler" )); return count; } void IdleRequestTimeoutHandler::DeleteCycleCollectable (void) { delete (this); } | |||
| 803 | ||||
| 804 | NS_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" , 804); 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 | |||
| 805 | NS_INTERFACE_MAP_ENTRY(nsISupports)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t <decltype(*this)>, nsISupports>)) foundInterface = static_cast <nsISupports*>(this); else | |||
| 806 | NS_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" , 806); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aIID.Equals((nsISupports::kIID))" ")"); do { MOZ_CrashSequence(__null, 806); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); status = NS_NOINTERFACE ; } else { (foundInterface)->AddRef(); status = NS_OK; } * aInstancePtr = foundInterface; return status; } | |||
| 807 | ||||
| 808 | uint32_t nsGlobalWindowInner::RequestIdleCallback( | |||
| 809 | JSContext* aCx, IdleRequestCallback& aCallback, | |||
| 810 | const IdleRequestOptions& aOptions, ErrorResult& aError) { | |||
| 811 | AssertIsOnMainThread(); | |||
| 812 | ||||
| 813 | if (IsDying()) { | |||
| 814 | return 0; | |||
| 815 | } | |||
| 816 | ||||
| 817 | uint32_t handle = mIdleRequestCallbackCounter++; | |||
| 818 | ||||
| 819 | RefPtr request = MakeRefPtr<IdleRequest>(&aCallback, handle); | |||
| 820 | ||||
| 821 | if (aOptions.mTimeout.WasPassed()) { | |||
| 822 | int32_t timeoutHandle; | |||
| 823 | RefPtr handler = MakeRefPtr<IdleRequestTimeoutHandler>(aCx, request, this); | |||
| 824 | ||||
| 825 | nsresult rv = mTimeoutManager->SetTimeout( | |||
| 826 | handler, aOptions.mTimeout.Value(), false, | |||
| 827 | Timeout::Reason::eIdleCallbackTimeout, &timeoutHandle); | |||
| 828 | ||||
| 829 | 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" , 829)) { | |||
| 830 | return 0; | |||
| 831 | } | |||
| 832 | ||||
| 833 | request->SetTimeoutHandle(timeoutHandle); | |||
| 834 | } | |||
| 835 | ||||
| 836 | request->SetContainer(mIdleRequestCallbacksByHandle); | |||
| 837 | mIdleRequestCallbacks.insertBack(request); | |||
| 838 | ||||
| 839 | if (!IsSuspended()) { | |||
| 840 | ScheduleIdleRequestDispatch(); | |||
| 841 | } | |||
| 842 | ||||
| 843 | return handle; | |||
| 844 | } | |||
| 845 | ||||
| 846 | void nsGlobalWindowInner::CancelIdleCallback(uint32_t aHandle) { | |||
| 847 | if (IdleRequest* request = mIdleRequestCallbacksByHandle->Get(aHandle)) { | |||
| 848 | RemoveIdleCallback(request); | |||
| 849 | } | |||
| 850 | } | |||
| 851 | ||||
| 852 | void nsGlobalWindowInner::DisableIdleCallbackRequests() { | |||
| 853 | if (mIdleRequestExecutor) { | |||
| 854 | mIdleRequestExecutor->Cancel(); | |||
| 855 | mIdleRequestExecutor = nullptr; | |||
| 856 | } | |||
| 857 | ||||
| 858 | while (!mIdleRequestCallbacks.isEmpty()) { | |||
| 859 | RefPtr<IdleRequest> request = mIdleRequestCallbacks.getFirst(); | |||
| 860 | RemoveIdleCallback(request); | |||
| 861 | } | |||
| 862 | } | |||
| 863 | ||||
| 864 | bool nsGlobalWindowInner::IsBackgroundInternal() const { | |||
| 865 | return !mOuterWindow || mOuterWindow->IsBackground(); | |||
| 866 | } | |||
| 867 | ||||
| 868 | class PromiseDocumentFlushedResolver final { | |||
| 869 | public: | |||
| 870 | PromiseDocumentFlushedResolver(Promise* aPromise, | |||
| 871 | PromiseDocumentFlushedCallback& aCallback) | |||
| 872 | : mPromise(aPromise), mCallback(&aCallback) {} | |||
| 873 | ||||
| 874 | virtual ~PromiseDocumentFlushedResolver() = default; | |||
| 875 | ||||
| 876 | void Call() { | |||
| 877 | nsMutationGuard guard; | |||
| 878 | ErrorResult error; | |||
| 879 | JS::Rooted<JS::Value> returnVal(RootingCx()); | |||
| 880 | mCallback->Call(&returnVal, error); | |||
| 881 | ||||
| 882 | if (error.Failed()) { | |||
| 883 | mPromise->MaybeReject(std::move(error)); | |||
| 884 | } else if (guard.Mutated(0)) { | |||
| 885 | // Something within the callback mutated the DOM. | |||
| 886 | mPromise->MaybeRejectWithNoModificationAllowedError( | |||
| 887 | "DOM mutated from promiseDocumentFlushed callbacks"); | |||
| 888 | } else { | |||
| 889 | mPromise->MaybeResolve(returnVal); | |||
| 890 | } | |||
| 891 | } | |||
| 892 | ||||
| 893 | RefPtr<Promise> mPromise; | |||
| 894 | RefPtr<PromiseDocumentFlushedCallback> mCallback; | |||
| 895 | }; | |||
| 896 | ||||
| 897 | //***************************************************************************** | |||
| 898 | //*** nsGlobalWindowInner: Object Management | |||
| 899 | //***************************************************************************** | |||
| 900 | ||||
| 901 | nsGlobalWindowInner::nsGlobalWindowInner(nsGlobalWindowOuter* aOuterWindow, | |||
| 902 | WindowGlobalChild* aActor) | |||
| 903 | : nsPIDOMWindowInner(aOuterWindow, aActor), | |||
| 904 | mHasOrientationChangeListeners(false), | |||
| 905 | mWasOffline(false), | |||
| 906 | mHasHadSlowScript(false), | |||
| 907 | mIsChrome(false), | |||
| 908 | mCleanMessageManager(false), | |||
| 909 | mNeedsFocus(true), | |||
| 910 | mFocusByKeyOccurred(false), | |||
| 911 | mDidFireDocElemInserted(false), | |||
| 912 | mHasGamepad(false), | |||
| 913 | mHasXRSession(false), | |||
| 914 | mHasVRDisplayActivateEvents(false), | |||
| 915 | mXRRuntimeDetectionInFlight(false), | |||
| 916 | mXRPermissionRequestInFlight(false), | |||
| 917 | mXRPermissionGranted(false), | |||
| 918 | mWasCurrentInnerWindow(false), | |||
| 919 | mHasSeenGamepadInput(false), | |||
| 920 | mHintedWasLoading(false), | |||
| 921 | mHasOpenedExternalProtocolFrame(false), | |||
| 922 | mScrollMarksOnHScrollbar(false), | |||
| 923 | mStorageAllowedReasonCache(0), | |||
| 924 | mSuspendDepth(0), | |||
| 925 | mFreezeDepth(0), | |||
| 926 | #ifdef DEBUG1 | |||
| 927 | mSerial(0), | |||
| 928 | #endif | |||
| 929 | mFocusMethod(0), | |||
| 930 | mIdleRequestCallbackCounter(1), | |||
| 931 | mIdleRequestCallbacksByHandle(new mozilla::dom::IdleRequestMap()), | |||
| 932 | mIdleRequestExecutor(nullptr), | |||
| 933 | mObservingRefresh(false), | |||
| 934 | mIteratingDocumentFlushedResolvers(false), | |||
| 935 | mCanSkipCCGeneration(0) { | |||
| 936 | mIsInnerWindow = true; | |||
| 937 | ||||
| 938 | AssertIsOnMainThread(); | |||
| 939 | SetIsOnMainThread(); | |||
| 940 | nsLayoutStatics::AddRef(); | |||
| 941 | ||||
| 942 | // Initialize the PRCList (this). | |||
| 943 | PR_INIT_CLIST(this)do {(this)->next = (this); (this)->prev = (this); } while (0); | |||
| 944 | ||||
| 945 | // add this inner window to the outer window list of inners. | |||
| 946 | PR_INSERT_AFTER(this, aOuterWindow)do {(this)->next = (aOuterWindow)->next; (this)->prev = (aOuterWindow); (aOuterWindow)->next->prev = (this); (aOuterWindow)->next = (this); } while (0); | |||
| 947 | ||||
| 948 | mTimeoutManager = std::make_unique<dom::TimeoutManager>( | |||
| 949 | *this, StaticPrefs::dom_timeout_max_idle_defer_ms(), | |||
| 950 | static_cast<nsISerialEventTarget*>(nsPIDOMWindowInner::From(this) | |||
| 951 | ->GetBrowsingContextGroup() | |||
| 952 | ->GetTimerEventQueue())); | |||
| 953 | ||||
| 954 | mObserver = MakeRefPtr<nsGlobalWindowObserver>(this); | |||
| 955 | if (nsCOMPtr<nsIObserverService> os = services::GetObserverService()) { | |||
| 956 | // Watch for online/offline status changes so we can fire events. Use | |||
| 957 | // a strong reference. | |||
| 958 | os->AddObserver(mObserver, NS_IOSERVICE_OFFLINE_STATUS_TOPIC"network:offline-status-changed", false); | |||
| 959 | os->AddObserver(mObserver, MEMORY_PRESSURE_OBSERVER_TOPIC"memory-pressure", false); | |||
| 960 | os->AddObserver(mObserver, PERMISSION_CHANGED_TOPIC"perm-changed", false); | |||
| 961 | os->AddObserver(mObserver, "browser-perm-changed", false); | |||
| 962 | os->AddObserver(mObserver, "screen-information-changed", false); | |||
| 963 | os->AddObserver(mObserver, "audio-playback", false); | |||
| 964 | } | |||
| 965 | ||||
| 966 | Preferences::AddStrongObserver(mObserver, "intl.accept_languages"); | |||
| 967 | ||||
| 968 | // Watch for storage notifications so we can fire storage events. | |||
| 969 | RefPtr<StorageNotifierService> sns = StorageNotifierService::GetOrCreate(); | |||
| 970 | if (sns) { | |||
| 971 | sns->Register(mObserver); | |||
| 972 | } | |||
| 973 | ||||
| 974 | if (XRE_IsContentProcess()) { | |||
| 975 | nsCOMPtr<nsIDocShell> docShell = GetDocShell(); | |||
| 976 | if (docShell) { | |||
| 977 | mBrowserChild = docShell->GetBrowserChild(); | |||
| 978 | } | |||
| 979 | } | |||
| 980 | ||||
| 981 | if (gDumpFile == nullptr) { | |||
| 982 | nsAutoCString fname; | |||
| 983 | Preferences::GetCString("browser.dom.window.dump.file", fname); | |||
| 984 | if (!fname.IsEmpty()) { | |||
| 985 | // If this fails to open, Dump() knows to just go to stdout on null. | |||
| 986 | gDumpFile = fopen(fname.get(), "wb+"); | |||
| 987 | } else { | |||
| 988 | gDumpFile = stdoutstdout; | |||
| 989 | } | |||
| 990 | } | |||
| 991 | ||||
| 992 | #ifdef DEBUG1 | |||
| 993 | mSerial = nsContentUtils::InnerOrOuterWindowCreated(); | |||
| 994 | ||||
| 995 | if (MOZ_LOG_TEST(gDocShellAndDOMWindowLeakLogging, LogLevel::Info)(__builtin_expect(!!(mozilla::detail::log_test(gDocShellAndDOMWindowLeakLogging , LogLevel::Info)), 0))) { | |||
| 996 | 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) | |||
| 997 | ("++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) | |||
| 998 | 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) | |||
| 999 | 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) | |||
| 1000 | 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); | |||
| 1001 | ||||
| 1002 | nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); | |||
| 1003 | if (obs) { | |||
| 1004 | nsString data; | |||
| 1005 | data.AppendPrintf( | |||
| 1006 | "serial=%d address=0x%" PRIxPTR"l" "x" " type=inner outer=0x%" PRIxPTR"l" "x", | |||
| 1007 | mSerial, reinterpret_cast<uintptr_t>(ToCanonicalSupports(this)), | |||
| 1008 | reinterpret_cast<uintptr_t>(ToCanonicalSupports(aOuterWindow))); | |||
| 1009 | obs->NotifyObservers(nullptr, "debug-domwindow-created", data.get()); | |||
| 1010 | } | |||
| 1011 | } | |||
| 1012 | #endif | |||
| 1013 | ||||
| 1014 | 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) | |||
| 1015 | ("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); | |||
| 1016 | ||||
| 1017 | // Add ourselves to the inner windows list. | |||
| 1018 | 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" , 1018); AnnotateMozCrashReason("MOZ_ASSERT" "(" "sInnerWindowsById" ") (" "Inner Windows hash table must be created!" ")"); do { MOZ_CrashSequence(__null, 1018); __attribute__((nomerge)) :: abort(); } while (false); } } while (false); | |||
| 1019 | 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" , 1020); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!sInnerWindowsById->Contains(mWindowID)" ") (" "This window shouldn't be in the hash table yet!" ")") ; do { MOZ_CrashSequence(__null, 1020); __attribute__((nomerge )) ::abort(); } while (false); } } while (false) | |||
| 1020 | "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" , 1020); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!sInnerWindowsById->Contains(mWindowID)" ") (" "This window shouldn't be in the hash table yet!" ")") ; do { MOZ_CrashSequence(__null, 1020); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 1021 | // We seem to see crashes in release builds because of null | |||
| 1022 | // |sInnerWindowsById|. | |||
| 1023 | if (sInnerWindowsById) { | |||
| 1024 | sInnerWindowsById->InsertOrUpdate(mWindowID, this); | |||
| 1025 | } | |||
| 1026 | } | |||
| 1027 | ||||
| 1028 | #ifdef DEBUG1 | |||
| 1029 | ||||
| 1030 | /* static */ | |||
| 1031 | void nsGlobalWindowInner::AssertIsOnMainThread() { | |||
| 1032 | 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", 1032 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence(__null, 1032); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 1033 | } | |||
| 1034 | ||||
| 1035 | #endif // DEBUG | |||
| 1036 | ||||
| 1037 | /* static */ | |||
| 1038 | void nsGlobalWindowInner::Init() { | |||
| 1039 | AssertIsOnMainThread(); | |||
| 1040 | ||||
| 1041 | NS_ASSERTION(gDOMLeakPRLogInner,do { if (!(gDOMLeakPRLogInner)) { NS_DebugBreak(NS_DEBUG_ASSERTION , "gDOMLeakPRLogInner should have been initialized!", "gDOMLeakPRLogInner" , "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 1042 ); MOZ_PretendNoReturn(); } } while (0) | |||
| 1042 | "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", 1042 ); MOZ_PretendNoReturn(); } } while (0); | |||
| 1043 | ||||
| 1044 | sInnerWindowsById = new InnerWindowByIdTable(); | |||
| 1045 | } | |||
| 1046 | ||||
| 1047 | nsGlobalWindowInner::~nsGlobalWindowInner() { | |||
| 1048 | AssertIsOnMainThread(); | |||
| 1049 | 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", 1049 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mHintedWasLoading" ")"); do { MOZ_CrashSequence(__null, 1049); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 1050 | ||||
| 1051 | if (IsChromeWindow()) { | |||
| 1052 | 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", 1053 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCleanMessageManager" ") (" "chrome windows may always disconnect the msg manager" ")"); do { MOZ_CrashSequence(__null, 1053); __attribute__((nomerge )) ::abort(); } while (false); } } while (false) | |||
| 1053 | "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", 1053 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCleanMessageManager" ") (" "chrome windows may always disconnect the msg manager" ")"); do { MOZ_CrashSequence(__null, 1053); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 1054 | ||||
| 1055 | DisconnectAndClearGroupMessageManagers(); | |||
| 1056 | ||||
| 1057 | if (mChromeFields.mMessageManager) { | |||
| 1058 | static_cast<nsFrameMessageManager*>(mChromeFields.mMessageManager.get()) | |||
| 1059 | ->Disconnect(); | |||
| 1060 | } | |||
| 1061 | ||||
| 1062 | mCleanMessageManager = false; | |||
| 1063 | } | |||
| 1064 | ||||
| 1065 | // In most cases this should already have been called, but call it again | |||
| 1066 | // here to catch any corner cases. | |||
| 1067 | FreeInnerObjects(); | |||
| 1068 | ||||
| 1069 | if (sInnerWindowsById) { | |||
| 1070 | sInnerWindowsById->Remove(mWindowID); | |||
| 1071 | } | |||
| 1072 | ||||
| 1073 | nsContentUtils::InnerOrOuterWindowDestroyed(); | |||
| 1074 | ||||
| 1075 | #ifdef DEBUG1 | |||
| 1076 | if (MOZ_LOG_TEST(gDocShellAndDOMWindowLeakLogging, LogLevel::Info)(__builtin_expect(!!(mozilla::detail::log_test(gDocShellAndDOMWindowLeakLogging , LogLevel::Info)), 0))) { | |||
| 1077 | nsAutoCString url; | |||
| 1078 | if (mLastOpenedURI) { | |||
| 1079 | url = mLastOpenedURI->GetSpecOrDefault(); | |||
| 1080 | ||||
| 1081 | // Data URLs can be very long, so truncate to avoid flooding the log. | |||
| 1082 | const uint32_t maxURLLength = 1000; | |||
| 1083 | if (url.Length() > maxURLLength) { | |||
| 1084 | url.Truncate(maxURLLength); | |||
| 1085 | } | |||
| 1086 | } | |||
| 1087 | ||||
| 1088 | nsGlobalWindowOuter* outer = nsGlobalWindowOuter::Cast(mOuterWindow); | |||
| 1089 | 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) | |||
| 1090 | 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) | |||
| 1091 | ("--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) | |||
| 1092 | "%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) | |||
| 1093 | 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) | |||
| 1094 | 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) | |||
| 1095 | 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); | |||
| 1096 | ||||
| 1097 | uint32_t serial = mSerial; | |||
| 1098 | NS_DispatchToMainThread( | |||
| 1099 | NS_NewRunnableFunction( | |||
| 1100 | "TestDOMWindowDestroyed", | |||
| 1101 | [serial, url = std::move(url)] { | |||
| 1102 | nsCOMPtr<nsIObserverService> obs = | |||
| 1103 | mozilla::services::GetObserverService(); | |||
| 1104 | if (obs) { | |||
| 1105 | nsString data; | |||
| 1106 | data.AppendPrintf("serial=%d type=inner url=%s", serial, | |||
| 1107 | url.get()); | |||
| 1108 | obs->NotifyObservers(nullptr, "debug-domwindow-destroyed", | |||
| 1109 | data.get()); | |||
| 1110 | } | |||
| 1111 | }), | |||
| 1112 | NS_DISPATCH_FALLIBLEnsIEventTarget::DISPATCH_FALLIBLE); | |||
| 1113 | } | |||
| 1114 | #endif | |||
| 1115 | 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) | |||
| 1116 | ("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); | |||
| 1117 | ||||
| 1118 | // An inner window is destroyed, pull it out of the outer window's | |||
| 1119 | // list if inner windows. | |||
| 1120 | ||||
| 1121 | PR_REMOVE_LINK(this)do {(this)->prev->next = (this)->next; (this)->next ->prev = (this)->prev; } while (0); | |||
| 1122 | ||||
| 1123 | // If our outer window's inner window is this window, null out the | |||
| 1124 | // outer window's reference to this window that's being deleted. | |||
| 1125 | nsGlobalWindowOuter* outer = GetOuterWindowInternal(); | |||
| 1126 | if (outer) { | |||
| 1127 | outer->MaybeClearInnerWindow(this); | |||
| 1128 | } | |||
| 1129 | ||||
| 1130 | // We don't have to leave the tab group if we are an inner window. | |||
| 1131 | ||||
| 1132 | nsCOMPtr<nsIDeviceSensors> ac = do_GetService(NS_DEVICE_SENSORS_CONTRACTID"@mozilla.org/devicesensors;1"); | |||
| 1133 | if (ac) ac->RemoveWindowAsListener(this); | |||
| 1134 | ||||
| 1135 | nsLayoutStatics::Release(); | |||
| 1136 | } | |||
| 1137 | ||||
| 1138 | // static | |||
| 1139 | void nsGlobalWindowInner::ShutDown() { | |||
| 1140 | AssertIsOnMainThread(); | |||
| 1141 | ||||
| 1142 | if (gDumpFile && gDumpFile != stdoutstdout) { | |||
| 1143 | fclose(gDumpFile); | |||
| 1144 | } | |||
| 1145 | gDumpFile = nullptr; | |||
| 1146 | ||||
| 1147 | sInnerWindowsById = nullptr; | |||
| 1148 | } | |||
| 1149 | ||||
| 1150 | void nsGlobalWindowInner::FreeInnerObjects() { | |||
| 1151 | if (IsDying()) { | |||
| 1152 | return; | |||
| 1153 | } | |||
| 1154 | StartDying(); | |||
| 1155 | ||||
| 1156 | if (JSObject* global = GetWrapperPreserveColor()) { | |||
| 1157 | js::SetRealmIsDyingHint(global); | |||
| 1158 | } | |||
| 1159 | ||||
| 1160 | ClearHasPointerRawUpdateEventListeners(); | |||
| 1161 | ||||
| 1162 | if (mDoc && mDoc->GetWindowContext()) { | |||
| 1163 | // The document is about to lose its window, so this is a good time to send | |||
| 1164 | // our page use counters. | |||
| 1165 | // | |||
| 1166 | // (We also do this in Document::SetScriptGlobalObject(nullptr), which | |||
| 1167 | // catches most cases of documents losing their window, but not all.) | |||
| 1168 | mDoc->SendPageUseCounters(); | |||
| 1169 | } | |||
| 1170 | ||||
| 1171 | // Make sure that this is called before we null out the document and | |||
| 1172 | // other members that the window destroyed observers could | |||
| 1173 | // re-create. | |||
| 1174 | if (auto* reporter = nsWindowMemoryReporter::Get()) { | |||
| 1175 | reporter->ObserveDOMWindowDetached(this); | |||
| 1176 | } | |||
| 1177 | ||||
| 1178 | // Kill all of the workers for this window. | |||
| 1179 | CancelWorkersForWindow(*this); | |||
| 1180 | ||||
| 1181 | for (RefPtr<mozilla::dom::SharedWorker> pinnedWorker : | |||
| 1182 | mSharedWorkers.ForwardRange()) { | |||
| 1183 | pinnedWorker->Close(); | |||
| 1184 | } | |||
| 1185 | ||||
| 1186 | if (mTimeoutManager) { | |||
| 1187 | mTimeoutManager->ClearAllTimeouts(); | |||
| 1188 | } | |||
| 1189 | ||||
| 1190 | DisableIdleCallbackRequests(); | |||
| 1191 | ||||
| 1192 | mChromeEventHandler = nullptr; | |||
| 1193 | ||||
| 1194 | if (mListenerManager) { | |||
| 1195 | mListenerManager->RemoveAllListeners(); | |||
| 1196 | mListenerManager->Disconnect(); | |||
| 1197 | mListenerManager = nullptr; | |||
| 1198 | } | |||
| 1199 | ||||
| 1200 | mHistory = nullptr; | |||
| 1201 | ||||
| 1202 | mNavigation = nullptr; | |||
| 1203 | ||||
| 1204 | if (mNavigator) { | |||
| 1205 | mNavigator->OnNavigation(); | |||
| 1206 | mNavigator->Invalidate(); | |||
| 1207 | mNavigator = nullptr; | |||
| 1208 | } | |||
| 1209 | ||||
| 1210 | mScreen = nullptr; | |||
| 1211 | ||||
| 1212 | if (mDoc) { | |||
| 1213 | // Remember the document's principal, URI, and policyContainer. | |||
| 1214 | mDocumentPrincipal = mDoc->NodePrincipal(); | |||
| 1215 | mDocumentCookiePrincipal = mDoc->EffectiveCookiePrincipal(); | |||
| 1216 | mDocumentStoragePrincipal = mDoc->EffectiveStoragePrincipal(); | |||
| 1217 | mDocumentPartitionedPrincipal = mDoc->PartitionedPrincipal(); | |||
| 1218 | mDocumentURI = mDoc->GetDocumentURI(); | |||
| 1219 | mDocBaseURI = mDoc->GetDocBaseURI(); | |||
| 1220 | mDocumentPolicyContainer = mDoc->GetPolicyContainer(); | |||
| 1221 | ||||
| 1222 | while (mDoc->EventHandlingSuppressed()) { | |||
| 1223 | mDoc->UnsuppressEventHandlingAndFireEvents(false); | |||
| 1224 | } | |||
| 1225 | } | |||
| 1226 | ||||
| 1227 | // Remove our reference to the document and the document principal. | |||
| 1228 | mFocusedElement = nullptr; | |||
| 1229 | ||||
| 1230 | // Unregister any remaining media source blob: URLs created by this window. | |||
| 1231 | if (RefPtr<DocGroup> docGroup = GetDocGroup()) { | |||
| 1232 | nsTArray<nsCString> mediaSourceURLs = std::move(mMediaSourceURLs); | |||
| 1233 | for (auto& url : mediaSourceURLs) { | |||
| 1234 | docGroup->UnregisterMediaSourceURL(url, /* aNotifyWindow */ false); | |||
| 1235 | } | |||
| 1236 | } | |||
| 1237 | ||||
| 1238 | nsIGlobalObject::UnlinkObjectsInGlobal(); | |||
| 1239 | ||||
| 1240 | NotifyWindowIDDestroyed("inner-window-destroyed"); | |||
| 1241 | ||||
| 1242 | for (uint32_t i = 0; i < mAudioContexts.Length(); ++i) { | |||
| 1243 | mAudioContexts[i]->OnWindowDestroy(); | |||
| 1244 | } | |||
| 1245 | mAudioContexts.Clear(); | |||
| 1246 | ||||
| 1247 | for (MediaKeys* mediaKeys : mMediaKeysInstances) { | |||
| 1248 | mediaKeys->OnInnerWindowDestroy(); | |||
| 1249 | } | |||
| 1250 | mMediaKeysInstances.Clear(); | |||
| 1251 | ||||
| 1252 | DisableGamepadUpdates(); | |||
| 1253 | mHasGamepad = false; | |||
| 1254 | mGamepads.Clear(); | |||
| 1255 | DisableVRUpdates(); | |||
| 1256 | mHasXRSession = false; | |||
| 1257 | mHasVRDisplayActivateEvents = false; | |||
| 1258 | mXRRuntimeDetectionInFlight = false; | |||
| 1259 | mXRPermissionRequestInFlight = false; | |||
| 1260 | mXRPermissionGranted = false; | |||
| 1261 | mVRDisplays.Clear(); | |||
| 1262 | ||||
| 1263 | // This breaks a cycle between the window and the ClientSource object. | |||
| 1264 | mClientSource.reset(); | |||
| 1265 | ||||
| 1266 | if (mWindowGlobalChild) { | |||
| 1267 | // Remove any remaining listeners. | |||
| 1268 | int64_t nListeners = mWindowGlobalChild->BeforeUnloadListeners(); | |||
| 1269 | for (int64_t i = 0; i < nListeners; ++i) { | |||
| 1270 | mWindowGlobalChild->BeforeUnloadRemoved(); | |||
| 1271 | } | |||
| 1272 | 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", 1272 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mWindowGlobalChild->BeforeUnloadListeners() == 0" ")"); do { MOZ_CrashSequence(__null, 1272); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 1273 | } | |||
| 1274 | ||||
| 1275 | // If we have any promiseDocumentFlushed callbacks, fire them now so | |||
| 1276 | // that the Promises can resolve. | |||
| 1277 | CallDocumentFlushedResolvers(/* aUntilExhaustion = */ true); | |||
| 1278 | ||||
| 1279 | DisconnectGlobalTeardownObservers(); | |||
| 1280 | ||||
| 1281 | #ifdef MOZ_WIDGET_ANDROID | |||
| 1282 | DisableOrientationChangeListener(); | |||
| 1283 | #endif | |||
| 1284 | ||||
| 1285 | if (mObserver) { | |||
| 1286 | if (nsCOMPtr<nsIObserverService> os = services::GetObserverService()) { | |||
| 1287 | os->RemoveObserver(mObserver, NS_IOSERVICE_OFFLINE_STATUS_TOPIC"network:offline-status-changed"); | |||
| 1288 | os->RemoveObserver(mObserver, MEMORY_PRESSURE_OBSERVER_TOPIC"memory-pressure"); | |||
| 1289 | os->RemoveObserver(mObserver, PERMISSION_CHANGED_TOPIC"perm-changed"); | |||
| 1290 | os->RemoveObserver(mObserver, "browser-perm-changed"); | |||
| 1291 | os->RemoveObserver(mObserver, "screen-information-changed"); | |||
| 1292 | os->RemoveObserver(mObserver, "audio-playback"); | |||
| 1293 | } | |||
| 1294 | ||||
| 1295 | RefPtr<StorageNotifierService> sns = StorageNotifierService::GetOrCreate(); | |||
| 1296 | if (sns) { | |||
| 1297 | sns->Unregister(mObserver); | |||
| 1298 | } | |||
| 1299 | ||||
| 1300 | Preferences::RemoveObserver(mObserver, "intl.accept_languages"); | |||
| 1301 | ||||
| 1302 | // Drop its reference to this dying window, in case for some bogus reason | |||
| 1303 | // the object stays around. | |||
| 1304 | mObserver->Forget(); | |||
| 1305 | } | |||
| 1306 | ||||
| 1307 | mMenubar = nullptr; | |||
| 1308 | mToolbar = nullptr; | |||
| 1309 | mLocationbar = nullptr; | |||
| 1310 | mPersonalbar = nullptr; | |||
| 1311 | mStatusbar = nullptr; | |||
| 1312 | mScrollbars = nullptr; | |||
| 1313 | ||||
| 1314 | mConsole = nullptr; | |||
| 1315 | mCookieStore = nullptr; | |||
| 1316 | mDocumentPiP = nullptr; | |||
| 1317 | mPushManager = nullptr; | |||
| 1318 | mCloseWatcherManager = nullptr; | |||
| 1319 | ||||
| 1320 | mPaintWorklet = nullptr; | |||
| 1321 | ||||
| 1322 | mExternal = nullptr; | |||
| 1323 | ||||
| 1324 | if (mLocalStorage) { | |||
| 1325 | mLocalStorage->Disconnect(); | |||
| 1326 | mLocalStorage = nullptr; | |||
| 1327 | } | |||
| 1328 | mSessionStorage = nullptr; | |||
| 1329 | if (mPerformance) { | |||
| 1330 | // Since window is dying, nothing is going to be painted with meaningful | |||
| 1331 | // sizes, so the temp data for LCP and container timing is no longer needed. | |||
| 1332 | // Clearing the container timing records also drops their raw element keys. | |||
| 1333 | auto* perf = static_cast<PerformanceMainThread*>(mPerformance.get()); | |||
| 1334 | perf->ClearGeneratedTempDataForLCP(); | |||
| 1335 | perf->ClearContainerTimingData(); | |||
| 1336 | } | |||
| 1337 | mPerformance = nullptr; | |||
| 1338 | ||||
| 1339 | mContentMediaController = nullptr; | |||
| 1340 | ||||
| 1341 | if (mWebTaskScheduler) { | |||
| 1342 | mWebTaskScheduler->Disconnect(); | |||
| 1343 | mWebTaskScheduler = nullptr; | |||
| 1344 | } | |||
| 1345 | ||||
| 1346 | mTrustedTypePolicyFactory = nullptr; | |||
| 1347 | ||||
| 1348 | mSharedWorkers.Clear(); | |||
| 1349 | ||||
| 1350 | #ifdef MOZ_WEBSPEECH1 | |||
| 1351 | mSpeechSynthesis = nullptr; | |||
| 1352 | #endif | |||
| 1353 | ||||
| 1354 | mGlean = nullptr; | |||
| 1355 | mGleanPings = nullptr; | |||
| 1356 | ||||
| 1357 | mParentTarget = nullptr; | |||
| 1358 | ||||
| 1359 | if (mCleanMessageManager) { | |||
| 1360 | 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", 1360); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mIsChrome" ") (" "only chrome should have msg manager cleaned" ")"); do { MOZ_CrashSequence (__null, 1360); __attribute__((nomerge)) ::abort(); } while ( false); } } while (false); | |||
| 1361 | if (mChromeFields.mMessageManager) { | |||
| 1362 | mChromeFields.mMessageManager->Disconnect(); | |||
| 1363 | } | |||
| 1364 | } | |||
| 1365 | ||||
| 1366 | if (mWindowGlobalChild && !mWindowGlobalChild->IsClosed()) { | |||
| 1367 | mWindowGlobalChild->Destroy(); | |||
| 1368 | } | |||
| 1369 | ||||
| 1370 | mIntlUtils = nullptr; | |||
| 1371 | ||||
| 1372 | HintIsLoading(false); | |||
| 1373 | } | |||
| 1374 | ||||
| 1375 | //***************************************************************************** | |||
| 1376 | // nsGlobalWindowInner::nsISupports | |||
| 1377 | //***************************************************************************** | |||
| 1378 | ||||
| 1379 | // QueryInterface implementation for nsGlobalWindowInner | |||
| 1380 | NS_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" , 1380); 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 | |||
| 1381 | NS_WRAPPERCACHE_INTERFACE_MAP_ENTRYif (aIID.Equals((nsWrapperCache::kIID))) { *aInstancePtr = static_cast <nsWrapperCache*>(this); return NS_OK; } else | |||
| 1382 | 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 | |||
| 1383 | NS_INTERFACE_MAP_ENTRY(nsIDOMWindow)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t <decltype(*this)>, nsIDOMWindow>)) foundInterface = static_cast <nsIDOMWindow*>(this); else | |||
| 1384 | NS_INTERFACE_MAP_ENTRY(nsIGlobalObject)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t <decltype(*this)>, nsIGlobalObject>)) foundInterface = static_cast<nsIGlobalObject*>(this); else | |||
| 1385 | NS_INTERFACE_MAP_ENTRY(nsIScriptGlobalObject)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t <decltype(*this)>, nsIScriptGlobalObject>)) foundInterface = static_cast<nsIScriptGlobalObject*>(this); else | |||
| 1386 | NS_INTERFACE_MAP_ENTRY(nsIScriptObjectPrincipal)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t <decltype(*this)>, nsIScriptObjectPrincipal>)) foundInterface = static_cast<nsIScriptObjectPrincipal*>(this); else | |||
| 1387 | 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 | |||
| 1388 | NS_INTERFACE_MAP_ENTRY(nsPIDOMWindowInner)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t <decltype(*this)>, nsPIDOMWindowInner>)) foundInterface = static_cast<nsPIDOMWindowInner*>(this); else | |||
| 1389 | NS_INTERFACE_MAP_ENTRY(mozIDOMWindow)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t <decltype(*this)>, mozIDOMWindow>)) foundInterface = static_cast<mozIDOMWindow*>(this); else | |||
| 1390 | NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t <decltype(*this)>, nsISupportsWeakReference>)) foundInterface = static_cast<nsISupportsWeakReference*>(this); else | |||
| 1391 | NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t <decltype(*this)>, nsIInterfaceRequestor>)) foundInterface = static_cast<nsIInterfaceRequestor*>(this); else | |||
| 1392 | NS_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" , 1392); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aIID.Equals((nsISupports::kIID))" ")"); do { MOZ_CrashSequence(__null, 1392); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); status = NS_NOINTERFACE ; } else { (foundInterface)->AddRef(); status = NS_OK; } * aInstancePtr = foundInterface; return status; } | |||
| 1393 | ||||
| 1394 | NS_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" , 1394); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0" ") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 1394 ); __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; } | |||
| 1395 | NS_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" , 1395); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0" ") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 1395 ); __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); } | |||
| 1396 | ||||
| 1397 | NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsGlobalWindowInner)bool nsGlobalWindowInner::cycleCollection::CanSkipReal( void* p, [[maybe_unused]] bool aRemovingAllowed) { nsGlobalWindowInner * tmp = DowncastCCParticipant<nsGlobalWindowInner>(p); | |||
| 1398 | if (tmp->IsBlackForCC(false)) { | |||
| 1399 | if (nsCCUncollectableMarker::InGeneration(tmp->mCanSkipCCGeneration)) { | |||
| 1400 | return true; | |||
| 1401 | } | |||
| 1402 | tmp->mCanSkipCCGeneration = nsCCUncollectableMarker::sGeneration; | |||
| 1403 | if (EventListenerManager* elm = tmp->GetExistingListenerManager()) { | |||
| 1404 | elm->MarkForCC(); | |||
| 1405 | } | |||
| 1406 | if (tmp->mTimeoutManager) { | |||
| 1407 | tmp->mTimeoutManager->UnmarkGrayTimers(); | |||
| 1408 | } | |||
| 1409 | return true; | |||
| 1410 | } | |||
| 1411 | NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END(void)tmp; return false; } | |||
| 1412 | ||||
| 1413 | NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(nsGlobalWindowInner)bool nsGlobalWindowInner::cycleCollection::CanSkipInCCReal(void * p) { nsGlobalWindowInner* tmp = DowncastCCParticipant<nsGlobalWindowInner >(p); | |||
| 1414 | return tmp->IsBlackForCC(true); | |||
| 1415 | NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END(void)tmp; return false; } | |||
| 1416 | ||||
| 1417 | NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(nsGlobalWindowInner)bool nsGlobalWindowInner::cycleCollection::CanSkipThisReal(void * p) { nsGlobalWindowInner* tmp = DowncastCCParticipant<nsGlobalWindowInner >(p); | |||
| 1418 | return tmp->IsBlackForCC(false); | |||
| 1419 | NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END(void)tmp; return false; } | |||
| 1420 | ||||
| 1421 | NS_IMPL_CYCLE_COLLECTION_CLASS(nsGlobalWindowInner)nsGlobalWindowInner::cycleCollection nsGlobalWindowInner::_cycleCollectorGlobal ; | |||
| 1422 | ||||
| 1423 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGlobalWindowInner)nsresult nsGlobalWindowInner::cycleCollection::TraverseNative ( void* p, nsCycleCollectionTraversalCallback& cb) { nsGlobalWindowInner * tmp = DowncastCCParticipant<nsGlobalWindowInner>(p); | |||
| 1424 | if (MOZ_UNLIKELY(cb.WantDebugInfo())(__builtin_expect(!!(cb.WantDebugInfo()), 0))) { | |||
| 1425 | char name[512]; | |||
| 1426 | nsAutoCString uri; | |||
| 1427 | if (tmp->mDoc && tmp->mDoc->GetDocumentURI()) { | |||
| 1428 | uri = tmp->mDoc->GetDocumentURI()->GetSpecOrDefault(); | |||
| 1429 | } | |||
| 1430 | SprintfLiteral(name, "nsGlobalWindowInner # %" PRIu64"l" "u" " inner %s", | |||
| 1431 | tmp->mWindowID, uri.get()); | |||
| 1432 | cb.DescribeRefCountedNode(tmp->mRefCnt.get(), name); | |||
| 1433 | } else { | |||
| 1434 | NS_IMPL_CYCLE_COLLECTION_DESCRIBE(nsGlobalWindowInner, tmp->mRefCnt.get())cb.DescribeRefCountedNode(tmp->mRefCnt.get(), "nsGlobalWindowInner" ); | |||
| 1435 | } | |||
| 1436 | ||||
| 1437 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNavigation)ImplCycleCollectionTraverse(cb, tmp->mNavigation, "mNavigation" , 0); | |||
| 1438 | ||||
| 1439 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNavigator)ImplCycleCollectionTraverse(cb, tmp->mNavigator, "mNavigator" , 0); | |||
| 1440 | ||||
| 1441 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPerformance)ImplCycleCollectionTraverse(cb, tmp->mPerformance, "mPerformance" , 0); | |||
| 1442 | ||||
| 1443 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWebTaskScheduler)ImplCycleCollectionTraverse(cb, tmp->mWebTaskScheduler, "mWebTaskScheduler" , 0); | |||
| 1444 | ||||
| 1445 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTrustedTypePolicyFactory)ImplCycleCollectionTraverse(cb, tmp->mTrustedTypePolicyFactory , "mTrustedTypePolicyFactory", 0); | |||
| 1446 | ||||
| 1447 | #ifdef MOZ_WEBSPEECH1 | |||
| 1448 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSpeechSynthesis)ImplCycleCollectionTraverse(cb, tmp->mSpeechSynthesis, "mSpeechSynthesis" , 0); | |||
| 1449 | #endif | |||
| 1450 | ||||
| 1451 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGlean)ImplCycleCollectionTraverse(cb, tmp->mGlean, "mGlean", 0); | |||
| 1452 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGleanPings)ImplCycleCollectionTraverse(cb, tmp->mGleanPings, "mGleanPings" , 0); | |||
| 1453 | ||||
| 1454 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOuterWindow)ImplCycleCollectionTraverse(cb, tmp->mOuterWindow, "mOuterWindow" , 0); | |||
| 1455 | ||||
| 1456 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTopInnerWindow)ImplCycleCollectionTraverse(cb, tmp->mTopInnerWindow, "mTopInnerWindow" , 0); | |||
| 1457 | ||||
| 1458 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mListenerManager)ImplCycleCollectionTraverse(cb, tmp->mListenerManager, "mListenerManager" , 0); | |||
| 1459 | ||||
| 1460 | if (tmp->mTimeoutManager) { | |||
| 1461 | tmp->mTimeoutManager->ForEachUnorderedTimeout([&cb](Timeout* timeout) { | |||
| 1462 | cb.NoteNativeChild(timeout, NS_CYCLE_COLLECTION_PARTICIPANT(Timeout)Timeout::cycleCollection::GetParticipant()); | |||
| 1463 | }); | |||
| 1464 | } | |||
| 1465 | ||||
| 1466 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLocation)ImplCycleCollectionTraverse(cb, tmp->mLocation, "mLocation" , 0); | |||
| 1467 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mHistory)ImplCycleCollectionTraverse(cb, tmp->mHistory, "mHistory", 0); | |||
| 1468 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCustomElements)ImplCycleCollectionTraverse(cb, tmp->mCustomElements, "mCustomElements" , 0); | |||
| 1469 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSharedWorkers)ImplCycleCollectionTraverse(cb, tmp->mSharedWorkers, "mSharedWorkers" , 0); | |||
| 1470 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLocalStorage)ImplCycleCollectionTraverse(cb, tmp->mLocalStorage, "mLocalStorage" , 0); | |||
| 1471 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSessionStorage)ImplCycleCollectionTraverse(cb, tmp->mSessionStorage, "mSessionStorage" , 0); | |||
| 1472 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIndexedDB)ImplCycleCollectionTraverse(cb, tmp->mIndexedDB, "mIndexedDB" , 0); | |||
| 1473 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentPrincipal)ImplCycleCollectionTraverse(cb, tmp->mDocumentPrincipal, "mDocumentPrincipal" , 0); | |||
| 1474 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentCookiePrincipal)ImplCycleCollectionTraverse(cb, tmp->mDocumentCookiePrincipal , "mDocumentCookiePrincipal", 0); | |||
| 1475 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentStoragePrincipal)ImplCycleCollectionTraverse(cb, tmp->mDocumentStoragePrincipal , "mDocumentStoragePrincipal", 0); | |||
| 1476 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentPartitionedPrincipal)ImplCycleCollectionTraverse(cb, tmp->mDocumentPartitionedPrincipal , "mDocumentPartitionedPrincipal", 0); | |||
| 1477 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentPolicyContainer)ImplCycleCollectionTraverse(cb, tmp->mDocumentPolicyContainer , "mDocumentPolicyContainer", 0); | |||
| 1478 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBrowserChild)ImplCycleCollectionTraverse(cb, tmp->mBrowserChild, "mBrowserChild" , 0); | |||
| 1479 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDoc)ImplCycleCollectionTraverse(cb, tmp->mDoc, "mDoc", 0); | |||
| 1480 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWebIdentityHandler)ImplCycleCollectionTraverse(cb, tmp->mWebIdentityHandler, "mWebIdentityHandler" , 0); | |||
| 1481 | ||||
| 1482 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIdleRequestExecutor)ImplCycleCollectionTraverse(cb, tmp->mIdleRequestExecutor, "mIdleRequestExecutor", 0); | |||
| 1483 | for (IdleRequest* request : tmp->mIdleRequestCallbacks) { | |||
| 1484 | cb.NoteNativeChild(request, NS_CYCLE_COLLECTION_PARTICIPANT(IdleRequest)IdleRequest::cycleCollection::GetParticipant()); | |||
| 1485 | } | |||
| 1486 | ||||
| 1487 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mClientSource)ImplCycleCollectionTraverse(cb, tmp->mClientSource, "mClientSource" , 0); | |||
| 1488 | ||||
| 1489 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGamepads)ImplCycleCollectionTraverse(cb, tmp->mGamepads, "mGamepads" , 0); | |||
| 1490 | ||||
| 1491 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCacheStorage)ImplCycleCollectionTraverse(cb, tmp->mCacheStorage, "mCacheStorage" , 0); | |||
| 1492 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mVRDisplays)ImplCycleCollectionTraverse(cb, tmp->mVRDisplays, "mVRDisplays" , 0); | |||
| 1493 | ||||
| 1494 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDebuggerNotificationManager)ImplCycleCollectionTraverse(cb, tmp->mDebuggerNotificationManager , "mDebuggerNotificationManager", 0); | |||
| 1495 | ||||
| 1496 | // Traverse stuff from nsPIDOMWindow | |||
| 1497 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChromeEventHandler)ImplCycleCollectionTraverse(cb, tmp->mChromeEventHandler, "mChromeEventHandler" , 0); | |||
| 1498 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParentTarget)ImplCycleCollectionTraverse(cb, tmp->mParentTarget, "mParentTarget" , 0); | |||
| 1499 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFocusedElement)ImplCycleCollectionTraverse(cb, tmp->mFocusedElement, "mFocusedElement" , 0); | |||
| 1500 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBrowsingContext)ImplCycleCollectionTraverse(cb, tmp->mBrowsingContext, "mBrowsingContext" , 0); | |||
| 1501 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindowGlobalChild)ImplCycleCollectionTraverse(cb, tmp->mWindowGlobalChild, "mWindowGlobalChild" , 0); | |||
| 1502 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCloseWatcherManager)ImplCycleCollectionTraverse(cb, tmp->mCloseWatcherManager, "mCloseWatcherManager", 0); | |||
| 1503 | ||||
| 1504 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMenubar)ImplCycleCollectionTraverse(cb, tmp->mMenubar, "mMenubar", 0); | |||
| 1505 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mToolbar)ImplCycleCollectionTraverse(cb, tmp->mToolbar, "mToolbar", 0); | |||
| 1506 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLocationbar)ImplCycleCollectionTraverse(cb, tmp->mLocationbar, "mLocationbar" , 0); | |||
| 1507 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPersonalbar)ImplCycleCollectionTraverse(cb, tmp->mPersonalbar, "mPersonalbar" , 0); | |||
| 1508 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStatusbar)ImplCycleCollectionTraverse(cb, tmp->mStatusbar, "mStatusbar" , 0); | |||
| 1509 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mScrollbars)ImplCycleCollectionTraverse(cb, tmp->mScrollbars, "mScrollbars" , 0); | |||
| 1510 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCrypto)ImplCycleCollectionTraverse(cb, tmp->mCrypto, "mCrypto", 0 ); | |||
| 1511 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mConsole)ImplCycleCollectionTraverse(cb, tmp->mConsole, "mConsole", 0); | |||
| 1512 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCookieStore)ImplCycleCollectionTraverse(cb, tmp->mCookieStore, "mCookieStore" , 0); | |||
| 1513 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentPiP)ImplCycleCollectionTraverse(cb, tmp->mDocumentPiP, "mDocumentPiP" , 0); | |||
| 1514 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPushManager)ImplCycleCollectionTraverse(cb, tmp->mPushManager, "mPushManager" , 0); | |||
| 1515 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPaintWorklet)ImplCycleCollectionTraverse(cb, tmp->mPaintWorklet, "mPaintWorklet" , 0); | |||
| 1516 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mExternal)ImplCycleCollectionTraverse(cb, tmp->mExternal, "mExternal" , 0); | |||
| 1517 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIntlUtils)ImplCycleCollectionTraverse(cb, tmp->mIntlUtils, "mIntlUtils" , 0); | |||
| 1518 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mVisualViewport)ImplCycleCollectionTraverse(cb, tmp->mVisualViewport, "mVisualViewport" , 0); | |||
| 1519 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCurrentPasteDataTransfer)ImplCycleCollectionTraverse(cb, tmp->mCurrentPasteDataTransfer , "mCurrentPasteDataTransfer", 0); | |||
| 1520 | ||||
| 1521 | tmp->TraverseObjectsInGlobal(cb); | |||
| 1522 | ||||
| 1523 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChromeFields.mMessageManager)ImplCycleCollectionTraverse(cb, tmp->mChromeFields.mMessageManager , "mChromeFields.mMessageManager", 0); | |||
| 1524 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChromeFields.mGroupMessageManagers)ImplCycleCollectionTraverse(cb, tmp->mChromeFields.mGroupMessageManagers , "mChromeFields.mGroupMessageManagers", 0); | |||
| 1525 | ||||
| 1526 | for (size_t i = 0; i < tmp->mDocumentFlushedResolvers.Length(); i++) { | |||
| 1527 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentFlushedResolvers[i]->mPromise)ImplCycleCollectionTraverse(cb, tmp->mDocumentFlushedResolvers [i]->mPromise, "mDocumentFlushedResolvers[i]->mPromise" , 0);; | |||
| 1528 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentFlushedResolvers[i]->mCallback)ImplCycleCollectionTraverse(cb, tmp->mDocumentFlushedResolvers [i]->mCallback, "mDocumentFlushedResolvers[i]->mCallback" , 0);; | |||
| 1529 | } | |||
| 1530 | ||||
| 1531 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END(void)tmp; return NS_OK; } | |||
| 1532 | ||||
| 1533 | NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGlobalWindowInner)void nsGlobalWindowInner::cycleCollection::Unlink(void* p) { nsGlobalWindowInner * tmp = DowncastCCParticipant<nsGlobalWindowInner>(p); | |||
| 1534 | NS_IMPL_CYCLE_COLLECTION_UNLINK_WEAK_REFERENCEtmp->ClearWeakReferences(); | |||
| 1535 | if (sInnerWindowsById) { | |||
| 1536 | sInnerWindowsById->Remove(tmp->mWindowID); | |||
| 1537 | } | |||
| 1538 | ||||
| 1539 | JSObject* wrapper = tmp->GetWrapperPreserveColor(); | |||
| 1540 | if (wrapper) { | |||
| 1541 | // Mark our realm as dead, so the JS engine won't hand out our | |||
| 1542 | // global after this point. | |||
| 1543 | JS::SetRealmNonLive(js::GetNonCCWObjectRealm(wrapper)); | |||
| 1544 | } | |||
| 1545 | ||||
| 1546 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mNavigation)ImplCycleCollectionUnlink(tmp->mNavigation); | |||
| 1547 | ||||
| 1548 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mNavigator)ImplCycleCollectionUnlink(tmp->mNavigator); | |||
| 1549 | ||||
| 1550 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mPerformance)ImplCycleCollectionUnlink(tmp->mPerformance); | |||
| 1551 | ||||
| 1552 | if (tmp->mWebTaskScheduler) { | |||
| 1553 | tmp->mWebTaskScheduler->Disconnect(); | |||
| 1554 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mWebTaskScheduler)ImplCycleCollectionUnlink(tmp->mWebTaskScheduler); | |||
| 1555 | } | |||
| 1556 | ||||
| 1557 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mTrustedTypePolicyFactory)ImplCycleCollectionUnlink(tmp->mTrustedTypePolicyFactory); | |||
| 1558 | ||||
| 1559 | #ifdef MOZ_WEBSPEECH1 | |||
| 1560 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mSpeechSynthesis)ImplCycleCollectionUnlink(tmp->mSpeechSynthesis); | |||
| 1561 | #endif | |||
| 1562 | ||||
| 1563 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mGlean)ImplCycleCollectionUnlink(tmp->mGlean); | |||
| 1564 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mGleanPings)ImplCycleCollectionUnlink(tmp->mGleanPings); | |||
| 1565 | ||||
| 1566 | if (tmp->mOuterWindow) { | |||
| 1567 | nsGlobalWindowOuter::Cast(tmp->mOuterWindow)->MaybeClearInnerWindow(tmp); | |||
| 1568 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mOuterWindow)ImplCycleCollectionUnlink(tmp->mOuterWindow); | |||
| 1569 | } | |||
| 1570 | ||||
| 1571 | if (tmp->mListenerManager) { | |||
| 1572 | tmp->mListenerManager->Disconnect(); | |||
| 1573 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mListenerManager)ImplCycleCollectionUnlink(tmp->mListenerManager); | |||
| 1574 | } | |||
| 1575 | ||||
| 1576 | // Here the Timeouts list would've been unlinked, but we rely on | |||
| 1577 | // that Timeout objects have been traced and will remove themselves | |||
| 1578 | // while unlinking. | |||
| 1579 | ||||
| 1580 | tmp->UpdateTopInnerWindow(); | |||
| 1581 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mTopInnerWindow)ImplCycleCollectionUnlink(tmp->mTopInnerWindow); | |||
| 1582 | ||||
| 1583 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mLocation)ImplCycleCollectionUnlink(tmp->mLocation); | |||
| 1584 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mHistory)ImplCycleCollectionUnlink(tmp->mHistory); | |||
| 1585 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mNavigation)ImplCycleCollectionUnlink(tmp->mNavigation); | |||
| 1586 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mCustomElements)ImplCycleCollectionUnlink(tmp->mCustomElements); | |||
| 1587 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mSharedWorkers)ImplCycleCollectionUnlink(tmp->mSharedWorkers); | |||
| 1588 | if (tmp->mLocalStorage) { | |||
| 1589 | tmp->mLocalStorage->Disconnect(); | |||
| 1590 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mLocalStorage)ImplCycleCollectionUnlink(tmp->mLocalStorage); | |||
| 1591 | } | |||
| 1592 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mSessionStorage)ImplCycleCollectionUnlink(tmp->mSessionStorage); | |||
| 1593 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mIndexedDB)ImplCycleCollectionUnlink(tmp->mIndexedDB); | |||
| 1594 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentPrincipal)ImplCycleCollectionUnlink(tmp->mDocumentPrincipal); | |||
| 1595 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentCookiePrincipal)ImplCycleCollectionUnlink(tmp->mDocumentCookiePrincipal); | |||
| 1596 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentStoragePrincipal)ImplCycleCollectionUnlink(tmp->mDocumentStoragePrincipal); | |||
| 1597 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentPartitionedPrincipal)ImplCycleCollectionUnlink(tmp->mDocumentPartitionedPrincipal ); | |||
| 1598 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentPolicyContainer)ImplCycleCollectionUnlink(tmp->mDocumentPolicyContainer); | |||
| 1599 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mBrowserChild)ImplCycleCollectionUnlink(tmp->mBrowserChild); | |||
| 1600 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mDoc)ImplCycleCollectionUnlink(tmp->mDoc); | |||
| 1601 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mWebIdentityHandler)ImplCycleCollectionUnlink(tmp->mWebIdentityHandler); | |||
| 1602 | ||||
| 1603 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mGamepads)ImplCycleCollectionUnlink(tmp->mGamepads); | |||
| 1604 | ||||
| 1605 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mCacheStorage)ImplCycleCollectionUnlink(tmp->mCacheStorage); | |||
| 1606 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mVRDisplays)ImplCycleCollectionUnlink(tmp->mVRDisplays); | |||
| 1607 | ||||
| 1608 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mDebuggerNotificationManager)ImplCycleCollectionUnlink(tmp->mDebuggerNotificationManager ); | |||
| 1609 | ||||
| 1610 | // Unlink stuff from nsPIDOMWindow | |||
| 1611 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mChromeEventHandler)ImplCycleCollectionUnlink(tmp->mChromeEventHandler); | |||
| 1612 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mParentTarget)ImplCycleCollectionUnlink(tmp->mParentTarget); | |||
| 1613 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mFocusedElement)ImplCycleCollectionUnlink(tmp->mFocusedElement); | |||
| 1614 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mBrowsingContext)ImplCycleCollectionUnlink(tmp->mBrowsingContext); | |||
| 1615 | ||||
| 1616 | 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", 1618); 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, 1618); __attribute__((nomerge )) ::abort(); } while (false); } } while (false) | |||
| 1617 | !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", 1618); 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, 1618); __attribute__((nomerge )) ::abort(); } while (false); } } while (false) | |||
| 1618 | "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", 1618); 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, 1618); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 1619 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindowGlobalChild)ImplCycleCollectionUnlink(tmp->mWindowGlobalChild); | |||
| 1620 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mCloseWatcherManager)ImplCycleCollectionUnlink(tmp->mCloseWatcherManager); | |||
| 1621 | ||||
| 1622 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mMenubar)ImplCycleCollectionUnlink(tmp->mMenubar); | |||
| 1623 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mToolbar)ImplCycleCollectionUnlink(tmp->mToolbar); | |||
| 1624 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mLocationbar)ImplCycleCollectionUnlink(tmp->mLocationbar); | |||
| 1625 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mPersonalbar)ImplCycleCollectionUnlink(tmp->mPersonalbar); | |||
| 1626 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mStatusbar)ImplCycleCollectionUnlink(tmp->mStatusbar); | |||
| 1627 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mScrollbars)ImplCycleCollectionUnlink(tmp->mScrollbars); | |||
| 1628 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mCrypto)ImplCycleCollectionUnlink(tmp->mCrypto); | |||
| 1629 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mConsole)ImplCycleCollectionUnlink(tmp->mConsole); | |||
| 1630 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mCookieStore)ImplCycleCollectionUnlink(tmp->mCookieStore); | |||
| 1631 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mPaintWorklet)ImplCycleCollectionUnlink(tmp->mPaintWorklet); | |||
| 1632 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mExternal)ImplCycleCollectionUnlink(tmp->mExternal); | |||
| 1633 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mIntlUtils)ImplCycleCollectionUnlink(tmp->mIntlUtils); | |||
| 1634 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mVisualViewport)ImplCycleCollectionUnlink(tmp->mVisualViewport); | |||
| 1635 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mCurrentPasteDataTransfer)ImplCycleCollectionUnlink(tmp->mCurrentPasteDataTransfer); | |||
| 1636 | ||||
| 1637 | tmp->UnlinkObjectsInGlobal(); | |||
| 1638 | ||||
| 1639 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mIdleRequestExecutor)ImplCycleCollectionUnlink(tmp->mIdleRequestExecutor); | |||
| 1640 | ||||
| 1641 | // Here the IdleRequest list would've been unlinked, but we rely on | |||
| 1642 | // that IdleRequest objects have been traced and will remove | |||
| 1643 | // themselves while unlinking. | |||
| 1644 | ||||
| 1645 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mClientSource)ImplCycleCollectionUnlink(tmp->mClientSource); | |||
| 1646 | ||||
| 1647 | if (tmp->IsChromeWindow()) { | |||
| 1648 | if (tmp->mChromeFields.mMessageManager) { | |||
| 1649 | static_cast<nsFrameMessageManager*>( | |||
| 1650 | tmp->mChromeFields.mMessageManager.get()) | |||
| 1651 | ->Disconnect(); | |||
| 1652 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mChromeFields.mMessageManager)ImplCycleCollectionUnlink(tmp->mChromeFields.mMessageManager ); | |||
| 1653 | } | |||
| 1654 | tmp->DisconnectAndClearGroupMessageManagers(); | |||
| 1655 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mChromeFields.mGroupMessageManagers)ImplCycleCollectionUnlink(tmp->mChromeFields.mGroupMessageManagers ); | |||
| 1656 | } | |||
| 1657 | ||||
| 1658 | for (size_t i = 0; i < tmp->mDocumentFlushedResolvers.Length(); i++) { | |||
| 1659 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentFlushedResolvers[i]->mPromise)ImplCycleCollectionUnlink(tmp->mDocumentFlushedResolvers[i ]->mPromise);; | |||
| 1660 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentFlushedResolvers[i]->mCallback)ImplCycleCollectionUnlink(tmp->mDocumentFlushedResolvers[i ]->mCallback);; | |||
| 1661 | } | |||
| 1662 | tmp->mDocumentFlushedResolvers.Clear(); | |||
| 1663 | ||||
| 1664 | NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPERtmp->ReleaseWrapper(p); | |||
| 1665 | NS_IMPL_CYCLE_COLLECTION_UNLINK_END(void)tmp; } | |||
| 1666 | ||||
| 1667 | #ifdef DEBUG1 | |||
| 1668 | void nsGlobalWindowInner::RiskyUnlink() { | |||
| 1669 | NS_CYCLE_COLLECTION_INNERNAME_cycleCollectorGlobal.Unlink(this); | |||
| 1670 | } | |||
| 1671 | #endif | |||
| 1672 | ||||
| 1673 | NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsGlobalWindowInner)void nsGlobalWindowInner::cycleCollection::Trace( void* p, [[ maybe_unused]] const TraceCallbacks& aCallbacks, [[maybe_unused ]] void* aClosure) { nsGlobalWindowInner* tmp = DowncastCCParticipant <nsGlobalWindowInner>(p); | |||
| 1674 | NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPERtmp->TraceWrapper(aCallbacks, aClosure); | |||
| 1675 | NS_IMPL_CYCLE_COLLECTION_TRACE_END(void)tmp; } | |||
| 1676 | ||||
| 1677 | bool nsGlobalWindowInner::IsBlackForCC(bool aTracingNeeded) { | |||
| 1678 | if (!nsCCUncollectableMarker::sGeneration) { | |||
| 1679 | return false; | |||
| 1680 | } | |||
| 1681 | ||||
| 1682 | return (nsCCUncollectableMarker::InGeneration(GetMarkedCCGeneration()) || | |||
| 1683 | HasKnownLiveWrapper()) && | |||
| 1684 | (!aTracingNeeded || HasNothingToTrace(ToSupports(this))); | |||
| 1685 | } | |||
| 1686 | ||||
| 1687 | //***************************************************************************** | |||
| 1688 | // nsGlobalWindowInner::nsIScriptGlobalObject | |||
| 1689 | //***************************************************************************** | |||
| 1690 | ||||
| 1691 | bool nsGlobalWindowInner::ShouldResistFingerprinting(RFPTarget aTarget) const { | |||
| 1692 | if (mDoc) { | |||
| 1693 | return mDoc->ShouldResistFingerprinting(aTarget); | |||
| 1694 | } | |||
| 1695 | return nsContentUtils::ShouldResistFingerprinting( | |||
| 1696 | "If we do not have a document then we do not have any context" | |||
| 1697 | "to make an informed RFP choice, so we fall back to the global pref", | |||
| 1698 | aTarget); | |||
| 1699 | } | |||
| 1700 | ||||
| 1701 | OriginTrials nsGlobalWindowInner::Trials() const { | |||
| 1702 | return OriginTrials::FromWindow(this); | |||
| 1703 | } | |||
| 1704 | ||||
| 1705 | FontFaceSet* nsGlobalWindowInner::GetFonts() { | |||
| 1706 | if (mDoc) { | |||
| 1707 | return mDoc->Fonts(); | |||
| 1708 | } | |||
| 1709 | return nullptr; | |||
| 1710 | } | |||
| 1711 | ||||
| 1712 | mozilla::Result<mozilla::ipc::PrincipalInfo, nsresult> | |||
| 1713 | nsGlobalWindowInner::GetStorageKey() { | |||
| 1714 | 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", 1714 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence(__null, 1714); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 1715 | ||||
| 1716 | nsIPrincipal* principal = GetEffectiveStoragePrincipal(); | |||
| 1717 | if (!principal) { | |||
| 1718 | return mozilla::Err(NS_ERROR_FAILURE); | |||
| 1719 | } | |||
| 1720 | ||||
| 1721 | mozilla::ipc::PrincipalInfo principalInfo; | |||
| 1722 | nsresult rv = PrincipalToPrincipalInfo(principal, &principalInfo); | |||
| 1723 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { | |||
| 1724 | return mozilla::Err(rv); | |||
| 1725 | } | |||
| 1726 | ||||
| 1727 | // Block expanded and null principals, let content and system through. | |||
| 1728 | if (principalInfo.type() != | |||
| 1729 | mozilla::ipc::PrincipalInfo::TContentPrincipalInfo && | |||
| 1730 | principalInfo.type() != | |||
| 1731 | mozilla::ipc::PrincipalInfo::TSystemPrincipalInfo) { | |||
| 1732 | return Err(NS_ERROR_DOM_SECURITY_ERR); | |||
| 1733 | } | |||
| 1734 | ||||
| 1735 | return std::move(principalInfo); | |||
| 1736 | } | |||
| 1737 | ||||
| 1738 | mozilla::dom::StorageManager* nsGlobalWindowInner::GetStorageManager() { | |||
| 1739 | return Navigator()->Storage(); | |||
| 1740 | } | |||
| 1741 | ||||
| 1742 | // https://html.spec.whatwg.org/multipage/web-messaging.html#eligible-for-messaging | |||
| 1743 | // * a Window object whose associated Document is fully active | |||
| 1744 | bool nsGlobalWindowInner::IsEligibleForMessaging() { return IsFullyActive(); } | |||
| 1745 | ||||
| 1746 | void nsGlobalWindowInner::ReportToConsole( | |||
| 1747 | uint32_t aErrorFlags, const nsCString& aCategory, PropertiesFile aFile, | |||
| 1748 | const nsCString& aMessageName, const nsTArray<nsString>& aParams, | |||
| 1749 | const mozilla::SourceLocation& aLocation) { | |||
| 1750 | nsContentUtils::ReportToConsole(aErrorFlags, aCategory, mDoc, aFile, | |||
| 1751 | aMessageName.get(), aParams, aLocation); | |||
| 1752 | } | |||
| 1753 | ||||
| 1754 | nsresult nsGlobalWindowInner::EnsureScriptEnvironment() { | |||
| 1755 | // NOTE: We can't use FORWARD_TO_OUTER here because we don't want to fail if | |||
| 1756 | // we're called on an inactive inner window. | |||
| 1757 | nsGlobalWindowOuter* outer = GetOuterWindowInternal(); | |||
| 1758 | if (!outer) { | |||
| 1759 | NS_WARNING("No outer window available!")NS_DebugBreak(NS_DEBUG_WARNING, "No outer window available!", nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp" , 1759); | |||
| 1760 | return NS_ERROR_FAILURE; | |||
| 1761 | } | |||
| 1762 | return outer->EnsureScriptEnvironment(); | |||
| 1763 | } | |||
| 1764 | ||||
| 1765 | nsIScriptContext* nsGlobalWindowInner::GetScriptContext() { | |||
| 1766 | nsGlobalWindowOuter* outer = GetOuterWindowInternal(); | |||
| 1767 | if (!outer) { | |||
| 1768 | return nullptr; | |||
| 1769 | } | |||
| 1770 | return outer->GetScriptContext(); | |||
| 1771 | } | |||
| 1772 | ||||
| 1773 | void nsGlobalWindowInner::TraceGlobalJSObject(JSTracer* aTrc) { | |||
| 1774 | TraceWrapper(aTrc, "active window global"); | |||
| 1775 | } | |||
| 1776 | ||||
| 1777 | void nsGlobalWindowInner::UpdateAutoplayPermission() { | |||
| 1778 | if (!GetWindowContext()) { | |||
| 1779 | return; | |||
| 1780 | } | |||
| 1781 | uint32_t perm = | |||
| 1782 | media::AutoplayPolicy::GetSiteAutoplayPermission(GetPrincipal()); | |||
| 1783 | if (GetWindowContext()->GetAutoplayPermission() == perm) { | |||
| 1784 | return; | |||
| 1785 | } | |||
| 1786 | ||||
| 1787 | // Setting autoplay permission on a discarded context has no effect. | |||
| 1788 | (void)GetWindowContext()->SetAutoplayPermission(perm); | |||
| 1789 | } | |||
| 1790 | ||||
| 1791 | void nsGlobalWindowInner::UpdateShortcutsPermission() { | |||
| 1792 | if (!GetWindowContext() || | |||
| 1793 | !GetWindowContext()->GetBrowsingContext()->IsTop()) { | |||
| 1794 | // We only cache the shortcuts permission on top-level WindowContexts | |||
| 1795 | // since we always check the top-level principal for the permission. | |||
| 1796 | return; | |||
| 1797 | } | |||
| 1798 | ||||
| 1799 | uint32_t perm = GetShortcutsPermission(GetPrincipal()); | |||
| 1800 | ||||
| 1801 | if (GetWindowContext()->GetShortcutsPermission() == perm) { | |||
| 1802 | return; | |||
| 1803 | } | |||
| 1804 | ||||
| 1805 | // If the WindowContext is discarded this has no effect. | |||
| 1806 | (void)GetWindowContext()->SetShortcutsPermission(perm); | |||
| 1807 | } | |||
| 1808 | ||||
| 1809 | /* static */ | |||
| 1810 | uint32_t nsGlobalWindowInner::GetShortcutsPermission(nsIPrincipal* aPrincipal) { | |||
| 1811 | uint32_t perm = nsIPermissionManager::DENY_ACTION; | |||
| 1812 | nsCOMPtr<nsIPermissionManager> permMgr = | |||
| 1813 | mozilla::components::PermissionManager::Service(); | |||
| 1814 | if (aPrincipal && permMgr) { | |||
| 1815 | permMgr->TestExactPermissionFromPrincipal(aPrincipal, "shortcuts"_ns, | |||
| 1816 | &perm); | |||
| 1817 | } | |||
| 1818 | return perm; | |||
| 1819 | } | |||
| 1820 | ||||
| 1821 | void nsGlobalWindowInner::UpdatePopupPermission() { | |||
| 1822 | if (!GetWindowContext()) { | |||
| 1823 | return; | |||
| 1824 | } | |||
| 1825 | ||||
| 1826 | uint32_t perm = PopupBlocker::GetPopupPermission(GetPrincipal()); | |||
| 1827 | if (GetWindowContext()->GetPopupPermission() == perm) { | |||
| 1828 | return; | |||
| 1829 | } | |||
| 1830 | ||||
| 1831 | // If the WindowContext is discarded this has no effect. | |||
| 1832 | (void)GetWindowContext()->SetPopupPermission(perm); | |||
| 1833 | } | |||
| 1834 | ||||
| 1835 | void nsGlobalWindowInner::UpdatePermissions() { | |||
| 1836 | if (!GetWindowContext()) { | |||
| 1837 | return; | |||
| 1838 | } | |||
| 1839 | ||||
| 1840 | nsCOMPtr<nsIPrincipal> principal = GetPrincipal(); | |||
| 1841 | RefPtr<WindowContext> windowContext = GetWindowContext(); | |||
| 1842 | ||||
| 1843 | WindowContext::Transaction txn; | |||
| 1844 | txn.SetAutoplayPermission( | |||
| 1845 | media::AutoplayPolicy::GetSiteAutoplayPermission(principal)); | |||
| 1846 | txn.SetPopupPermission(PopupBlocker::GetPopupPermission(principal)); | |||
| 1847 | ||||
| 1848 | if (windowContext->IsTop()) { | |||
| 1849 | txn.SetShortcutsPermission(GetShortcutsPermission(principal)); | |||
| 1850 | } | |||
| 1851 | ||||
| 1852 | // Setting permissions on a discarded WindowContext has no effect | |||
| 1853 | (void)txn.Commit(windowContext); | |||
| 1854 | } | |||
| 1855 | ||||
| 1856 | void nsGlobalWindowInner::InitDocumentDependentState(JSContext* aCx) { | |||
| 1857 | 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" , 1857); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mDoc" ")"); do { MOZ_CrashSequence(__null, 1857); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 1858 | ||||
| 1859 | if (MOZ_LOG_TEST(gDOMLeakPRLogInner, LogLevel::Debug)(__builtin_expect(!!(mozilla::detail::log_test(gDOMLeakPRLogInner , LogLevel::Debug)), 0))) { | |||
| 1860 | nsIURI* uri = mDoc->GetDocumentURI(); | |||
| 1861 | 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) | |||
| 1862 | ("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) | |||
| 1863 | 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); | |||
| 1864 | } | |||
| 1865 | ||||
| 1866 | mFocusedElement = nullptr; | |||
| 1867 | mLocalStorage = nullptr; | |||
| 1868 | mSessionStorage = nullptr; | |||
| 1869 | mPerformance = nullptr; | |||
| 1870 | if (mWebTaskScheduler) { | |||
| 1871 | mWebTaskScheduler->Disconnect(); | |||
| 1872 | mWebTaskScheduler = nullptr; | |||
| 1873 | SetWebTaskSchedulingState(nullptr); | |||
| 1874 | } | |||
| 1875 | ||||
| 1876 | // This must be called after nullifying the internal objects because here we | |||
| 1877 | // could recreate them, calling the getter methods, and store them into the JS | |||
| 1878 | // slots. If we nullify them after, the slot values and the objects will be | |||
| 1879 | // out of sync. | |||
| 1880 | ClearDocumentDependentSlots(aCx); | |||
| 1881 | ||||
| 1882 | if (!mWindowGlobalChild) { | |||
| 1883 | mWindowGlobalChild = WindowGlobalChild::Create(this); | |||
| 1884 | } else { | |||
| 1885 | // If the window global existed before the window, it must've come from the | |||
| 1886 | // AboutBlankInitializer | |||
| 1887 | 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", 1888); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsAboutBlankAllowQueryAndFragment(GetDocumentURI())" ") (" "AboutBlankInitializer should only be used with about:blank" ")"); do { MOZ_CrashSequence(__null, 1888); __attribute__((nomerge )) ::abort(); } while (false); } } while (false) | |||
| 1888 | "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", 1888); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsAboutBlankAllowQueryAndFragment(GetDocumentURI())" ") (" "AboutBlankInitializer should only be used with about:blank" ")"); do { MOZ_CrashSequence(__null, 1888); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 1889 | } | |||
| 1890 | 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" , 1892); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!GetWindowContext()->HasBeenUserGestureActivated()" ") (" "WindowContext should always not have user gesture activation at " "this point." ")"); do { MOZ_CrashSequence(__null, 1892); __attribute__ ((nomerge)) ::abort(); } while (false); } } while (false) | |||
| 1891 | "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" , 1892); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!GetWindowContext()->HasBeenUserGestureActivated()" ") (" "WindowContext should always not have user gesture activation at " "this point." ")"); do { MOZ_CrashSequence(__null, 1892); __attribute__ ((nomerge)) ::abort(); } while (false); } } while (false) | |||
| 1892 | "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" , 1892); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!GetWindowContext()->HasBeenUserGestureActivated()" ") (" "WindowContext should always not have user gesture activation at " "this point." ")"); do { MOZ_CrashSequence(__null, 1892); __attribute__ ((nomerge)) ::abort(); } while (false); } } while (false); | |||
| 1893 | ||||
| 1894 | UpdatePermissions(); | |||
| 1895 | ||||
| 1896 | RefPtr<PermissionDelegateHandler> permDelegateHandler = | |||
| 1897 | mDoc->GetPermissionDelegateHandler(); | |||
| 1898 | ||||
| 1899 | if (permDelegateHandler) { | |||
| 1900 | permDelegateHandler->PopulateAllDelegatedPermissions(); | |||
| 1901 | } | |||
| 1902 | ||||
| 1903 | #if defined(MOZ_WIDGET_ANDROID) | |||
| 1904 | // When we insert the new document to the window in the top-level browsing | |||
| 1905 | // context, we should reset the status of the request which is used for the | |||
| 1906 | // previous document. | |||
| 1907 | if (mWindowGlobalChild && GetBrowsingContext() && | |||
| 1908 | !GetBrowsingContext()->GetParent()) { | |||
| 1909 | // Return value of setting synced field should be checked. See bug 1656492. | |||
| 1910 | (void)GetBrowsingContext()->ResetGVAutoplayRequestStatus(); | |||
| 1911 | } | |||
| 1912 | #endif | |||
| 1913 | ||||
| 1914 | #ifdef DEBUG1 | |||
| 1915 | mLastOpenedURI = mDoc->GetDocumentURI(); | |||
| 1916 | #endif | |||
| 1917 | } | |||
| 1918 | ||||
| 1919 | nsresult nsGlobalWindowInner::EnsureClientSource() { | |||
| 1920 | 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" , 1920); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mDoc" ")"); do { MOZ_CrashSequence(__null, 1920); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 1921 | ||||
| 1922 | bool newClientSource = false; | |||
| 1923 | ||||
| 1924 | // Get the load info for the document if we performed a load. Be careful not | |||
| 1925 | // to look at local URLs, though. Local URLs are those that have a scheme of: | |||
| 1926 | // * about: | |||
| 1927 | // * data: | |||
| 1928 | // * blob: | |||
| 1929 | // We also do an additional check here so that we only treat about:blank | |||
| 1930 | // and about:srcdoc as local URLs. Other internal firefox about: URLs should | |||
| 1931 | // not be treated this way. | |||
| 1932 | nsCOMPtr<nsILoadInfo> loadInfo; | |||
| 1933 | nsCOMPtr<nsIChannel> channel = mDoc->GetChannel(); | |||
| 1934 | if (channel) { | |||
| 1935 | nsCOMPtr<nsIURI> uri; | |||
| 1936 | (void)channel->GetURI(getter_AddRefs(uri)); | |||
| 1937 | ||||
| 1938 | bool ignoreLoadInfo = false; | |||
| 1939 | ||||
| 1940 | if (uri->SchemeIs("about")) { | |||
| 1941 | ignoreLoadInfo = | |||
| 1942 | NS_IsAboutBlankAllowQueryAndFragment(uri) || NS_IsAboutSrcdoc(uri); | |||
| 1943 | } else { | |||
| 1944 | // Its not an about: URL, so now check for our other URL types. | |||
| 1945 | ignoreLoadInfo = uri->SchemeIs("data") || uri->SchemeIs("blob"); | |||
| 1946 | } | |||
| 1947 | ||||
| 1948 | if (!ignoreLoadInfo) { | |||
| 1949 | loadInfo = channel->LoadInfo(); | |||
| 1950 | } | |||
| 1951 | } | |||
| 1952 | ||||
| 1953 | // Take the initial client source from the docshell immediately. Even if we | |||
| 1954 | // don't end up using it here we should consume it. | |||
| 1955 | UniquePtr<ClientSource> initialClientSource; | |||
| 1956 | nsIDocShell* docshell = GetDocShell(); | |||
| 1957 | if (docshell) { | |||
| 1958 | initialClientSource = docshell->TakeInitialClientSource(); | |||
| 1959 | } | |||
| 1960 | ||||
| 1961 | // Try to get the reserved client from the LoadInfo. A Client is | |||
| 1962 | // reserved at the start of the channel load if there is not an | |||
| 1963 | // initial uncommitted about:blank whose window will be reused. It is also | |||
| 1964 | // created if the channel load encounters a cross-origin redirect. | |||
| 1965 | if (loadInfo) { | |||
| 1966 | UniquePtr<ClientSource> reservedClient = | |||
| 1967 | loadInfo->TakeReservedClientSource(); | |||
| 1968 | if (reservedClient) { | |||
| 1969 | mClientSource.reset(); | |||
| 1970 | mClientSource = std::move(reservedClient); | |||
| 1971 | newClientSource = true; | |||
| 1972 | } | |||
| 1973 | } | |||
| 1974 | ||||
| 1975 | // We don't have a LoadInfo reserved client, but maybe we should | |||
| 1976 | // be inheriting an initial one from the docshell. This means | |||
| 1977 | // that the docshell started the channel load before creating the | |||
| 1978 | // initial about:blank document. This is an optimization, though, | |||
| 1979 | // and it created an initial Client as a placeholder for the document. | |||
| 1980 | // In this case we want to inherit this placeholder Client here. | |||
| 1981 | if (!mClientSource) { | |||
| 1982 | mClientSource = std::move(initialClientSource); | |||
| 1983 | if (mClientSource) { | |||
| 1984 | newClientSource = true; | |||
| 1985 | } | |||
| 1986 | } | |||
| 1987 | ||||
| 1988 | nsCOMPtr<nsIPrincipal> foreignPartitionedPrincipal; | |||
| 1989 | ||||
| 1990 | nsresult rv = StoragePrincipalHelper::GetPrincipal( | |||
| 1991 | this, StoragePrincipalHelper::eForeignPartitionedPrincipal, | |||
| 1992 | getter_AddRefs(foreignPartitionedPrincipal)); | |||
| 1993 | 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" , 1993); return rv; } } while (false); | |||
| 1994 | ||||
| 1995 | // Verify the final ClientSource principal matches the final document | |||
| 1996 | // principal. The ClientChannelHelper handles things like network | |||
| 1997 | // redirects, but there are other ways the document principal can change. | |||
| 1998 | // For example, if something sets the nsIChannel.owner property, then | |||
| 1999 | // the final channel principal can be anything. Unfortunately there is | |||
| 2000 | // no good way to detect this until after the channel completes loading. | |||
| 2001 | // | |||
| 2002 | // For now we handle this just by reseting the ClientSource. This will | |||
| 2003 | // result in a new ClientSource with the correct principal being created. | |||
| 2004 | // To APIs like ServiceWorker and Clients API it will look like there was | |||
| 2005 | // an initial content page created that was then immediately replaced. | |||
| 2006 | // This is pretty close to what we are actually doing. | |||
| 2007 | if (mClientSource) { | |||
| 2008 | auto principalOrErr = mClientSource->Info().GetPrincipal(); | |||
| 2009 | nsCOMPtr<nsIPrincipal> clientPrincipal = | |||
| 2010 | principalOrErr.isOk() ? principalOrErr.unwrap() : nullptr; | |||
| 2011 | if (!clientPrincipal || | |||
| 2012 | !clientPrincipal->Equals(foreignPartitionedPrincipal)) { | |||
| 2013 | mClientSource.reset(); | |||
| 2014 | } | |||
| 2015 | } | |||
| 2016 | ||||
| 2017 | // If we don't have a reserved client or an initial client, then create | |||
| 2018 | // one now. This can happen in certain cases where we avoid preallocating | |||
| 2019 | // the client in the docshell. This mainly occurs in situations where | |||
| 2020 | // the principal is not clearly inherited from the parent; e.g. sandboxed | |||
| 2021 | // iframes, window.open(), etc. | |||
| 2022 | // | |||
| 2023 | // We also do this late ClientSource creation if the final document ended | |||
| 2024 | // up with a different principal. | |||
| 2025 | // | |||
| 2026 | // TODO: We may not be marking initial about:blank documents created | |||
| 2027 | // this way as controlled by a service worker properly. The | |||
| 2028 | // controller should be coming from the same place as the inheritted | |||
| 2029 | // principal. We do this in docshell, but as mentioned we aren't | |||
| 2030 | // smart enough to handle all cases yet. For example, a | |||
| 2031 | // window.open() with new URL should inherit the controller from | |||
| 2032 | // the opener, but we probably don't handle that yet. | |||
| 2033 | if (!mClientSource) { | |||
| 2034 | mClientSource = ClientManager::CreateSource( | |||
| 2035 | ClientType::Window, SerialEventTarget(), foreignPartitionedPrincipal); | |||
| 2036 | 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", 2036 ); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mClientSource" ")"); do { MOZ_CrashSequence(__null, 2036); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 2037 | newClientSource = true; | |||
| 2038 | ||||
| 2039 | // Note, we don't apply the loadinfo controller below if we create | |||
| 2040 | // the ClientSource here. | |||
| 2041 | } | |||
| 2042 | ||||
| 2043 | // The load may have started controlling the Client as well. If | |||
| 2044 | // so, mark it as controlled immediately here. The actor may | |||
| 2045 | // or may not have been notified by the parent side about being | |||
| 2046 | // controlled yet. | |||
| 2047 | // | |||
| 2048 | // Note: We should be careful not to control a client that was created late. | |||
| 2049 | // These clients were not seen by the ServiceWorkerManager when it | |||
| 2050 | // marked the LoadInfo controlled and it won't know about them. Its | |||
| 2051 | // also possible we are creating the client late due to the final | |||
| 2052 | // principal changing and these clients should definitely not be | |||
| 2053 | // controlled by a service worker with a different principal. | |||
| 2054 | else if (loadInfo) { | |||
| 2055 | const Maybe<ServiceWorkerDescriptor> controller = loadInfo->GetController(); | |||
| 2056 | if (controller.isSome()) { | |||
| 2057 | mClientSource->SetController(controller.ref()); | |||
| 2058 | } | |||
| 2059 | ||||
| 2060 | // We also have to handle the case where te initial about:blank is | |||
| 2061 | // controlled due to inheritting the service worker from its parent, | |||
| 2062 | // but the actual nsIChannel load is not covered by any service worker. | |||
| 2063 | // In this case we want the final page to be uncontrolled. There is | |||
| 2064 | // an open spec issue about how exactly this should be handled, but for | |||
| 2065 | // now we just force creation of a new ClientSource to clear the | |||
| 2066 | // controller. | |||
| 2067 | // | |||
| 2068 | // https://github.com/w3c/ServiceWorker/issues/1232 | |||
| 2069 | // | |||
| 2070 | else if (mClientSource->GetController().isSome()) { | |||
| 2071 | mClientSource.reset(); | |||
| 2072 | mClientSource = ClientManager::CreateSource( | |||
| 2073 | ClientType::Window, SerialEventTarget(), foreignPartitionedPrincipal); | |||
| 2074 | 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", 2074 ); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mClientSource" ")"); do { MOZ_CrashSequence(__null, 2074); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 2075 | newClientSource = true; | |||
| 2076 | } | |||
| 2077 | } | |||
| 2078 | ||||
| 2079 | if (mClientSource) { | |||
| 2080 | // Generally the policyContainer is stored within the Client and cached on | |||
| 2081 | // the document. At the time of policyContainer parsing however, the Client | |||
| 2082 | // has not been created yet, hence we store the policyContainer on the | |||
| 2083 | // document and propagate/sync the policyContainer with Client here when we | |||
| 2084 | // create the Client. | |||
| 2085 | mClientSource->SetPolicyContainer(mDoc->GetPolicyContainer()); | |||
| 2086 | ||||
| 2087 | DocGroup* docGroup = GetDocGroup(); | |||
| 2088 | 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" , 2088); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "docGroup" ")"); do { MOZ_CrashSequence(__null, 2088); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 2089 | mClientSource->SetAgentClusterId(docGroup->AgentClusterId()); | |||
| 2090 | ||||
| 2091 | if (mWindowGlobalChild) { | |||
| 2092 | mWindowGlobalChild->SendSetClientInfo(mClientSource->Info().ToIPC()); | |||
| 2093 | } | |||
| 2094 | } | |||
| 2095 | ||||
| 2096 | // Its possible that we got a client just after being frozen in | |||
| 2097 | // the bfcache. In that case freeze the client immediately. | |||
| 2098 | if (newClientSource && IsFrozen()) { | |||
| 2099 | mClientSource->Freeze(); | |||
| 2100 | } | |||
| 2101 | ||||
| 2102 | return NS_OK; | |||
| 2103 | } | |||
| 2104 | ||||
| 2105 | nsresult nsGlobalWindowInner::ExecutionReady() { | |||
| 2106 | nsresult rv = EnsureClientSource(); | |||
| 2107 | 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" , 2107); return rv; } } while (false); | |||
| 2108 | ||||
| 2109 | rv = mClientSource->WindowExecutionReady(this); | |||
| 2110 | 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" , 2110); return rv; } } while (false); | |||
| 2111 | ||||
| 2112 | return NS_OK; | |||
| 2113 | } | |||
| 2114 | ||||
| 2115 | void nsGlobalWindowInner::UpdateParentTarget() { | |||
| 2116 | // NOTE: This method is identical to | |||
| 2117 | // nsGlobalWindowOuter::UpdateParentTarget(). IF YOU UPDATE THIS METHOD, | |||
| 2118 | // UPDATE THE OTHER ONE TOO! | |||
| 2119 | ||||
| 2120 | // Try to get our frame element's tab child global (its in-process message | |||
| 2121 | // manager). If that fails, fall back to the chrome event handler's tab | |||
| 2122 | // child global, and if it doesn't have one, just use the chrome event | |||
| 2123 | // handler itself. | |||
| 2124 | ||||
| 2125 | nsPIDOMWindowOuter* outer = GetOuterWindow(); | |||
| 2126 | if (!outer) { | |||
| 2127 | return; | |||
| 2128 | } | |||
| 2129 | nsCOMPtr<Element> frameElement = outer->GetFrameElementInternal(); | |||
| 2130 | nsCOMPtr<EventTarget> eventTarget = | |||
| 2131 | nsContentUtils::TryGetBrowserChildGlobal(frameElement); | |||
| 2132 | ||||
| 2133 | if (!eventTarget) { | |||
| 2134 | nsGlobalWindowOuter* topWin = GetInProcessScriptableTopInternal(); | |||
| 2135 | if (topWin) { | |||
| 2136 | frameElement = topWin->GetFrameElementInternal(); | |||
| 2137 | eventTarget = nsContentUtils::TryGetBrowserChildGlobal(frameElement); | |||
| 2138 | } | |||
| 2139 | } | |||
| 2140 | ||||
| 2141 | if (!eventTarget) { | |||
| 2142 | eventTarget = nsContentUtils::TryGetBrowserChildGlobal(mChromeEventHandler); | |||
| 2143 | } | |||
| 2144 | ||||
| 2145 | if (!eventTarget) { | |||
| 2146 | eventTarget = mChromeEventHandler; | |||
| 2147 | } | |||
| 2148 | ||||
| 2149 | mParentTarget = std::move(eventTarget); | |||
| 2150 | } | |||
| 2151 | ||||
| 2152 | EventTarget* nsGlobalWindowInner::GetTargetForDOMEvent() { | |||
| 2153 | return GetOuterWindowInternal(); | |||
| 2154 | } | |||
| 2155 | ||||
| 2156 | void nsGlobalWindowInner::GetEventTargetParent(EventChainPreVisitor& aVisitor) { | |||
| 2157 | aVisitor.mCanHandle = true; | |||
| 2158 | aVisitor.mForceContentDispatch = true; // FIXME! Bug 329119 | |||
| 2159 | switch (aVisitor.mEvent->mMessage) { | |||
| 2160 | case eResize: | |||
| 2161 | if (aVisitor.mEvent->IsTrusted()) { | |||
| 2162 | // Checking whether the event target is an inner window or not, so we | |||
| 2163 | // can keep the old behavior also in case a child window is handling | |||
| 2164 | // resize. | |||
| 2165 | if (aVisitor.mEvent->mOriginalTarget && | |||
| 2166 | aVisitor.mEvent->mOriginalTarget->IsInnerWindow()) { | |||
| 2167 | mIsHandlingResizeEvent = true; | |||
| 2168 | } | |||
| 2169 | } | |||
| 2170 | break; | |||
| 2171 | case eMouseDown: | |||
| 2172 | if (aVisitor.mEvent->IsTrusted()) { | |||
| 2173 | sMouseDown = true; | |||
| 2174 | } | |||
| 2175 | break; | |||
| 2176 | case eMouseUp: | |||
| 2177 | case eDragEnd: | |||
| 2178 | if (aVisitor.mEvent->IsTrusted()) { | |||
| 2179 | MouseButtonReleased(); | |||
| 2180 | } | |||
| 2181 | break; | |||
| 2182 | default: | |||
| 2183 | break; | |||
| 2184 | } | |||
| 2185 | ||||
| 2186 | aVisitor.SetParentTarget(GetParentTarget(), true); | |||
| 2187 | } | |||
| 2188 | ||||
| 2189 | /* static */ | |||
| 2190 | void nsGlobalWindowInner::MouseButtonReleased() { | |||
| 2191 | if (!sMouseDown) { | |||
| 2192 | return; | |||
| 2193 | } | |||
| 2194 | sMouseDown = false; | |||
| 2195 | if (sDragServiceDisabled) { | |||
| 2196 | nsCOMPtr<nsIDragService> ds = | |||
| 2197 | do_GetService("@mozilla.org/widget/dragservice;1"); | |||
| 2198 | if (ds) { | |||
| 2199 | sDragServiceDisabled = false; | |||
| 2200 | ds->Unsuppress(); | |||
| 2201 | } | |||
| 2202 | } | |||
| 2203 | } | |||
| 2204 | ||||
| 2205 | // Editor library types for about:blank compat workaround | |||
| 2206 | enum class EmptyFrameLibrary { | |||
| 2207 | None, | |||
| 2208 | CKEditor, | |||
| 2209 | GWT, | |||
| 2210 | ZE, | |||
| 2211 | }; | |||
| 2212 | ||||
| 2213 | // ckeditor 4 uses UA sniffing to wait for an async load event for its editor | |||
| 2214 | // iframe. This patch makes it work by delaying the sync-about:blank's load | |||
| 2215 | // event on such frames. See bug 2002481 and: | |||
| 2216 | // https://github.com/ckeditor/ckeditor4/blob/c7e59ec199298b6b23f4aa7a7668f18572385bac/plugins/wysiwygarea/plugin.js#L43 | |||
| 2217 | // | |||
| 2218 | // GWT RichTextArea also uses UA sniffing and expects an async `load` event | |||
| 2219 | // for its editor iframe. See bug 2020927, | |||
| 2220 | // https://github.com/gwtproject/gwt/issues/10292 , and | |||
| 2221 | // https://github.com/gwtproject/gwt/blob/4b6a646faf0e9ce579658d78b6acf9fe5c840379/user/src/com/google/gwt/user/client/ui/impl/RichTextAreaImplMozilla.java#L44 | |||
| 2222 | // . | |||
| 2223 | // | |||
| 2224 | // Polarion appears to use the GWT Editor too, but with a different class name. | |||
| 2225 | // | |||
| 2226 | // Old version of ZE appears to have a similar problem. Newer versions don't, | |||
| 2227 | // because they have `srcdoc`. See bug 2020668. | |||
| 2228 | MOZ_CAN_RUN_SCRIPT static bool IsDeferredLoadEmptyFrame(Element& aEmbedder) { | |||
| 2229 | const nsAttrValue* classes = aEmbedder.GetClasses(); | |||
| 2230 | if (!classes) { | |||
| 2231 | return false; | |||
| 2232 | } | |||
| 2233 | EmptyFrameLibrary lib = EmptyFrameLibrary::None; | |||
| 2234 | if (StaticPrefs::dom_about_blank_ckeditor_hack_enabled() && | |||
| 2235 | classes->Contains(nsGkAtoms::cke_wysiwyg_frame, eCaseMatters)) { | |||
| 2236 | lib = EmptyFrameLibrary::CKEditor; | |||
| 2237 | } else if (StaticPrefs::dom_about_blank_gwt_hack_enabled() && | |||
| 2238 | classes->Contains(nsGkAtoms::gwt_RichTextArea, eCaseMatters)) { | |||
| 2239 | lib = EmptyFrameLibrary::GWT; | |||
| 2240 | } else if (StaticPrefs::dom_about_blank_polarion_gwt_hack_enabled() && | |||
| 2241 | classes->Contains(nsGkAtoms::polarion_rte_RichTextArea, | |||
| 2242 | eCaseMatters)) { | |||
| 2243 | lib = EmptyFrameLibrary::GWT; | |||
| 2244 | } else if (StaticPrefs::dom_about_blank_ze_hack_enabled() && | |||
| 2245 | classes->Contains(nsGkAtoms::ze_area, eCaseMatters)) { | |||
| 2246 | lib = EmptyFrameLibrary::ZE; | |||
| 2247 | } | |||
| 2248 | if (lib == EmptyFrameLibrary::None) { | |||
| 2249 | return false; | |||
| 2250 | } | |||
| 2251 | if (!aEmbedder.IsHTMLElement(nsGkAtoms::iframe)) { | |||
| 2252 | return false; | |||
| 2253 | } | |||
| 2254 | // We only come here if the initial document is reaching its load event. | |||
| 2255 | // That doesn't happen with `srcdoc`, which is an immediate navigation | |||
| 2256 | // to a non-about:blank document. Newer versions of ZE don't need this | |||
| 2257 | // and don't come here, because they have `srcdoc`. | |||
| 2258 | // Note: We can assert on `srcdoc` only after excluding non-iframe | |||
| 2259 | // element type above! | |||
| 2260 | 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", 2260 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aEmbedder.HasAttr(nsGkAtoms::srcdoc)" ")"); do { MOZ_CrashSequence(__null, 2260); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 2261 | const auto* src = aEmbedder.GetParsedAttr(nsGkAtoms::src); | |||
| 2262 | // Require empty src for CKEditor 4 and no src for GWT and ZE. | |||
| 2263 | switch (lib) { | |||
| 2264 | case EmptyFrameLibrary::CKEditor: | |||
| 2265 | if (!src || !src->IsEmptyString()) { | |||
| 2266 | return false; | |||
| 2267 | } | |||
| 2268 | break; | |||
| 2269 | default: | |||
| 2270 | if (src) { | |||
| 2271 | return false; | |||
| 2272 | } | |||
| 2273 | break; | |||
| 2274 | } | |||
| 2275 | const char* blocklistPref = ""; | |||
| 2276 | switch (lib) { | |||
| 2277 | case EmptyFrameLibrary::CKEditor: | |||
| 2278 | blocklistPref = "dom.about-blank-ckeditor-hack.disabled-domains"; | |||
| 2279 | break; | |||
| 2280 | case EmptyFrameLibrary::GWT: | |||
| 2281 | blocklistPref = "dom.about-blank-gwt-hack.disabled-domains"; | |||
| 2282 | break; | |||
| 2283 | case EmptyFrameLibrary::ZE: | |||
| 2284 | blocklistPref = "dom.about-blank-ze-hack.disabled-domains"; | |||
| 2285 | break; | |||
| 2286 | case EmptyFrameLibrary::None: | |||
| 2287 | 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", 2287); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") (" "MOZ_ASSERT_UNREACHABLE: " ")"); do { MOZ_CrashSequence(__null , 2287); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); | |||
| 2288 | return false; | |||
| 2289 | } | |||
| 2290 | ||||
| 2291 | // Deal with the blocklist here before properties on the global | |||
| 2292 | // (which is potentially observable via JS getters). | |||
| 2293 | if (aEmbedder.NodePrincipal()->IsURIInPrefList(blocklistPref)) { | |||
| 2294 | return false; | |||
| 2295 | } | |||
| 2296 | // Finally, we also look for an identifying property on the embedder's global | |||
| 2297 | // to be extra sure. | |||
| 2298 | RefPtr global = aEmbedder.GetRelevantGlobal(); | |||
| 2299 | if (!global || !global->GetGlobalJSObject()) { | |||
| 2300 | return false; | |||
| 2301 | } | |||
| 2302 | AutoJSAPI jsapi; | |||
| 2303 | if (!jsapi.Init(global)) { | |||
| 2304 | return false; | |||
| 2305 | } | |||
| 2306 | if (lib == EmptyFrameLibrary::GWT) { | |||
| 2307 | JS::Rooted<JSObject*> globalObj(jsapi.cx(), global->GetGlobalJSObject()); | |||
| 2308 | JS::Rooted<JS::Value> val(jsapi.cx()); | |||
| 2309 | if (!JS_GetProperty(jsapi.cx(), globalObj, "__gwt_stylesLoaded", &val)) { | |||
| 2310 | JS_ClearPendingException(jsapi.cx()); | |||
| 2311 | return false; | |||
| 2312 | } | |||
| 2313 | if (!val.isObject()) { | |||
| 2314 | return false; | |||
| 2315 | } | |||
| 2316 | aEmbedder.OwnerDoc()->WarnOnceAbout( | |||
| 2317 | DeprecatedOperations::eGWTRichTextAreaCompatHack); | |||
| 2318 | return true; | |||
| 2319 | } | |||
| 2320 | CkEditorProperty property; | |||
| 2321 | JS::Rooted<JS::Value> v(jsapi.cx(), | |||
| 2322 | JS::ObjectValue(*global->GetGlobalJSObject())); | |||
| 2323 | if (!property.Init(jsapi.cx(), v)) { | |||
| 2324 | JS_ClearPendingException(jsapi.cx()); | |||
| 2325 | return false; | |||
| 2326 | } | |||
| 2327 | switch (lib) { | |||
| 2328 | case EmptyFrameLibrary::GWT: | |||
| 2329 | case EmptyFrameLibrary::None: | |||
| 2330 | 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", 2330); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") (" "MOZ_ASSERT_UNREACHABLE: " ")"); do { MOZ_CrashSequence(__null , 2330); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); | |||
| 2331 | return false; | |||
| 2332 | case EmptyFrameLibrary::ZE: | |||
| 2333 | if (!property.mZE_Init.WasPassed()) { | |||
| 2334 | return false; | |||
| 2335 | } | |||
| 2336 | // No use counter at least for now. | |||
| 2337 | aEmbedder.OwnerDoc()->WarnOnceAbout( | |||
| 2338 | DeprecatedOperations::eOldZECompatHack); | |||
| 2339 | return true; | |||
| 2340 | case EmptyFrameLibrary::CKEditor: | |||
| 2341 | const auto* version = [&]() -> const CkEditorVersion* { | |||
| 2342 | if (property.mCKEDITOR.WasPassed()) { | |||
| 2343 | return &property.mCKEDITOR.Value(); | |||
| 2344 | } | |||
| 2345 | if (property.mJEDITOR.WasPassed()) { | |||
| 2346 | return &property.mJEDITOR.Value(); | |||
| 2347 | } | |||
| 2348 | return nullptr; | |||
| 2349 | }(); | |||
| 2350 | if (!version) { | |||
| 2351 | return false; | |||
| 2352 | } | |||
| 2353 | // The CKEditor source code has "%VERSION%", which may be left in place | |||
| 2354 | // in deployment if a proper build step is missing. | |||
| 2355 | if (!(StringBeginsWith(version->mVersion, u"4."_ns) || | |||
| 2356 | version->mVersion.EqualsLiteral(u"%VERSION%"))) { | |||
| 2357 | return false; | |||
| 2358 | } | |||
| 2359 | aEmbedder.OwnerDoc()->WarnOnceAbout( | |||
| 2360 | DeprecatedOperations::eCKEditor4CompatHack); | |||
| 2361 | return true; | |||
| 2362 | } | |||
| 2363 | 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" , 2363); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") (" "MOZ_ASSERT_UNREACHABLE: " "Every switch case should have returned." ")"); do { MOZ_CrashSequence(__null, 2363); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 2364 | return false; | |||
| 2365 | } | |||
| 2366 | ||||
| 2367 | MOZ_CAN_RUN_SCRIPT static bool NeedsAsyncLoadEventForInitialDocument( | |||
| 2368 | nsGlobalWindowInner& aInner, Element& aEmbedder) { | |||
| 2369 | if (auto* doc = aInner.GetExtantDoc(); !doc || !doc->IsInitialDocument()) { | |||
| 2370 | return false; | |||
| 2371 | } | |||
| 2372 | return IsDeferredLoadEmptyFrame(aEmbedder); | |||
| 2373 | } | |||
| 2374 | ||||
| 2375 | void nsGlobalWindowInner::FireFrameLoadEvent() { | |||
| 2376 | // If we're not in a content frame, or are at a BrowsingContext tree boundary, | |||
| 2377 | // such as the content-chrome boundary, don't fire the "load" event. | |||
| 2378 | if (GetBrowsingContext()->IsTopContent() || | |||
| 2379 | GetBrowsingContext()->IsChrome()) { | |||
| 2380 | return; | |||
| 2381 | } | |||
| 2382 | ||||
| 2383 | // If embedder is same-process, fire the event on our embedder element. | |||
| 2384 | // | |||
| 2385 | // XXX: Bug 1440212 is looking into potentially changing this behaviour to act | |||
| 2386 | // more like the remote case when in-process. | |||
| 2387 | if (RefPtr<Element> element = GetBrowsingContext()->GetEmbedderElement()) { | |||
| 2388 | if (NeedsAsyncLoadEventForInitialDocument(*this, *element)) { | |||
| 2389 | (new AsyncEventDispatcher(element, eLoad, CanBubble::eNo)) | |||
| 2390 | ->PostDOMEvent(); | |||
| 2391 | return; | |||
| 2392 | } | |||
| 2393 | ||||
| 2394 | nsEventStatus status = nsEventStatus_eIgnore; | |||
| 2395 | WidgetEvent event(/* aIsTrusted = */ true, eLoad); | |||
| 2396 | event.mFlags.mBubbles = false; | |||
| 2397 | event.mFlags.mCancelable = false; | |||
| 2398 | ||||
| 2399 | // Most of the time we could get a pres context to pass in here, but not | |||
| 2400 | // always (i.e. if this window is not shown there won't be a pres context | |||
| 2401 | // available). Since we're not firing a GUI event we don't need a pres | |||
| 2402 | // context anyway so we just pass null as the pres context all the time. | |||
| 2403 | EventDispatcher::Dispatch(element, nullptr, &event, nullptr, &status); | |||
| 2404 | return; | |||
| 2405 | } | |||
| 2406 | ||||
| 2407 | // We don't have an in-process embedder. Try to get our `BrowserChild` actor | |||
| 2408 | // to send a message to that embedder. We want to double-check that our outer | |||
| 2409 | // window is actually the one at the root of this browserChild though, just in | |||
| 2410 | // case. | |||
| 2411 | RefPtr<BrowserChild> browserChild = | |||
| 2412 | BrowserChild::GetFrom(static_cast<nsPIDOMWindowInner*>(this)); | |||
| 2413 | if (browserChild && | |||
| 2414 | !GetBrowsingContext()->GetParentWindowContext()->IsInProcess()) { | |||
| 2415 | // Double-check that our outer window is actually at the root of this | |||
| 2416 | // `BrowserChild`, in case we're in an odd maybe-unhosted situation like a | |||
| 2417 | // print preview dialog. | |||
| 2418 | nsCOMPtr<nsPIDOMWindowOuter> rootOuter = | |||
| 2419 | do_GetInterface(browserChild->WebNavigation()); | |||
| 2420 | if (!rootOuter || rootOuter != GetOuterWindow()) { | |||
| 2421 | return; | |||
| 2422 | } | |||
| 2423 | ||||
| 2424 | (void)browserChild->SendMaybeFireEmbedderLoadEvents( | |||
| 2425 | EmbedderElementEventType::LoadEvent); | |||
| 2426 | } | |||
| 2427 | } | |||
| 2428 | ||||
| 2429 | nsresult nsGlobalWindowInner::PostHandleEvent(EventChainPostVisitor& aVisitor) { | |||
| 2430 | // Return early if there is nothing to do. | |||
| 2431 | switch (aVisitor.mEvent->mMessage) { | |||
| 2432 | case eResize: | |||
| 2433 | case eUnload: | |||
| 2434 | case eLoad: | |||
| 2435 | break; | |||
| 2436 | default: | |||
| 2437 | return NS_OK; | |||
| 2438 | } | |||
| 2439 | ||||
| 2440 | /* mChromeEventHandler and mContext go dangling in the middle of this | |||
| 2441 | function under some circumstances (events that destroy the window) | |||
| 2442 | without this addref. */ | |||
| 2443 | RefPtr<EventTarget> kungFuDeathGrip1(mChromeEventHandler); | |||
| 2444 | (void)kungFuDeathGrip1; // These aren't referred to through the function | |||
| 2445 | nsCOMPtr<nsIScriptContext> kungFuDeathGrip2(GetContextInternal()); | |||
| 2446 | (void)kungFuDeathGrip2; // These aren't referred to through the function | |||
| 2447 | ||||
| 2448 | if (aVisitor.mEvent->mMessage == eResize) { | |||
| 2449 | mIsHandlingResizeEvent = false; | |||
| 2450 | } else if (aVisitor.mEvent->mMessage == eUnload && | |||
| 2451 | aVisitor.mEvent->IsTrusted()) { | |||
| 2452 | // If any VR display presentation is active at unload, the next page | |||
| 2453 | // will receive a vrdisplayactive event to indicate that it should | |||
| 2454 | // immediately begin vr presentation. This should occur when navigating | |||
| 2455 | // forwards, navigating backwards, and on page reload. | |||
| 2456 | for (const auto& display : mVRDisplays) { | |||
| 2457 | if (display->IsPresenting()) { | |||
| 2458 | display->StartVRNavigation(); | |||
| 2459 | // Save this VR display ID to trigger vrdisplayactivate event | |||
| 2460 | // after the next load event. | |||
| 2461 | nsGlobalWindowOuter* outer = GetOuterWindowInternal(); | |||
| 2462 | if (outer) { | |||
| 2463 | outer->SetAutoActivateVRDisplayID(display->DisplayId()); | |||
| 2464 | } | |||
| 2465 | ||||
| 2466 | // XXX The WebVR 1.1 spec does not define which of multiple VR | |||
| 2467 | // presenting VR displays will be chosen during navigation. | |||
| 2468 | // As the underlying platform VR API's currently only allow a single | |||
| 2469 | // VR display, it is safe to choose the first VR display for now. | |||
| 2470 | break; | |||
| 2471 | } | |||
| 2472 | } | |||
| 2473 | mIsDocumentLoaded = false; | |||
| 2474 | // Tell the parent process that the document is not loaded. | |||
| 2475 | if (mWindowGlobalChild) { | |||
| 2476 | mWindowGlobalChild->SendUpdateDocumentHasLoaded(mIsDocumentLoaded); | |||
| 2477 | mWindowGlobalChild->OnDocumentUnloaded(); | |||
| 2478 | } | |||
| 2479 | } else if (aVisitor.mEvent->mMessage == eLoad && | |||
| 2480 | aVisitor.mEvent->IsTrusted()) { | |||
| 2481 | // This is page load event since load events don't propagate to |window|. | |||
| 2482 | // @see Document::GetEventTargetParent. | |||
| 2483 | mIsDocumentLoaded = true; | |||
| 2484 | // Tell the parent process that the document is loaded. | |||
| 2485 | if (mWindowGlobalChild) { | |||
| 2486 | mWindowGlobalChild->SendUpdateDocumentHasLoaded(mIsDocumentLoaded); | |||
| 2487 | mWindowGlobalChild->OnDocumentLoaded(); | |||
| 2488 | } | |||
| 2489 | ||||
| 2490 | mTimeoutManager->OnDocumentLoaded(); | |||
| 2491 | ||||
| 2492 | 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" , 2492); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aVisitor.mEvent->IsTrusted()" ")"); do { MOZ_CrashSequence(__null, 2492); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 2493 | FireFrameLoadEvent(); | |||
| 2494 | ||||
| 2495 | if (mVREventObserver) { | |||
| 2496 | mVREventObserver->NotifyAfterLoad(); | |||
| 2497 | } | |||
| 2498 | ||||
| 2499 | uint32_t autoActivateVRDisplayID = 0; | |||
| 2500 | nsGlobalWindowOuter* outer = GetOuterWindowInternal(); | |||
| 2501 | if (outer) { | |||
| 2502 | autoActivateVRDisplayID = outer->GetAutoActivateVRDisplayID(); | |||
| 2503 | } | |||
| 2504 | if (autoActivateVRDisplayID) { | |||
| 2505 | DispatchVRDisplayActivate(autoActivateVRDisplayID, | |||
| 2506 | VRDisplayEventReason::Navigation); | |||
| 2507 | } | |||
| 2508 | } | |||
| 2509 | ||||
| 2510 | return NS_OK; | |||
| 2511 | } | |||
| 2512 | ||||
| 2513 | nsresult nsGlobalWindowInner::DefineArgumentsProperty(nsIArray* aArguments) { | |||
| 2514 | nsIScriptContext* ctx = GetOuterWindowInternal()->mContext; | |||
| 2515 | 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" , 2515); return NS_ERROR_NOT_INITIALIZED; } } while (false); | |||
| 2516 | ||||
| 2517 | JS::Rooted<JSObject*> obj(RootingCx(), GetWrapperPreserveColor()); | |||
| 2518 | return ctx->SetProperty(obj, "arguments", aArguments); | |||
| 2519 | } | |||
| 2520 | ||||
| 2521 | //***************************************************************************** | |||
| 2522 | // nsGlobalWindowInner::nsIScriptObjectPrincipal | |||
| 2523 | //***************************************************************************** | |||
| 2524 | ||||
| 2525 | nsIPrincipal* nsGlobalWindowInner::GetPrincipal() { | |||
| 2526 | if (mDoc) { | |||
| 2527 | // If we have a document, get the principal from the document | |||
| 2528 | return mDoc->NodePrincipal(); | |||
| 2529 | } | |||
| 2530 | ||||
| 2531 | if (mDocumentPrincipal) { | |||
| 2532 | return mDocumentPrincipal; | |||
| 2533 | } | |||
| 2534 | ||||
| 2535 | // If we don't have a principal and we don't have a document we | |||
| 2536 | // ask the parent window for the principal. This can happen when | |||
| 2537 | // loading a frameset that has a <frame src="javascript:xxx">, in | |||
| 2538 | // that case the global window is used in JS before we've loaded | |||
| 2539 | // a document into the window. | |||
| 2540 | ||||
| 2541 | nsCOMPtr<nsIScriptObjectPrincipal> objPrincipal = | |||
| 2542 | do_QueryInterface(GetInProcessParentInternal()); | |||
| 2543 | ||||
| 2544 | if (objPrincipal) { | |||
| 2545 | return objPrincipal->GetPrincipal(); | |||
| 2546 | } | |||
| 2547 | ||||
| 2548 | return nullptr; | |||
| 2549 | } | |||
| 2550 | ||||
| 2551 | nsIPrincipal* nsGlobalWindowInner::GetEffectiveCookiePrincipal() { | |||
| 2552 | if (mDoc) { | |||
| 2553 | // If we have a document, get the principal from the document | |||
| 2554 | return mDoc->EffectiveCookiePrincipal(); | |||
| 2555 | } | |||
| 2556 | ||||
| 2557 | if (mDocumentCookiePrincipal) { | |||
| 2558 | return mDocumentCookiePrincipal; | |||
| 2559 | } | |||
| 2560 | ||||
| 2561 | // If we don't have a cookie principal and we don't have a document we ask | |||
| 2562 | // the parent window for the cookie principal. | |||
| 2563 | ||||
| 2564 | nsCOMPtr<nsIScriptObjectPrincipal> objPrincipal = | |||
| 2565 | do_QueryInterface(GetInProcessParentInternal()); | |||
| 2566 | ||||
| 2567 | if (objPrincipal) { | |||
| 2568 | return objPrincipal->GetEffectiveCookiePrincipal(); | |||
| 2569 | } | |||
| 2570 | ||||
| 2571 | return nullptr; | |||
| 2572 | } | |||
| 2573 | ||||
| 2574 | nsIPrincipal* nsGlobalWindowInner::GetEffectiveStoragePrincipal() { | |||
| 2575 | if (mDoc) { | |||
| 2576 | // If we have a document, get the principal from the document | |||
| 2577 | return mDoc->EffectiveStoragePrincipal(); | |||
| 2578 | } | |||
| 2579 | ||||
| 2580 | if (mDocumentStoragePrincipal) { | |||
| 2581 | return mDocumentStoragePrincipal; | |||
| 2582 | } | |||
| 2583 | ||||
| 2584 | // If we don't have a cookie principal and we don't have a document we ask | |||
| 2585 | // the parent window for the cookie principal. | |||
| 2586 | ||||
| 2587 | nsCOMPtr<nsIScriptObjectPrincipal> objPrincipal = | |||
| 2588 | do_QueryInterface(GetInProcessParentInternal()); | |||
| 2589 | ||||
| 2590 | if (objPrincipal) { | |||
| 2591 | return objPrincipal->GetEffectiveStoragePrincipal(); | |||
| 2592 | } | |||
| 2593 | ||||
| 2594 | return nullptr; | |||
| 2595 | } | |||
| 2596 | ||||
| 2597 | nsIPrincipal* nsGlobalWindowInner::PartitionedPrincipal() { | |||
| 2598 | if (mDoc) { | |||
| 2599 | // If we have a document, get the principal from the document | |||
| 2600 | return mDoc->PartitionedPrincipal(); | |||
| 2601 | } | |||
| 2602 | ||||
| 2603 | if (mDocumentPartitionedPrincipal) { | |||
| 2604 | return mDocumentPartitionedPrincipal; | |||
| 2605 | } | |||
| 2606 | ||||
| 2607 | // If we don't have a partitioned principal and we don't have a document we | |||
| 2608 | // ask the parent window for the partitioned principal. | |||
| 2609 | ||||
| 2610 | nsCOMPtr<nsIScriptObjectPrincipal> objPrincipal = | |||
| 2611 | do_QueryInterface(GetInProcessParentInternal()); | |||
| 2612 | ||||
| 2613 | if (objPrincipal) { | |||
| 2614 | return objPrincipal->PartitionedPrincipal(); | |||
| 2615 | } | |||
| 2616 | ||||
| 2617 | return nullptr; | |||
| 2618 | } | |||
| 2619 | ||||
| 2620 | //***************************************************************************** | |||
| 2621 | // nsGlobalWindowInner::nsIDOMWindow | |||
| 2622 | //***************************************************************************** | |||
| 2623 | ||||
| 2624 | bool nsPIDOMWindowInner::AddAudioContext(AudioContext* aAudioContext) { | |||
| 2625 | mAudioContexts.AppendElement(aAudioContext); | |||
| 2626 | ||||
| 2627 | // Return true if the context should be muted and false if not. | |||
| 2628 | nsIDocShell* docShell = GetDocShell(); | |||
| 2629 | return docShell && !docShell->GetAllowMedia() && !aAudioContext->IsOffline(); | |||
| 2630 | } | |||
| 2631 | ||||
| 2632 | void nsPIDOMWindowInner::RemoveAudioContext(AudioContext* aAudioContext) { | |||
| 2633 | mAudioContexts.RemoveElement(aAudioContext); | |||
| 2634 | } | |||
| 2635 | ||||
| 2636 | void nsPIDOMWindowInner::MuteAudioContexts() { | |||
| 2637 | for (uint32_t i = 0; i < mAudioContexts.Length(); ++i) { | |||
| 2638 | if (!mAudioContexts[i]->IsOffline()) { | |||
| 2639 | mAudioContexts[i]->Mute(); | |||
| 2640 | } | |||
| 2641 | } | |||
| 2642 | } | |||
| 2643 | ||||
| 2644 | void nsPIDOMWindowInner::UnmuteAudioContexts() { | |||
| 2645 | for (uint32_t i = 0; i < mAudioContexts.Length(); ++i) { | |||
| 2646 | if (!mAudioContexts[i]->IsOffline()) { | |||
| 2647 | mAudioContexts[i]->Unmute(); | |||
| 2648 | } | |||
| 2649 | } | |||
| 2650 | } | |||
| 2651 | ||||
| 2652 | WindowProxyHolder nsGlobalWindowInner::Window() { | |||
| 2653 | return WindowProxyHolder(GetBrowsingContext()); | |||
| 2654 | } | |||
| 2655 | ||||
| 2656 | Navigation* nsPIDOMWindowInner::Navigation() { | |||
| 2657 | if (!mNavigation && Navigation::IsAPIEnabled()) { | |||
| 2658 | mNavigation = MakeRefPtr<mozilla::dom::Navigation>(this); | |||
| 2659 | } | |||
| 2660 | ||||
| 2661 | return mNavigation; | |||
| 2662 | } | |||
| 2663 | ||||
| 2664 | Navigator* nsPIDOMWindowInner::Navigator() { | |||
| 2665 | if (!mNavigator) { | |||
| 2666 | mNavigator = MakeRefPtr<mozilla::dom::Navigator>(this); | |||
| 2667 | } | |||
| 2668 | ||||
| 2669 | return mNavigator; | |||
| 2670 | } | |||
| 2671 | ||||
| 2672 | MediaDevices* nsPIDOMWindowInner::GetExtantMediaDevices() const { | |||
| 2673 | return mNavigator ? mNavigator->GetExtantMediaDevices() : nullptr; | |||
| 2674 | } | |||
| 2675 | ||||
| 2676 | VisualViewport* nsGlobalWindowInner::VisualViewport() { | |||
| 2677 | if (!mVisualViewport) { | |||
| 2678 | mVisualViewport = MakeRefPtr<mozilla::dom::VisualViewport>(this); | |||
| 2679 | } | |||
| 2680 | return mVisualViewport; | |||
| 2681 | } | |||
| 2682 | ||||
| 2683 | nsScreen* nsGlobalWindowInner::Screen() { | |||
| 2684 | if (!mScreen) { | |||
| 2685 | mScreen = nsScreen::Create(this); | |||
| 2686 | } | |||
| 2687 | return mScreen; | |||
| 2688 | } | |||
| 2689 | ||||
| 2690 | nsHistory* nsGlobalWindowInner::GetHistory(ErrorResult& aError) { | |||
| 2691 | if (!mHistory) { | |||
| 2692 | mHistory = MakeRefPtr<nsHistory>(this); | |||
| 2693 | } | |||
| 2694 | return mHistory; | |||
| 2695 | } | |||
| 2696 | ||||
| 2697 | CustomElementRegistry* nsGlobalWindowInner::CustomElements() { | |||
| 2698 | if (!mCustomElements) { | |||
| 2699 | mCustomElements = MakeRefPtr<CustomElementRegistry>(this); | |||
| 2700 | } | |||
| 2701 | ||||
| 2702 | return mCustomElements; | |||
| 2703 | } | |||
| 2704 | ||||
| 2705 | CustomElementRegistry* nsGlobalWindowInner::GetExistingCustomElements() { | |||
| 2706 | return mCustomElements; | |||
| 2707 | } | |||
| 2708 | ||||
| 2709 | Performance* nsPIDOMWindowInner::GetPerformance() { | |||
| 2710 | CreatePerformanceObjectIfNeeded(); | |||
| 2711 | return mPerformance; | |||
| 2712 | } | |||
| 2713 | ||||
| 2714 | void nsPIDOMWindowInner::QueuePerformanceNavigationTiming() { | |||
| 2715 | CreatePerformanceObjectIfNeeded(); | |||
| 2716 | if (mPerformance) { | |||
| 2717 | mPerformance->QueueNavigationTimingEntry(); | |||
| 2718 | } | |||
| 2719 | } | |||
| 2720 | ||||
| 2721 | void nsPIDOMWindowInner::CreatePerformanceObjectIfNeeded() { | |||
| 2722 | if (mPerformance || !mDoc) { | |||
| 2723 | return; | |||
| 2724 | } | |||
| 2725 | RefPtr<nsDOMNavigationTiming> timing = mDoc->GetNavigationTiming(); | |||
| 2726 | nsCOMPtr<nsITimedChannel> timedChannel(do_QueryInterface(mDoc->GetChannel())); | |||
| 2727 | if (timing) { | |||
| 2728 | mPerformance = Performance::CreateForMainThread(this, mDoc->NodePrincipal(), | |||
| 2729 | timing, timedChannel); | |||
| 2730 | } | |||
| 2731 | } | |||
| 2732 | ||||
| 2733 | bool nsPIDOMWindowInner::IsSecureContext() const { | |||
| 2734 | return nsGlobalWindowInner::Cast(this)->IsSecureContext(); | |||
| 2735 | } | |||
| 2736 | ||||
| 2737 | void nsPIDOMWindowInner::Suspend(bool aIncludeSubWindows) { | |||
| 2738 | nsGlobalWindowInner::Cast(this)->Suspend(aIncludeSubWindows); | |||
| 2739 | } | |||
| 2740 | ||||
| 2741 | void nsPIDOMWindowInner::Resume(bool aIncludeSubWindows) { | |||
| 2742 | nsGlobalWindowInner::Cast(this)->Resume(aIncludeSubWindows); | |||
| 2743 | } | |||
| 2744 | ||||
| 2745 | void nsPIDOMWindowInner::SyncStateFromParentWindow() { | |||
| 2746 | nsGlobalWindowInner::Cast(this)->SyncStateFromParentWindow(); | |||
| 2747 | } | |||
| 2748 | ||||
| 2749 | Maybe<ClientInfo> nsPIDOMWindowInner::GetClientInfo() const { | |||
| 2750 | return nsGlobalWindowInner::Cast(this)->GetClientInfo(); | |||
| 2751 | } | |||
| 2752 | ||||
| 2753 | Maybe<ClientState> nsPIDOMWindowInner::GetClientState() const { | |||
| 2754 | return nsGlobalWindowInner::Cast(this)->GetClientState(); | |||
| 2755 | } | |||
| 2756 | ||||
| 2757 | Maybe<ServiceWorkerDescriptor> nsPIDOMWindowInner::GetController() const { | |||
| 2758 | return nsGlobalWindowInner::Cast(this)->GetController(); | |||
| 2759 | } | |||
| 2760 | ||||
| 2761 | ClientSource* nsPIDOMWindowInner::GetClientSource() const { | |||
| 2762 | return nsGlobalWindowInner::Cast(this)->GetClientSource(); | |||
| 2763 | } | |||
| 2764 | ||||
| 2765 | void nsPIDOMWindowInner::SetPolicyContainer( | |||
| 2766 | nsIPolicyContainer* aPolicyContainer) { | |||
| 2767 | return nsGlobalWindowInner::Cast(this)->SetPolicyContainer(aPolicyContainer); | |||
| 2768 | } | |||
| 2769 | ||||
| 2770 | void nsPIDOMWindowInner::SetPreloadCsp(nsIContentSecurityPolicy* aPreloadCsp) { | |||
| 2771 | return nsGlobalWindowInner::Cast(this)->SetPreloadCsp(aPreloadCsp); | |||
| 2772 | } | |||
| 2773 | ||||
| 2774 | nsIPolicyContainer* nsPIDOMWindowInner::GetPolicyContainer() { | |||
| 2775 | return nsGlobalWindowInner::Cast(this)->GetPolicyContainer(); | |||
| 2776 | } | |||
| 2777 | ||||
| 2778 | void nsPIDOMWindowInner::NoteCalledRegisterForServiceWorkerScope( | |||
| 2779 | const nsACString& aScope) { | |||
| 2780 | nsGlobalWindowInner::Cast(this)->NoteCalledRegisterForServiceWorkerScope( | |||
| 2781 | aScope); | |||
| 2782 | } | |||
| 2783 | ||||
| 2784 | void nsPIDOMWindowInner::NoteDOMContentLoaded() { | |||
| 2785 | nsGlobalWindowInner::Cast(this)->NoteDOMContentLoaded(); | |||
| 2786 | } | |||
| 2787 | ||||
| 2788 | bool nsGlobalWindowInner::ShouldReportForServiceWorkerScope( | |||
| 2789 | const nsAString& aScope) { | |||
| 2790 | bool result = false; | |||
| 2791 | ||||
| 2792 | nsPIDOMWindowOuter* topOuter = GetInProcessScriptableTop(); | |||
| 2793 | 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", 2793 ); return false; } } while (false); | |||
| 2794 | ||||
| 2795 | nsGlobalWindowInner* topInner = | |||
| 2796 | nsGlobalWindowInner::Cast(topOuter->GetCurrentInnerWindow()); | |||
| 2797 | 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", 2797 ); return false; } } while (false); | |||
| 2798 | ||||
| 2799 | topInner->ShouldReportForServiceWorkerScopeInternal( | |||
| 2800 | NS_ConvertUTF16toUTF8(aScope), &result); | |||
| 2801 | return result; | |||
| 2802 | } | |||
| 2803 | ||||
| 2804 | void nsGlobalWindowInner::GetInstallTrigger( | |||
| 2805 | JSContext* aCx, JS::MutableHandle<JSObject*> aResult) { | |||
| 2806 | // Return nullptr, to avoid breaking "typeof InstallTrigger !== 'undefined" | |||
| 2807 | // "UA detection" use case. | |||
| 2808 | // | |||
| 2809 | // A pref ("extensions.InstallTrigger.enabled"), associated to this | |||
| 2810 | // property using the [Pref] extended attribute in Window.webidl, hides the | |||
| 2811 | // entire InstallTrigger property. | |||
| 2812 | // | |||
| 2813 | // See Bug 1754441 for more details about this deprecation. | |||
| 2814 | aResult.set(nullptr); | |||
| 2815 | } | |||
| 2816 | ||||
| 2817 | nsIDOMWindowUtils* nsGlobalWindowInner::GetWindowUtils(ErrorResult& aRv) { | |||
| 2818 | FORWARD_TO_OUTER_OR_THROW(WindowUtils, (), aRv, nullptr); | |||
| 2819 | } | |||
| 2820 | ||||
| 2821 | bool nsGlobalWindowInner::SynthesizeMouseEvent( | |||
| 2822 | const nsAString& aType, float aOffsetX, float aOffsetY, | |||
| 2823 | const SynthesizeMouseEventData& aMouseEventData, | |||
| 2824 | const SynthesizeMouseEventOptions& aOptions, | |||
| 2825 | const Optional<OwningNonNull<VoidFunction>>& aCallback, | |||
| 2826 | ErrorResult& aError) { | |||
| 2827 | nsIDocShell* docShell = GetDocShell(); | |||
| 2828 | RefPtr<PresShell> presShell = docShell ? docShell->GetPresShell() : nullptr; | |||
| 2829 | if (!presShell) { | |||
| 2830 | aError.Throw(NS_ERROR_FAILURE); | |||
| 2831 | return false; | |||
| 2832 | } | |||
| 2833 | ||||
| 2834 | nsPoint offset; | |||
| 2835 | nsCOMPtr<nsIWidget> widget = nsContentUtils::GetWidget(presShell, &offset); | |||
| 2836 | if (!widget) { | |||
| 2837 | aError.Throw(NS_ERROR_FAILURE); | |||
| 2838 | return false; | |||
| 2839 | } | |||
| 2840 | ||||
| 2841 | LayoutDeviceIntPoint refPoint = nsContentUtils::ToWidgetPoint( | |||
| 2842 | CSSPoint(aOffsetX, aOffsetY), offset, presShell->GetPresContext()); | |||
| 2843 | auto result = nsContentUtils::SynthesizeMouseEvent( | |||
| 2844 | presShell, widget, aType, refPoint, aMouseEventData, aOptions, aCallback); | |||
| 2845 | if (result.isErr()) { | |||
| 2846 | aError.Throw(result.unwrapErr()); | |||
| 2847 | return false; | |||
| 2848 | } | |||
| 2849 | ||||
| 2850 | return result.unwrap(); | |||
| 2851 | } | |||
| 2852 | ||||
| 2853 | bool nsGlobalWindowInner::SynthesizeTouchEvent( | |||
| 2854 | const nsAString& aType, const nsTArray<SynthesizeTouchEventData>& aTouches, | |||
| 2855 | const int32_t aModifiers, const SynthesizeTouchEventOptions& aOptions, | |||
| 2856 | const Optional<OwningNonNull<VoidFunction>>& aCallback, | |||
| 2857 | mozilla::ErrorResult& aError) { | |||
| 2858 | nsIDocShell* docShell = GetDocShell(); | |||
| 2859 | RefPtr<PresShell> presShell = docShell ? docShell->GetPresShell() : nullptr; | |||
| 2860 | if (!presShell) { | |||
| 2861 | aError.Throw(NS_ERROR_FAILURE); | |||
| 2862 | return false; | |||
| 2863 | } | |||
| 2864 | ||||
| 2865 | nsPoint offset; | |||
| 2866 | nsCOMPtr<nsIWidget> widget = nsContentUtils::GetWidget(presShell, &offset); | |||
| 2867 | if (!widget) { | |||
| 2868 | aError.Throw(NS_ERROR_FAILURE); | |||
| 2869 | return false; | |||
| 2870 | } | |||
| 2871 | ||||
| 2872 | RefPtr<nsPresContext> presContext = mDoc->GetPresContext(); | |||
| 2873 | if (!presContext) { | |||
| 2874 | aError.Throw(NS_ERROR_FAILURE); | |||
| 2875 | return false; | |||
| 2876 | } | |||
| 2877 | ||||
| 2878 | auto result = nsContentUtils::SynthesizeTouchEvent( | |||
| 2879 | presContext, widget, offset, aType, aTouches, aModifiers, aOptions, | |||
| 2880 | aCallback); | |||
| 2881 | if (result.isErr()) { | |||
| 2882 | aError.Throw(result.unwrapErr()); | |||
| 2883 | return false; | |||
| 2884 | } | |||
| 2885 | ||||
| 2886 | return result.unwrap(); | |||
| 2887 | } | |||
| 2888 | ||||
| 2889 | CallState nsGlobalWindowInner::ShouldReportForServiceWorkerScopeInternal( | |||
| 2890 | const nsACString& aScope, bool* aResultOut) { | |||
| 2891 | 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" , 2891); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "aResultOut" ")"); do { MOZ_CrashSequence(__null, 2891); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 2892 | ||||
| 2893 | // First check to see if this window is controlled. If so, then we have | |||
| 2894 | // found a match and are done. | |||
| 2895 | const Maybe<ServiceWorkerDescriptor> swd = GetController(); | |||
| 2896 | if (swd.isSome() && swd.ref().Scope() == aScope) { | |||
| 2897 | *aResultOut = true; | |||
| 2898 | return CallState::Stop; | |||
| 2899 | } | |||
| 2900 | ||||
| 2901 | // Next, check to see if this window has called | |||
| 2902 | // navigator.serviceWorker.register() for this scope. If so, then treat this | |||
| 2903 | // as a match so console reports appear in the devtools console. | |||
| 2904 | if (mClientSource && | |||
| 2905 | mClientSource->CalledRegisterForServiceWorkerScope(aScope)) { | |||
| 2906 | *aResultOut = true; | |||
| 2907 | return CallState::Stop; | |||
| 2908 | } | |||
| 2909 | ||||
| 2910 | // Finally check the current docshell nsILoadGroup to see if there are any | |||
| 2911 | // outstanding navigation requests. If so, match the scope against the | |||
| 2912 | // channel's URL. We want to show console reports during the FetchEvent | |||
| 2913 | // intercepting the navigation itself. | |||
| 2914 | nsCOMPtr<nsIDocumentLoader> loader(do_QueryInterface(GetDocShell())); | |||
| 2915 | if (loader) { | |||
| 2916 | nsCOMPtr<nsILoadGroup> loadgroup; | |||
| 2917 | (void)loader->GetLoadGroup(getter_AddRefs(loadgroup)); | |||
| 2918 | if (loadgroup) { | |||
| 2919 | nsCOMPtr<nsISimpleEnumerator> iter; | |||
| 2920 | (void)loadgroup->GetRequests(getter_AddRefs(iter)); | |||
| 2921 | if (iter) { | |||
| 2922 | nsCOMPtr<nsISupports> tmp; | |||
| 2923 | bool hasMore = true; | |||
| 2924 | // Check each network request in the load group. | |||
| 2925 | while (NS_SUCCEEDED(iter->HasMoreElements(&hasMore))((bool)(__builtin_expect(!!(!NS_FAILED_impl(iter->HasMoreElements (&hasMore))), 1))) && hasMore) { | |||
| 2926 | iter->GetNext(getter_AddRefs(tmp)); | |||
| 2927 | nsCOMPtr<nsIChannel> loadingChannel(do_QueryInterface(tmp)); | |||
| 2928 | // Ignore subresource requests. Logging for a subresource | |||
| 2929 | // FetchEvent should be handled above since the client is | |||
| 2930 | // already controlled. | |||
| 2931 | if (!loadingChannel || | |||
| 2932 | !nsContentUtils::IsNonSubresourceRequest(loadingChannel)) { | |||
| 2933 | continue; | |||
| 2934 | } | |||
| 2935 | nsCOMPtr<nsIURI> loadingURL; | |||
| 2936 | (void)loadingChannel->GetURI(getter_AddRefs(loadingURL)); | |||
| 2937 | if (!loadingURL) { | |||
| 2938 | continue; | |||
| 2939 | } | |||
| 2940 | nsAutoCString loadingSpec; | |||
| 2941 | (void)loadingURL->GetSpec(loadingSpec); | |||
| 2942 | // Perform a simple substring comparison to match the scope | |||
| 2943 | // against the channel URL. | |||
| 2944 | if (StringBeginsWith(loadingSpec, aScope)) { | |||
| 2945 | *aResultOut = true; | |||
| 2946 | return CallState::Stop; | |||
| 2947 | } | |||
| 2948 | } | |||
| 2949 | } | |||
| 2950 | } | |||
| 2951 | } | |||
| 2952 | ||||
| 2953 | // The current window doesn't care about this service worker, but maybe | |||
| 2954 | // one of our child frames does. | |||
| 2955 | return CallOnInProcessChildren( | |||
| 2956 | &nsGlobalWindowInner::ShouldReportForServiceWorkerScopeInternal, aScope, | |||
| 2957 | aResultOut); | |||
| 2958 | } | |||
| 2959 | ||||
| 2960 | void nsGlobalWindowInner::NoteCalledRegisterForServiceWorkerScope( | |||
| 2961 | const nsACString& aScope) { | |||
| 2962 | if (!mClientSource) { | |||
| 2963 | return; | |||
| 2964 | } | |||
| 2965 | ||||
| 2966 | mClientSource->NoteCalledRegisterForServiceWorkerScope(aScope); | |||
| 2967 | } | |||
| 2968 | ||||
| 2969 | void nsGlobalWindowInner::NoteDOMContentLoaded() { | |||
| 2970 | if (!mClientSource) { | |||
| 2971 | return; | |||
| 2972 | } | |||
| 2973 | ||||
| 2974 | mClientSource->NoteDOMContentLoaded(); | |||
| 2975 | } | |||
| 2976 | ||||
| 2977 | void nsGlobalWindowInner::UpdateTopInnerWindow() { | |||
| 2978 | if (IsTopInnerWindow() || !mTopInnerWindow) { | |||
| 2979 | return; | |||
| 2980 | } | |||
| 2981 | ||||
| 2982 | nsGlobalWindowInner::Cast(mTopInnerWindow) | |||
| 2983 | ->UpdateWebSocketCount(-(int32_t)mNumOfOpenWebSockets); | |||
| 2984 | } | |||
| 2985 | ||||
| 2986 | bool nsGlobalWindowInner::IsInSyncOperation() { | |||
| 2987 | return GetExtantDoc() && GetExtantDoc()->IsInSyncOperation(); | |||
| 2988 | } | |||
| 2989 | ||||
| 2990 | bool nsGlobalWindowInner::IsSharedMemoryAllowedInternal( | |||
| 2991 | nsIPrincipal* aPrincipal) const { | |||
| 2992 | 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", 2992 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence(__null, 2992); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 2993 | ||||
| 2994 | if (StaticPrefs:: | |||
| 2995 | dom_postMessage_sharedArrayBuffer_bypassCOOP_COEP_insecure_enabled()) { | |||
| 2996 | return true; | |||
| 2997 | } | |||
| 2998 | ||||
| 2999 | if (ExtensionPolicyService::GetSingleton().IsExtensionProcess()) { | |||
| 3000 | if (auto* basePrincipal = BasePrincipal::Cast(aPrincipal)) { | |||
| 3001 | if (auto* policy = basePrincipal->AddonPolicy()) { | |||
| 3002 | return policy->IsPrivileged(); | |||
| 3003 | } | |||
| 3004 | } | |||
| 3005 | } | |||
| 3006 | ||||
| 3007 | return CrossOriginIsolated(); | |||
| 3008 | } | |||
| 3009 | ||||
| 3010 | bool nsGlobalWindowInner::CrossOriginIsolated() const { | |||
| 3011 | 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", 3011 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence(__null, 3011); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 3012 | ||||
| 3013 | RefPtr<BrowsingContext> bc = GetBrowsingContext(); | |||
| 3014 | 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" , 3014); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "bc" ")"); do { MOZ_CrashSequence(__null, 3014); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 3015 | return bc->CrossOriginIsolated(); | |||
| 3016 | } | |||
| 3017 | ||||
| 3018 | bool nsGlobalWindowInner::OriginAgentCluster() const { | |||
| 3019 | if (DocGroup* docGroup = GetDocGroup()) { | |||
| 3020 | return docGroup->IsOriginKeyed(); | |||
| 3021 | } | |||
| 3022 | return false; | |||
| 3023 | } | |||
| 3024 | ||||
| 3025 | WindowContext* TopWindowContext(nsPIDOMWindowInner& aWindow) { | |||
| 3026 | WindowContext* wc = aWindow.GetWindowContext(); | |||
| 3027 | if (!wc) { | |||
| 3028 | return nullptr; | |||
| 3029 | } | |||
| 3030 | ||||
| 3031 | return wc->TopWindowContext(); | |||
| 3032 | } | |||
| 3033 | ||||
| 3034 | void nsPIDOMWindowInner::AddPeerConnection() { | |||
| 3035 | 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", 3035 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence(__null, 3035); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 3036 | ++mActivePeerConnections; | |||
| 3037 | if (mActivePeerConnections == 1 && mWindowGlobalChild) { | |||
| 3038 | mWindowGlobalChild->SendUpdateActivePeerConnectionStatus( | |||
| 3039 | /*aIsAdded*/ true); | |||
| 3040 | ||||
| 3041 | // We need to present having active peer connections immediately. If we need | |||
| 3042 | // to wait for the parent process to come back with this information we | |||
| 3043 | // might start throttling. | |||
| 3044 | if (WindowContext* top = TopWindowContext(*this)) { | |||
| 3045 | top->TransientSetHasActivePeerConnections(); | |||
| 3046 | } | |||
| 3047 | } | |||
| 3048 | } | |||
| 3049 | ||||
| 3050 | void nsPIDOMWindowInner::RemovePeerConnection() { | |||
| 3051 | 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", 3051 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence(__null, 3051); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 3052 | 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" , 3052); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mActivePeerConnections > 0" ")"); do { MOZ_CrashSequence(__null, 3052); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 3053 | --mActivePeerConnections; | |||
| 3054 | if (mActivePeerConnections == 0 && mWindowGlobalChild) { | |||
| 3055 | mWindowGlobalChild->SendUpdateActivePeerConnectionStatus( | |||
| 3056 | /*aIsAdded*/ false); | |||
| 3057 | } | |||
| 3058 | } | |||
| 3059 | ||||
| 3060 | bool nsGlobalWindowInner::HasActivePeerConnections() { | |||
| 3061 | 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", 3061 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence(__null, 3061); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 3062 | ||||
| 3063 | WindowContext* topWindowContext = TopWindowContext(*this); | |||
| 3064 | return topWindowContext && topWindowContext->GetHasActivePeerConnections(); | |||
| 3065 | } | |||
| 3066 | ||||
| 3067 | void nsPIDOMWindowInner::AddMediaKeysInstance(MediaKeys* aMediaKeys) { | |||
| 3068 | 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", 3068 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence(__null, 3068); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 3069 | mMediaKeysInstances.AppendElement(aMediaKeys); | |||
| 3070 | if (mWindowGlobalChild && mMediaKeysInstances.Length() == 1) { | |||
| 3071 | mWindowGlobalChild->BlockBFCacheFor(BFCacheStatus::CONTAINS_EME_CONTENT); | |||
| 3072 | } | |||
| 3073 | } | |||
| 3074 | ||||
| 3075 | void nsPIDOMWindowInner::RemoveMediaKeysInstance(MediaKeys* aMediaKeys) { | |||
| 3076 | 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", 3076 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence(__null, 3076); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 3077 | mMediaKeysInstances.RemoveElement(aMediaKeys); | |||
| 3078 | if (mWindowGlobalChild && mMediaKeysInstances.IsEmpty()) { | |||
| 3079 | mWindowGlobalChild->UnblockBFCacheFor(BFCacheStatus::CONTAINS_EME_CONTENT); | |||
| 3080 | } | |||
| 3081 | } | |||
| 3082 | ||||
| 3083 | bool nsPIDOMWindowInner::HasActiveMediaKeysInstance() { | |||
| 3084 | 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", 3084 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence(__null, 3084); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 3085 | return !mMediaKeysInstances.IsEmpty(); | |||
| 3086 | } | |||
| 3087 | ||||
| 3088 | bool nsGlobalWindowInner::IsPlayingAudio() { | |||
| 3089 | for (uint32_t i = 0; i < mAudioContexts.Length(); i++) { | |||
| 3090 | if (mAudioContexts[i]->IsRunning()) { | |||
| 3091 | return true; | |||
| 3092 | } | |||
| 3093 | } | |||
| 3094 | RefPtr<AudioChannelService> acs = AudioChannelService::Get(); | |||
| 3095 | if (!acs) { | |||
| 3096 | return false; | |||
| 3097 | } | |||
| 3098 | auto outer = GetOuterWindow(); | |||
| 3099 | if (!outer) { | |||
| 3100 | // We've been unlinked and are about to die. Not a good time to pretend to | |||
| 3101 | // be playing audio. | |||
| 3102 | return false; | |||
| 3103 | } | |||
| 3104 | return acs->IsWindowActive(outer); | |||
| 3105 | } | |||
| 3106 | ||||
| 3107 | bool nsPIDOMWindowInner::IsDocumentLoaded() const { return mIsDocumentLoaded; } | |||
| 3108 | ||||
| 3109 | mozilla::dom::TimeoutManager* nsGlobalWindowInner::GetTimeoutManager() { | |||
| 3110 | return mTimeoutManager.get(); | |||
| 3111 | } | |||
| 3112 | ||||
| 3113 | bool nsGlobalWindowInner::IsRunningTimeout() { | |||
| 3114 | return GetTimeoutManager()->IsRunningTimeout(); | |||
| 3115 | } | |||
| 3116 | ||||
| 3117 | void nsPIDOMWindowInner::TryToCacheTopInnerWindow() { | |||
| 3118 | if (mHasTriedToCacheTopInnerWindow) { | |||
| 3119 | return; | |||
| 3120 | } | |||
| 3121 | ||||
| 3122 | nsGlobalWindowInner* window = nsGlobalWindowInner::Cast(this); | |||
| 3123 | ||||
| 3124 | 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", 3124 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!window->IsDying()" ")"); do { MOZ_CrashSequence(__null, 3124); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 3125 | ||||
| 3126 | mHasTriedToCacheTopInnerWindow = true; | |||
| 3127 | ||||
| 3128 | 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" , 3128); AnnotateMozCrashReason("MOZ_ASSERT" "(" "window" ")" ); do { MOZ_CrashSequence(__null, 3128); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 3129 | ||||
| 3130 | if (nsCOMPtr<nsPIDOMWindowOuter> topOutter = | |||
| 3131 | window->GetInProcessScriptableTop()) { | |||
| 3132 | mTopInnerWindow = topOutter->GetCurrentInnerWindow(); | |||
| 3133 | } | |||
| 3134 | } | |||
| 3135 | ||||
| 3136 | void nsGlobalWindowInner::UpdateActiveIndexedDBDatabaseCount(int32_t aDelta) { | |||
| 3137 | 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", 3137 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence(__null, 3137); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 3138 | ||||
| 3139 | if (aDelta == 0) { | |||
| 3140 | return; | |||
| 3141 | } | |||
| 3142 | ||||
| 3143 | // We count databases but not transactions because only active databases | |||
| 3144 | // could block throttling. | |||
| 3145 | uint32_t& counter = mTopInnerWindow | |||
| 3146 | ? mTopInnerWindow->mNumOfIndexedDBDatabases | |||
| 3147 | : mNumOfIndexedDBDatabases; | |||
| 3148 | ||||
| 3149 | counter += aDelta; | |||
| 3150 | } | |||
| 3151 | ||||
| 3152 | bool nsGlobalWindowInner::HasActiveIndexedDBDatabases() const { | |||
| 3153 | 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", 3153 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence(__null, 3153); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 3154 | ||||
| 3155 | return mTopInnerWindow ? mTopInnerWindow->mNumOfIndexedDBDatabases > 0 | |||
| 3156 | : mNumOfIndexedDBDatabases > 0; | |||
| 3157 | } | |||
| 3158 | ||||
| 3159 | void nsGlobalWindowInner::UpdateWebSocketCount(int32_t aDelta) { | |||
| 3160 | 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", 3160 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence(__null, 3160); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 3161 | ||||
| 3162 | if (aDelta == 0) { | |||
| 3163 | return; | |||
| 3164 | } | |||
| 3165 | ||||
| 3166 | if (mTopInnerWindow && !IsTopInnerWindow()) { | |||
| 3167 | nsGlobalWindowInner::Cast(mTopInnerWindow)->UpdateWebSocketCount(aDelta); | |||
| 3168 | } | |||
| 3169 | ||||
| 3170 | 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", 3171 ); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "aDelta > 0 || ((aDelta + mNumOfOpenWebSockets) < mNumOfOpenWebSockets)" ")"); do { MOZ_CrashSequence(__null, 3171); __attribute__((nomerge )) ::abort(); } while (false); } } while (false) | |||
| 3171 | 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", 3171 ); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "aDelta > 0 || ((aDelta + mNumOfOpenWebSockets) < mNumOfOpenWebSockets)" ")"); do { MOZ_CrashSequence(__null, 3171); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 3172 | ||||
| 3173 | mNumOfOpenWebSockets += aDelta; | |||
| 3174 | } | |||
| 3175 | ||||
| 3176 | bool nsGlobalWindowInner::HasOpenWebSockets() const { | |||
| 3177 | 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", 3177 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence(__null, 3177); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 3178 | ||||
| 3179 | return mNumOfOpenWebSockets || | |||
| 3180 | (mTopInnerWindow && mTopInnerWindow->mNumOfOpenWebSockets); | |||
| 3181 | } | |||
| 3182 | ||||
| 3183 | void nsGlobalWindowInner::AudioPlaybackChanged(bool aIsPlayingAudio) { | |||
| 3184 | AUTO_PROFILER_MARKER_UNTYPED("AudioPlaybackChanged", DOM, {})AutoProfilerUntypedMarker raiiObject3184( "AudioPlaybackChanged" , ::mozilla::baseprofiler::category::DOM, {}); | |||
| 3185 | UpdateWorkersPlaybackState(*this, aIsPlayingAudio); | |||
| 3186 | } | |||
| 3187 | ||||
| 3188 | bool nsPIDOMWindowInner::IsCurrentInnerWindow() const { | |||
| 3189 | if (mBrowsingContext && mBrowsingContext->IsInBFCache()) { | |||
| 3190 | return false; | |||
| 3191 | } | |||
| 3192 | ||||
| 3193 | if (!mBrowsingContext || mBrowsingContext->IsDiscarded()) { | |||
| 3194 | // If our BrowsingContext has been discarded, we consider ourselves | |||
| 3195 | // still-current if we were current at the time it was discarded. | |||
| 3196 | return mOuterWindow && WasCurrentInnerWindow(); | |||
| 3197 | } | |||
| 3198 | ||||
| 3199 | nsPIDOMWindowOuter* outer = mBrowsingContext->GetDOMWindow(); | |||
| 3200 | return outer && outer->GetCurrentInnerWindow() == this; | |||
| 3201 | } | |||
| 3202 | ||||
| 3203 | bool nsGlobalWindowInner::HasScheduledNormalOrHighPriorityWebTasks() const { | |||
| 3204 | return gNumNormalOrHighPriorityQueuesHaveTaskScheduledMainThread > 0; | |||
| 3205 | } | |||
| 3206 | ||||
| 3207 | bool nsPIDOMWindowInner::IsFullyActive() const { | |||
| 3208 | WindowContext* wc = GetWindowContext(); | |||
| 3209 | if (!wc || wc->IsDiscarded() || !wc->IsCurrent()) { | |||
| 3210 | return false; | |||
| 3211 | } | |||
| 3212 | return GetBrowsingContext()->AncestorsAreCurrent(); | |||
| 3213 | } | |||
| 3214 | ||||
| 3215 | void nsPIDOMWindowInner::SetAudioCapture(bool aCapture) { | |||
| 3216 | RefPtr<AudioChannelService> service = AudioChannelService::GetOrCreate(); | |||
| 3217 | if (service) { | |||
| 3218 | service->SetWindowAudioCaptured(GetOuterWindow(), mWindowID, aCapture); | |||
| 3219 | } | |||
| 3220 | } | |||
| 3221 | ||||
| 3222 | void nsGlobalWindowInner::SetActiveLoadingState(bool aIsLoading) { | |||
| 3223 | 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) | |||
| 3224 | 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) | |||
| 3225 | ("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); | |||
| 3226 | if (GetBrowsingContext()) { | |||
| 3227 | // Setting loading on a discarded context has no effect. | |||
| 3228 | (void)GetBrowsingContext()->SetLoading(aIsLoading); | |||
| 3229 | } | |||
| 3230 | ||||
| 3231 | if (StaticPrefs::dom_timeout_defer_during_load() && !IsChromeWindow()) { | |||
| 3232 | nsIPrincipal* principal = GetPrincipal(); | |||
| 3233 | if (!principal || !principal->IsURIInPrefList( | |||
| 3234 | "dom.timeout.defer_during_load.force-disable")) { | |||
| 3235 | mTimeoutManager->SetLoading(aIsLoading); | |||
| 3236 | } | |||
| 3237 | } | |||
| 3238 | ||||
| 3239 | HintIsLoading(aIsLoading); | |||
| 3240 | } | |||
| 3241 | ||||
| 3242 | void nsGlobalWindowInner::HintIsLoading(bool aIsLoading) { | |||
| 3243 | // Hint to tell the JS GC to use modified triggers during pageload. | |||
| 3244 | if (mHintedWasLoading != aIsLoading) { | |||
| 3245 | using namespace js::gc; | |||
| 3246 | SetPerformanceHint(danger::GetJSContext(), aIsLoading | |||
| 3247 | ? PerformanceHint::InPageLoad | |||
| 3248 | : PerformanceHint::Normal); | |||
| 3249 | mHintedWasLoading = aIsLoading; | |||
| 3250 | } | |||
| 3251 | } | |||
| 3252 | ||||
| 3253 | // nsISpeechSynthesisGetter | |||
| 3254 | ||||
| 3255 | #ifdef MOZ_WEBSPEECH1 | |||
| 3256 | SpeechSynthesis* nsGlobalWindowInner::GetSpeechSynthesis(ErrorResult& aError) { | |||
| 3257 | if (!mSpeechSynthesis) { | |||
| 3258 | mSpeechSynthesis = MakeRefPtr<SpeechSynthesis>(this); | |||
| 3259 | } | |||
| 3260 | ||||
| 3261 | return mSpeechSynthesis; | |||
| 3262 | } | |||
| 3263 | ||||
| 3264 | bool nsGlobalWindowInner::HasActiveSpeechSynthesis() { | |||
| 3265 | if (mSpeechSynthesis) { | |||
| 3266 | return !mSpeechSynthesis->HasEmptyQueue(); | |||
| 3267 | } | |||
| 3268 | ||||
| 3269 | return false; | |||
| 3270 | } | |||
| 3271 | ||||
| 3272 | #endif | |||
| 3273 | ||||
| 3274 | mozilla::glean::Glean* nsGlobalWindowInner::Glean() { | |||
| 3275 | if (!mGlean) { | |||
| 3276 | mGlean = MakeRefPtr<mozilla::glean::Glean>(this); | |||
| 3277 | } | |||
| 3278 | ||||
| 3279 | return mGlean; | |||
| 3280 | } | |||
| 3281 | ||||
| 3282 | mozilla::glean::GleanPings* nsGlobalWindowInner::GleanPings() { | |||
| 3283 | if (!mGleanPings) { | |||
| 3284 | mGleanPings = MakeRefPtr<mozilla::glean::GleanPings>(); | |||
| 3285 | } | |||
| 3286 | ||||
| 3287 | return mGleanPings; | |||
| 3288 | } | |||
| 3289 | ||||
| 3290 | Nullable<WindowProxyHolder> nsGlobalWindowInner::GetParent( | |||
| 3291 | ErrorResult& aError) { | |||
| 3292 | FORWARD_TO_OUTER_OR_THROW(GetParentOuter, (), aError, nullptr); | |||
| 3293 | } | |||
| 3294 | ||||
| 3295 | /** | |||
| 3296 | * GetInProcessScriptableParent used to be called when a script read | |||
| 3297 | * window.parent. Under Fission, that is now handled by | |||
| 3298 | * BrowsingContext::GetParent, and the result is a WindowProxyHolder rather than | |||
| 3299 | * an actual global window. This method still exists for legacy callers which | |||
| 3300 | * relied on the old logic, and require in-process windows. However, it only | |||
| 3301 | * works correctly when no out-of-process frames exist between this window and | |||
| 3302 | * the top-level window, so it should not be used in new code. | |||
| 3303 | * | |||
| 3304 | * In contrast to GetRealParent, GetInProcessScriptableParent respects <iframe | |||
| 3305 | * mozbrowser> boundaries, so if |this| is contained by an <iframe | |||
| 3306 | * mozbrowser>, we will return |this| as its own parent. | |||
| 3307 | */ | |||
| 3308 | nsPIDOMWindowOuter* nsGlobalWindowInner::GetInProcessScriptableParent() { | |||
| 3309 | FORWARD_TO_OUTER(GetInProcessScriptableParent, (), nullptr); | |||
| 3310 | } | |||
| 3311 | ||||
| 3312 | /** | |||
| 3313 | * GetInProcessScriptableTop used to be called when a script read window.top. | |||
| 3314 | * Under Fission, that is now handled by BrowsingContext::Top, and the result is | |||
| 3315 | * a WindowProxyHolder rather than an actual global window. This method still | |||
| 3316 | * exists for legacy callers which relied on the old logic, and require | |||
| 3317 | * in-process windows. However, it only works correctly when no out-of-process | |||
| 3318 | * frames exist between this window and the top-level window, so it should not | |||
| 3319 | * be used in new code. | |||
| 3320 | * | |||
| 3321 | * In contrast to GetRealTop, GetInProcessScriptableTop respects <iframe | |||
| 3322 | * mozbrowser> boundaries. If we encounter a window owned by an <iframe | |||
| 3323 | * mozbrowser> while walking up the window hierarchy, we'll stop and return that | |||
| 3324 | * window. | |||
| 3325 | */ | |||
| 3326 | nsPIDOMWindowOuter* nsGlobalWindowInner::GetInProcessScriptableTop() { | |||
| 3327 | FORWARD_TO_OUTER(GetInProcessScriptableTop, (), nullptr); | |||
| 3328 | } | |||
| 3329 | ||||
| 3330 | void nsGlobalWindowInner::GetContent(JSContext* aCx, | |||
| 3331 | JS::MutableHandle<JSObject*> aRetval, | |||
| 3332 | CallerType aCallerType, | |||
| 3333 | ErrorResult& aError) { | |||
| 3334 | FORWARD_TO_OUTER_OR_THROW(GetContentOuter, | |||
| 3335 | (aCx, aRetval, aCallerType, aError), aError, ); | |||
| 3336 | } | |||
| 3337 | ||||
| 3338 | BarProp* nsGlobalWindowInner::GetMenubar(ErrorResult& aError) { | |||
| 3339 | if (!mMenubar) { | |||
| 3340 | mMenubar = MakeRefPtr<MenubarProp>(this); | |||
| 3341 | } | |||
| 3342 | ||||
| 3343 | return mMenubar; | |||
| 3344 | } | |||
| 3345 | ||||
| 3346 | BarProp* nsGlobalWindowInner::GetToolbar(ErrorResult& aError) { | |||
| 3347 | if (!mToolbar) { | |||
| 3348 | mToolbar = MakeRefPtr<ToolbarProp>(this); | |||
| 3349 | } | |||
| 3350 | ||||
| 3351 | return mToolbar; | |||
| 3352 | } | |||
| 3353 | ||||
| 3354 | BarProp* nsGlobalWindowInner::GetLocationbar(ErrorResult& aError) { | |||
| 3355 | if (!mLocationbar) { | |||
| 3356 | mLocationbar = MakeRefPtr<LocationbarProp>(this); | |||
| 3357 | } | |||
| 3358 | return mLocationbar; | |||
| 3359 | } | |||
| 3360 | ||||
| 3361 | BarProp* nsGlobalWindowInner::GetPersonalbar(ErrorResult& aError) { | |||
| 3362 | if (!mPersonalbar) { | |||
| 3363 | mPersonalbar = MakeRefPtr<PersonalbarProp>(this); | |||
| 3364 | } | |||
| 3365 | return mPersonalbar; | |||
| 3366 | } | |||
| 3367 | ||||
| 3368 | BarProp* nsGlobalWindowInner::GetStatusbar(ErrorResult& aError) { | |||
| 3369 | if (!mStatusbar) { | |||
| 3370 | mStatusbar = MakeRefPtr<StatusbarProp>(this); | |||
| 3371 | } | |||
| 3372 | return mStatusbar; | |||
| 3373 | } | |||
| 3374 | ||||
| 3375 | BarProp* nsGlobalWindowInner::GetScrollbars(ErrorResult& aError) { | |||
| 3376 | if (!mScrollbars) { | |||
| 3377 | mScrollbars = MakeRefPtr<ScrollbarsProp>(this); | |||
| 3378 | } | |||
| 3379 | ||||
| 3380 | return mScrollbars; | |||
| 3381 | } | |||
| 3382 | ||||
| 3383 | bool nsGlobalWindowInner::GetClosed(ErrorResult& aError) { | |||
| 3384 | // If we're called from JS (which is the only way we should be getting called | |||
| 3385 | // here) and we reach this point, that means our JS global is the current | |||
| 3386 | // target of the WindowProxy, which means that we are the "current inner" | |||
| 3387 | // of our outer. So if FORWARD_TO_OUTER fails to forward, that means the | |||
| 3388 | // outer is already torn down, which corresponds to the closed state. | |||
| 3389 | FORWARD_TO_OUTER(GetClosedOuter, (), true); | |||
| 3390 | } | |||
| 3391 | ||||
| 3392 | Nullable<WindowProxyHolder> nsGlobalWindowInner::IndexedGetter( | |||
| 3393 | uint32_t aIndex) { | |||
| 3394 | FORWARD_TO_OUTER(IndexedGetterOuter, (aIndex), nullptr); | |||
| 3395 | } | |||
| 3396 | ||||
| 3397 | namespace { | |||
| 3398 | ||||
| 3399 | struct InterfaceShimEntry { | |||
| 3400 | const char* geckoName; | |||
| 3401 | const char* domName; | |||
| 3402 | }; | |||
| 3403 | ||||
| 3404 | } // anonymous namespace | |||
| 3405 | ||||
| 3406 | // We add shims from Components.interfaces.nsIDOMFoo to window.Foo for each | |||
| 3407 | // interface that has interface constants that sites might be getting off | |||
| 3408 | // of Ci. | |||
| 3409 | const InterfaceShimEntry kInterfaceShimMap[] = { | |||
| 3410 | {"nsIXMLHttpRequest", "XMLHttpRequest"}, | |||
| 3411 | {"nsIDOMDOMException", "DOMException"}, | |||
| 3412 | {"nsIDOMNode", "Node"}, | |||
| 3413 | {"nsIDOMCSSRule", "CSSRule"}, | |||
| 3414 | {"nsIDOMEvent", "Event"}, | |||
| 3415 | {"nsIDOMNSEvent", "Event"}, | |||
| 3416 | {"nsIDOMKeyEvent", "KeyEvent"}, | |||
| 3417 | {"nsIDOMMouseEvent", "MouseEvent"}, | |||
| 3418 | {"nsIDOMMouseScrollEvent", "MouseScrollEvent"}, | |||
| 3419 | {"nsIDOMMutationEvent", "MutationEvent"}, | |||
| 3420 | {"nsIDOMUIEvent", "UIEvent"}, | |||
| 3421 | {"nsIDOMHTMLMediaElement", "HTMLMediaElement"}, | |||
| 3422 | {"nsIDOMRange", "Range"}, | |||
| 3423 | // Think about whether Ci.nsINodeFilter can just go away for websites! | |||
| 3424 | {"nsIDOMNodeFilter", "NodeFilter"}, | |||
| 3425 | {"nsIDOMXPathResult", "XPathResult"}}; | |||
| 3426 | ||||
| 3427 | bool nsGlobalWindowInner::ResolveComponentsShim( | |||
| 3428 | JSContext* aCx, JS::Handle<JSObject*> aGlobal, | |||
| 3429 | JS::MutableHandle<mozilla::Maybe<JS::PropertyDescriptor>> aDesc) { | |||
| 3430 | // Warn once. | |||
| 3431 | nsCOMPtr<Document> doc = GetExtantDoc(); | |||
| 3432 | if (doc) { | |||
| 3433 | doc->WarnOnceAndReportAbout( | |||
| 3434 | DeprecatedOperations::eComponents, /* asError = */ | |||
| 3435 | true); | |||
| 3436 | // Keep track of how often this happens. | |||
| 3437 | doc->SetUseCounter(eUseCounter_custom_ComponentsShimResolved); | |||
| 3438 | } | |||
| 3439 | ||||
| 3440 | // Create a fake Components object. | |||
| 3441 | AssertSameCompartment(aCx, aGlobal); | |||
| 3442 | JS::Rooted<JSObject*> components(aCx, JS_NewPlainObject(aCx)); | |||
| 3443 | if (NS_WARN_IF(!components)NS_warn_if_impl(!components, "!components", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp" , 3443)) { | |||
| 3444 | return false; | |||
| 3445 | } | |||
| 3446 | ||||
| 3447 | // Create a fake interfaces object. | |||
| 3448 | JS::Rooted<JSObject*> interfaces(aCx, JS_NewPlainObject(aCx)); | |||
| 3449 | if (NS_WARN_IF(!interfaces)NS_warn_if_impl(!interfaces, "!interfaces", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp" , 3449)) { | |||
| 3450 | return false; | |||
| 3451 | } | |||
| 3452 | bool ok = | |||
| 3453 | JS_DefineProperty(aCx, components, "interfaces", interfaces, | |||
| 3454 | JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY); | |||
| 3455 | if (NS_WARN_IF(!ok)NS_warn_if_impl(!ok, "!ok", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp" , 3455)) { | |||
| 3456 | return false; | |||
| 3457 | } | |||
| 3458 | ||||
| 3459 | // Define a bunch of shims from the Ci.nsIDOMFoo to window.Foo for DOM | |||
| 3460 | // interfaces with constants. | |||
| 3461 | for (auto entry : kInterfaceShimMap) { | |||
| 3462 | // Grab the names from the table. | |||
| 3463 | const char* geckoName = entry.geckoName; | |||
| 3464 | const char* domName = entry.domName; | |||
| 3465 | ||||
| 3466 | // Look up the appopriate interface object on the global. | |||
| 3467 | JS::Rooted<JS::Value> v(aCx, JS::UndefinedValue()); | |||
| 3468 | ok = JS_GetProperty(aCx, aGlobal, domName, &v); | |||
| 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 | if (!v.isObject()) { | |||
| 3473 | 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" , 3473); | |||
| 3474 | continue; | |||
| 3475 | } | |||
| 3476 | ||||
| 3477 | // Define the shim on the interfaces object. | |||
| 3478 | ok = JS_DefineProperty( | |||
| 3479 | aCx, interfaces, geckoName, v, | |||
| 3480 | JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY); | |||
| 3481 | if (NS_WARN_IF(!ok)NS_warn_if_impl(!ok, "!ok", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp" , 3481)) { | |||
| 3482 | return false; | |||
| 3483 | } | |||
| 3484 | } | |||
| 3485 | ||||
| 3486 | aDesc.set(mozilla::Some(JS::PropertyDescriptor::Data( | |||
| 3487 | JS::ObjectValue(*components), | |||
| 3488 | {JS::PropertyAttribute::Configurable, JS::PropertyAttribute::Enumerable, | |||
| 3489 | JS::PropertyAttribute::Writable}))); | |||
| 3490 | return true; | |||
| 3491 | } | |||
| 3492 | ||||
| 3493 | #ifdef RELEASE_OR_BETA | |||
| 3494 | # define USE_CONTROLLERS_SHIM | |||
| 3495 | #endif | |||
| 3496 | ||||
| 3497 | #ifdef USE_CONTROLLERS_SHIM | |||
| 3498 | static const JSClass ControllersShimClass = {"Controllers", 0}; | |||
| 3499 | static const JSClass XULControllersShimClass = {"XULControllers", 0}; | |||
| 3500 | #endif | |||
| 3501 | ||||
| 3502 | bool nsGlobalWindowInner::DoResolve( | |||
| 3503 | JSContext* aCx, JS::Handle<JSObject*> aObj, JS::Handle<jsid> aId, | |||
| 3504 | JS::MutableHandle<mozilla::Maybe<JS::PropertyDescriptor>> aDesc) { | |||
| 3505 | // Note: Keep this in sync with MayResolve. | |||
| 3506 | ||||
| 3507 | // Note: The infallibleInit call in GlobalResolve depends on this check. | |||
| 3508 | if (!aId.isString()) { | |||
| 3509 | return true; | |||
| 3510 | } | |||
| 3511 | ||||
| 3512 | bool found; | |||
| 3513 | if (!WebIDLGlobalNameHash::DefineIfEnabled(aCx, aObj, aId, aDesc, &found)) { | |||
| 3514 | return false; | |||
| 3515 | } | |||
| 3516 | ||||
| 3517 | if (found) { | |||
| 3518 | return true; | |||
| 3519 | } | |||
| 3520 | ||||
| 3521 | // We support a cut-down Components.interfaces in case websites are | |||
| 3522 | // using Components.interfaces.nsIFoo.CONSTANT_NAME for the ones | |||
| 3523 | // that have constants. | |||
| 3524 | if (StaticPrefs::dom_use_components_shim() && | |||
| 3525 | aId == XPCJSRuntime::Get()->GetStringID(XPCJSContext::IDX_COMPONENTS)) { | |||
| 3526 | return ResolveComponentsShim(aCx, aObj, aDesc); | |||
| 3527 | } | |||
| 3528 | ||||
| 3529 | // Bug 2072122: Trusted Types readiness experiment only, to be removed. | |||
| 3530 | // React DOM looks up this global when it loads. A lookup that reaches us | |||
| 3531 | // means the page does not define it; we never resolve it. | |||
| 3532 | if (StaticPrefs::dom_security_trusted_types_readiness_telemetry_enabled() && | |||
| 3533 | aId == XPCJSRuntime::Get()->GetStringID( | |||
| 3534 | XPCJSContext::IDX_REACT_DEVTOOLS_GLOBAL_HOOK) && | |||
| 3535 | !xpc::IsXrayWrapper(aObj)) { | |||
| 3536 | if (Document* doc = GetExtantDoc(); | |||
| 3537 | doc && !doc->IsDetectingTrustedTypesLibrary()) { | |||
| 3538 | doc->SetTrustedTypesReadinessSignal( | |||
| 3539 | TrustedTypesReadinessSignal::LookedUpReactDevToolsHook); | |||
| 3540 | } | |||
| 3541 | return true; | |||
| 3542 | } | |||
| 3543 | ||||
| 3544 | // We also support a "window.controllers" thing; apparently some | |||
| 3545 | // sites use it for browser-sniffing. See bug 1010577. | |||
| 3546 | #ifdef USE_CONTROLLERS_SHIM | |||
| 3547 | // Note: We use |aObj| rather than |this| to get the principal here, because | |||
| 3548 | // this is called during Window setup when the Document isn't necessarily | |||
| 3549 | // hooked up yet. | |||
| 3550 | if ((aId == XPCJSRuntime::Get()->GetStringID(XPCJSContext::IDX_CONTROLLERS) || | |||
| 3551 | aId == XPCJSRuntime::Get()->GetStringID( | |||
| 3552 | XPCJSContext::IDX_CONTROLLERS_CLASS)) && | |||
| 3553 | !xpc::IsXrayWrapper(aObj) && | |||
| 3554 | !nsContentUtils::ObjectPrincipal(aObj)->IsSystemPrincipal()) { | |||
| 3555 | if (GetExtantDoc()) { | |||
| 3556 | GetExtantDoc()->WarnOnceAndReportAbout( | |||
| 3557 | DeprecatedOperations::eWindow_Cc_ontrollers); | |||
| 3558 | } | |||
| 3559 | const JSClass* clazz; | |||
| 3560 | if (aId == | |||
| 3561 | XPCJSRuntime::Get()->GetStringID(XPCJSContext::IDX_CONTROLLERS)) { | |||
| 3562 | clazz = &XULControllersShimClass; | |||
| 3563 | } else { | |||
| 3564 | clazz = &ControllersShimClass; | |||
| 3565 | } | |||
| 3566 | 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", 3566 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "JS_IsGlobalObject(aObj)" ")"); do { MOZ_CrashSequence(__null, 3566); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 3567 | JS::Rooted<JSObject*> shim(aCx, JS_NewObject(aCx, clazz)); | |||
| 3568 | if (NS_WARN_IF(!shim)NS_warn_if_impl(!shim, "!shim", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp" , 3568)) { | |||
| 3569 | return false; | |||
| 3570 | } | |||
| 3571 | ||||
| 3572 | aDesc.set(mozilla::Some(JS::PropertyDescriptor::Data( | |||
| 3573 | JS::ObjectValue(*shim), | |||
| 3574 | {JS::PropertyAttribute::Configurable, JS::PropertyAttribute::Enumerable, | |||
| 3575 | JS::PropertyAttribute::Writable}))); | |||
| 3576 | return true; | |||
| 3577 | } | |||
| 3578 | #endif | |||
| 3579 | ||||
| 3580 | return true; | |||
| 3581 | } | |||
| 3582 | ||||
| 3583 | /* static */ | |||
| 3584 | bool nsGlobalWindowInner::MayResolve(jsid aId) { | |||
| 3585 | // Note: This function does not fail and may not have any side-effects. | |||
| 3586 | // Note: Keep this in sync with DoResolve. | |||
| 3587 | if (!aId.isString()) { | |||
| 3588 | return false; | |||
| 3589 | } | |||
| 3590 | ||||
| 3591 | if (aId == XPCJSRuntime::Get()->GetStringID(XPCJSContext::IDX_COMPONENTS)) { | |||
| 3592 | return true; | |||
| 3593 | } | |||
| 3594 | ||||
| 3595 | if (aId == XPCJSRuntime::Get()->GetStringID(XPCJSContext::IDX_CONTROLLERS) || | |||
| 3596 | aId == XPCJSRuntime::Get()->GetStringID( | |||
| 3597 | XPCJSContext::IDX_CONTROLLERS_CLASS)) { | |||
| 3598 | // We only resolve .controllers/.Controllers in release builds and on | |||
| 3599 | // non-chrome windows, but let's not worry about any of that stuff. | |||
| 3600 | return true; | |||
| 3601 | } | |||
| 3602 | ||||
| 3603 | // Bug 2072122: Trusted Types readiness experiment only, to be removed. | |||
| 3604 | if (StaticPrefs::dom_security_trusted_types_readiness_telemetry_enabled() && | |||
| 3605 | aId == XPCJSRuntime::Get()->GetStringID( | |||
| 3606 | XPCJSContext::IDX_REACT_DEVTOOLS_GLOBAL_HOOK)) { | |||
| 3607 | return true; | |||
| 3608 | } | |||
| 3609 | ||||
| 3610 | return WebIDLGlobalNameHash::MayResolve(aId); | |||
| 3611 | } | |||
| 3612 | ||||
| 3613 | void nsGlobalWindowInner::GetOwnPropertyNames( | |||
| 3614 | JSContext* aCx, JS::MutableHandleVector<jsid> aNames, bool aEnumerableOnly, | |||
| 3615 | ErrorResult& aRv) { | |||
| 3616 | if (aEnumerableOnly) { | |||
| 3617 | // The names we would return from here get defined on the window via one of | |||
| 3618 | // two codepaths. The ones coming from the WebIDLGlobalNameHash will end up | |||
| 3619 | // in the DefineConstructor function in BindingUtils, which always defines | |||
| 3620 | // things as non-enumerable. The ones coming from the script namespace | |||
| 3621 | // manager get defined by our resolve hook using FillPropertyDescriptor with | |||
| 3622 | // 0 for the property attributes, so non-enumerable as well. | |||
| 3623 | // | |||
| 3624 | // So in the aEnumerableOnly case we have nothing to do. | |||
| 3625 | return; | |||
| 3626 | } | |||
| 3627 | ||||
| 3628 | // "Components" is marked as enumerable but only resolved on demand :-/. | |||
| 3629 | // aNames.AppendElement(u"Components"_ns); | |||
| 3630 | ||||
| 3631 | JS::Rooted<JSObject*> wrapper(aCx, GetWrapper()); | |||
| 3632 | ||||
| 3633 | // There are actually two ways we can get called here: For normal | |||
| 3634 | // enumeration or for Xray enumeration. In the latter case, we want to | |||
| 3635 | // return all possible WebIDL names, because we don't really support | |||
| 3636 | // deleting these names off our Xray; trying to resolve them will just make | |||
| 3637 | // them come back. In the former case, we want to avoid returning deleted | |||
| 3638 | // names. But the JS engine already knows about the non-deleted | |||
| 3639 | // already-resolved names, so we can just return the so-far-unresolved ones. | |||
| 3640 | // | |||
| 3641 | // We can tell which case we're in by whether aCx is in our wrapper's | |||
| 3642 | // compartment. If not, we're in the Xray case. | |||
| 3643 | WebIDLGlobalNameHash::NameType nameType = | |||
| 3644 | js::IsObjectInContextCompartment(wrapper, aCx) | |||
| 3645 | ? WebIDLGlobalNameHash::UnresolvedNamesOnly | |||
| 3646 | : WebIDLGlobalNameHash::AllNames; | |||
| 3647 | if (!WebIDLGlobalNameHash::GetNames(aCx, wrapper, nameType, aNames)) { | |||
| 3648 | aRv.NoteJSContextException(aCx); | |||
| 3649 | } | |||
| 3650 | } | |||
| 3651 | ||||
| 3652 | /* static */ | |||
| 3653 | bool nsGlobalWindowInner::IsPrivilegedChromeWindow(JSContext*, JSObject* aObj) { | |||
| 3654 | // For now, have to deal with XPConnect objects here. | |||
| 3655 | nsGlobalWindowInner* win = xpc::WindowOrNull(aObj); | |||
| 3656 | return win && win->IsChromeWindow() && | |||
| 3657 | nsContentUtils::ObjectPrincipal(aObj) == | |||
| 3658 | nsContentUtils::GetSystemPrincipal(); | |||
| 3659 | } | |||
| 3660 | ||||
| 3661 | /* static */ | |||
| 3662 | bool nsGlobalWindowInner::DeviceSensorsEnabled(JSContext*, JSObject*) { | |||
| 3663 | return Preferences::GetBool("device.sensors.enabled"); | |||
| 3664 | } | |||
| 3665 | ||||
| 3666 | Crypto* nsGlobalWindowInner::GetCrypto(ErrorResult& aError) { | |||
| 3667 | if (!mCrypto) { | |||
| 3668 | mCrypto = MakeRefPtr<Crypto>(this); | |||
| 3669 | } | |||
| 3670 | return mCrypto; | |||
| 3671 | } | |||
| 3672 | ||||
| 3673 | nsIControllers* nsGlobalWindowInner::GetControllers(ErrorResult& aError) { | |||
| 3674 | FORWARD_TO_OUTER_OR_THROW(GetControllersOuter, (aError), aError, nullptr); | |||
| 3675 | } | |||
| 3676 | ||||
| 3677 | nsresult nsGlobalWindowInner::GetControllers(nsIControllers** aResult) { | |||
| 3678 | ErrorResult rv; | |||
| 3679 | nsCOMPtr<nsIControllers> controllers = GetControllers(rv); | |||
| 3680 | controllers.forget(aResult); | |||
| 3681 | ||||
| 3682 | return rv.StealNSResult(); | |||
| 3683 | } | |||
| 3684 | ||||
| 3685 | Nullable<WindowProxyHolder> nsGlobalWindowInner::GetOpenerWindow( | |||
| 3686 | ErrorResult& aError) { | |||
| 3687 | FORWARD_TO_OUTER_OR_THROW(GetOpenerWindowOuter, (), aError, nullptr); | |||
| 3688 | } | |||
| 3689 | ||||
| 3690 | void nsGlobalWindowInner::GetOpener(JSContext* aCx, | |||
| 3691 | JS::MutableHandle<JS::Value> aRetval, | |||
| 3692 | ErrorResult& aError) { | |||
| 3693 | Nullable<WindowProxyHolder> opener = GetOpenerWindow(aError); | |||
| 3694 | if (aError.Failed() || opener.IsNull()) { | |||
| 3695 | aRetval.setNull(); | |||
| 3696 | return; | |||
| 3697 | } | |||
| 3698 | ||||
| 3699 | if (!ToJSValue(aCx, opener.Value(), aRetval)) { | |||
| 3700 | aError.NoteJSContextException(aCx); | |||
| 3701 | } | |||
| 3702 | } | |||
| 3703 | ||||
| 3704 | void nsGlobalWindowInner::SetOpener(JSContext* aCx, | |||
| 3705 | JS::Handle<JS::Value> aOpener, | |||
| 3706 | ErrorResult& aError) { | |||
| 3707 | if (aOpener.isNull()) { | |||
| 3708 | RefPtr<BrowsingContext> bc(GetBrowsingContext()); | |||
| 3709 | if (!bc->IsDiscarded()) { | |||
| 3710 | bc->SetOpener(nullptr); | |||
| 3711 | } | |||
| 3712 | return; | |||
| 3713 | } | |||
| 3714 | ||||
| 3715 | // If something other than null is passed, just define aOpener on our inner | |||
| 3716 | // window's JS object, wrapped into the current compartment so that for Xrays | |||
| 3717 | // we define on the Xray expando object, but don't set it on the outer window, | |||
| 3718 | // so that it'll get reset on navigation. This is just like replaceable | |||
| 3719 | // properties, but we're not quite readonly. | |||
| 3720 | RedefineProperty(aCx, "opener", aOpener, aError); | |||
| 3721 | } | |||
| 3722 | ||||
| 3723 | void nsGlobalWindowInner::GetEvent(OwningEventOrUndefined& aRetval) { | |||
| 3724 | if (mEvent) { | |||
| 3725 | aRetval.SetAsEvent() = mEvent; | |||
| 3726 | } else { | |||
| 3727 | aRetval.SetUndefined(); | |||
| 3728 | } | |||
| 3729 | } | |||
| 3730 | ||||
| 3731 | void nsGlobalWindowInner::GetStatus(nsAString& aStatus, ErrorResult& aError) { | |||
| 3732 | FORWARD_TO_OUTER_OR_THROW(GetStatusOuter, (aStatus), aError, ); | |||
| 3733 | } | |||
| 3734 | ||||
| 3735 | void nsGlobalWindowInner::SetStatus(const nsAString& aStatus, | |||
| 3736 | ErrorResult& aError) { | |||
| 3737 | FORWARD_TO_OUTER_OR_THROW(SetStatusOuter, (aStatus), aError, ); | |||
| 3738 | } | |||
| 3739 | ||||
| 3740 | void nsGlobalWindowInner::GetName(nsAString& aName, ErrorResult& aError) { | |||
| 3741 | FORWARD_TO_OUTER_OR_THROW(GetNameOuter, (aName), aError, ); | |||
| 3742 | } | |||
| 3743 | ||||
| 3744 | void nsGlobalWindowInner::SetName(const nsAString& aName, | |||
| 3745 | mozilla::ErrorResult& aError) { | |||
| 3746 | FORWARD_TO_OUTER_OR_THROW(SetNameOuter, (aName, aError), aError, ); | |||
| 3747 | } | |||
| 3748 | ||||
| 3749 | double nsGlobalWindowInner::GetInnerWidth(CallerType aCallerType, | |||
| 3750 | ErrorResult& aError) { | |||
| 3751 | FORWARD_TO_OUTER_OR_THROW(GetInnerWidthOuter, (aCallerType, aError), aError, | |||
| 3752 | 0); | |||
| 3753 | } | |||
| 3754 | ||||
| 3755 | nsresult nsGlobalWindowInner::GetInnerWidth(CallerType aCallerType, | |||
| 3756 | double* aWidth) { | |||
| 3757 | ErrorResult rv; | |||
| 3758 | *aWidth = GetInnerWidth(aCallerType, rv); | |||
| 3759 | return rv.StealNSResult(); | |||
| 3760 | } | |||
| 3761 | ||||
| 3762 | double nsGlobalWindowInner::GetInnerHeight(CallerType aCallerType, | |||
| 3763 | ErrorResult& aError) { | |||
| 3764 | FORWARD_TO_OUTER_OR_THROW(GetInnerHeightOuter, (aCallerType, aError), aError, | |||
| 3765 | 0); | |||
| 3766 | } | |||
| 3767 | ||||
| 3768 | nsresult nsGlobalWindowInner::GetInnerHeight(CallerType aCallerType, | |||
| 3769 | double* aHeight) { | |||
| 3770 | ErrorResult rv; | |||
| 3771 | *aHeight = GetInnerHeight(aCallerType, rv); | |||
| 3772 | return rv.StealNSResult(); | |||
| 3773 | } | |||
| 3774 | ||||
| 3775 | int32_t nsGlobalWindowInner::GetOuterWidth(CallerType aCallerType, | |||
| 3776 | ErrorResult& aError) { | |||
| 3777 | FORWARD_TO_OUTER_OR_THROW(GetOuterWidthOuter, (aCallerType, aError), aError, | |||
| 3778 | 0); | |||
| 3779 | } | |||
| 3780 | ||||
| 3781 | int32_t nsGlobalWindowInner::GetOuterHeight(CallerType aCallerType, | |||
| 3782 | ErrorResult& aError) { | |||
| 3783 | FORWARD_TO_OUTER_OR_THROW(GetOuterHeightOuter, (aCallerType, aError), aError, | |||
| 3784 | 0); | |||
| 3785 | } | |||
| 3786 | ||||
| 3787 | double nsGlobalWindowInner::ScreenEdgeSlopX() const { | |||
| 3788 | FORWARD_TO_OUTER(ScreenEdgeSlopX, (), 0); | |||
| 3789 | } | |||
| 3790 | ||||
| 3791 | double nsGlobalWindowInner::ScreenEdgeSlopY() const { | |||
| 3792 | FORWARD_TO_OUTER(ScreenEdgeSlopY, (), 0); | |||
| 3793 | } | |||
| 3794 | ||||
| 3795 | int32_t nsGlobalWindowInner::GetScreenX(CallerType aCallerType, | |||
| 3796 | ErrorResult& aError) { | |||
| 3797 | FORWARD_TO_OUTER_OR_THROW(GetScreenXOuter, (aCallerType, aError), aError, 0); | |||
| 3798 | } | |||
| 3799 | ||||
| 3800 | int32_t nsGlobalWindowInner::GetScreenY(CallerType aCallerType, | |||
| 3801 | ErrorResult& aError) { | |||
| 3802 | FORWARD_TO_OUTER_OR_THROW(GetScreenYOuter, (aCallerType, aError), aError, 0); | |||
| 3803 | } | |||
| 3804 | ||||
| 3805 | float nsGlobalWindowInner::GetMozInnerScreenX(CallerType aCallerType, | |||
| 3806 | ErrorResult& aError) { | |||
| 3807 | FORWARD_TO_OUTER_OR_THROW(GetMozInnerScreenXOuter, (aCallerType), aError, 0); | |||
| 3808 | } | |||
| 3809 | ||||
| 3810 | float nsGlobalWindowInner::GetMozInnerScreenY(CallerType aCallerType, | |||
| 3811 | ErrorResult& aError) { | |||
| 3812 | FORWARD_TO_OUTER_OR_THROW(GetMozInnerScreenYOuter, (aCallerType), aError, 0); | |||
| 3813 | } | |||
| 3814 | ||||
| 3815 | static nsPresContext* GetPresContextForRatio(Document* aDoc) { | |||
| 3816 | if (nsPresContext* presContext = aDoc->GetPresContext()) { | |||
| 3817 | return presContext; | |||
| 3818 | } | |||
| 3819 | // We're in an undisplayed subdocument... There's not really an awesome way | |||
| 3820 | // to tell what the right DPI is from here, so we try to walk up our parent | |||
| 3821 | // document chain to the extent that the docs can observe each other. | |||
| 3822 | Document* doc = aDoc; | |||
| 3823 | while (doc->StyleOrLayoutObservablyDependsOnParentDocumentLayout()) { | |||
| 3824 | doc = doc->GetInProcessParentDocument(); | |||
| 3825 | if (nsPresContext* presContext = doc->GetPresContext()) { | |||
| 3826 | return presContext; | |||
| 3827 | } | |||
| 3828 | } | |||
| 3829 | return nullptr; | |||
| 3830 | } | |||
| 3831 | ||||
| 3832 | double nsGlobalWindowInner::GetDevicePixelRatio(CallerType aCallerType, | |||
| 3833 | ErrorResult& aError) { | |||
| 3834 | 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); | |||
| 3835 | ||||
| 3836 | RefPtr<nsPresContext> presContext = GetPresContextForRatio(mDoc); | |||
| 3837 | if (NS_WARN_IF(!presContext)NS_warn_if_impl(!presContext, "!presContext", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp" , 3837)) { | |||
| 3838 | // Still nothing, oh well. | |||
| 3839 | return 1.0; | |||
| 3840 | } | |||
| 3841 | ||||
| 3842 | if (nsIGlobalObject::ShouldResistFingerprinting( | |||
| 3843 | aCallerType, RFPTarget::WindowDevicePixelRatio)) { | |||
| 3844 | return nsRFPService::GetDevicePixelRatioAtZoom(presContext->GetFullZoom()); | |||
| 3845 | } | |||
| 3846 | ||||
| 3847 | if (aCallerType == CallerType::NonSystem) { | |||
| 3848 | float overrideDPPX = presContext->GetOverrideDPPX(); | |||
| 3849 | if (overrideDPPX > 0.0f) { | |||
| 3850 | return overrideDPPX; | |||
| 3851 | } | |||
| 3852 | } | |||
| 3853 | ||||
| 3854 | return double(AppUnitsPerCSSPixel()) / | |||
| 3855 | double(presContext->AppUnitsPerDevPixel()); | |||
| 3856 | } | |||
| 3857 | ||||
| 3858 | double nsGlobalWindowInner::GetDesktopToDeviceScale(ErrorResult& aError) { | |||
| 3859 | 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); | |||
| 3860 | nsPresContext* presContext = GetPresContextForRatio(mDoc); | |||
| 3861 | if (!presContext) { | |||
| 3862 | return 1.0; | |||
| 3863 | } | |||
| 3864 | return presContext->DeviceContext()->GetDesktopToDeviceScale().scale; | |||
| 3865 | } | |||
| 3866 | ||||
| 3867 | uint32_t nsGlobalWindowInner::RequestAnimationFrame( | |||
| 3868 | FrameRequestCallback& aCallback, ErrorResult& aError) { | |||
| 3869 | if (!mDoc) { | |||
| 3870 | return 0; | |||
| 3871 | } | |||
| 3872 | ||||
| 3873 | if (GetWrapperPreserveColor()) { | |||
| 3874 | js::NotifyAnimationActivity(GetWrapperPreserveColor()); | |||
| 3875 | } | |||
| 3876 | ||||
| 3877 | DebuggerNotificationDispatch(this, | |||
| 3878 | DebuggerNotificationType::RequestAnimationFrame); | |||
| 3879 | ||||
| 3880 | uint32_t handle; | |||
| 3881 | aError = mDoc->ScheduleFrameRequestCallback(aCallback, &handle); | |||
| 3882 | return handle; | |||
| 3883 | } | |||
| 3884 | ||||
| 3885 | void nsGlobalWindowInner::CancelAnimationFrame(uint32_t aHandle, | |||
| 3886 | ErrorResult& aError) { | |||
| 3887 | if (!mDoc) { | |||
| 3888 | return; | |||
| 3889 | } | |||
| 3890 | ||||
| 3891 | DebuggerNotificationDispatch(this, | |||
| 3892 | DebuggerNotificationType::CancelAnimationFrame); | |||
| 3893 | ||||
| 3894 | mDoc->CancelFrameRequestCallback(aHandle); | |||
| 3895 | } | |||
| 3896 | ||||
| 3897 | already_AddRefed<MediaQueryList> nsGlobalWindowInner::MatchMedia( | |||
| 3898 | const nsACString& aMediaQueryList, CallerType aCallerType, | |||
| 3899 | ErrorResult& aError) { | |||
| 3900 | ENSURE_ACTIVE_DOCUMENT(aError, nullptr)do { if ((__builtin_expect(!!(!HasActiveDocument()), 0))) { aError .Throw(NS_ERROR_XPC_SECURITY_MANAGER_VETO); return nullptr; } } while (0); | |||
| 3901 | return mDoc->MatchMedia(aMediaQueryList, aCallerType); | |||
| 3902 | } | |||
| 3903 | ||||
| 3904 | int32_t nsGlobalWindowInner::GetScrollMinX(ErrorResult& aError) { | |||
| 3905 | FORWARD_TO_OUTER_OR_THROW(GetScrollBoundaryOuter, (eSideLeft), aError, 0); | |||
| 3906 | } | |||
| 3907 | ||||
| 3908 | int32_t nsGlobalWindowInner::GetScrollMinY(ErrorResult& aError) { | |||
| 3909 | FORWARD_TO_OUTER_OR_THROW(GetScrollBoundaryOuter, (eSideTop), aError, 0); | |||
| 3910 | } | |||
| 3911 | ||||
| 3912 | int32_t nsGlobalWindowInner::GetScrollMaxX(ErrorResult& aError) { | |||
| 3913 | FORWARD_TO_OUTER_OR_THROW(GetScrollBoundaryOuter, (eSideRight), aError, 0); | |||
| 3914 | } | |||
| 3915 | ||||
| 3916 | int32_t nsGlobalWindowInner::GetScrollMaxY(ErrorResult& aError) { | |||
| 3917 | FORWARD_TO_OUTER_OR_THROW(GetScrollBoundaryOuter, (eSideBottom), aError, 0); | |||
| 3918 | } | |||
| 3919 | ||||
| 3920 | double nsGlobalWindowInner::GetScrollX(ErrorResult& aError) { | |||
| 3921 | FORWARD_TO_OUTER_OR_THROW(GetScrollXOuter, (), aError, 0); | |||
| 3922 | } | |||
| 3923 | ||||
| 3924 | double nsGlobalWindowInner::GetScrollY(ErrorResult& aError) { | |||
| 3925 | FORWARD_TO_OUTER_OR_THROW(GetScrollYOuter, (), aError, 0); | |||
| 3926 | } | |||
| 3927 | ||||
| 3928 | uint32_t nsGlobalWindowInner::Length() { FORWARD_TO_OUTER(Length, (), 0); } | |||
| 3929 | ||||
| 3930 | Nullable<WindowProxyHolder> nsGlobalWindowInner::GetTop( | |||
| 3931 | mozilla::ErrorResult& aError) { | |||
| 3932 | FORWARD_TO_OUTER_OR_THROW(GetTopOuter, (), aError, nullptr); | |||
| 3933 | } | |||
| 3934 | ||||
| 3935 | already_AddRefed<BrowsingContext> nsGlobalWindowInner::GetChildWindow( | |||
| 3936 | const nsAString& aName) { | |||
| 3937 | if (GetOuterWindowInternal()) { | |||
| 3938 | return GetOuterWindowInternal()->GetChildWindow(aName); | |||
| 3939 | } | |||
| 3940 | return nullptr; | |||
| 3941 | } | |||
| 3942 | ||||
| 3943 | void nsGlobalWindowInner::RefreshRealmPrincipal() { | |||
| 3944 | JS::Realm* realm = js::GetNonCCWObjectRealm(GetWrapperPreserveColor()); | |||
| 3945 | nsJSPrincipals* existing = nsJSPrincipals::get(JS::GetRealmPrincipals(realm)); | |||
| 3946 | nsJSPrincipals* jsPrincipals = nsJSPrincipals::get(mDoc->NodePrincipal()); | |||
| 3947 | if (existing != jsPrincipals) { | |||
| 3948 | HoldOldPrincipal(existing); | |||
| 3949 | } | |||
| 3950 | JS::SetRealmPrincipals(realm, jsPrincipals); | |||
| 3951 | } | |||
| 3952 | ||||
| 3953 | void nsGlobalWindowInner::RefreshReduceTimerPrecisionCallerType() { | |||
| 3954 | JS::SetRealmReduceTimerPrecisionCallerType( | |||
| 3955 | js::GetNonCCWObjectRealm(GetWrapperPreserveColor()), | |||
| 3956 | RTPCallerTypeToToken(GetRTPCallerType())); | |||
| 3957 | } | |||
| 3958 | ||||
| 3959 | already_AddRefed<nsIWidget> nsGlobalWindowInner::GetMainWidget() const { | |||
| 3960 | FORWARD_TO_OUTER(GetMainWidget, (), nullptr); | |||
| 3961 | } | |||
| 3962 | ||||
| 3963 | nsIWidget* nsGlobalWindowInner::GetNearestWidget() const { | |||
| 3964 | if (GetOuterWindowInternal()) { | |||
| 3965 | return GetOuterWindowInternal()->GetNearestWidget(); | |||
| 3966 | } | |||
| 3967 | return nullptr; | |||
| 3968 | } | |||
| 3969 | ||||
| 3970 | void nsGlobalWindowInner::SetFullScreen(bool aFullscreen, | |||
| 3971 | CallerType aCallerType, | |||
| 3972 | ErrorResult& aError) { | |||
| 3973 | if (aCallerType == CallerType::NonSystem) { | |||
| 3974 | if (Document* doc = GetExtantDoc()) { | |||
| 3975 | doc->WarnOnceAndReportAbout(DeprecatedOperations::eFullscreenAttribute); | |||
| 3976 | } | |||
| 3977 | } | |||
| 3978 | FORWARD_TO_OUTER_OR_THROW(SetFullscreenOuter, (aFullscreen, aError), aError, | |||
| 3979 | /* void */); | |||
| 3980 | } | |||
| 3981 | ||||
| 3982 | bool nsGlobalWindowInner::GetFullScreen(CallerType aCallerType, | |||
| 3983 | ErrorResult& aError) { | |||
| 3984 | if (aCallerType == CallerType::NonSystem) { | |||
| 3985 | if (Document* doc = GetExtantDoc()) { | |||
| 3986 | doc->WarnOnceAndReportAbout(DeprecatedOperations::eFullscreenAttribute); | |||
| 3987 | } | |||
| 3988 | } | |||
| 3989 | FORWARD_TO_OUTER_OR_THROW(GetFullscreenOuter, (), aError, false); | |||
| 3990 | } | |||
| 3991 | ||||
| 3992 | bool nsGlobalWindowInner::GetFullScreen() { | |||
| 3993 | bool fullscreen = GetFullScreen(CallerType::System, IgnoreErrors()); | |||
| 3994 | return fullscreen; | |||
| 3995 | } | |||
| 3996 | ||||
| 3997 | void nsGlobalWindowInner::Dump(const nsAString& aStr) { | |||
| 3998 | if (!nsJSUtils::DumpEnabled()) { | |||
| 3999 | return; | |||
| 4000 | } | |||
| 4001 | ||||
| 4002 | char* cstr = ToNewUTF8String(aStr); | |||
| 4003 | ||||
| 4004 | #if defined(XP_MACOSX) | |||
| 4005 | // have to convert \r to \n so that printing to the console works | |||
| 4006 | char *c = cstr, *cEnd = cstr + strlen(cstr); | |||
| 4007 | while (c < cEnd) { | |||
| 4008 | if (*c == '\r') *c = '\n'; | |||
| 4009 | c++; | |||
| 4010 | } | |||
| 4011 | #endif | |||
| 4012 | ||||
| 4013 | if (cstr) { | |||
| 4014 | 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) | |||
| 4015 | ("[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); | |||
| 4016 | #ifdef XP_WIN | |||
| 4017 | PrintToDebugger(cstr); | |||
| 4018 | #endif | |||
| 4019 | #ifdef ANDROID | |||
| 4020 | __android_log_write(ANDROID_LOG_INFO, "GeckoDump", cstr); | |||
| 4021 | #endif | |||
| 4022 | FILE* fp = gDumpFile ? gDumpFile : stdoutstdout; | |||
| 4023 | fputs(cstr, fp); | |||
| 4024 | fflush(fp); | |||
| 4025 | free(cstr); | |||
| 4026 | } | |||
| 4027 | } | |||
| 4028 | ||||
| 4029 | void nsGlobalWindowInner::Alert(nsIPrincipal& aSubjectPrincipal, | |||
| 4030 | ErrorResult& aError) { | |||
| 4031 | Alert(u""_ns, aSubjectPrincipal, aError); | |||
| 4032 | } | |||
| 4033 | ||||
| 4034 | void nsGlobalWindowInner::Alert(const nsAString& aMessage, | |||
| 4035 | nsIPrincipal& aSubjectPrincipal, | |||
| 4036 | ErrorResult& aError) { | |||
| 4037 | FORWARD_TO_OUTER_OR_THROW(AlertOuter, (aMessage, aSubjectPrincipal, aError), | |||
| 4038 | aError, ); | |||
| 4039 | } | |||
| 4040 | ||||
| 4041 | bool nsGlobalWindowInner::Confirm(const nsAString& aMessage, | |||
| 4042 | nsIPrincipal& aSubjectPrincipal, | |||
| 4043 | ErrorResult& aError) { | |||
| 4044 | FORWARD_TO_OUTER_OR_THROW(ConfirmOuter, (aMessage, aSubjectPrincipal, aError), | |||
| 4045 | aError, false); | |||
| 4046 | } | |||
| 4047 | ||||
| 4048 | already_AddRefed<Promise> nsGlobalWindowInner::Fetch( | |||
| 4049 | const RequestOrUTF8String& aInput, const RequestInit& aInit, | |||
| 4050 | CallerType aCallerType, ErrorResult& aRv) { | |||
| 4051 | return FetchRequest(this, aInput, aInit, aCallerType, aRv); | |||
| 4052 | } | |||
| 4053 | ||||
| 4054 | void nsGlobalWindowInner::Prompt(const nsAString& aMessage, | |||
| 4055 | const nsAString& aInitial, nsAString& aReturn, | |||
| 4056 | nsIPrincipal& aSubjectPrincipal, | |||
| 4057 | ErrorResult& aError) { | |||
| 4058 | FORWARD_TO_OUTER_OR_THROW( | |||
| 4059 | PromptOuter, (aMessage, aInitial, aReturn, aSubjectPrincipal, aError), | |||
| 4060 | aError, ); | |||
| 4061 | } | |||
| 4062 | ||||
| 4063 | void nsGlobalWindowInner::Focus(CallerType aCallerType, ErrorResult& aError) { | |||
| 4064 | FORWARD_TO_OUTER_OR_THROW(FocusOuter, | |||
| 4065 | (aCallerType, /* aFromOtherProcess */ false, | |||
| 4066 | nsFocusManager::GenerateFocusActionId()), | |||
| 4067 | aError, ); | |||
| 4068 | } | |||
| 4069 | ||||
| 4070 | nsresult nsGlobalWindowInner::Focus(CallerType aCallerType) { | |||
| 4071 | ErrorResult rv; | |||
| 4072 | Focus(aCallerType, rv); | |||
| 4073 | ||||
| 4074 | return rv.StealNSResult(); | |||
| 4075 | } | |||
| 4076 | ||||
| 4077 | void nsGlobalWindowInner::Blur(CallerType aCallerType, ErrorResult& aError) { | |||
| 4078 | FORWARD_TO_OUTER_OR_THROW(BlurOuter, (aCallerType), aError, ); | |||
| 4079 | } | |||
| 4080 | ||||
| 4081 | void nsGlobalWindowInner::Stop(ErrorResult& aError) { | |||
| 4082 | FORWARD_TO_OUTER_OR_THROW(StopOuter, (aError), aError, ); | |||
| 4083 | } | |||
| 4084 | ||||
| 4085 | void nsGlobalWindowInner::Print(ErrorResult& aError) { | |||
| 4086 | FORWARD_TO_OUTER_OR_THROW(PrintOuter, (aError), aError, ); | |||
| 4087 | } | |||
| 4088 | ||||
| 4089 | Nullable<WindowProxyHolder> nsGlobalWindowInner::PrintPreview( | |||
| 4090 | nsIPrintSettings* aSettings, nsIWebProgressListener* aListener, | |||
| 4091 | nsIDocShell* aDocShellToCloneInto, ErrorResult& aError) { | |||
| 4092 | FORWARD_TO_OUTER_OR_THROW( | |||
| 4093 | Print, | |||
| 4094 | (aSettings, | |||
| 4095 | /* aRemotePrintJob = */ nullptr, aListener, aDocShellToCloneInto, | |||
| 4096 | nsGlobalWindowOuter::IsPreview::Yes, | |||
| 4097 | nsGlobalWindowOuter::IsForWindowDotPrint::No, | |||
| 4098 | /* aPrintPreviewCallback = */ nullptr, nullptr, aError), | |||
| 4099 | aError, nullptr); | |||
| 4100 | } | |||
| 4101 | ||||
| 4102 | void nsGlobalWindowInner::MoveTo(int32_t aXPos, int32_t aYPos, | |||
| 4103 | CallerType aCallerType, ErrorResult& aError) { | |||
| 4104 | FORWARD_TO_OUTER_OR_THROW(MoveToOuter, (aXPos, aYPos, aCallerType, aError), | |||
| 4105 | aError, ); | |||
| 4106 | } | |||
| 4107 | ||||
| 4108 | void nsGlobalWindowInner::MoveBy(int32_t aXDif, int32_t aYDif, | |||
| 4109 | CallerType aCallerType, ErrorResult& aError) { | |||
| 4110 | FORWARD_TO_OUTER_OR_THROW(MoveByOuter, (aXDif, aYDif, aCallerType, aError), | |||
| 4111 | aError, ); | |||
| 4112 | } | |||
| 4113 | ||||
| 4114 | void nsGlobalWindowInner::ResizeTo(int32_t aWidth, int32_t aHeight, | |||
| 4115 | CallerType aCallerType, | |||
| 4116 | ErrorResult& aError) { | |||
| 4117 | FORWARD_TO_OUTER_OR_THROW(ResizeToOuter, | |||
| 4118 | (aWidth, aHeight, aCallerType, aError), aError, ); | |||
| 4119 | } | |||
| 4120 | ||||
| 4121 | void nsGlobalWindowInner::ResizeBy(int32_t aWidthDif, int32_t aHeightDif, | |||
| 4122 | CallerType aCallerType, | |||
| 4123 | ErrorResult& aError) { | |||
| 4124 | FORWARD_TO_OUTER_OR_THROW( | |||
| 4125 | ResizeByOuter, (aWidthDif, aHeightDif, aCallerType, aError), aError, ); | |||
| 4126 | } | |||
| 4127 | ||||
| 4128 | void nsGlobalWindowInner::MoveResize(int32_t aX, int32_t aY, int32_t aWidth, | |||
| 4129 | int32_t aHeight, ErrorResult& aError) { | |||
| 4130 | const auto callerType = CallerType::System; // We're ChromeOnly | |||
| 4131 | FORWARD_TO_OUTER_OR_THROW( | |||
| 4132 | MoveResizeOuter, (aX, aY, aWidth, aHeight, callerType, aError), aError, ); | |||
| 4133 | } | |||
| 4134 | ||||
| 4135 | void nsGlobalWindowInner::SizeToContent( | |||
| 4136 | const SizeToContentConstraints& aConstraints, ErrorResult& aError) { | |||
| 4137 | FORWARD_TO_OUTER_OR_THROW(SizeToContentOuter, (aConstraints, aError), | |||
| 4138 | aError, ); | |||
| 4139 | } | |||
| 4140 | ||||
| 4141 | already_AddRefed<nsPIWindowRoot> nsGlobalWindowInner::GetTopWindowRoot() { | |||
| 4142 | nsGlobalWindowOuter* outer = GetOuterWindowInternal(); | |||
| 4143 | if (!outer) { | |||
| 4144 | return nullptr; | |||
| 4145 | } | |||
| 4146 | return outer->GetTopWindowRoot(); | |||
| 4147 | } | |||
| 4148 | ||||
| 4149 | void nsGlobalWindowInner::ScrollTo(double aXScroll, double aYScroll) { | |||
| 4150 | ScrollToOptions options; | |||
| 4151 | options.mLeft.Construct(aXScroll); | |||
| 4152 | options.mTop.Construct(aYScroll); | |||
| 4153 | ScrollTo(options); | |||
| 4154 | } | |||
| 4155 | ||||
| 4156 | void nsGlobalWindowInner::ScrollTo(const ScrollToOptions& aOptions) { | |||
| 4157 | Maybe<double> left; | |||
| 4158 | Maybe<double> top; | |||
| 4159 | if (aOptions.mLeft.WasPassed()) { | |||
| 4160 | left.emplace(ToZeroIfNonfinite(aOptions.mLeft.Value())); | |||
| 4161 | } | |||
| 4162 | if (aOptions.mTop.WasPassed()) { | |||
| 4163 | top.emplace(ToZeroIfNonfinite(aOptions.mTop.Value())); | |||
| 4164 | } | |||
| 4165 | ||||
| 4166 | // When scrolling to a non-zero offset, we need to determine whether that | |||
| 4167 | // position is within our scrollable range, so we need updated layout | |||
| 4168 | // information. | |||
| 4169 | if ((top && *top != 0) || (left && *left != 0)) { | |||
| 4170 | FlushPendingNotifications(FlushType::Layout); | |||
| 4171 | } | |||
| 4172 | ||||
| 4173 | ScrollContainerFrame* sf = GetScrollContainerFrame(); | |||
| 4174 | if (!sf) { | |||
| 4175 | return; | |||
| 4176 | } | |||
| 4177 | CSSPoint scrollPos = sf->GetScrollPositionCSSPixels(); | |||
| 4178 | if (left) { | |||
| 4179 | scrollPos.x = *left; | |||
| 4180 | } | |||
| 4181 | if (top) { | |||
| 4182 | scrollPos.y = *top; | |||
| 4183 | } | |||
| 4184 | // Here we calculate what the max pixel value is that we can | |||
| 4185 | // scroll to, we do this by dividing maxint with the pixel to | |||
| 4186 | // twips conversion factor, and subtracting 4, the 4 comes from | |||
| 4187 | // experimenting with this value, anything less makes the view | |||
| 4188 | // code not scroll correctly, I have no idea why. -- jst | |||
| 4189 | // | |||
| 4190 | // FIXME(emilio): This seems like if needed it should be done by the | |||
| 4191 | // scrolling code itself... | |||
| 4192 | const double maxpx = CSSPixel::FromAppUnits(0x7fffffff) - 4; | |||
| 4193 | if (scrollPos.x > maxpx) { | |||
| 4194 | scrollPos.x = maxpx; | |||
| 4195 | } | |||
| 4196 | if (scrollPos.y > maxpx) { | |||
| 4197 | scrollPos.y = maxpx; | |||
| 4198 | } | |||
| 4199 | auto scrollMode = sf->ScrollModeForScrollBehavior(aOptions.mBehavior); | |||
| 4200 | sf->ScrollToCSSPixels(scrollPos, scrollMode); | |||
| 4201 | } | |||
| 4202 | ||||
| 4203 | void nsGlobalWindowInner::ScrollBy(double aXScrollDif, double aYScrollDif) { | |||
| 4204 | ScrollToOptions options; | |||
| 4205 | options.mLeft.Construct(aXScrollDif); | |||
| 4206 | options.mTop.Construct(aYScrollDif); | |||
| 4207 | // It seems like it would make more sense for ScrollBy to use | |||
| 4208 | // SMOOTH mode, but tests seem to depend on the synchronous behaviour. | |||
| 4209 | // Perhaps Web content does too. | |||
| 4210 | ScrollBy(options); | |||
| 4211 | } | |||
| 4212 | ||||
| 4213 | void nsGlobalWindowInner::ScrollBy(const ScrollToOptions& aOptions) { | |||
| 4214 | CSSPoint scrollDelta; | |||
| 4215 | if (aOptions.mLeft.WasPassed()) { | |||
| 4216 | scrollDelta.x = ToZeroIfNonfinite(aOptions.mLeft.Value()); | |||
| 4217 | } | |||
| 4218 | if (aOptions.mTop.WasPassed()) { | |||
| 4219 | scrollDelta.y = ToZeroIfNonfinite(aOptions.mTop.Value()); | |||
| 4220 | } | |||
| 4221 | ||||
| 4222 | if (!scrollDelta.x && !scrollDelta.y) { | |||
| 4223 | return; | |||
| 4224 | } | |||
| 4225 | ||||
| 4226 | FlushPendingNotifications(FlushType::Layout); | |||
| 4227 | ScrollContainerFrame* sf = GetScrollContainerFrame(); | |||
| 4228 | if (!sf) { | |||
| 4229 | return; | |||
| 4230 | } | |||
| 4231 | ||||
| 4232 | auto scrollMode = sf->ScrollModeForScrollBehavior(aOptions.mBehavior); | |||
| 4233 | sf->ScrollByCSSPixels(scrollDelta, scrollMode); | |||
| 4234 | } | |||
| 4235 | ||||
| 4236 | void nsGlobalWindowInner::ScrollByLines(int32_t numLines, | |||
| 4237 | const ScrollOptions& aOptions) { | |||
| 4238 | if (!numLines) { | |||
| 4239 | return; | |||
| 4240 | } | |||
| 4241 | FlushPendingNotifications(FlushType::Layout); | |||
| 4242 | ScrollContainerFrame* sf = GetScrollContainerFrame(); | |||
| 4243 | if (!sf) { | |||
| 4244 | return; | |||
| 4245 | } | |||
| 4246 | // It seems like it would make more sense for ScrollByLines to use | |||
| 4247 | // SMOOTH mode, but tests seem to depend on the synchronous behaviour. | |||
| 4248 | // Perhaps Web content does too. | |||
| 4249 | ScrollMode scrollMode = sf->ScrollModeForScrollBehavior(aOptions.mBehavior); | |||
| 4250 | sf->ScrollBy(nsIntPoint(0, numLines), ScrollUnit::LINES, scrollMode); | |||
| 4251 | } | |||
| 4252 | ||||
| 4253 | void nsGlobalWindowInner::ScrollByPages(int32_t numPages, | |||
| 4254 | const ScrollOptions& aOptions) { | |||
| 4255 | if (!numPages) { | |||
| 4256 | return; | |||
| 4257 | } | |||
| 4258 | FlushPendingNotifications(FlushType::Layout); | |||
| 4259 | ScrollContainerFrame* sf = GetScrollContainerFrame(); | |||
| 4260 | if (!sf) { | |||
| 4261 | return; | |||
| 4262 | } | |||
| 4263 | // It seems like it would make more sense for ScrollByPages to use | |||
| 4264 | // SMOOTH mode, but tests seem to depend on the synchronous behaviour. | |||
| 4265 | // Perhaps Web content does too. | |||
| 4266 | ScrollMode scrollMode = sf->ScrollModeForScrollBehavior(aOptions.mBehavior); | |||
| 4267 | ||||
| 4268 | sf->ScrollBy(nsIntPoint(0, numPages), ScrollUnit::PAGES, scrollMode); | |||
| 4269 | } | |||
| 4270 | ||||
| 4271 | void nsGlobalWindowInner::MozScrollSnap() { | |||
| 4272 | FlushPendingNotifications(FlushType::Layout); | |||
| 4273 | if (ScrollContainerFrame* sf = GetScrollContainerFrame()) { | |||
| 4274 | sf->ScrollSnap(); | |||
| 4275 | } | |||
| 4276 | } | |||
| 4277 | ||||
| 4278 | void nsGlobalWindowInner::ClearTimeout(int32_t aHandle) { | |||
| 4279 | DebuggerNotificationDispatch(this, DebuggerNotificationType::ClearTimeout); | |||
| 4280 | ||||
| 4281 | if (aHandle > 0) { | |||
| 4282 | mTimeoutManager->ClearTimeout(aHandle, Timeout::Reason::eTimeoutOrInterval); | |||
| 4283 | } | |||
| 4284 | } | |||
| 4285 | ||||
| 4286 | void nsGlobalWindowInner::ClearInterval(int32_t aHandle) { | |||
| 4287 | DebuggerNotificationDispatch(this, DebuggerNotificationType::ClearInterval); | |||
| 4288 | ||||
| 4289 | if (aHandle > 0) { | |||
| 4290 | mTimeoutManager->ClearTimeout(aHandle, Timeout::Reason::eTimeoutOrInterval); | |||
| 4291 | } | |||
| 4292 | } | |||
| 4293 | ||||
| 4294 | void nsGlobalWindowInner::SetResizable(bool aResizable) const { | |||
| 4295 | // nop | |||
| 4296 | } | |||
| 4297 | ||||
| 4298 | void nsGlobalWindowInner::CaptureEvents() { | |||
| 4299 | // Intentionally a no-op, as this API is deprecated. | |||
| 4300 | } | |||
| 4301 | ||||
| 4302 | void nsGlobalWindowInner::ReleaseEvents() { | |||
| 4303 | // Intentionally a no-op, as this API is deprecated. | |||
| 4304 | } | |||
| 4305 | ||||
| 4306 | Nullable<WindowProxyHolder> nsGlobalWindowInner::Open(const nsAString& aUrl, | |||
| 4307 | const nsAString& aName, | |||
| 4308 | const nsAString& aOptions, | |||
| 4309 | ErrorResult& aError) { | |||
| 4310 | FORWARD_TO_OUTER_OR_THROW(OpenOuter, (aUrl, aName, aOptions, aError), aError, | |||
| 4311 | nullptr); | |||
| 4312 | } | |||
| 4313 | ||||
| 4314 | Nullable<WindowProxyHolder> nsGlobalWindowInner::OpenDialog( | |||
| 4315 | JSContext* aCx, const nsAString& aUrl, const nsAString& aName, | |||
| 4316 | const nsAString& aOptions, const Sequence<JS::Value>& aExtraArgument, | |||
| 4317 | ErrorResult& aError) { | |||
| 4318 | FORWARD_TO_OUTER_OR_THROW( | |||
| 4319 | OpenDialogOuter, (aCx, aUrl, aName, aOptions, aExtraArgument, aError), | |||
| 4320 | aError, nullptr); | |||
| 4321 | } | |||
| 4322 | ||||
| 4323 | WindowProxyHolder nsGlobalWindowInner::GetFrames(ErrorResult& aError) { | |||
| 4324 | FORWARD_TO_OUTER_OR_THROW(GetFramesOuter, (), aError, Window()); | |||
| 4325 | } | |||
| 4326 | ||||
| 4327 | void nsGlobalWindowInner::PostMessageMoz(JSContext* aCx, | |||
| 4328 | JS::Handle<JS::Value> aMessage, | |||
| 4329 | const nsAString& aTargetOrigin, | |||
| 4330 | JS::Handle<JS::Value> aTransfer, | |||
| 4331 | nsIPrincipal& aSubjectPrincipal, | |||
| 4332 | ErrorResult& aError) { | |||
| 4333 | FORWARD_TO_OUTER_OR_THROW( | |||
| 4334 | PostMessageMozOuter, | |||
| 4335 | (aCx, aMessage, aTargetOrigin, aTransfer, aSubjectPrincipal, aError), | |||
| 4336 | aError, ); | |||
| 4337 | } | |||
| 4338 | ||||
| 4339 | void nsGlobalWindowInner::PostMessageMoz(JSContext* aCx, | |||
| 4340 | JS::Handle<JS::Value> aMessage, | |||
| 4341 | const nsAString& aTargetOrigin, | |||
| 4342 | const Sequence<JSObject*>& aTransfer, | |||
| 4343 | nsIPrincipal& aSubjectPrincipal, | |||
| 4344 | ErrorResult& aRv) { | |||
| 4345 | JS::Rooted<JS::Value> transferArray(aCx, JS::UndefinedValue()); | |||
| 4346 | ||||
| 4347 | aRv = nsContentUtils::CreateJSValueFromSequenceOfObject(aCx, aTransfer, | |||
| 4348 | &transferArray); | |||
| 4349 | if (NS_WARN_IF(aRv.Failed())NS_warn_if_impl(aRv.Failed(), "aRv.Failed()", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp" , 4349)) { | |||
| 4350 | return; | |||
| 4351 | } | |||
| 4352 | ||||
| 4353 | PostMessageMoz(aCx, aMessage, aTargetOrigin, transferArray, aSubjectPrincipal, | |||
| 4354 | aRv); | |||
| 4355 | } | |||
| 4356 | ||||
| 4357 | void nsGlobalWindowInner::PostMessageMoz( | |||
| 4358 | JSContext* aCx, JS::Handle<JS::Value> aMessage, | |||
| 4359 | const WindowPostMessageOptions& aOptions, nsIPrincipal& aSubjectPrincipal, | |||
| 4360 | ErrorResult& aRv) { | |||
| 4361 | JS::Rooted<JS::Value> transferArray(aCx, JS::UndefinedValue()); | |||
| 4362 | ||||
| 4363 | aRv = nsContentUtils::CreateJSValueFromSequenceOfObject( | |||
| 4364 | aCx, aOptions.mTransfer, &transferArray); | |||
| 4365 | if (NS_WARN_IF(aRv.Failed())NS_warn_if_impl(aRv.Failed(), "aRv.Failed()", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp" , 4365)) { | |||
| 4366 | return; | |||
| 4367 | } | |||
| 4368 | ||||
| 4369 | PostMessageMoz(aCx, aMessage, aOptions.mTargetOrigin, transferArray, | |||
| 4370 | aSubjectPrincipal, aRv); | |||
| 4371 | } | |||
| 4372 | ||||
| 4373 | void nsGlobalWindowInner::Close(CallerType aCallerType, ErrorResult& aError) { | |||
| 4374 | FORWARD_TO_OUTER_OR_THROW(CloseOuter, (aCallerType == CallerType::System), | |||
| 4375 | aError, ); | |||
| 4376 | } | |||
| 4377 | ||||
| 4378 | nsresult nsGlobalWindowInner::Close() { | |||
| 4379 | FORWARD_TO_OUTER(Close, (), NS_ERROR_UNEXPECTED); | |||
| 4380 | } | |||
| 4381 | ||||
| 4382 | bool nsGlobalWindowInner::IsInModalState() { | |||
| 4383 | FORWARD_TO_OUTER(IsInModalState, (), false); | |||
| 4384 | } | |||
| 4385 | ||||
| 4386 | void nsGlobalWindowInner::NotifyWindowIDDestroyed(const char* aTopic) { | |||
| 4387 | RefPtr runnable = MakeRefPtr<WindowDestroyedEvent>(this, mWindowID, aTopic); | |||
| 4388 | Dispatch(runnable.forget()); | |||
| 4389 | } | |||
| 4390 | ||||
| 4391 | Element* nsGlobalWindowInner::GetFrameElement(nsIPrincipal& aSubjectPrincipal, | |||
| 4392 | ErrorResult& aError) { | |||
| 4393 | FORWARD_TO_OUTER_OR_THROW(GetFrameElement, (aSubjectPrincipal), aError, | |||
| 4394 | nullptr); | |||
| 4395 | } | |||
| 4396 | ||||
| 4397 | Element* nsGlobalWindowInner::GetRealFrameElement(ErrorResult& aError) { | |||
| 4398 | FORWARD_TO_OUTER_OR_THROW(GetFrameElement, (), aError, nullptr); | |||
| 4399 | } | |||
| 4400 | ||||
| 4401 | void nsGlobalWindowInner::UpdateCommands(const nsAString& anAction) { | |||
| 4402 | if (GetOuterWindowInternal()) { | |||
| 4403 | GetOuterWindowInternal()->UpdateCommands(anAction); | |||
| 4404 | } | |||
| 4405 | } | |||
| 4406 | ||||
| 4407 | Selection* nsGlobalWindowInner::GetSelection(ErrorResult& aError) { | |||
| 4408 | FORWARD_TO_OUTER_OR_THROW(GetSelectionOuter, (), aError, nullptr); | |||
| 4409 | } | |||
| 4410 | ||||
| 4411 | WebTaskScheduler* nsGlobalWindowInner::Scheduler() { | |||
| 4412 | if (!mWebTaskScheduler) { | |||
| 4413 | mWebTaskScheduler = WebTaskScheduler::CreateForMainThread(this); | |||
| 4414 | } | |||
| 4415 | 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", 4415 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mWebTaskScheduler" ")"); do { MOZ_CrashSequence(__null, 4415); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 4416 | return mWebTaskScheduler; | |||
| 4417 | } | |||
| 4418 | ||||
| 4419 | bool nsGlobalWindowInner::Find(const nsAString& aString, bool aCaseSensitive, | |||
| 4420 | bool aBackwards, bool aWrapAround, | |||
| 4421 | bool aWholeWord, bool aSearchInFrames, | |||
| 4422 | bool aShowDialog, ErrorResult& aError) { | |||
| 4423 | FORWARD_TO_OUTER_OR_THROW(FindOuter, | |||
| 4424 | (aString, aCaseSensitive, aBackwards, aWrapAround, | |||
| 4425 | aWholeWord, aSearchInFrames, aShowDialog, aError), | |||
| 4426 | aError, false); | |||
| 4427 | } | |||
| 4428 | ||||
| 4429 | void nsGlobalWindowInner::GetOrigin(nsAString& aOrigin) { | |||
| 4430 | nsContentUtils::GetWebExposedOriginSerialization(GetPrincipal(), aOrigin); | |||
| 4431 | } | |||
| 4432 | ||||
| 4433 | // See also AutoJSAPI::ReportException | |||
| 4434 | void nsGlobalWindowInner::ReportError(JSContext* aCx, | |||
| 4435 | JS::Handle<JS::Value> aError, | |||
| 4436 | CallerType aCallerType, | |||
| 4437 | ErrorResult& aRv) { | |||
| 4438 | if (MOZ_UNLIKELY(!HasActiveDocument())(__builtin_expect(!!(!HasActiveDocument()), 0))) { | |||
| 4439 | return aRv.Throw(NS_ERROR_XPC_SECURITY_MANAGER_VETO); | |||
| 4440 | } | |||
| 4441 | ||||
| 4442 | JS::ErrorReportBuilder jsReport(aCx); | |||
| 4443 | JS::ExceptionStack exnStack(aCx, aError, nullptr); | |||
| 4444 | if (!jsReport.init(aCx, exnStack, JS::ErrorReportBuilder::NoSideEffects)) { | |||
| 4445 | return aRv.NoteJSContextException(aCx); | |||
| 4446 | } | |||
| 4447 | ||||
| 4448 | RefPtr xpcReport = MakeRefPtr<xpc::ErrorReport>(); | |||
| 4449 | bool isChrome = aCallerType == CallerType::System; | |||
| 4450 | xpcReport->Init(jsReport.report(), jsReport.toStringResult().c_str(), | |||
| 4451 | isChrome, WindowID()); | |||
| 4452 | ||||
| 4453 | JS::RootingContext* rcx = JS::RootingContext::get(aCx); | |||
| 4454 | DispatchScriptErrorEvent(this, rcx, xpcReport, exnStack.exception(), | |||
| 4455 | exnStack.stack()); | |||
| 4456 | } | |||
| 4457 | ||||
| 4458 | void nsGlobalWindowInner::Atob(const nsAString& aAsciiBase64String, | |||
| 4459 | nsAString& aBinaryData, ErrorResult& aError) { | |||
| 4460 | aError = nsContentUtils::Atob(aAsciiBase64String, aBinaryData); | |||
| 4461 | } | |||
| 4462 | ||||
| 4463 | void nsGlobalWindowInner::Btoa(const nsAString& aBinaryData, | |||
| 4464 | nsAString& aAsciiBase64String, | |||
| 4465 | ErrorResult& aError) { | |||
| 4466 | aError = nsContentUtils::Btoa(aBinaryData, aAsciiBase64String); | |||
| 4467 | } | |||
| 4468 | ||||
| 4469 | //***************************************************************************** | |||
| 4470 | // EventTarget | |||
| 4471 | //***************************************************************************** | |||
| 4472 | ||||
| 4473 | bool nsGlobalWindowInner::DispatchEvent(Event& aEvent, CallerType aCallerType, | |||
| 4474 | ErrorResult& aRv) { | |||
| 4475 | if (!IsCurrentInnerWindow()) { | |||
| 4476 | 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" , 4478) | |||
| 4477 | "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" , 4478) | |||
| 4478 | "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" , 4478); | |||
| 4479 | aRv.Throw(NS_ERROR_FAILURE); | |||
| 4480 | return false; | |||
| 4481 | } | |||
| 4482 | ||||
| 4483 | if (!mDoc) { | |||
| 4484 | aRv.Throw(NS_ERROR_FAILURE); | |||
| 4485 | return false; | |||
| 4486 | } | |||
| 4487 | ||||
| 4488 | // Obtain a presentation shell | |||
| 4489 | RefPtr<nsPresContext> presContext = mDoc->GetPresContext(); | |||
| 4490 | ||||
| 4491 | nsEventStatus status = nsEventStatus_eIgnore; | |||
| 4492 | nsresult rv = EventDispatcher::DispatchDOMEvent(this, nullptr, &aEvent, | |||
| 4493 | presContext, &status); | |||
| 4494 | bool retval = !aEvent.DefaultPrevented(aCallerType); | |||
| 4495 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { | |||
| 4496 | aRv.Throw(rv); | |||
| 4497 | } | |||
| 4498 | return retval; | |||
| 4499 | } | |||
| 4500 | ||||
| 4501 | mozilla::Maybe<mozilla::dom::EventCallbackDebuggerNotificationType> | |||
| 4502 | nsGlobalWindowInner::GetDebuggerNotificationType() const { | |||
| 4503 | return mozilla::Some( | |||
| 4504 | mozilla::dom::EventCallbackDebuggerNotificationType::Global); | |||
| 4505 | } | |||
| 4506 | ||||
| 4507 | bool nsGlobalWindowInner::ComputeDefaultWantsUntrusted(ErrorResult& aRv) { | |||
| 4508 | return !nsContentUtils::IsChromeDoc(mDoc); | |||
| 4509 | } | |||
| 4510 | ||||
| 4511 | EventListenerManager* nsGlobalWindowInner::GetOrCreateListenerManager() { | |||
| 4512 | if (!mListenerManager) { | |||
| 4513 | mListenerManager = | |||
| 4514 | MakeRefPtr<EventListenerManager>(static_cast<EventTarget*>(this)); | |||
| 4515 | } | |||
| 4516 | ||||
| 4517 | return mListenerManager; | |||
| 4518 | } | |||
| 4519 | ||||
| 4520 | EventListenerManager* nsGlobalWindowInner::GetExistingListenerManager() const { | |||
| 4521 | return mListenerManager; | |||
| 4522 | } | |||
| 4523 | ||||
| 4524 | mozilla::dom::DebuggerNotificationManager* | |||
| 4525 | nsGlobalWindowInner::GetOrCreateDebuggerNotificationManager() { | |||
| 4526 | if (!mDebuggerNotificationManager) { | |||
| 4527 | mDebuggerNotificationManager = | |||
| 4528 | MakeRefPtr<DebuggerNotificationManager>(this); | |||
| 4529 | } | |||
| 4530 | ||||
| 4531 | return mDebuggerNotificationManager; | |||
| 4532 | } | |||
| 4533 | ||||
| 4534 | mozilla::dom::DebuggerNotificationManager* | |||
| 4535 | nsGlobalWindowInner::GetExistingDebuggerNotificationManager() { | |||
| 4536 | return mDebuggerNotificationManager; | |||
| 4537 | } | |||
| 4538 | ||||
| 4539 | //***************************************************************************** | |||
| 4540 | // nsGlobalWindowInner::nsPIDOMWindow | |||
| 4541 | //***************************************************************************** | |||
| 4542 | ||||
| 4543 | Location* nsGlobalWindowInner::Location() { | |||
| 4544 | if (!mLocation) { | |||
| 4545 | mLocation = MakeRefPtr<dom::Location>(this); | |||
| 4546 | } | |||
| 4547 | ||||
| 4548 | return mLocation; | |||
| 4549 | } | |||
| 4550 | ||||
| 4551 | void nsGlobalWindowInner::MaybeUpdateTouchState() { | |||
| 4552 | if (mMayHaveTouchEventListener) { | |||
| 4553 | nsCOMPtr<nsIObserverService> observerService = | |||
| 4554 | services::GetObserverService(); | |||
| 4555 | ||||
| 4556 | if (observerService) { | |||
| 4557 | observerService->NotifyObservers(static_cast<nsIDOMWindow*>(this), | |||
| 4558 | DOM_TOUCH_LISTENER_ADDED"dom-touch-listener-added", nullptr); | |||
| 4559 | } | |||
| 4560 | } | |||
| 4561 | } | |||
| 4562 | ||||
| 4563 | void nsGlobalWindowInner::EnableGamepadUpdates() { | |||
| 4564 | if (mHasGamepad) { | |||
| 4565 | RefPtr<GamepadManager> gamepadManager(GamepadManager::GetService()); | |||
| 4566 | if (gamepadManager) { | |||
| 4567 | gamepadManager->AddListener(this); | |||
| 4568 | } | |||
| 4569 | } | |||
| 4570 | } | |||
| 4571 | ||||
| 4572 | void nsGlobalWindowInner::DisableGamepadUpdates() { | |||
| 4573 | if (mHasGamepad) { | |||
| 4574 | RefPtr<GamepadManager> gamepadManager(GamepadManager::GetService()); | |||
| 4575 | if (gamepadManager) { | |||
| 4576 | gamepadManager->RemoveListener(this); | |||
| 4577 | } | |||
| 4578 | } | |||
| 4579 | } | |||
| 4580 | ||||
| 4581 | void nsGlobalWindowInner::EnableVRUpdates() { | |||
| 4582 | // We need to create a VREventObserver before we can either detect XR runtimes | |||
| 4583 | // or start an XR session | |||
| 4584 | if (!mVREventObserver && (mHasXRSession || mXRRuntimeDetectionInFlight)) { | |||
| 4585 | // Assert that we are not creating the observer while IsDying() as | |||
| 4586 | // that would result in a leak. VREventObserver holds a RefPtr to | |||
| 4587 | // this nsGlobalWindowInner and would prevent it from being deallocated. | |||
| 4588 | 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" , 4590); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!IsDying()" ") (" "Creating a VREventObserver for an nsGlobalWindow that is " "dying would cause it to leak." ")"); do { MOZ_CrashSequence (__null, 4590); __attribute__((nomerge)) ::abort(); } while ( false); } } while (false) | |||
| 4589 | "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" , 4590); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!IsDying()" ") (" "Creating a VREventObserver for an nsGlobalWindow that is " "dying would cause it to leak." ")"); do { MOZ_CrashSequence (__null, 4590); __attribute__((nomerge)) ::abort(); } while ( false); } } while (false) | |||
| 4590 | "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" , 4590); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!IsDying()" ") (" "Creating a VREventObserver for an nsGlobalWindow that is " "dying would cause it to leak." ")"); do { MOZ_CrashSequence (__null, 4590); __attribute__((nomerge)) ::abort(); } while ( false); } } while (false); | |||
| 4591 | mVREventObserver = MakeRefPtr<VREventObserver>(this); | |||
| 4592 | } | |||
| 4593 | // If the content has an XR session, then we need to tell | |||
| 4594 | // VREventObserver that there is VR activity. | |||
| 4595 | if (mHasXRSession) { | |||
| 4596 | nsPIDOMWindowOuter* outer = GetOuterWindow(); | |||
| 4597 | if (outer && !outer->IsBackground()) { | |||
| 4598 | StartVRActivity(); | |||
| 4599 | } | |||
| 4600 | } | |||
| 4601 | } | |||
| 4602 | ||||
| 4603 | void nsGlobalWindowInner::DisableVRUpdates() { | |||
| 4604 | if (mVREventObserver) { | |||
| 4605 | mVREventObserver->DisconnectFromOwner(); | |||
| 4606 | mVREventObserver = nullptr; | |||
| 4607 | } | |||
| 4608 | } | |||
| 4609 | ||||
| 4610 | void nsGlobalWindowInner::StartVRActivity() { | |||
| 4611 | /** | |||
| 4612 | * If the content has an XR session, tell | |||
| 4613 | * the VREventObserver that the window is accessing | |||
| 4614 | * VR devices. | |||
| 4615 | * | |||
| 4616 | * It's possible to have a VREventObserver without | |||
| 4617 | * and XR session, if we are using it to get updates | |||
| 4618 | * about XR runtime enumeration. In this case, | |||
| 4619 | * we would not tell the VREventObserver that | |||
| 4620 | * we are accessing VR devices. | |||
| 4621 | */ | |||
| 4622 | if (mVREventObserver && mHasXRSession) { | |||
| 4623 | mVREventObserver->StartActivity(); | |||
| 4624 | } | |||
| 4625 | } | |||
| 4626 | ||||
| 4627 | void nsGlobalWindowInner::StopVRActivity() { | |||
| 4628 | /** | |||
| 4629 | * If the content has an XR session, tell | |||
| 4630 | * the VReventObserver that the window is no longer | |||
| 4631 | * accessing VR devices. This does not stop the | |||
| 4632 | * XR session itself, which may be resumed with | |||
| 4633 | * EnableVRUpdates. | |||
| 4634 | * It's possible to have a VREventObserver without | |||
| 4635 | * and XR session, if we are using it to get updates | |||
| 4636 | * about XR runtime enumeration. In this case, | |||
| 4637 | * we would not tell the VREventObserver that | |||
| 4638 | * we ending an activity that accesses VR devices. | |||
| 4639 | */ | |||
| 4640 | if (mVREventObserver && mHasXRSession) { | |||
| 4641 | mVREventObserver->StopActivity(); | |||
| 4642 | } | |||
| 4643 | } | |||
| 4644 | ||||
| 4645 | void nsGlobalWindowInner::SetFocusedElement(Element* aElement, | |||
| 4646 | uint32_t aFocusMethod, | |||
| 4647 | bool aNeedsFocus) { | |||
| 4648 | if (aElement && aElement->GetComposedDoc() != mDoc) { | |||
| 4649 | 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" , 4649); | |||
| 4650 | return; | |||
| 4651 | } | |||
| 4652 | ||||
| 4653 | if (IsDying()) { | |||
| 4654 | 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" , 4654); MOZ_PretendNoReturn(); } } while (0); | |||
| 4655 | aElement = nullptr; | |||
| 4656 | aNeedsFocus = false; | |||
| 4657 | } | |||
| 4658 | if (mFocusedElement != aElement) { | |||
| 4659 | mFocusedElement = aElement; | |||
| 4660 | // TODO: Maybe this should be set on refocus too? | |||
| 4661 | mFocusMethod = aFocusMethod & nsIFocusManager::METHOD_MASK; | |||
| 4662 | } | |||
| 4663 | ||||
| 4664 | if (mFocusedElement) { | |||
| 4665 | // if a node was focused by a keypress, turn on focus rings for the | |||
| 4666 | // window. | |||
| 4667 | if (mFocusMethod & nsIFocusManager::FLAG_BYKEY) { | |||
| 4668 | mUnknownFocusMethodShouldShowOutline = true; | |||
| 4669 | mFocusByKeyOccurred = true; | |||
| 4670 | } else if (nsFocusManager::GetFocusMoveActionCause(mFocusMethod) != | |||
| 4671 | widget::InputContextAction::CAUSE_UNKNOWN) { | |||
| 4672 | mUnknownFocusMethodShouldShowOutline = false; | |||
| 4673 | } else if (aFocusMethod & nsIFocusManager::FLAG_NOSHOWRING) { | |||
| 4674 | // If we get focused via script, and script has explicitly opted out of | |||
| 4675 | // outlines via FLAG_NOSHOWRING, we don't want to make a refocus start | |||
| 4676 | // showing outlines. | |||
| 4677 | mUnknownFocusMethodShouldShowOutline = false; | |||
| 4678 | } | |||
| 4679 | } | |||
| 4680 | ||||
| 4681 | if (aNeedsFocus) { | |||
| 4682 | mNeedsFocus = aNeedsFocus; | |||
| 4683 | } | |||
| 4684 | } | |||
| 4685 | ||||
| 4686 | uint32_t nsGlobalWindowInner::GetFocusMethod() { return mFocusMethod; } | |||
| 4687 | ||||
| 4688 | bool nsGlobalWindowInner::ShouldShowFocusRing() { | |||
| 4689 | if (mFocusByKeyOccurred && | |||
| 4690 | StaticPrefs::browser_display_always_show_rings_after_key_focus()) { | |||
| 4691 | return true; | |||
| 4692 | } | |||
| 4693 | return StaticPrefs::browser_display_show_focus_rings(); | |||
| 4694 | } | |||
| 4695 | ||||
| 4696 | bool nsGlobalWindowInner::TakeFocus(bool aFocus, uint32_t aFocusMethod) { | |||
| 4697 | if (IsDying()) { | |||
| 4698 | return false; | |||
| 4699 | } | |||
| 4700 | ||||
| 4701 | if (aFocus) { | |||
| 4702 | mFocusMethod = aFocusMethod & nsIFocusManager::METHOD_MASK; | |||
| 4703 | } | |||
| 4704 | ||||
| 4705 | // if mNeedsFocus is true, then the document has not yet received a | |||
| 4706 | // document-level focus event. If there is a root content node, then return | |||
| 4707 | // true to tell the calling focus manager that a focus event is expected. If | |||
| 4708 | // there is no root content node, the document hasn't loaded enough yet, or | |||
| 4709 | // there isn't one and there is no point in firing a focus event. | |||
| 4710 | if (aFocus && mNeedsFocus && mDoc && mDoc->GetRootElement()) { | |||
| 4711 | mNeedsFocus = false; | |||
| 4712 | return true; | |||
| 4713 | } | |||
| 4714 | ||||
| 4715 | mNeedsFocus = false; | |||
| 4716 | return false; | |||
| 4717 | } | |||
| 4718 | ||||
| 4719 | void nsGlobalWindowInner::SetReadyForFocus() { | |||
| 4720 | bool oldNeedsFocus = mNeedsFocus; | |||
| 4721 | mNeedsFocus = false; | |||
| 4722 | ||||
| 4723 | if (RefPtr<nsFocusManager> fm = nsFocusManager::GetFocusManager()) { | |||
| 4724 | nsCOMPtr<nsPIDOMWindowOuter> outerWindow = GetOuterWindow(); | |||
| 4725 | fm->WindowShown(outerWindow, oldNeedsFocus); | |||
| 4726 | } | |||
| 4727 | } | |||
| 4728 | ||||
| 4729 | void nsGlobalWindowInner::PageHidden(bool aIsEnteringBFCacheInParent) { | |||
| 4730 | // the window is being hidden, so tell the focus manager that the frame is | |||
| 4731 | // no longer valid. Use the persisted field to determine if the document | |||
| 4732 | // is being destroyed. | |||
| 4733 | ||||
| 4734 | if (RefPtr<nsFocusManager> fm = nsFocusManager::GetFocusManager()) { | |||
| 4735 | nsCOMPtr<nsPIDOMWindowOuter> outerWindow = GetOuterWindow(); | |||
| 4736 | fm->WindowHidden(outerWindow, nsFocusManager::GenerateFocusActionId(), | |||
| 4737 | aIsEnteringBFCacheInParent); | |||
| 4738 | } | |||
| 4739 | ||||
| 4740 | mNeedsFocus = true; | |||
| 4741 | } | |||
| 4742 | ||||
| 4743 | class HashchangeCallback : public Runnable { | |||
| 4744 | public: | |||
| 4745 | HashchangeCallback(const nsAString& aOldURL, const nsAString& aNewURL, | |||
| 4746 | nsGlobalWindowInner* aWindow) | |||
| 4747 | : mozilla::Runnable("HashchangeCallback"), mWindow(aWindow) { | |||
| 4748 | 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" , 4748); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mWindow" ")" ); do { MOZ_CrashSequence(__null, 4748); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 4749 | mOldURL.Assign(aOldURL); | |||
| 4750 | mNewURL.Assign(aNewURL); | |||
| 4751 | } | |||
| 4752 | ||||
| 4753 | NS_IMETHODvirtual nsresult Run() override { | |||
| 4754 | 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" , 4754); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()" ") (" "Should be called on the main thread." ")"); do { MOZ_CrashSequence (__null, 4754); __attribute__((nomerge)) ::abort(); } while ( false); } } while (false); | |||
| 4755 | return mWindow->FireHashchange(mOldURL, mNewURL); | |||
| 4756 | } | |||
| 4757 | ||||
| 4758 | private: | |||
| 4759 | nsString mOldURL; | |||
| 4760 | nsString mNewURL; | |||
| 4761 | RefPtr<nsGlobalWindowInner> mWindow; | |||
| 4762 | }; | |||
| 4763 | ||||
| 4764 | nsresult nsGlobalWindowInner::DispatchAsyncHashchange(nsIURI* aOldURI, | |||
| 4765 | nsIURI* aNewURI) { | |||
| 4766 | // Make sure that aOldURI and aNewURI are identical up to the '#', and that | |||
| 4767 | // their hashes are different. | |||
| 4768 | bool equal = false; | |||
| 4769 | 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" , 4770); return NS_ERROR_UNEXPECTED; } } while (false) | |||
| 4770 | 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" , 4770); return NS_ERROR_UNEXPECTED; } } while (false); | |||
| 4771 | nsAutoCString oldHash, newHash; | |||
| 4772 | bool oldHasHash, newHasHash; | |||
| 4773 | 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" , 4777); return NS_ERROR_UNEXPECTED; } } while (false) | |||
| 4774 | 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" , 4777); return NS_ERROR_UNEXPECTED; } } while (false) | |||
| 4775 | 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" , 4777); return NS_ERROR_UNEXPECTED; } } while (false) | |||
| 4776 | 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" , 4777); return NS_ERROR_UNEXPECTED; } } while (false) | |||
| 4777 | (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" , 4777); return NS_ERROR_UNEXPECTED; } } while (false); | |||
| 4778 | ||||
| 4779 | nsAutoCString oldSpec, newSpec; | |||
| 4780 | nsresult rv = aOldURI->GetSpec(oldSpec); | |||
| 4781 | 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" , 4781); return rv; } } while (false); | |||
| 4782 | rv = aNewURI->GetSpec(newSpec); | |||
| 4783 | 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" , 4783); return rv; } } while (false); | |||
| 4784 | ||||
| 4785 | NS_ConvertUTF8toUTF16 oldWideSpec(oldSpec); | |||
| 4786 | NS_ConvertUTF8toUTF16 newWideSpec(newSpec); | |||
| 4787 | ||||
| 4788 | RefPtr callback = | |||
| 4789 | MakeRefPtr<HashchangeCallback>(oldWideSpec, newWideSpec, this); | |||
| 4790 | return Dispatch(callback.forget()); | |||
| 4791 | } | |||
| 4792 | ||||
| 4793 | nsresult nsGlobalWindowInner::FireHashchange(const nsAString& aOldURL, | |||
| 4794 | const nsAString& aNewURL) { | |||
| 4795 | // Don't do anything if the window is frozen. | |||
| 4796 | if (IsFrozen()) { | |||
| 4797 | return NS_OK; | |||
| 4798 | } | |||
| 4799 | ||||
| 4800 | // Get a presentation shell for use in creating the hashchange event. | |||
| 4801 | 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" , 4801); return NS_ERROR_UNEXPECTED; } } while (false); | |||
| 4802 | ||||
| 4803 | HashChangeEventInit init; | |||
| 4804 | init.mNewURL = aNewURL; | |||
| 4805 | init.mOldURL = aOldURL; | |||
| 4806 | ||||
| 4807 | RefPtr<HashChangeEvent> event = | |||
| 4808 | HashChangeEvent::Constructor(this, u"hashchange"_ns, init); | |||
| 4809 | ||||
| 4810 | event->SetTrusted(true); | |||
| 4811 | ||||
| 4812 | ErrorResult rv; | |||
| 4813 | DispatchEvent(*event, rv); | |||
| 4814 | return rv.StealNSResult(); | |||
| 4815 | } | |||
| 4816 | ||||
| 4817 | nsresult nsGlobalWindowInner::DispatchSyncPopState() { | |||
| 4818 | 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", 4819 ); MOZ_PretendNoReturn(); } } while (0) | |||
| 4819 | "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", 4819 ); MOZ_PretendNoReturn(); } } while (0); | |||
| 4820 | ||||
| 4821 | // Bail if the window is frozen. | |||
| 4822 | if (IsFrozen()) { | |||
| 4823 | return NS_OK; | |||
| 4824 | } | |||
| 4825 | ||||
| 4826 | AutoJSAPI jsapi; | |||
| 4827 | bool result = jsapi.Init(this); | |||
| 4828 | 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", 4828 ); return NS_ERROR_FAILURE; } } while (false); | |||
| 4829 | ||||
| 4830 | JSContext* cx = jsapi.cx(); | |||
| 4831 | ||||
| 4832 | // Get the document's pending state object -- it contains the data we're | |||
| 4833 | // going to send along with the popstate event. The object is serialized | |||
| 4834 | // using structured clone. | |||
| 4835 | JS::Rooted<JS::Value> stateJSValue(cx); | |||
| 4836 | nsresult rv = mDoc->GetStateObject(&stateJSValue); | |||
| 4837 | 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" , 4837); return rv; } } while (false); | |||
| 4838 | ||||
| 4839 | if (!JS_WrapValue(cx, &stateJSValue)) { | |||
| 4840 | return NS_ERROR_OUT_OF_MEMORY; | |||
| 4841 | } | |||
| 4842 | ||||
| 4843 | RootedDictionary<PopStateEventInit> init(cx); | |||
| 4844 | init.mState = stateJSValue; | |||
| 4845 | ||||
| 4846 | RefPtr<PopStateEvent> event = | |||
| 4847 | PopStateEvent::Constructor(this, u"popstate"_ns, init); | |||
| 4848 | event->SetTrusted(true); | |||
| 4849 | event->SetTarget(this); | |||
| 4850 | ||||
| 4851 | ErrorResult err; | |||
| 4852 | DispatchEvent(*event, err); | |||
| 4853 | return err.StealNSResult(); | |||
| 4854 | } | |||
| 4855 | ||||
| 4856 | already_AddRefed<nsDOMCSSDeclaration> nsGlobalWindowInner::GetComputedStyle( | |||
| 4857 | Element& aElt, const nsAString& aPseudoElt, ErrorResult& aError) { | |||
| 4858 | return GetComputedStyleHelper(aElt, aPseudoElt, false, aError); | |||
| 4859 | } | |||
| 4860 | ||||
| 4861 | already_AddRefed<nsDOMCSSDeclaration> | |||
| 4862 | nsGlobalWindowInner::GetDefaultComputedStyle(Element& aElt, | |||
| 4863 | const nsAString& aPseudoElt, | |||
| 4864 | ErrorResult& aError) { | |||
| 4865 | return GetComputedStyleHelper(aElt, aPseudoElt, true, aError); | |||
| 4866 | } | |||
| 4867 | ||||
| 4868 | already_AddRefed<nsDOMCSSDeclaration> | |||
| 4869 | nsGlobalWindowInner::GetComputedStyleHelper(Element& aElt, | |||
| 4870 | const nsAString& aPseudoElt, | |||
| 4871 | bool aDefaultStylesOnly, | |||
| 4872 | ErrorResult& aError) { | |||
| 4873 | FORWARD_TO_OUTER_OR_THROW(GetComputedStyleHelperOuter, | |||
| 4874 | (aElt, aPseudoElt, aDefaultStylesOnly, aError), | |||
| 4875 | aError, nullptr); | |||
| 4876 | } | |||
| 4877 | ||||
| 4878 | Storage* nsGlobalWindowInner::GetSessionStorage(ErrorResult& aError) { | |||
| 4879 | nsIPrincipal* principal = GetPrincipal(); | |||
| 4880 | nsIPrincipal* storagePrincipal = GetEffectiveStoragePrincipal(); | |||
| 4881 | BrowsingContext* browsingContext = GetBrowsingContext(); | |||
| 4882 | ||||
| 4883 | if (!principal || !storagePrincipal || !browsingContext || | |||
| 4884 | !Storage::StoragePrefIsEnabled()) { | |||
| 4885 | return nullptr; | |||
| 4886 | } | |||
| 4887 | ||||
| 4888 | if (mSessionStorage) { | |||
| 4889 | 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) | |||
| 4890 | ("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) | |||
| 4891 | 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); | |||
| 4892 | bool canAccess = | |||
| 4893 | principal->Subsumes(mSessionStorage->Principal()) && | |||
| 4894 | storagePrincipal->Subsumes(mSessionStorage->StoragePrincipal()); | |||
| 4895 | if (!canAccess) { | |||
| 4896 | mSessionStorage = nullptr; | |||
| 4897 | } | |||
| 4898 | } | |||
| 4899 | ||||
| 4900 | if (!mSessionStorage) { | |||
| 4901 | nsString documentURI; | |||
| 4902 | if (mDoc) { | |||
| 4903 | aError = mDoc->GetDocumentURI(documentURI); | |||
| 4904 | if (NS_WARN_IF(aError.Failed())NS_warn_if_impl(aError.Failed(), "aError.Failed()", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp" , 4904)) { | |||
| 4905 | return nullptr; | |||
| 4906 | } | |||
| 4907 | } | |||
| 4908 | ||||
| 4909 | if (!mDoc) { | |||
| 4910 | aError.Throw(NS_ERROR_FAILURE); | |||
| 4911 | return nullptr; | |||
| 4912 | } | |||
| 4913 | ||||
| 4914 | // If the document's sandboxed origin flag is set, then accessing | |||
| 4915 | // sessionStorage is prohibited. | |||
| 4916 | if (mDoc->GetSandboxFlags() & SANDBOXED_ORIGIN) { | |||
| 4917 | aError.ThrowSecurityError( | |||
| 4918 | "Forbidden in a sandboxed document without the 'allow-same-origin' " | |||
| 4919 | "flag."); | |||
| 4920 | return nullptr; | |||
| 4921 | } | |||
| 4922 | ||||
| 4923 | uint32_t rejectedReason = 0; | |||
| 4924 | StorageAccess access = StorageAllowedForWindow(this, &rejectedReason); | |||
| 4925 | ||||
| 4926 | // SessionStorage is an ephemeral per-tab per-origin storage that only lives | |||
| 4927 | // as long as the tab is open, although it may survive browser restarts | |||
| 4928 | // thanks to the session store. So we interpret storage access differently | |||
| 4929 | // than we would for persistent per-origin storage like LocalStorage and so | |||
| 4930 | // it may be okay to provide SessionStorage even when we receive a value of | |||
| 4931 | // eDeny. | |||
| 4932 | // | |||
| 4933 | // ContentBlocking::ShouldAllowAccessFor will return false for 3 main | |||
| 4934 | // reasons. | |||
| 4935 | // | |||
| 4936 | // 1. Cookies are entirely blocked due to a per-origin permission | |||
| 4937 | // (nsICookiePermission::ACCESS_DENY for the top-level principal or this | |||
| 4938 | // window's principal) or the very broad BEHAVIOR_REJECT. This will return | |||
| 4939 | // eDeny with a reason of STATE_COOKIES_BLOCKED_BY_PERMISSION or | |||
| 4940 | // STATE_COOKIES_BLOCKED_ALL. | |||
| 4941 | // | |||
| 4942 | // 2. Third-party cookies are limited via BEHAVIOR_REJECT_FOREIGN and | |||
| 4943 | // BEHAVIOR_LIMIT_FOREIGN and this is a third-party window. This will return | |||
| 4944 | // eDeny with a reason of STATE_COOKIES_BLOCKED_FOREIGN. | |||
| 4945 | // | |||
| 4946 | // 3. Tracking protection (BEHAVIOR_REJECT_TRACKER and | |||
| 4947 | // BEHAVIOR_PARTITION_FOREIGN) is in effect and | |||
| 4948 | // IsThirdPartyTrackingResourceWindow() returned true and there wasn't a | |||
| 4949 | // permission that allows it. This will return ePartitionTrackersOrDeny with | |||
| 4950 | // a reason of STATE_COOKIES_BLOCKED_TRACKER or | |||
| 4951 | // STATE_COOKIES_BLOCKED_SOCIALTRACKER. | |||
| 4952 | // TODO(Bug 2039931): case 3 is out of date. | |||
| 4953 | // | |||
| 4954 | // In the 1st case, the user has explicitly indicated that they don't want | |||
| 4955 | // to allow any storage to the origin or all origins and so we throw an | |||
| 4956 | // error and deny access to SessionStorage. In the 2nd case, a legacy | |||
| 4957 | // decision reasoned that there's no harm in providing SessionStorage | |||
| 4958 | // because the information is not durable and cannot escape the current tab. | |||
| 4959 | // The rationale is similar for the 3rd case. | |||
| 4960 | if (access == StorageAccess::eDeny && | |||
| 4961 | rejectedReason != | |||
| 4962 | nsIWebProgressListener::STATE_COOKIES_BLOCKED_FOREIGN) { | |||
| 4963 | aError.Throw(NS_ERROR_DOM_SECURITY_ERR); | |||
| 4964 | return nullptr; | |||
| 4965 | } | |||
| 4966 | ||||
| 4967 | const RefPtr<SessionStorageManager> storageManager = | |||
| 4968 | browsingContext->GetSessionStorageManager(); | |||
| 4969 | if (!storageManager) { | |||
| 4970 | aError.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); | |||
| 4971 | return nullptr; | |||
| 4972 | } | |||
| 4973 | ||||
| 4974 | RefPtr<Storage> storage; | |||
| 4975 | aError = storageManager->CreateStorage(this, principal, storagePrincipal, | |||
| 4976 | documentURI, IsPrivateBrowsing(), | |||
| 4977 | getter_AddRefs(storage)); | |||
| 4978 | if (aError.Failed()) { | |||
| 4979 | return nullptr; | |||
| 4980 | } | |||
| 4981 | ||||
| 4982 | mSessionStorage = storage; | |||
| 4983 | 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", 4983 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mSessionStorage" ")" ); do { MOZ_CrashSequence(__null, 4983); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 4984 | ||||
| 4985 | 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) | |||
| 4986 | ("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) | |||
| 4987 | 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); | |||
| 4988 | ||||
| 4989 | if (!mSessionStorage) { | |||
| 4990 | aError.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); | |||
| 4991 | return nullptr; | |||
| 4992 | } | |||
| 4993 | } | |||
| 4994 | ||||
| 4995 | 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) | |||
| 4996 | ("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) | |||
| 4997 | 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); | |||
| 4998 | ||||
| 4999 | return mSessionStorage; | |||
| 5000 | } | |||
| 5001 | ||||
| 5002 | Storage* nsGlobalWindowInner::GetLocalStorage(ErrorResult& aError) { | |||
| 5003 | if (!Storage::StoragePrefIsEnabled()) { | |||
| 5004 | return nullptr; | |||
| 5005 | } | |||
| 5006 | ||||
| 5007 | // If the document's sandboxed origin flag is set, then accessing localStorage | |||
| 5008 | // is prohibited. | |||
| 5009 | if (mDoc && mDoc->GetSandboxFlags() & SANDBOXED_ORIGIN) { | |||
| 5010 | aError.ThrowSecurityError( | |||
| 5011 | "Forbidden in a sandboxed document without the 'allow-same-origin' " | |||
| 5012 | "flag."); | |||
| 5013 | return nullptr; | |||
| 5014 | } | |||
| 5015 | ||||
| 5016 | // LocalStorage needs to be exposed in every context except for sandboxes and | |||
| 5017 | // NullPrincipals (data: URLs, for instance). But we need to keep data | |||
| 5018 | // separate in some scenarios: private-browsing and partitioned trackers. | |||
| 5019 | // In private-browsing, LocalStorage keeps data in memory, and it shares | |||
| 5020 | // StorageEvents just with other origins in the same private-browsing | |||
| 5021 | // environment. | |||
| 5022 | // For Partitioned Trackers, we expose a partitioned LocalStorage, which | |||
| 5023 | // doesn't share data with other contexts, and it's just in memory. | |||
| 5024 | // Partitioned localStorage is available only for trackers listed in the | |||
| 5025 | // privacy.restrict3rdpartystorage.partitionedHosts pref. See | |||
| 5026 | // nsContentUtils::IsURIInPrefList to know the syntax for the pref value. | |||
| 5027 | // This is a temporary web-compatibility hack. | |||
| 5028 | ||||
| 5029 | StorageAccess access = StorageAllowedForWindow(this); | |||
| 5030 | ||||
| 5031 | // We allow partitioned localStorage only to some hosts. | |||
| 5032 | bool isolated = false; | |||
| 5033 | if (ShouldPartitionStorage(access)) { | |||
| 5034 | if (!mDoc) { | |||
| 5035 | access = StorageAccess::eDeny; | |||
| 5036 | } else if (!StoragePartitioningEnabled(access, mDoc->CookieJarSettings())) { | |||
| 5037 | static const char* kPrefName = | |||
| 5038 | "privacy.restrict3rdpartystorage.partitionedHosts"; | |||
| 5039 | ||||
| 5040 | bool isInList = false; | |||
| 5041 | mDoc->NodePrincipal()->IsURIInPrefList(kPrefName, &isInList); | |||
| 5042 | if (!isInList) { | |||
| 5043 | access = StorageAccess::eDeny; | |||
| 5044 | } else { | |||
| 5045 | isolated = true; | |||
| 5046 | } | |||
| 5047 | } | |||
| 5048 | } | |||
| 5049 | ||||
| 5050 | if (access == StorageAccess::eDeny) { | |||
| 5051 | aError.Throw(NS_ERROR_DOM_SECURITY_ERR); | |||
| 5052 | return nullptr; | |||
| 5053 | } | |||
| 5054 | ||||
| 5055 | nsCOMPtr<nsICookieJarSettings> cookieJarSettings; | |||
| 5056 | if (mDoc) { | |||
| 5057 | cookieJarSettings = mDoc->CookieJarSettings(); | |||
| 5058 | } else { | |||
| 5059 | cookieJarSettings = net::CookieJarSettings::GetBlockingAll( | |||
| 5060 | ShouldResistFingerprinting(RFPTarget::IsAlwaysEnabledForPrecompute)); | |||
| 5061 | } | |||
| 5062 | ||||
| 5063 | // Note that this behavior is observable: if we grant storage permission to a | |||
| 5064 | // tracker, we pass from the partitioned LocalStorage (or a partitioned cookie | |||
| 5065 | // jar) to the 'normal' one. The previous data is lost and the 2 | |||
| 5066 | // window.localStorage objects, before and after the permission granted, will | |||
| 5067 | // be different. | |||
| 5068 | if (mLocalStorage) { | |||
| 5069 | if ((mLocalStorage->Type() == (isolated ? Storage::ePartitionedLocalStorage | |||
| 5070 | : Storage::eLocalStorage)) && | |||
| 5071 | (mLocalStorage->StoragePrincipal() == GetEffectiveStoragePrincipal())) { | |||
| 5072 | return mLocalStorage; | |||
| 5073 | } | |||
| 5074 | ||||
| 5075 | // storage needs change | |||
| 5076 | mLocalStorage = nullptr; | |||
| 5077 | } | |||
| 5078 | ||||
| 5079 | 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", 5079 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mLocalStorage" ")" ); do { MOZ_CrashSequence(__null, 5079); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 5080 | ||||
| 5081 | if (!isolated) { | |||
| 5082 | RefPtr<Storage> storage; | |||
| 5083 | ||||
| 5084 | if (NextGenLocalStorageEnabled()) { | |||
| 5085 | aError = LSObject::CreateForWindow(this, getter_AddRefs(storage)); | |||
| 5086 | } else { | |||
| 5087 | nsresult rv; | |||
| 5088 | nsCOMPtr<nsIDOMStorageManager> storageManager = | |||
| 5089 | do_GetService("@mozilla.org/dom/localStorage-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 | nsString documentURI; | |||
| 5096 | if (mDoc) { | |||
| 5097 | aError = mDoc->GetDocumentURI(documentURI); | |||
| 5098 | if (NS_WARN_IF(aError.Failed())NS_warn_if_impl(aError.Failed(), "aError.Failed()", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp" , 5098)) { | |||
| 5099 | return nullptr; | |||
| 5100 | } | |||
| 5101 | } | |||
| 5102 | ||||
| 5103 | nsIPrincipal* principal = GetPrincipal(); | |||
| 5104 | if (!principal) { | |||
| 5105 | aError.Throw(NS_ERROR_DOM_SECURITY_ERR); | |||
| 5106 | return nullptr; | |||
| 5107 | } | |||
| 5108 | ||||
| 5109 | nsIPrincipal* storagePrincipal = GetEffectiveStoragePrincipal(); | |||
| 5110 | if (!storagePrincipal) { | |||
| 5111 | aError.Throw(NS_ERROR_DOM_SECURITY_ERR); | |||
| 5112 | return nullptr; | |||
| 5113 | } | |||
| 5114 | ||||
| 5115 | aError = storageManager->CreateStorage(this, principal, storagePrincipal, | |||
| 5116 | documentURI, IsPrivateBrowsing(), | |||
| 5117 | getter_AddRefs(storage)); | |||
| 5118 | } | |||
| 5119 | ||||
| 5120 | if (aError.Failed()) { | |||
| 5121 | return nullptr; | |||
| 5122 | } | |||
| 5123 | ||||
| 5124 | mLocalStorage = storage; | |||
| 5125 | } else { | |||
| 5126 | nsresult rv; | |||
| 5127 | nsCOMPtr<nsIDOMSessionStorageManager> storageManager = | |||
| 5128 | do_GetService("@mozilla.org/dom/sessionStorage-manager;1", &rv); | |||
| 5129 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { | |||
| 5130 | aError.Throw(rv); | |||
| 5131 | return nullptr; | |||
| 5132 | } | |||
| 5133 | ||||
| 5134 | nsIPrincipal* principal = GetPrincipal(); | |||
| 5135 | if (!principal) { | |||
| 5136 | aError.Throw(NS_ERROR_DOM_SECURITY_ERR); | |||
| 5137 | return nullptr; | |||
| 5138 | } | |||
| 5139 | ||||
| 5140 | nsIPrincipal* storagePrincipal = GetEffectiveStoragePrincipal(); | |||
| 5141 | if (!storagePrincipal) { | |||
| 5142 | aError.Throw(NS_ERROR_DOM_SECURITY_ERR); | |||
| 5143 | return nullptr; | |||
| 5144 | } | |||
| 5145 | ||||
| 5146 | RefPtr<SessionStorageCache> cache; | |||
| 5147 | if (isolated) { | |||
| 5148 | cache = MakeRefPtr<SessionStorageCache>(); | |||
| 5149 | } else { | |||
| 5150 | // This will clone the session storage if it exists. | |||
| 5151 | rv = storageManager->GetSessionStorageCache(principal, storagePrincipal, | |||
| 5152 | &cache); | |||
| 5153 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { | |||
| 5154 | aError.Throw(rv); | |||
| 5155 | return nullptr; | |||
| 5156 | } | |||
| 5157 | } | |||
| 5158 | ||||
| 5159 | mLocalStorage = MakeRefPtr<PartitionedLocalStorage>( | |||
| 5160 | this, principal, storagePrincipal, cache); | |||
| 5161 | } | |||
| 5162 | ||||
| 5163 | 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", 5163 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLocalStorage" ")" ); do { MOZ_CrashSequence(__null, 5163); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 5164 | 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", 5166 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLocalStorage->Type() == (isolated ? Storage::ePartitionedLocalStorage : Storage::eLocalStorage)" ")"); do { MOZ_CrashSequence(__null, 5166); __attribute__((nomerge )) ::abort(); } while (false); } } while (false) | |||
| 5165 | 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", 5166 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLocalStorage->Type() == (isolated ? Storage::ePartitionedLocalStorage : Storage::eLocalStorage)" ")"); do { MOZ_CrashSequence(__null, 5166); __attribute__((nomerge )) ::abort(); } while (false); } } while (false) | |||
| 5166 | (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", 5166 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLocalStorage->Type() == (isolated ? Storage::ePartitionedLocalStorage : Storage::eLocalStorage)" ")"); do { MOZ_CrashSequence(__null, 5166); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 5167 | return mLocalStorage; | |||
| 5168 | } | |||
| 5169 | ||||
| 5170 | IDBFactory* nsGlobalWindowInner::GetIndexedDB(JSContext* aCx, | |||
| 5171 | ErrorResult& aError) { | |||
| 5172 | if (!mIndexedDB) { | |||
| 5173 | // This may keep mIndexedDB null without setting an error. | |||
| 5174 | auto res = IDBFactory::CreateForWindow(this); | |||
| 5175 | if (res.isErr()) { | |||
| 5176 | aError = res.unwrapErr(); | |||
| 5177 | } else { | |||
| 5178 | mIndexedDB = res.unwrap(); | |||
| 5179 | } | |||
| 5180 | } | |||
| 5181 | ||||
| 5182 | return mIndexedDB; | |||
| 5183 | } | |||
| 5184 | ||||
| 5185 | //***************************************************************************** | |||
| 5186 | // nsGlobalWindowInner::nsIInterfaceRequestor | |||
| 5187 | //***************************************************************************** | |||
| 5188 | ||||
| 5189 | NS_IMETHODIMPnsresult | |||
| 5190 | nsGlobalWindowInner::GetInterface(const nsIID& aIID, void** aSink) { | |||
| 5191 | nsGlobalWindowOuter* outer = GetOuterWindowInternal(); | |||
| 5192 | 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", 5192 ); return NS_ERROR_NOT_INITIALIZED; } } while (false); | |||
| 5193 | ||||
| 5194 | nsresult rv = outer->GetInterfaceInternal(aIID, aSink); | |||
| 5195 | if (rv == NS_ERROR_NO_INTERFACE) { | |||
| 5196 | return QueryInterface(aIID, aSink); | |||
| 5197 | } | |||
| 5198 | return rv; | |||
| 5199 | } | |||
| 5200 | ||||
| 5201 | void nsGlobalWindowInner::GetInterface(JSContext* aCx, | |||
| 5202 | JS::Handle<JS::Value> aIID, | |||
| 5203 | JS::MutableHandle<JS::Value> aRetval, | |||
| 5204 | ErrorResult& aError) { | |||
| 5205 | dom::GetInterface(aCx, this, aIID, aRetval, aError); | |||
| 5206 | } | |||
| 5207 | ||||
| 5208 | already_AddRefed<CacheStorage> nsGlobalWindowInner::GetCaches( | |||
| 5209 | ErrorResult& aRv) { | |||
| 5210 | if (!mCacheStorage) { | |||
| 5211 | bool forceTrustedOrigin = | |||
| 5212 | GetBrowsingContext() && | |||
| 5213 | GetBrowsingContext()->Top()->GetServiceWorkersTestingEnabled(); | |||
| 5214 | mCacheStorage = CacheStorage::CreateOnMainThread( | |||
| 5215 | cache::DEFAULT_NAMESPACE, this, GetEffectiveStoragePrincipal(), | |||
| 5216 | forceTrustedOrigin, aRv); | |||
| 5217 | } | |||
| 5218 | ||||
| 5219 | RefPtr<CacheStorage> ref = mCacheStorage; | |||
| 5220 | return ref.forget(); | |||
| 5221 | } | |||
| 5222 | ||||
| 5223 | void nsGlobalWindowInner::FireOfflineStatusEventIfChanged() { | |||
| 5224 | if (!IsCurrentInnerWindow()) return; | |||
| 5225 | ||||
| 5226 | bool isOffline = | |||
| 5227 | NS_IsOffline() || | |||
| 5228 | (GetBrowsingContext() && GetBrowsingContext()->Top()->GetForceOffline()); | |||
| 5229 | ||||
| 5230 | // Don't fire an event if the status hasn't changed | |||
| 5231 | if (mWasOffline == isOffline) { | |||
| 5232 | return; | |||
| 5233 | } | |||
| 5234 | ||||
| 5235 | if (ShouldResistFingerprinting(RFPTarget::NetworkConnection)) { | |||
| 5236 | // We always report online=true when resistFingerprinting is enabled. | |||
| 5237 | return; | |||
| 5238 | } | |||
| 5239 | ||||
| 5240 | mWasOffline = !mWasOffline; | |||
| 5241 | ||||
| 5242 | nsAutoString name; | |||
| 5243 | if (mWasOffline) { | |||
| 5244 | name.AssignLiteral("offline"); | |||
| 5245 | } else { | |||
| 5246 | name.AssignLiteral("online"); | |||
| 5247 | } | |||
| 5248 | nsContentUtils::DispatchTrustedEvent(this, this, name, CanBubble::eNo, | |||
| 5249 | Cancelable::eNo); | |||
| 5250 | } | |||
| 5251 | ||||
| 5252 | nsGlobalWindowInner::SlowScriptResponse | |||
| 5253 | nsGlobalWindowInner::ShowSlowScriptDialog(JSContext* aCx, | |||
| 5254 | const nsString& aAddonId, | |||
| 5255 | const double aDuration) { | |||
| 5256 | nsresult rv; | |||
| 5257 | ||||
| 5258 | if (Preferences::GetBool("dom.always_stop_slow_scripts")) { | |||
| ||||
| 5259 | return KillSlowScript; | |||
| 5260 | } | |||
| 5261 | ||||
| 5262 | // If it isn't safe to run script, then it isn't safe to bring up the prompt | |||
| 5263 | // (since that spins the event loop). In that (rare) case, we just kill the | |||
| 5264 | // script and report a warning. | |||
| 5265 | if (!nsContentUtils::IsSafeToRunScript()) { | |||
| 5266 | JS::WarnASCII(aCx, "A long running script was terminated"); | |||
| 5267 | return KillSlowScript; | |||
| 5268 | } | |||
| 5269 | ||||
| 5270 | // If our document is not active, just kill the script: we've been unloaded | |||
| 5271 | if (!HasActiveDocument()) { | |||
| 5272 | return KillSlowScript; | |||
| 5273 | } | |||
| 5274 | ||||
| 5275 | // Check if we should offer the option to debug | |||
| 5276 | JS::AutoFilename filename; | |||
| 5277 | uint32_t lineno; | |||
| 5278 | // Computing the line number can be very expensive (see bug 1330231 for | |||
| 5279 | // example), and we don't use the line number anywhere except than in the | |||
| 5280 | // parent process, so we avoid computing it elsewhere. This gives us most of | |||
| 5281 | // the wins we are interested in, since the source of the slowness here is | |||
| 5282 | // minified scripts which is more common in Web content that is loaded in the | |||
| 5283 | // content process. | |||
| 5284 | uint32_t* linenop = XRE_IsParentProcess() ? &lineno : nullptr; | |||
| 5285 | JS::DescribeScriptedCaller(&filename, aCx, linenop); | |||
| 5286 | ||||
| 5287 | // Record the slow script event if we haven't done so already for this inner | |||
| 5288 | // window (which represents a particular page to the user). | |||
| 5289 | if (!mHasHadSlowScript) { | |||
| 5290 | glean::dom::slow_script_page_count.Add(1); | |||
| 5291 | } | |||
| 5292 | mHasHadSlowScript = true; | |||
| 5293 | ||||
| 5294 | // Override the cursor to something that we're sure the user can see. | |||
| 5295 | SetCursor("auto"_ns, IgnoreErrors()); | |||
| 5296 | ||||
| 5297 | if (XRE_IsContentProcess() && ProcessHangMonitor::Get()) { | |||
| 5298 | ProcessHangMonitor::SlowScriptAction action; | |||
| 5299 | RefPtr<ProcessHangMonitor> monitor = ProcessHangMonitor::Get(); | |||
| 5300 | nsIDocShell* docShell = GetDocShell(); | |||
| 5301 | nsCOMPtr<nsIBrowserChild> child = | |||
| 5302 | docShell ? docShell->GetBrowserChild() : nullptr; | |||
| 5303 | action = | |||
| 5304 | monitor->NotifySlowScript(child, filename.get(), aAddonId, aDuration); | |||
| 5305 | if (action == ProcessHangMonitor::Terminate) { | |||
| 5306 | return KillSlowScript; | |||
| 5307 | } | |||
| 5308 | ||||
| 5309 | return ContinueSlowScriptAndKeepNotifying; | |||
| 5310 | } | |||
| 5311 | ||||
| 5312 | // Reached only on non-e10s - once per slow script dialog. | |||
| 5313 | // On e10s - we probe once at ProcessHangsMonitor.sys.mjs | |||
| 5314 | glean::dom::slow_script_notice_count.Add(1); | |||
| 5315 | ||||
| 5316 | // Get the nsIPrompt interface from the docshell | |||
| 5317 | nsCOMPtr<nsIDocShell> ds = GetDocShell(); | |||
| 5318 | 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" , 5318); return KillSlowScript; } } while (false); | |||
| 5319 | nsCOMPtr<nsIPrompt> prompt = do_GetInterface(ds); | |||
| 5320 | 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", 5320 ); return KillSlowScript; } } while (false); | |||
| 5321 | ||||
| 5322 | bool failed = false; | |||
| 5323 | auto getString = [&](const char* name, PropertiesFile propFile = | |||
| 5324 | PropertiesFile::DOM_PROPERTIES) { | |||
| 5325 | nsAutoString result; | |||
| 5326 | nsresult rv = nsContentUtils::GetLocalizedString(propFile, name, result); | |||
| 5327 | ||||
| 5328 | // GetStringFromName can return NS_OK and still give nullptr string | |||
| 5329 | failed = failed || NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || result.IsEmpty(); | |||
| 5330 | return result; | |||
| 5331 | }; | |||
| 5332 | ||||
| 5333 | bool isAddonScript = !aAddonId.IsEmpty(); | |||
| 5334 | ||||
| 5335 | // Get localizable strings | |||
| 5336 | ||||
| 5337 | nsAutoString title, checkboxMsg, msg; | |||
| 5338 | if (isAddonScript
| |||
| 5339 | title = getString("KillAddonScriptTitle"); | |||
| 5340 | checkboxMsg = getString("KillAddonScriptGlobalMessage"); | |||
| 5341 | ||||
| 5342 | auto appName = | |||
| 5343 | getString("brandShortName", PropertiesFile::BRAND_PROPERTIES); | |||
| 5344 | ||||
| 5345 | nsCOMPtr<nsIAddonPolicyService> aps = | |||
| 5346 | do_GetService("@mozilla.org/addons/policy-service;1"); | |||
| 5347 | nsString addonName; | |||
| 5348 | if (!aps || NS_FAILED(aps->GetExtensionName(aAddonId, addonName))((bool)(__builtin_expect(!!(NS_FAILED_impl(aps->GetExtensionName (aAddonId, addonName))), 0)))) { | |||
| 5349 | addonName = aAddonId; | |||
| 5350 | } | |||
| 5351 | ||||
| 5352 | rv = nsContentUtils::FormatLocalizedString( | |||
| 5353 | msg, PropertiesFile::DOM_PROPERTIES, "KillAddonScriptMessage", | |||
| 5354 | addonName, appName); | |||
| 5355 | ||||
| 5356 | failed = failed || NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))); | |||
| 5357 | } else { | |||
| 5358 | title = getString("KillScriptTitle"); | |||
| 5359 | checkboxMsg = getString("DontAskAgain"); | |||
| 5360 | msg = getString("KillScriptMessage"); | |||
| 5361 | } | |||
| 5362 | ||||
| 5363 | auto stopButton = getString("StopScriptButton"); | |||
| 5364 | auto waitButton = getString("WaitForScriptButton"); | |||
| 5365 | ||||
| 5366 | if (failed) { | |||
| 5367 | 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" , 5367); MOZ_PretendNoReturn(); } while (0); | |||
| 5368 | return ContinueSlowScript; | |||
| 5369 | } | |||
| 5370 | ||||
| 5371 | // Append file and line number information, if available | |||
| 5372 | if (filename.get()) { | |||
| 5373 | nsAutoString scriptLocation; | |||
| 5374 | // We want to drop the middle part of too-long locations. We'll | |||
| 5375 | // define "too-long" as longer than 60 UTF-16 code units. Just | |||
| 5376 | // have to be a bit careful about unpaired surrogates. | |||
| 5377 | NS_ConvertUTF8toUTF16 filenameUTF16(filename.get()); | |||
| 5378 | if (filenameUTF16.Length() > 60) { | |||
| 5379 | // XXXbz Do we need to insert any bidi overrides here? | |||
| 5380 | size_t cutStart = 30; | |||
| 5381 | size_t cutLength = filenameUTF16.Length() - 60; | |||
| 5382 | 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", 5382 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "cutLength > 0" ")"); do { MOZ_CrashSequence(__null, 5382); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 5383 | if (IsLowSurrogate(filenameUTF16[cutStart])) { | |||
| 5384 | // Don't truncate before the low surrogate, in case it's preceded by a | |||
| 5385 | // high surrogate and forms a single Unicode character. Instead, just | |||
| 5386 | // include the low surrogate. | |||
| 5387 | ++cutStart; | |||
| 5388 | --cutLength; | |||
| 5389 | } | |||
| 5390 | if (IsLowSurrogate(filenameUTF16[cutStart + cutLength])) { | |||
| 5391 | // Likewise, don't drop a trailing low surrogate here. We want to | |||
| 5392 | // increase cutLength, since it might be 0 already so we can't very well | |||
| 5393 | // decrease it. | |||
| 5394 | ++cutLength; | |||
| 5395 | } | |||
| 5396 | ||||
| 5397 | // Insert U+2026 HORIZONTAL ELLIPSIS | |||
| 5398 | filenameUTF16.ReplaceLiteral(cutStart, cutLength, u"\x2026"); | |||
| 5399 | } | |||
| 5400 | rv = nsContentUtils::FormatLocalizedString( | |||
| 5401 | scriptLocation, PropertiesFile::DOM_PROPERTIES, "KillScriptLocation", | |||
| 5402 | filenameUTF16); | |||
| 5403 | ||||
| 5404 | if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) { | |||
| 5405 | msg.AppendLiteral("\n\n"); | |||
| 5406 | msg.Append(scriptLocation); | |||
| 5407 | msg.Append(':'); | |||
| 5408 | msg.AppendInt(lineno); | |||
| ||||
| 5409 | } | |||
| 5410 | } | |||
| 5411 | ||||
| 5412 | uint32_t buttonFlags = nsIPrompt::BUTTON_POS_1_DEFAULT + | |||
| 5413 | (nsIPrompt::BUTTON_TITLE_IS_STRING * | |||
| 5414 | (nsIPrompt::BUTTON_POS_0 + nsIPrompt::BUTTON_POS_1)); | |||
| 5415 | ||||
| 5416 | bool checkboxValue = false; | |||
| 5417 | int32_t buttonPressed = 0; // In case the user exits dialog by clicking X. | |||
| 5418 | { | |||
| 5419 | // Null out the operation callback while we're re-entering JS here. | |||
| 5420 | AutoDisableJSInterruptCallback disabler(aCx); | |||
| 5421 | ||||
| 5422 | // Open the dialog. | |||
| 5423 | rv = prompt->ConfirmEx(title.get(), msg.get(), buttonFlags, | |||
| 5424 | waitButton.get(), stopButton.get(), nullptr, | |||
| 5425 | checkboxMsg.get(), &checkboxValue, &buttonPressed); | |||
| 5426 | } | |||
| 5427 | ||||
| 5428 | if (buttonPressed == 0) { | |||
| 5429 | if (checkboxValue && !isAddonScript && NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) | |||
| 5430 | return AlwaysContinueSlowScript; | |||
| 5431 | return ContinueSlowScript; | |||
| 5432 | } | |||
| 5433 | ||||
| 5434 | JS_ClearPendingException(aCx); | |||
| 5435 | ||||
| 5436 | return KillSlowScript; | |||
| 5437 | } | |||
| 5438 | ||||
| 5439 | nsresult nsGlobalWindowInner::Observe(nsISupports* aSubject, const char* aTopic, | |||
| 5440 | const char16_t* aData) { | |||
| 5441 | if (!nsCRT::strcmp(aTopic, "audio-playback")) { | |||
| 5442 | if (ToSupports(GetOuterWindow()) != aSubject) { | |||
| 5443 | return NS_OK; | |||
| 5444 | } | |||
| 5445 | AUTO_PROFILER_MARKER_UNTYPED("audio-playback", DOM, {})AutoProfilerUntypedMarker raiiObject5445( "audio-playback", :: mozilla::baseprofiler::category::DOM, {}); | |||
| 5446 | ||||
| 5447 | nsGlobalWindowOuter* outer = | |||
| 5448 | nsGlobalWindowOuter::Cast(nsPIDOMWindowOuter::From(GetOuterWindow()) | |||
| 5449 | ->GetInProcessScriptableTop()); | |||
| 5450 | nsGlobalWindowInner* topInnerWindow = | |||
| 5451 | outer ? nsGlobalWindowInner::Cast(outer->GetCurrentInnerWindow()) | |||
| 5452 | : nullptr; | |||
| 5453 | ||||
| 5454 | if (topInnerWindow) { | |||
| 5455 | const bool isPlayingAudio{IsPlayingAudio()}; | |||
| 5456 | topInnerWindow->AudioPlaybackChanged(isPlayingAudio); | |||
| 5457 | topInnerWindow->CallOnInProcessDescendants( | |||
| 5458 | &nsGlobalWindowInner::AudioPlaybackChanged, isPlayingAudio); | |||
| 5459 | } | |||
| 5460 | ||||
| 5461 | return NS_OK; | |||
| 5462 | } | |||
| 5463 | ||||
| 5464 | if (!nsCRT::strcmp(aTopic, NS_IOSERVICE_OFFLINE_STATUS_TOPIC"network:offline-status-changed")) { | |||
| 5465 | if (!IsFrozen()) { | |||
| 5466 | // Fires an offline status event if the offline status has changed | |||
| 5467 | FireOfflineStatusEventIfChanged(); | |||
| 5468 | } | |||
| 5469 | return NS_OK; | |||
| 5470 | } | |||
| 5471 | ||||
| 5472 | if (!nsCRT::strcmp(aTopic, MEMORY_PRESSURE_OBSERVER_TOPIC"memory-pressure")) { | |||
| 5473 | if (mPerformance) { | |||
| 5474 | mPerformance->MemoryPressure(); | |||
| 5475 | } | |||
| 5476 | RemoveReportRecords(); | |||
| 5477 | return NS_OK; | |||
| 5478 | } | |||
| 5479 | ||||
| 5480 | if (!nsCRT::strcmp(aTopic, PERMISSION_CHANGED_TOPIC"perm-changed") || | |||
| 5481 | !nsCRT::strcmp(aTopic, "browser-perm-changed")) { | |||
| 5482 | bool isBrowserPerm = !nsCRT::strcmp(aTopic, "browser-perm-changed"); | |||
| 5483 | ||||
| 5484 | nsCOMPtr<nsIPermission> perm(do_QueryInterface(aSubject)); | |||
| 5485 | if (!perm) { | |||
| 5486 | // Bulk browser permission clear — subject is an nsISupportsPRUint64 | |||
| 5487 | // carrying the browserId. Only process if this window belongs to that | |||
| 5488 | // tab. | |||
| 5489 | if (isBrowserPerm) { | |||
| 5490 | nsCOMPtr<nsISupportsPRUint64> wrapper = do_QueryInterface(aSubject); | |||
| 5491 | if (wrapper) { | |||
| 5492 | uint64_t clearedBrowserId = 0; | |||
| 5493 | wrapper->GetData(&clearedBrowserId); | |||
| 5494 | if (clearedBrowserId) { | |||
| 5495 | RefPtr<BrowsingContext> bc = GetBrowsingContext(); | |||
| 5496 | if (!bc || bc->Top()->BrowserId() != clearedBrowserId) { | |||
| 5497 | return NS_OK; | |||
| 5498 | } | |||
| 5499 | } | |||
| 5500 | } | |||
| 5501 | } | |||
| 5502 | UpdatePermissions(); | |||
| 5503 | if (mDoc) { | |||
| 5504 | RefPtr<PermissionDelegateHandler> permDelegateHandler = | |||
| 5505 | mDoc->GetPermissionDelegateHandler(); | |||
| 5506 | if (permDelegateHandler) { | |||
| 5507 | permDelegateHandler->PopulateAllDelegatedPermissions(); | |||
| 5508 | } | |||
| 5509 | } | |||
| 5510 | return NS_OK; | |||
| 5511 | } | |||
| 5512 | ||||
| 5513 | if (isBrowserPerm) { | |||
| 5514 | uint64_t permBrowserId = 0; | |||
| 5515 | perm->GetBrowserId(&permBrowserId); | |||
| 5516 | if (!permBrowserId) { | |||
| 5517 | return NS_OK; | |||
| 5518 | } | |||
| 5519 | RefPtr<BrowsingContext> bc = GetBrowsingContext(); | |||
| 5520 | if (!bc || bc->Top()->BrowserId() != permBrowserId) { | |||
| 5521 | return NS_OK; | |||
| 5522 | } | |||
| 5523 | } | |||
| 5524 | ||||
| 5525 | nsAutoCString type; | |||
| 5526 | perm->GetType(type); | |||
| 5527 | if (type == "autoplay-media"_ns) { | |||
| 5528 | UpdateAutoplayPermission(); | |||
| 5529 | } else if (type == "shortcuts"_ns) { | |||
| 5530 | UpdateShortcutsPermission(); | |||
| 5531 | } else if (type == "popup"_ns) { | |||
| 5532 | UpdatePopupPermission(); | |||
| 5533 | } | |||
| 5534 | ||||
| 5535 | if (!mDoc) { | |||
| 5536 | return NS_OK; | |||
| 5537 | } | |||
| 5538 | ||||
| 5539 | RefPtr<PermissionDelegateHandler> permDelegateHandler = | |||
| 5540 | mDoc->GetPermissionDelegateHandler(); | |||
| 5541 | ||||
| 5542 | if (permDelegateHandler) { | |||
| 5543 | permDelegateHandler->UpdateDelegatedPermission(type); | |||
| 5544 | } | |||
| 5545 | ||||
| 5546 | return NS_OK; | |||
| 5547 | } | |||
| 5548 | ||||
| 5549 | if (!nsCRT::strcmp(aTopic, "screen-information-changed")) { | |||
| 5550 | if (mScreen) { | |||
| 5551 | if (RefPtr<ScreenOrientation> orientation = | |||
| 5552 | mScreen->GetOrientationIfExists()) { | |||
| 5553 | orientation->MaybeChanged(); | |||
| 5554 | } | |||
| 5555 | } | |||
| 5556 | if (mHasOrientationChangeListeners) { | |||
| 5557 | int32_t oldAngle = mOrientationAngle; | |||
| 5558 | mOrientationAngle = Orientation(CallerType::System); | |||
| 5559 | if (mOrientationAngle != oldAngle && IsCurrentInnerWindow()) { | |||
| 5560 | nsCOMPtr<nsPIDOMWindowOuter> outer = GetOuterWindow(); | |||
| 5561 | outer->DispatchCustomEvent(u"orientationchange"_ns); | |||
| 5562 | } | |||
| 5563 | } | |||
| 5564 | return NS_OK; | |||
| 5565 | } | |||
| 5566 | ||||
| 5567 | if (!nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID"nsPref:changed")) { | |||
| 5568 | 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", 5568 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!NS_strcmp(aData, u\"intl.accept_languages\")" ")"); do { MOZ_CrashSequence(__null, 5568); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 5569 | ||||
| 5570 | // The user preferred languages have changed, we need to fire an event on | |||
| 5571 | // Window object and invalidate the cache for navigator.languages. It is | |||
| 5572 | // done for every change which can be a waste of cycles but those should be | |||
| 5573 | // fairly rare. | |||
| 5574 | // We MUST invalidate navigator.languages before sending the event in the | |||
| 5575 | // very likely situation where an event handler will try to read its value. | |||
| 5576 | ||||
| 5577 | if (mNavigator) { | |||
| 5578 | Navigator_Binding::ClearCachedLanguageValue(mNavigator); | |||
| 5579 | Navigator_Binding::ClearCachedLanguagesValue(mNavigator); | |||
| 5580 | } | |||
| 5581 | ||||
| 5582 | // The event has to be dispatched only to the current inner window. | |||
| 5583 | if (!IsCurrentInnerWindow()) { | |||
| 5584 | return NS_OK; | |||
| 5585 | } | |||
| 5586 | ||||
| 5587 | RefPtr<Event> event = NS_NewDOMEvent(this, nullptr, nullptr); | |||
| 5588 | event->InitEvent(u"languagechange"_ns, false, false); | |||
| 5589 | event->SetTrusted(true); | |||
| 5590 | ||||
| 5591 | ErrorResult rv; | |||
| 5592 | DispatchEvent(*event, rv); | |||
| 5593 | return rv.StealNSResult(); | |||
| 5594 | } | |||
| 5595 | ||||
| 5596 | 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" , 5596); | |||
| 5597 | return NS_ERROR_FAILURE; | |||
| 5598 | } | |||
| 5599 | ||||
| 5600 | void nsGlobalWindowInner::ObserveStorageNotification( | |||
| 5601 | StorageEvent* aEvent, const char16_t* aStorageType, bool aPrivateBrowsing) { | |||
| 5602 | 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" , 5602); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aEvent" ")" ); do { MOZ_CrashSequence(__null, 5602); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 5603 | ||||
| 5604 | // The private browsing check must be done here again because this window | |||
| 5605 | // could have changed its state before the notification check and now. This | |||
| 5606 | // happens in case this window did have a docShell at that time. | |||
| 5607 | if (aPrivateBrowsing != IsPrivateBrowsing()) { | |||
| 5608 | return; | |||
| 5609 | } | |||
| 5610 | ||||
| 5611 | // LocalStorage can only exist on an inner window, and we don't want to | |||
| 5612 | // generate events on frozen or otherwise-navigated-away from windows. | |||
| 5613 | // (Actually, this code used to try and buffer events for frozen windows, | |||
| 5614 | // but it never worked, so we've removed it. See bug 1285898.) | |||
| 5615 | if (!IsCurrentInnerWindow() || IsFrozen()) { | |||
| 5616 | return; | |||
| 5617 | } | |||
| 5618 | ||||
| 5619 | nsIPrincipal* principal = GetPrincipal(); | |||
| 5620 | if (!principal) { | |||
| 5621 | return; | |||
| 5622 | } | |||
| 5623 | ||||
| 5624 | bool fireMozStorageChanged = false; | |||
| 5625 | nsAutoString eventType; | |||
| 5626 | eventType.AssignLiteral("storage"); | |||
| 5627 | ||||
| 5628 | if (!NS_strcmp(aStorageType, u"sessionStorage")) { | |||
| 5629 | RefPtr<Storage> changingStorage = aEvent->GetStorageArea(); | |||
| 5630 | 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", 5630 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "changingStorage" ")" ); do { MOZ_CrashSequence(__null, 5630); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 5631 | ||||
| 5632 | bool check = false; | |||
| 5633 | ||||
| 5634 | if (const RefPtr<SessionStorageManager> storageManager = | |||
| 5635 | GetBrowsingContext()->GetSessionStorageManager()) { | |||
| 5636 | nsresult rv = storageManager->CheckStorage(GetEffectiveStoragePrincipal(), | |||
| 5637 | changingStorage, &check); | |||
| 5638 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { | |||
| 5639 | return; | |||
| 5640 | } | |||
| 5641 | } | |||
| 5642 | ||||
| 5643 | if (!check) { | |||
| 5644 | // This storage event is not coming from our storage or is coming | |||
| 5645 | // from a different docshell, i.e. it is a clone, ignore this event. | |||
| 5646 | return; | |||
| 5647 | } | |||
| 5648 | ||||
| 5649 | 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) | |||
| 5650 | 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) | |||
| 5651 | ("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) | |||
| 5652 | 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); | |||
| 5653 | ||||
| 5654 | fireMozStorageChanged = mSessionStorage == changingStorage; | |||
| 5655 | if (fireMozStorageChanged) { | |||
| 5656 | eventType.AssignLiteral("MozSessionStorageChanged"); | |||
| 5657 | } | |||
| 5658 | } | |||
| 5659 | ||||
| 5660 | else { | |||
| 5661 | 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", 5661 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!NS_strcmp(aStorageType, u\"localStorage\")" ")"); do { MOZ_CrashSequence(__null, 5661); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 5662 | ||||
| 5663 | nsIPrincipal* storagePrincipal = GetEffectiveStoragePrincipal(); | |||
| 5664 | if (!storagePrincipal) { | |||
| 5665 | return; | |||
| 5666 | } | |||
| 5667 | ||||
| 5668 | 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", 5669 ); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "StorageUtils::PrincipalsEqual(aEvent->GetPrincipal(), storagePrincipal)" ")"); do { MOZ_CrashSequence(__null, 5669); __attribute__((nomerge )) ::abort(); } while (false); } } while (false) | |||
| 5669 | 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", 5669 ); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "StorageUtils::PrincipalsEqual(aEvent->GetPrincipal(), storagePrincipal)" ")"); do { MOZ_CrashSequence(__null, 5669); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 5670 | ||||
| 5671 | fireMozStorageChanged = | |||
| 5672 | mLocalStorage && mLocalStorage == aEvent->GetStorageArea(); | |||
| 5673 | ||||
| 5674 | if (fireMozStorageChanged) { | |||
| 5675 | eventType.AssignLiteral("MozLocalStorageChanged"); | |||
| 5676 | } | |||
| 5677 | } | |||
| 5678 | ||||
| 5679 | // Clone the storage event included in the observer notification. We want | |||
| 5680 | // to dispatch clones rather than the original event. | |||
| 5681 | IgnoredErrorResult error; | |||
| 5682 | RefPtr<StorageEvent> clonedEvent = | |||
| 5683 | CloneStorageEvent(eventType, aEvent, error); | |||
| 5684 | if (error.Failed() || !clonedEvent) { | |||
| 5685 | return; | |||
| 5686 | } | |||
| 5687 | ||||
| 5688 | clonedEvent->SetTrusted(true); | |||
| 5689 | ||||
| 5690 | if (fireMozStorageChanged) { | |||
| 5691 | WidgetEvent* internalEvent = clonedEvent->WidgetEventPtr(); | |||
| 5692 | internalEvent->mFlags.mOnlyChromeDispatch = true; | |||
| 5693 | } | |||
| 5694 | ||||
| 5695 | DispatchEvent(*clonedEvent); | |||
| 5696 | } | |||
| 5697 | ||||
| 5698 | already_AddRefed<StorageEvent> nsGlobalWindowInner::CloneStorageEvent( | |||
| 5699 | const nsAString& aType, const RefPtr<StorageEvent>& aEvent, | |||
| 5700 | ErrorResult& aRv) { | |||
| 5701 | StorageEventInit dict; | |||
| 5702 | ||||
| 5703 | dict.mBubbles = aEvent->Bubbles(); | |||
| 5704 | dict.mCancelable = aEvent->Cancelable(); | |||
| 5705 | aEvent->GetKey(dict.mKey); | |||
| 5706 | aEvent->GetOldValue(dict.mOldValue); | |||
| 5707 | aEvent->GetNewValue(dict.mNewValue); | |||
| 5708 | aEvent->GetUrl(dict.mUrl); | |||
| 5709 | ||||
| 5710 | RefPtr<Storage> storageArea = aEvent->GetStorageArea(); | |||
| 5711 | ||||
| 5712 | RefPtr<Storage> storage; | |||
| 5713 | ||||
| 5714 | // If null, this is a localStorage event received by IPC. | |||
| 5715 | if (!storageArea) { | |||
| 5716 | storage = GetLocalStorage(aRv); | |||
| 5717 | if (!NextGenLocalStorageEnabled()) { | |||
| 5718 | if (aRv.Failed() || !storage) { | |||
| 5719 | return nullptr; | |||
| 5720 | } | |||
| 5721 | ||||
| 5722 | if (storage->Type() == Storage::eLocalStorage) { | |||
| 5723 | RefPtr<LocalStorage> localStorage = | |||
| 5724 | static_cast<LocalStorage*>(storage.get()); | |||
| 5725 | ||||
| 5726 | // We must apply the current change to the 'local' localStorage. | |||
| 5727 | localStorage->ApplyEvent(aEvent); | |||
| 5728 | } | |||
| 5729 | } | |||
| 5730 | } else if (storageArea->Type() == Storage::eSessionStorage) { | |||
| 5731 | storage = GetSessionStorage(aRv); | |||
| 5732 | } else { | |||
| 5733 | 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", 5733 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "storageArea->Type() == Storage::eLocalStorage" ")"); do { MOZ_CrashSequence(__null, 5733); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 5734 | storage = GetLocalStorage(aRv); | |||
| 5735 | } | |||
| 5736 | ||||
| 5737 | if (aRv.Failed() || !storage) { | |||
| 5738 | return nullptr; | |||
| 5739 | } | |||
| 5740 | ||||
| 5741 | if (storage->Type() == Storage::ePartitionedLocalStorage) { | |||
| 5742 | // This error message is not exposed. | |||
| 5743 | aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); | |||
| 5744 | return nullptr; | |||
| 5745 | } | |||
| 5746 | ||||
| 5747 | 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" , 5747); AnnotateMozCrashReason("MOZ_ASSERT" "(" "storage" ")" ); do { MOZ_CrashSequence(__null, 5747); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 5748 | 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", 5748 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "storage->IsForkOf(storageArea)" ")"); do { MOZ_CrashSequence(__null, 5748); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); } } while ( false); | |||
| 5749 | ||||
| 5750 | dict.mStorageArea = storage; | |||
| 5751 | ||||
| 5752 | RefPtr<StorageEvent> event = StorageEvent::Constructor(this, aType, dict); | |||
| 5753 | return event.forget(); | |||
| 5754 | } | |||
| 5755 | ||||
| 5756 | void nsGlobalWindowInner::Suspend(bool aIncludeSubWindows) { | |||
| 5757 | 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", 5757 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence(__null, 5757); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 5758 | ||||
| 5759 | // We can only safely suspend windows that are the current inner window. If | |||
| 5760 | // its not the current inner, then we are in one of two different cases. | |||
| 5761 | // Either we are in the bfcache or we are doomed window that is going away. | |||
| 5762 | // When a window becomes inactive we purposely avoid placing already suspended | |||
| 5763 | // windows into the bfcache. It only expects windows suspended due to the | |||
| 5764 | // Freeze() method which occurs while the window is still the current inner. | |||
| 5765 | // So we must not call Suspend() on bfcache windows at this point or this | |||
| 5766 | // invariant will be broken. If the window is doomed there is no point in | |||
| 5767 | // suspending it since it will soon be gone. | |||
| 5768 | if (!IsCurrentInnerWindow()) { | |||
| 5769 | return; | |||
| 5770 | } | |||
| 5771 | ||||
| 5772 | // All in-process descendants are also suspended. This ensure mSuspendDepth | |||
| 5773 | // is set properly and the timers are properly canceled for each in-process | |||
| 5774 | // descendant. | |||
| 5775 | if (aIncludeSubWindows) { | |||
| 5776 | CallOnInProcessDescendants(&nsGlobalWindowInner::Suspend, false); | |||
| 5777 | } | |||
| 5778 | ||||
| 5779 | mSuspendDepth += 1; | |||
| 5780 | if (mSuspendDepth != 1) { | |||
| 5781 | return; | |||
| 5782 | } | |||
| 5783 | ||||
| 5784 | if (mWindowGlobalChild) { | |||
| 5785 | mWindowGlobalChild->BlockBFCacheFor(BFCacheStatus::SUSPENDED); | |||
| 5786 | } | |||
| 5787 | ||||
| 5788 | nsCOMPtr<nsIDeviceSensors> ac = do_GetService(NS_DEVICE_SENSORS_CONTRACTID"@mozilla.org/devicesensors;1"); | |||
| 5789 | if (ac) { | |||
| 5790 | for (uint32_t i = 0; i < mEnabledSensors.Length(); i++) | |||
| 5791 | ac->RemoveWindowListener(mEnabledSensors[i], this); | |||
| 5792 | } | |||
| 5793 | DisableGamepadUpdates(); | |||
| 5794 | DisableVRUpdates(); | |||
| 5795 | ||||
| 5796 | SuspendWorkersForWindow(*this); | |||
| 5797 | ||||
| 5798 | for (RefPtr<mozilla::dom::SharedWorker> pinnedWorker : | |||
| 5799 | mSharedWorkers.ForwardRange()) { | |||
| 5800 | pinnedWorker->Suspend(); | |||
| 5801 | } | |||
| 5802 | ||||
| 5803 | SuspendIdleRequests(); | |||
| 5804 | ||||
| 5805 | mTimeoutManager->Suspend(); | |||
| 5806 | ||||
| 5807 | // Suspend all of the AudioContexts for this window | |||
| 5808 | for (uint32_t i = 0; i < mAudioContexts.Length(); ++i) { | |||
| 5809 | mAudioContexts[i]->SuspendFromChrome(); | |||
| 5810 | } | |||
| 5811 | } | |||
| 5812 | ||||
| 5813 | void nsGlobalWindowInner::Resume(bool aIncludeSubWindows) { | |||
| 5814 | 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", 5814 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence(__null, 5814); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 5815 | ||||
| 5816 | // We can only safely resume a window if its the current inner window. If | |||
| 5817 | // its not the current inner, then we are in one of two different cases. | |||
| 5818 | // Either we are in the bfcache or we are doomed window that is going away. | |||
| 5819 | // If a window is suspended when it becomes inactive we purposely do not | |||
| 5820 | // put it in the bfcache, so Resume should never be needed in that case. | |||
| 5821 | // If the window is doomed then there is no point in resuming it. | |||
| 5822 | if (!IsCurrentInnerWindow()) { | |||
| 5823 | return; | |||
| 5824 | } | |||
| 5825 | ||||
| 5826 | // Resume all in-process descendants. This restores timers recursively | |||
| 5827 | // canceled in Suspend() and ensures all in-process descendants have the | |||
| 5828 | // correct mSuspendDepth. | |||
| 5829 | if (aIncludeSubWindows) { | |||
| 5830 | CallOnInProcessDescendants(&nsGlobalWindowInner::Resume, false); | |||
| 5831 | } | |||
| 5832 | ||||
| 5833 | if (mSuspendDepth == 0) { | |||
| 5834 | // Ignore if the window is not suspended. | |||
| 5835 | return; | |||
| 5836 | } | |||
| 5837 | ||||
| 5838 | mSuspendDepth -= 1; | |||
| 5839 | ||||
| 5840 | if (mSuspendDepth != 0) { | |||
| 5841 | return; | |||
| 5842 | } | |||
| 5843 | ||||
| 5844 | // We should not be able to resume a frozen window. It must be Thaw()'d | |||
| 5845 | // first. | |||
| 5846 | 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", 5846 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mFreezeDepth == 0" ")"); do { MOZ_CrashSequence(__null, 5846); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 5847 | ||||
| 5848 | nsCOMPtr<nsIDeviceSensors> ac = do_GetService(NS_DEVICE_SENSORS_CONTRACTID"@mozilla.org/devicesensors;1"); | |||
| 5849 | if (ac) { | |||
| 5850 | for (uint32_t i = 0; i < mEnabledSensors.Length(); i++) | |||
| 5851 | ac->AddWindowListener(mEnabledSensors[i], this); | |||
| 5852 | } | |||
| 5853 | EnableGamepadUpdates(); | |||
| 5854 | EnableVRUpdates(); | |||
| 5855 | ||||
| 5856 | // Resume all of the AudioContexts for this window | |||
| 5857 | for (uint32_t i = 0; i < mAudioContexts.Length(); ++i) { | |||
| 5858 | mAudioContexts[i]->ResumeFromChrome(); | |||
| 5859 | } | |||
| 5860 | ||||
| 5861 | if (RefPtr<MediaDevices> devices = GetExtantMediaDevices()) { | |||
| 5862 | devices->WindowResumed(); | |||
| 5863 | } | |||
| 5864 | ||||
| 5865 | mTimeoutManager->Resume(); | |||
| 5866 | ||||
| 5867 | ResumeIdleRequests(); | |||
| 5868 | ||||
| 5869 | // Resume all of the workers for this window. We must do this | |||
| 5870 | // after timeouts since workers may have queued events that can trigger | |||
| 5871 | // a setTimeout(). | |||
| 5872 | ResumeWorkersForWindow(*this); | |||
| 5873 | ||||
| 5874 | for (RefPtr<mozilla::dom::SharedWorker> pinnedWorker : | |||
| 5875 | mSharedWorkers.ForwardRange()) { | |||
| 5876 | pinnedWorker->Resume(); | |||
| 5877 | } | |||
| 5878 | ||||
| 5879 | if (mWindowGlobalChild) { | |||
| 5880 | mWindowGlobalChild->UnblockBFCacheFor(BFCacheStatus::SUSPENDED); | |||
| 5881 | } | |||
| 5882 | } | |||
| 5883 | ||||
| 5884 | bool nsGlobalWindowInner::IsSuspended() const { | |||
| 5885 | 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", 5885 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence(__null, 5885); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 5886 | return mSuspendDepth != 0; | |||
| 5887 | } | |||
| 5888 | ||||
| 5889 | void nsGlobalWindowInner::Freeze(bool aIncludeSubWindows) { | |||
| 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 | Suspend(aIncludeSubWindows); | |||
| 5892 | FreezeInternal(aIncludeSubWindows); | |||
| 5893 | } | |||
| 5894 | ||||
| 5895 | void nsGlobalWindowInner::FreezeInternal(bool aIncludeSubWindows) { | |||
| 5896 | 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", 5896 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence(__null, 5896); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 5897 | 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", 5897 ); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "IsCurrentInnerWindow()" ")"); do { MOZ_CrashSequence(__null, 5897); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 5898 | 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", 5898 ); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "IsSuspended()" ")"); do { MOZ_CrashSequence(__null, 5898); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 5899 | ||||
| 5900 | HintIsLoading(false); | |||
| 5901 | ||||
| 5902 | if (aIncludeSubWindows) { | |||
| 5903 | CallOnInProcessChildren(&nsGlobalWindowInner::FreezeInternal, | |||
| 5904 | aIncludeSubWindows); | |||
| 5905 | } | |||
| 5906 | ||||
| 5907 | mFreezeDepth += 1; | |||
| 5908 | 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" , 5908); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mSuspendDepth >= mFreezeDepth" ")"); do { MOZ_CrashSequence(__null, 5908); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 5909 | if (mFreezeDepth != 1) { | |||
| 5910 | return; | |||
| 5911 | } | |||
| 5912 | ||||
| 5913 | FreezeWorkersForWindow(*this); | |||
| 5914 | ||||
| 5915 | for (RefPtr<mozilla::dom::SharedWorker> pinnedWorker : | |||
| 5916 | mSharedWorkers.ForwardRange()) { | |||
| 5917 | pinnedWorker->Freeze(); | |||
| 5918 | } | |||
| 5919 | ||||
| 5920 | mTimeoutManager->Freeze(); | |||
| 5921 | if (mClientSource) { | |||
| 5922 | mClientSource->Freeze(); | |||
| 5923 | } | |||
| 5924 | ||||
| 5925 | NotifyGlobalFrozen(); | |||
| 5926 | } | |||
| 5927 | ||||
| 5928 | void nsGlobalWindowInner::Thaw(bool aIncludeSubWindows) { | |||
| 5929 | 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", 5929 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence(__null, 5929); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 5930 | ThawInternal(aIncludeSubWindows); | |||
| 5931 | Resume(aIncludeSubWindows); | |||
| 5932 | } | |||
| 5933 | ||||
| 5934 | void nsGlobalWindowInner::ThawInternal(bool aIncludeSubWindows) { | |||
| 5935 | 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", 5935 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence(__null, 5935); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 5936 | 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", 5936 ); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "IsCurrentInnerWindow()" ")"); do { MOZ_CrashSequence(__null, 5936); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 5937 | 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", 5937 ); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "IsSuspended()" ")"); do { MOZ_CrashSequence(__null, 5937); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 5938 | ||||
| 5939 | if (aIncludeSubWindows) { | |||
| 5940 | CallOnInProcessChildren(&nsGlobalWindowInner::ThawInternal, | |||
| 5941 | aIncludeSubWindows); | |||
| 5942 | } | |||
| 5943 | ||||
| 5944 | 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", 5944 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mFreezeDepth != 0" ")"); do { MOZ_CrashSequence(__null, 5944); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 5945 | mFreezeDepth -= 1; | |||
| 5946 | 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" , 5946); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mSuspendDepth >= mFreezeDepth" ")"); do { MOZ_CrashSequence(__null, 5946); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 5947 | if (mFreezeDepth != 0) { | |||
| 5948 | return; | |||
| 5949 | } | |||
| 5950 | ||||
| 5951 | if (mClientSource) { | |||
| 5952 | mClientSource->Thaw(); | |||
| 5953 | } | |||
| 5954 | mTimeoutManager->Thaw(); | |||
| 5955 | ||||
| 5956 | ThawWorkersForWindow(*this); | |||
| 5957 | ||||
| 5958 | for (RefPtr<mozilla::dom::SharedWorker> pinnedWorker : | |||
| 5959 | mSharedWorkers.ForwardRange()) { | |||
| 5960 | pinnedWorker->Thaw(); | |||
| 5961 | } | |||
| 5962 | ||||
| 5963 | NotifyGlobalThawed(); | |||
| 5964 | } | |||
| 5965 | ||||
| 5966 | bool nsGlobalWindowInner::IsFrozen() const { | |||
| 5967 | 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", 5967 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence(__null, 5967); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 5968 | bool frozen = mFreezeDepth != 0; | |||
| 5969 | 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", 5969 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsSuspended()" ")" ); do { MOZ_CrashSequence(__null, 5969); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); } } while ( false); | |||
| 5970 | return frozen; | |||
| 5971 | } | |||
| 5972 | ||||
| 5973 | void nsGlobalWindowInner::SyncStateFromParentWindow() { | |||
| 5974 | // This method should only be called on an inner window that has been | |||
| 5975 | // assigned to an outer window already. | |||
| 5976 | 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", 5976 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsCurrentInnerWindow()" ")"); do { MOZ_CrashSequence(__null, 5976); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 5977 | nsPIDOMWindowOuter* outer = GetOuterWindow(); | |||
| 5978 | 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" , 5978); AnnotateMozCrashReason("MOZ_ASSERT" "(" "outer" ")") ; do { MOZ_CrashSequence(__null, 5978); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 5979 | ||||
| 5980 | // Attempt to find our parent windows. | |||
| 5981 | nsCOMPtr<Element> frame = outer->GetFrameElementInternal(); | |||
| 5982 | nsPIDOMWindowOuter* parentOuter = | |||
| 5983 | frame ? frame->OwnerDoc()->GetWindow() : nullptr; | |||
| 5984 | nsGlobalWindowInner* parentInner = | |||
| 5985 | parentOuter | |||
| 5986 | ? nsGlobalWindowInner::Cast(parentOuter->GetCurrentInnerWindow()) | |||
| 5987 | : nullptr; | |||
| 5988 | ||||
| 5989 | // If our outer is in a modal state, but our parent is not in a modal | |||
| 5990 | // state, then we must apply the suspend directly. If our parent is | |||
| 5991 | // in a modal state then we should get the suspend automatically | |||
| 5992 | // via the parentSuspendDepth application below. | |||
| 5993 | if ((!parentInner || !parentInner->IsInModalState()) && IsInModalState()) { | |||
| 5994 | Suspend(); | |||
| 5995 | } | |||
| 5996 | ||||
| 5997 | uint32_t parentFreezeDepth = parentInner ? parentInner->mFreezeDepth : 0; | |||
| 5998 | uint32_t parentSuspendDepth = parentInner ? parentInner->mSuspendDepth : 0; | |||
| 5999 | ||||
| 6000 | // Since every Freeze() calls Suspend(), the suspend count must | |||
| 6001 | // be equal or greater to the freeze count. | |||
| 6002 | 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", 6002 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "parentFreezeDepth <= parentSuspendDepth" ")"); do { MOZ_CrashSequence(__null, 6002); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 6003 | ||||
| 6004 | // First apply the Freeze() calls. | |||
| 6005 | for (uint32_t i = 0; i < parentFreezeDepth; ++i) { | |||
| 6006 | Freeze(); | |||
| 6007 | } | |||
| 6008 | ||||
| 6009 | // Now apply only the number of Suspend() calls to reach the target | |||
| 6010 | // suspend count after applying the Freeze() calls. | |||
| 6011 | for (uint32_t i = 0; i < (parentSuspendDepth - parentFreezeDepth); ++i) { | |||
| 6012 | Suspend(); | |||
| 6013 | } | |||
| 6014 | } | |||
| 6015 | ||||
| 6016 | void nsGlobalWindowInner::UpdateBackgroundState() { | |||
| 6017 | if (RefPtr<MediaDevices> devices = GetExtantMediaDevices()) { | |||
| 6018 | devices->BackgroundStateChanged(); | |||
| 6019 | } | |||
| 6020 | mTimeoutManager->UpdateBackgroundState(); | |||
| 6021 | ||||
| 6022 | UpdateWorkersBackgroundState(*this, IsBackgroundInternal()); | |||
| 6023 | } | |||
| 6024 | ||||
| 6025 | template <typename Method, typename... Args> | |||
| 6026 | CallState nsGlobalWindowInner::CallOnInProcessDescendantsInternal( | |||
| 6027 | BrowsingContext* aBrowsingContext, bool aChildOnly, Method aMethod, | |||
| 6028 | Args&&... aArgs) { | |||
| 6029 | 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", 6029 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence(__null, 6029); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 6030 | 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", 6030 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aBrowsingContext" ")"); do { MOZ_CrashSequence(__null, 6030); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 6031 | ||||
| 6032 | CallState state = CallState::Continue; | |||
| 6033 | for (const RefPtr<BrowsingContext>& bc : aBrowsingContext->Children()) { | |||
| 6034 | if (nsCOMPtr<nsPIDOMWindowOuter> pWin = bc->GetDOMWindow()) { | |||
| 6035 | auto* win = nsGlobalWindowOuter::Cast(pWin); | |||
| 6036 | if (nsGlobalWindowInner* inner = | |||
| 6037 | nsGlobalWindowInner::Cast(win->GetCurrentInnerWindow())) { | |||
| 6038 | // Call the descendant method using our helper CallDescendant() template | |||
| 6039 | // method. This allows us to handle both void returning methods and | |||
| 6040 | // methods that return CallState explicitly. For void returning methods | |||
| 6041 | // we assume CallState::Continue. | |||
| 6042 | using returnType = decltype((inner->*aMethod)(aArgs...)); | |||
| 6043 | state = CallDescendant<returnType>(inner, aMethod, aArgs...); | |||
| 6044 | ||||
| 6045 | if (state == CallState::Stop) { | |||
| 6046 | return state; | |||
| 6047 | } | |||
| 6048 | } | |||
| 6049 | } | |||
| 6050 | ||||
| 6051 | if (!aChildOnly) { | |||
| 6052 | state = CallOnInProcessDescendantsInternal(bc.get(), aChildOnly, aMethod, | |||
| 6053 | aArgs...); | |||
| 6054 | if (state == CallState::Stop) { | |||
| 6055 | return state; | |||
| 6056 | } | |||
| 6057 | } | |||
| 6058 | } | |||
| 6059 | ||||
| 6060 | return state; | |||
| 6061 | } | |||
| 6062 | ||||
| 6063 | nsIURI* nsGlobalWindowInner::GetBaseURI() const { return GetDocBaseURI(); } | |||
| 6064 | ||||
| 6065 | Maybe<ClientInfo> nsGlobalWindowInner::GetClientInfo() const { | |||
| 6066 | 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", 6066 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence(__null, 6066); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 6067 | if (mDoc && mDoc->IsStaticDocument()) { | |||
| 6068 | if (Maybe<ClientInfo> info = mDoc->GetOriginalDocument()->GetClientInfo()) { | |||
| 6069 | return info; | |||
| 6070 | } | |||
| 6071 | } | |||
| 6072 | ||||
| 6073 | Maybe<ClientInfo> clientInfo; | |||
| 6074 | if (mClientSource) { | |||
| 6075 | clientInfo.emplace(mClientSource->Info()); | |||
| 6076 | } | |||
| 6077 | return clientInfo; | |||
| 6078 | } | |||
| 6079 | ||||
| 6080 | Maybe<ClientState> nsGlobalWindowInner::GetClientState() const { | |||
| 6081 | 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", 6081 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence(__null, 6081); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 6082 | if (mDoc && mDoc->IsStaticDocument()) { | |||
| 6083 | if (Maybe<ClientState> state = | |||
| 6084 | mDoc->GetOriginalDocument()->GetClientState()) { | |||
| 6085 | return state; | |||
| 6086 | } | |||
| 6087 | } | |||
| 6088 | ||||
| 6089 | Maybe<ClientState> clientState; | |||
| 6090 | if (mClientSource) { | |||
| 6091 | Result<ClientState, ErrorResult> res = mClientSource->SnapshotState(); | |||
| 6092 | if (res.isOk()) { | |||
| 6093 | clientState.emplace(res.unwrap()); | |||
| 6094 | } else { | |||
| 6095 | res.unwrapErr().SuppressException(); | |||
| 6096 | } | |||
| 6097 | } | |||
| 6098 | return clientState; | |||
| 6099 | } | |||
| 6100 | ||||
| 6101 | Maybe<ServiceWorkerDescriptor> nsGlobalWindowInner::GetController() const { | |||
| 6102 | 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", 6102 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence(__null, 6102); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 6103 | if (mDoc && mDoc->IsStaticDocument()) { | |||
| 6104 | if (Maybe<ServiceWorkerDescriptor> controller = | |||
| 6105 | mDoc->GetOriginalDocument()->GetController()) { | |||
| 6106 | return controller; | |||
| 6107 | } | |||
| 6108 | } | |||
| 6109 | ||||
| 6110 | Maybe<ServiceWorkerDescriptor> controller; | |||
| 6111 | if (mClientSource) { | |||
| 6112 | controller = mClientSource->GetController(); | |||
| 6113 | } | |||
| 6114 | return controller; | |||
| 6115 | } | |||
| 6116 | ||||
| 6117 | void nsGlobalWindowInner::SetPolicyContainer( | |||
| 6118 | nsIPolicyContainer* aPolicyContainer) { | |||
| 6119 | if (!mClientSource) { | |||
| 6120 | return; | |||
| 6121 | } | |||
| 6122 | mClientSource->SetPolicyContainer(aPolicyContainer); | |||
| 6123 | // Also cache the PolicyContainer within the document | |||
| 6124 | mDoc->SetPolicyContainer(aPolicyContainer); | |||
| 6125 | ||||
| 6126 | if (mWindowGlobalChild) { | |||
| 6127 | mWindowGlobalChild->SendSetClientInfo(mClientSource->Info().ToIPC()); | |||
| 6128 | } | |||
| 6129 | } | |||
| 6130 | ||||
| 6131 | nsIPolicyContainer* nsGlobalWindowInner::GetPolicyContainer() { | |||
| 6132 | if (mDoc) { | |||
| 6133 | return mDoc->GetPolicyContainer(); | |||
| 6134 | } | |||
| 6135 | ||||
| 6136 | // If the window is partially torn down and has its document nulled out, | |||
| 6137 | // we query the policy container we snapshot in FreeInnerObjects. | |||
| 6138 | if (mDocumentPolicyContainer) { | |||
| 6139 | return mDocumentPolicyContainer; | |||
| 6140 | } | |||
| 6141 | return nullptr; | |||
| 6142 | } | |||
| 6143 | ||||
| 6144 | void nsGlobalWindowInner::SetPreloadCsp(nsIContentSecurityPolicy* aPreloadCsp) { | |||
| 6145 | if (!mClientSource) { | |||
| 6146 | return; | |||
| 6147 | } | |||
| 6148 | mClientSource->SetPreloadCsp(aPreloadCsp); | |||
| 6149 | // Also cache the preload CSP within the document | |||
| 6150 | mDoc->SetPreloadCsp(aPreloadCsp); | |||
| 6151 | ||||
| 6152 | if (mWindowGlobalChild) { | |||
| 6153 | mWindowGlobalChild->SendSetClientInfo(mClientSource->Info().ToIPC()); | |||
| 6154 | } | |||
| 6155 | } | |||
| 6156 | ||||
| 6157 | already_AddRefed<ServiceWorkerContainer> | |||
| 6158 | nsGlobalWindowInner::GetServiceWorkerContainer() { | |||
| 6159 | return Navigator()->ServiceWorker(); | |||
| 6160 | } | |||
| 6161 | ||||
| 6162 | RefPtr<ServiceWorker> nsGlobalWindowInner::GetOrCreateServiceWorker( | |||
| 6163 | const ServiceWorkerDescriptor& aDescriptor) { | |||
| 6164 | 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", 6164 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence(__null, 6164); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 6165 | RefPtr<ServiceWorker> ref; | |||
| 6166 | ForEachGlobalTeardownObserver( | |||
| 6167 | [&](GlobalTeardownObserver* aObserver, bool* aDoneOut) { | |||
| 6168 | RefPtr<ServiceWorker> sw = do_QueryObject(aObserver); | |||
| 6169 | if (!sw || !sw->Descriptor().Matches(aDescriptor)) { | |||
| 6170 | return; | |||
| 6171 | } | |||
| 6172 | ||||
| 6173 | ref = std::move(sw); | |||
| 6174 | *aDoneOut = true; | |||
| 6175 | }); | |||
| 6176 | ||||
| 6177 | if (!ref) { | |||
| 6178 | ref = ServiceWorker::Create(this, aDescriptor); | |||
| 6179 | } | |||
| 6180 | ||||
| 6181 | return ref; | |||
| 6182 | } | |||
| 6183 | ||||
| 6184 | RefPtr<mozilla::dom::ServiceWorkerRegistration> | |||
| 6185 | nsGlobalWindowInner::GetServiceWorkerRegistration( | |||
| 6186 | const mozilla::dom::ServiceWorkerRegistrationDescriptor& aDescriptor) | |||
| 6187 | const { | |||
| 6188 | 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", 6188 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence(__null, 6188); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 6189 | RefPtr<ServiceWorkerRegistration> ref; | |||
| 6190 | ForEachGlobalTeardownObserver( | |||
| 6191 | [&](GlobalTeardownObserver* aObserver, bool* aDoneOut) { | |||
| 6192 | RefPtr<ServiceWorkerRegistration> swr = do_QueryObject(aObserver); | |||
| 6193 | if (!swr || !swr->MatchesDescriptor(aDescriptor)) { | |||
| 6194 | return; | |||
| 6195 | } | |||
| 6196 | ||||
| 6197 | ref = std::move(swr); | |||
| 6198 | *aDoneOut = true; | |||
| 6199 | }); | |||
| 6200 | return ref; | |||
| 6201 | } | |||
| 6202 | ||||
| 6203 | RefPtr<ServiceWorkerRegistration> | |||
| 6204 | nsGlobalWindowInner::GetOrCreateServiceWorkerRegistration( | |||
| 6205 | const ServiceWorkerRegistrationDescriptor& aDescriptor) { | |||
| 6206 | 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", 6206 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence(__null, 6206); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 6207 | RefPtr<ServiceWorkerRegistration> ref = | |||
| 6208 | GetServiceWorkerRegistration(aDescriptor); | |||
| 6209 | if (!ref) { | |||
| 6210 | ref = ServiceWorkerRegistration::CreateForMainThread(this, aDescriptor); | |||
| 6211 | } | |||
| 6212 | return ref; | |||
| 6213 | } | |||
| 6214 | ||||
| 6215 | StorageAccess nsGlobalWindowInner::GetStorageAccess() { | |||
| 6216 | return StorageAllowedForWindow(this); | |||
| 6217 | } | |||
| 6218 | ||||
| 6219 | nsICookieJarSettings* nsGlobalWindowInner::GetCookieJarSettings() { | |||
| 6220 | 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", 6220 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence(__null, 6220); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 6221 | if (mDoc) { | |||
| 6222 | return mDoc->CookieJarSettings(); | |||
| 6223 | } | |||
| 6224 | return nullptr; | |||
| 6225 | } | |||
| 6226 | ||||
| 6227 | nsresult nsGlobalWindowInner::FireDelayedDOMEvents(bool aIncludeSubWindows) { | |||
| 6228 | // Fires an offline status event if the offline status has changed | |||
| 6229 | FireOfflineStatusEventIfChanged(); | |||
| 6230 | ||||
| 6231 | if (mCookieStore) { | |||
| 6232 | mCookieStore->FireDelayedDOMEvents(); | |||
| 6233 | } | |||
| 6234 | ||||
| 6235 | if (!aIncludeSubWindows) { | |||
| 6236 | return NS_OK; | |||
| 6237 | } | |||
| 6238 | ||||
| 6239 | nsCOMPtr<nsIDocShell> docShell = GetDocShell(); | |||
| 6240 | if (docShell) { | |||
| 6241 | int32_t childCount = 0; | |||
| 6242 | docShell->GetInProcessChildCount(&childCount); | |||
| 6243 | ||||
| 6244 | // Take a copy of the current children so that modifications to | |||
| 6245 | // the child list don't affect to the iteration. | |||
| 6246 | AutoTArray<nsCOMPtr<nsIDocShellTreeItem>, 8> children; | |||
| 6247 | for (int32_t i = 0; i < childCount; ++i) { | |||
| 6248 | nsCOMPtr<nsIDocShellTreeItem> childShell; | |||
| 6249 | docShell->GetInProcessChildAt(i, getter_AddRefs(childShell)); | |||
| 6250 | if (childShell) { | |||
| 6251 | children.AppendElement(childShell); | |||
| 6252 | } | |||
| 6253 | } | |||
| 6254 | ||||
| 6255 | for (const nsCOMPtr<nsIDocShellTreeItem>& childShell : children) { | |||
| 6256 | if (const RefPtr<nsGlobalWindowOuter> win = | |||
| 6257 | nsGlobalWindowOuter::Cast(childShell->GetWindow())) { | |||
| 6258 | win->FireDelayedDOMEvents(true); | |||
| 6259 | } | |||
| 6260 | } | |||
| 6261 | } | |||
| 6262 | ||||
| 6263 | return NS_OK; | |||
| 6264 | } | |||
| 6265 | ||||
| 6266 | //***************************************************************************** | |||
| 6267 | // nsGlobalWindowInner: Window Control Functions | |||
| 6268 | //***************************************************************************** | |||
| 6269 | ||||
| 6270 | nsPIDOMWindowOuter* nsGlobalWindowInner::GetInProcessParentInternal() { | |||
| 6271 | nsGlobalWindowOuter* outer = GetOuterWindowInternal(); | |||
| 6272 | if (!outer) { | |||
| 6273 | // No outer window available! | |||
| 6274 | return nullptr; | |||
| 6275 | } | |||
| 6276 | return outer->GetInProcessParentInternal(); | |||
| 6277 | } | |||
| 6278 | ||||
| 6279 | nsIPrincipal* nsGlobalWindowInner::GetTopLevelAntiTrackingPrincipal() { | |||
| 6280 | nsPIDOMWindowOuter* outerWindow = GetOuterWindowInternal(); | |||
| 6281 | if (!outerWindow) { | |||
| 6282 | return nullptr; | |||
| 6283 | } | |||
| 6284 | ||||
| 6285 | nsPIDOMWindowOuter* topLevelOuterWindow = | |||
| 6286 | GetBrowsingContext()->Top()->GetDOMWindow(); | |||
| 6287 | if (!topLevelOuterWindow) { | |||
| 6288 | return nullptr; | |||
| 6289 | } | |||
| 6290 | ||||
| 6291 | bool stopAtOurLevel = | |||
| 6292 | mDoc && mDoc->CookieJarSettings()->GetCookieBehavior() == | |||
| 6293 | nsICookieService::BEHAVIOR_REJECT_TRACKER; | |||
| 6294 | ||||
| 6295 | if (stopAtOurLevel && topLevelOuterWindow == outerWindow) { | |||
| 6296 | return nullptr; | |||
| 6297 | } | |||
| 6298 | ||||
| 6299 | nsPIDOMWindowInner* topLevelInnerWindow = | |||
| 6300 | topLevelOuterWindow->GetCurrentInnerWindow(); | |||
| 6301 | if (NS_WARN_IF(!topLevelInnerWindow)NS_warn_if_impl(!topLevelInnerWindow, "!topLevelInnerWindow", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6301 )) { | |||
| 6302 | return nullptr; | |||
| 6303 | } | |||
| 6304 | ||||
| 6305 | nsIPrincipal* topLevelPrincipal = | |||
| 6306 | nsGlobalWindowInner::Cast(topLevelInnerWindow)->GetPrincipal(); | |||
| 6307 | if (NS_WARN_IF(!topLevelPrincipal)NS_warn_if_impl(!topLevelPrincipal, "!topLevelPrincipal", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp" , 6307)) { | |||
| 6308 | return nullptr; | |||
| 6309 | } | |||
| 6310 | ||||
| 6311 | return topLevelPrincipal; | |||
| 6312 | } | |||
| 6313 | ||||
| 6314 | nsIPrincipal* nsGlobalWindowInner::GetClientPrincipal() { | |||
| 6315 | return mClientSource ? mClientSource->GetPrincipal() : nullptr; | |||
| 6316 | } | |||
| 6317 | ||||
| 6318 | bool nsGlobalWindowInner::IsInFullScreenTransition() { | |||
| 6319 | if (!mIsChrome) { | |||
| 6320 | return false; | |||
| 6321 | } | |||
| 6322 | ||||
| 6323 | nsGlobalWindowOuter* outerWindow = GetOuterWindowInternal(); | |||
| 6324 | if (!outerWindow) { | |||
| 6325 | return false; | |||
| 6326 | } | |||
| 6327 | ||||
| 6328 | return outerWindow->mIsInFullScreenTransition; | |||
| 6329 | } | |||
| 6330 | ||||
| 6331 | //***************************************************************************** | |||
| 6332 | // nsGlobalWindowInner: Timeout Functions | |||
| 6333 | //***************************************************************************** | |||
| 6334 | ||||
| 6335 | class WindowScriptTimeoutHandler final : public ScriptTimeoutHandler { | |||
| 6336 | public: | |||
| 6337 | NS_DECL_ISUPPORTS_INHERITEDpublic: virtual nsresult QueryInterface(const nsIID& aIID , void** aInstancePtr) override; virtual MozExternalRefCountType AddRef(void) override; virtual MozExternalRefCountType Release (void) override; | |||
| 6338 | 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", 6339); AnnotateMozCrashReason("MOZ_ASSERT" "(" "p == &_cycleCollectorGlobal" ") (" "WindowScriptTimeoutHandler" " should QI to its own CC participant" ")"); do { MOZ_CrashSequence(__null, 6339); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); } static cycleCollection _cycleCollectorGlobal; | |||
| 6339 | 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", 6339); AnnotateMozCrashReason("MOZ_ASSERT" "(" "p == &_cycleCollectorGlobal" ") (" "WindowScriptTimeoutHandler" " should QI to its own CC participant" ")"); do { MOZ_CrashSequence(__null, 6339); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); } static cycleCollection _cycleCollectorGlobal; | |||
| 6340 | ||||
| 6341 | WindowScriptTimeoutHandler(JSContext* aCx, nsIGlobalObject* aGlobal, | |||
| 6342 | const nsAString& aExpression) | |||
| 6343 | : ScriptTimeoutHandler(aCx, aGlobal, aExpression), | |||
| 6344 | mInitiatingScriptFetchInfo( | |||
| 6345 | ScriptLoader::GetActiveScriptFetchInfo(aCx)) {} | |||
| 6346 | ||||
| 6347 | MOZ_CAN_RUN_SCRIPT virtual bool Call(const char* aExecutionReason) override; | |||
| 6348 | ||||
| 6349 | private: | |||
| 6350 | virtual ~WindowScriptTimeoutHandler() = default; | |||
| 6351 | ||||
| 6352 | // Initiating script's referrer info for use when evaluating mExpr on the main | |||
| 6353 | // thread. | |||
| 6354 | RefPtr<JS::loader::ScriptFetchInfo> mInitiatingScriptFetchInfo; | |||
| 6355 | }; | |||
| 6356 | ||||
| 6357 | NS_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; } | |||
| 6358 | 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; } | |||
| 6359 | 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; } | |||
| 6360 | ||||
| 6361 | NS_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" , 6361); 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 | |||
| 6362 | NS_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; } | |||
| 6363 | ||||
| 6364 | NS_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; } | |||
| 6365 | NS_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; } | |||
| 6366 | ||||
| 6367 | bool WindowScriptTimeoutHandler::Call(const char* aExecutionReason) { | |||
| 6368 | // New script entry point required, due to the "Create a script" sub-step | |||
| 6369 | // of | |||
| 6370 | // http://www.whatwg.org/specs/web-apps/current-work/#timer-initialisation-steps | |||
| 6371 | nsAutoMicroTask mt; | |||
| 6372 | AutoEntryScript aes(mGlobal, aExecutionReason, true); | |||
| 6373 | JS::CompileOptions options(aes.cx()); | |||
| 6374 | options.setFileAndLine(mCaller.FileName().get(), mCaller.mLine); | |||
| 6375 | options.setNoScriptRval(true); | |||
| 6376 | options.setIntroductionType("domTimer"); | |||
| 6377 | JS::Rooted<JSObject*> global(aes.cx(), mGlobal->GetGlobalJSObject()); | |||
| 6378 | { | |||
| 6379 | if (MOZ_UNLIKELY(!xpc::Scriptability::Get(global).Allowed())(__builtin_expect(!!(!xpc::Scriptability::Get(global).Allowed ()), 0))) { | |||
| 6380 | return true; | |||
| 6381 | } | |||
| 6382 | ||||
| 6383 | IgnoredErrorResult erv; | |||
| 6384 | mozilla::AutoProfilerLabel autoProfilerLabel("JSExecutionContext", | |||
| 6385 | /* dynamicStr */ nullptr, | |||
| 6386 | JS::ProfilingCategoryPair::JS); | |||
| 6387 | JSAutoRealm autoRealm(aes.cx(), global); | |||
| 6388 | RefPtr<JS::Stencil> stencil; | |||
| 6389 | JS::Rooted<JSScript*> script(aes.cx()); | |||
| 6390 | Compile(aes.cx(), options, mExpr, stencil, erv); | |||
| 6391 | if (stencil) { | |||
| 6392 | JS::InstantiateOptions instantiateOptions(options); | |||
| 6393 | 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", 6393 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!instantiateOptions.deferDebugMetadata" ")"); do { MOZ_CrashSequence(__null, 6393); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 6394 | script.set(JS::InstantiateGlobalStencil(aes.cx(), instantiateOptions, | |||
| 6395 | stencil, /* storage */ nullptr)); | |||
| 6396 | if (!script) { | |||
| 6397 | erv.NoteJSContextException(aes.cx()); | |||
| 6398 | } | |||
| 6399 | } | |||
| 6400 | ||||
| 6401 | if (script) { | |||
| 6402 | 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", 6402 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!erv.Failed()" ")" ); do { MOZ_CrashSequence(__null, 6402); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 6403 | if (mInitiatingScriptFetchInfo) { | |||
| 6404 | mInitiatingScriptFetchInfo->AssociateWithScript(script); | |||
| 6405 | } | |||
| 6406 | ||||
| 6407 | if (!JS_ExecuteScript(aes.cx(), script)) { | |||
| 6408 | erv.NoteJSContextException(aes.cx()); | |||
| 6409 | } | |||
| 6410 | } | |||
| 6411 | ||||
| 6412 | if (erv.IsUncatchableException()) { | |||
| 6413 | return false; | |||
| 6414 | } | |||
| 6415 | } | |||
| 6416 | ||||
| 6417 | return true; | |||
| 6418 | }; | |||
| 6419 | ||||
| 6420 | nsGlobalWindowInner* nsGlobalWindowInner::InnerForSetTimeoutOrInterval( | |||
| 6421 | ErrorResult& aError) { | |||
| 6422 | nsGlobalWindowOuter* outer = GetOuterWindowInternal(); | |||
| 6423 | nsPIDOMWindowInner* currentInner = | |||
| 6424 | outer ? outer->GetCurrentInnerWindow() : this; | |||
| 6425 | ||||
| 6426 | // If forwardTo is not the window with an active document then we want the | |||
| 6427 | // call to setTimeout/Interval to be a noop, so return null but don't set an | |||
| 6428 | // error. | |||
| 6429 | return HasActiveDocument() ? nsGlobalWindowInner::Cast(currentInner) | |||
| 6430 | : nullptr; | |||
| 6431 | } | |||
| 6432 | ||||
| 6433 | int32_t nsGlobalWindowInner::SetTimeout( | |||
| 6434 | JSContext* aCx, const FunctionOrTrustedScriptOrString& aHandler, | |||
| 6435 | int32_t aTimeout, const Sequence<JS::Value>& aArguments, | |||
| 6436 | nsIPrincipal* aSubjectPrincipal, ErrorResult& aError) { | |||
| 6437 | return SetTimeoutOrInterval(aCx, aHandler, aTimeout, aArguments, false, | |||
| 6438 | aSubjectPrincipal, aError); | |||
| 6439 | } | |||
| 6440 | ||||
| 6441 | int32_t nsGlobalWindowInner::SetInterval( | |||
| 6442 | JSContext* aCx, const FunctionOrTrustedScriptOrString& aHandler, | |||
| 6443 | const int32_t aTimeout, const Sequence<JS::Value>& aArguments, | |||
| 6444 | nsIPrincipal* aSubjectPrincipal, ErrorResult& aError) { | |||
| 6445 | return SetTimeoutOrInterval(aCx, aHandler, aTimeout, aArguments, true, | |||
| 6446 | aSubjectPrincipal, aError); | |||
| 6447 | } | |||
| 6448 | ||||
| 6449 | int32_t nsGlobalWindowInner::SetTimeoutOrInterval( | |||
| 6450 | JSContext* aCx, const FunctionOrTrustedScriptOrString& aHandler, | |||
| 6451 | int32_t aTimeout, const Sequence<JS::Value>& aArguments, bool aIsInterval, | |||
| 6452 | nsIPrincipal* aSubjectPrincipal, ErrorResult& aError) { | |||
| 6453 | nsGlobalWindowInner* inner = InnerForSetTimeoutOrInterval(aError); | |||
| 6454 | if (!inner) { | |||
| 6455 | return -1; | |||
| 6456 | } | |||
| 6457 | ||||
| 6458 | if (inner != this) { | |||
| 6459 | RefPtr<nsGlobalWindowInner> innerRef(inner); | |||
| 6460 | return innerRef->SetTimeoutOrInterval(aCx, aHandler, aTimeout, aArguments, | |||
| 6461 | aIsInterval, aSubjectPrincipal, | |||
| 6462 | aError); | |||
| 6463 | } | |||
| 6464 | ||||
| 6465 | DebuggerNotificationDispatch( | |||
| 6466 | this, aIsInterval ? DebuggerNotificationType::SetInterval | |||
| 6467 | : DebuggerNotificationType::SetTimeout); | |||
| 6468 | ||||
| 6469 | if (!GetContextInternal() || !HasJSGlobal()) { | |||
| 6470 | // This window was already closed, or never properly initialized, | |||
| 6471 | // don't let a timer be scheduled on such a window. | |||
| 6472 | return 0; | |||
| 6473 | } | |||
| 6474 | ||||
| 6475 | if (aHandler.IsFunction()) { | |||
| 6476 | nsTArray<JS::Heap<JS::Value>> args; | |||
| 6477 | if (!args.AppendElements(aArguments, fallible)) { | |||
| 6478 | aError.Throw(NS_ERROR_OUT_OF_MEMORY); | |||
| 6479 | return 0; | |||
| 6480 | } | |||
| 6481 | ||||
| 6482 | RefPtr handler = MakeRefPtr<CallbackTimeoutHandler>( | |||
| 6483 | aCx, this, &aHandler.GetAsFunction(), std::move(args)); | |||
| 6484 | ||||
| 6485 | int32_t result; | |||
| 6486 | aError = mTimeoutManager->SetTimeout(handler, aTimeout, aIsInterval, | |||
| 6487 | Timeout::Reason::eTimeoutOrInterval, | |||
| 6488 | &result); | |||
| 6489 | return result; | |||
| 6490 | } | |||
| 6491 | ||||
| 6492 | constexpr nsLiteralString sinkSetTimeout = u"Window setTimeout"_ns; | |||
| 6493 | constexpr nsLiteralString sinkSetInterval = u"Window setInterval"_ns; | |||
| 6494 | Maybe<nsAutoString> compliantStringHolder; | |||
| 6495 | nsCOMPtr<nsIGlobalObject> pinnedGlobal = this; | |||
| 6496 | const nsAString* compliantString = | |||
| 6497 | TrustedTypeUtils::GetTrustedTypesCompliantString( | |||
| 6498 | aHandler, aIsInterval ? sinkSetInterval : sinkSetTimeout, | |||
| 6499 | kTrustedTypesOnlySinkGroup, *pinnedGlobal, aSubjectPrincipal, | |||
| 6500 | compliantStringHolder, aError); | |||
| 6501 | if (aError.Failed()) { | |||
| 6502 | return 0; | |||
| 6503 | } | |||
| 6504 | ||||
| 6505 | bool allowEval = false; | |||
| 6506 | aError = | |||
| 6507 | CSPEvalChecker::CheckForWindow(aCx, this, *compliantString, &allowEval); | |||
| 6508 | if (NS_WARN_IF(aError.Failed())NS_warn_if_impl(aError.Failed(), "aError.Failed()", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp" , 6508) || !allowEval) { | |||
| 6509 | return 0; | |||
| 6510 | } | |||
| 6511 | RefPtr handler = | |||
| 6512 | MakeRefPtr<WindowScriptTimeoutHandler>(aCx, this, *compliantString); | |||
| 6513 | int32_t result; | |||
| 6514 | aError = | |||
| 6515 | mTimeoutManager->SetTimeout(handler, aTimeout, aIsInterval, | |||
| 6516 | Timeout::Reason::eTimeoutOrInterval, &result); | |||
| 6517 | return result; | |||
| 6518 | } | |||
| 6519 | ||||
| 6520 | static const char* GetTimeoutReasonString(Timeout* aTimeout) { | |||
| 6521 | switch (aTimeout->mReason) { | |||
| 6522 | case Timeout::Reason::eTimeoutOrInterval: | |||
| 6523 | if (aTimeout->mIsInterval) { | |||
| 6524 | return "setInterval handler"; | |||
| 6525 | } | |||
| 6526 | return "setTimeout handler"; | |||
| 6527 | case Timeout::Reason::eIdleCallbackTimeout: | |||
| 6528 | return "setIdleCallback handler (timed out)"; | |||
| 6529 | case Timeout::Reason::eAbortSignalTimeout: | |||
| 6530 | return "AbortSignal timeout"; | |||
| 6531 | case Timeout::Reason::eDelayedWebTaskTimeout: | |||
| 6532 | return "delayedWebTaskCallback handler (timed out)"; | |||
| 6533 | case Timeout::Reason::eJSTimeout: | |||
| 6534 | return "JavaScript TimeoutJob (timed out)"; | |||
| 6535 | default: | |||
| 6536 | MOZ_CRASH("Unexpected enum value")do { do { } while (false); MOZ_ReportCrash("" "Unexpected enum value" , "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6536 ); AnnotateMozCrashReason("MOZ_CRASH(" "Unexpected enum value" ")"); do { MOZ_CrashSequence(__null, 6536); __attribute__((nomerge )) ::abort(); } while (false); } while (false); | |||
| 6537 | return ""; | |||
| 6538 | } | |||
| 6539 | MOZ_CRASH("Unexpected enum value")do { do { } while (false); MOZ_ReportCrash("" "Unexpected enum value" , "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6539 ); AnnotateMozCrashReason("MOZ_CRASH(" "Unexpected enum value" ")"); do { MOZ_CrashSequence(__null, 6539); __attribute__((nomerge )) ::abort(); } while (false); } while (false); | |||
| 6540 | return ""; | |||
| 6541 | } | |||
| 6542 | ||||
| 6543 | bool nsGlobalWindowInner::RunTimeoutHandler(Timeout* aTimeout) { | |||
| 6544 | // Hold on to the timeout in case mExpr or mFunObj releases its | |||
| 6545 | // doc. | |||
| 6546 | // XXXbz Our caller guarantees it'll hold on to the timeout (because | |||
| 6547 | // we're MOZ_CAN_RUN_SCRIPT), so we can probably stop doing that... | |||
| 6548 | RefPtr<Timeout> timeout = aTimeout; | |||
| 6549 | Timeout* last_running_timeout = mTimeoutManager->BeginRunningTimeout(timeout); | |||
| 6550 | timeout->mRunning = true; | |||
| 6551 | ||||
| 6552 | // Push this timeout's popup control state, which should only be | |||
| 6553 | // enabled the first time a timeout fires that was created while | |||
| 6554 | // popups were enabled and with a delay less than | |||
| 6555 | // "dom.disable_open_click_delay". | |||
| 6556 | AutoPopupStatePusherAutoPopupStatePusherInternal popupStatePusher(timeout->mPopupState); | |||
| 6557 | ||||
| 6558 | // Clear the timeout's popup state, if any, to prevent interval | |||
| 6559 | // timeouts from repeatedly opening poups. | |||
| 6560 | timeout->mPopupState = PopupBlocker::openAbused; | |||
| 6561 | ||||
| 6562 | uint32_t nestingLevel = mTimeoutManager->GetNestingLevelForWindow(); | |||
| 6563 | mTimeoutManager->SetNestingLevelForWindow(timeout->mNestingLevel); | |||
| 6564 | ||||
| 6565 | const char* reason = GetTimeoutReasonString(timeout); | |||
| 6566 | ||||
| 6567 | nsCString str; | |||
| 6568 | if (profiler_thread_is_being_profiled_for_markers()) { | |||
| 6569 | TimeDuration originalInterval = timeout->When() - timeout->SubmitTime(); | |||
| 6570 | str.Append(reason); | |||
| 6571 | str.Append(" with interval "); | |||
| 6572 | str.AppendInt(int(originalInterval.ToMilliseconds())); | |||
| 6573 | str.Append("ms: "); | |||
| 6574 | nsCString handlerDescription; | |||
| 6575 | timeout->mScriptHandler->GetDescription(handlerDescription); | |||
| 6576 | str.Append(handlerDescription); | |||
| 6577 | } | |||
| 6578 | AUTO_PROFILER_MARKER_TEXT("setTimeout callback", DOM,AutoProfilerTextMarker raiiObject6582( "setTimeout callback", ::mozilla::baseprofiler::category::DOM, MarkerOptions(MarkerStack ::TakeBacktrace( timeout->TakeProfilerBacktrace()), MarkerInnerWindowId (mWindowID)), str) | |||
| 6579 | MarkerOptions(MarkerStack::TakeBacktrace(AutoProfilerTextMarker raiiObject6582( "setTimeout callback", ::mozilla::baseprofiler::category::DOM, MarkerOptions(MarkerStack ::TakeBacktrace( timeout->TakeProfilerBacktrace()), MarkerInnerWindowId (mWindowID)), str) | |||
| 6580 | timeout->TakeProfilerBacktrace()),AutoProfilerTextMarker raiiObject6582( "setTimeout callback", ::mozilla::baseprofiler::category::DOM, MarkerOptions(MarkerStack ::TakeBacktrace( timeout->TakeProfilerBacktrace()), MarkerInnerWindowId (mWindowID)), str) | |||
| 6581 | MarkerInnerWindowId(mWindowID)),AutoProfilerTextMarker raiiObject6582( "setTimeout callback", ::mozilla::baseprofiler::category::DOM, MarkerOptions(MarkerStack ::TakeBacktrace( timeout->TakeProfilerBacktrace()), MarkerInnerWindowId (mWindowID)), str) | |||
| 6582 | str)AutoProfilerTextMarker raiiObject6582( "setTimeout callback", ::mozilla::baseprofiler::category::DOM, MarkerOptions(MarkerStack ::TakeBacktrace( timeout->TakeProfilerBacktrace()), MarkerInnerWindowId (mWindowID)), str); | |||
| 6583 | ||||
| 6584 | bool abortIntervalHandler; | |||
| 6585 | { | |||
| 6586 | RefPtr<TimeoutHandler> handler(timeout->mScriptHandler); | |||
| 6587 | ||||
| 6588 | CallbackDebuggerNotificationGuard guard( | |||
| 6589 | this, timeout->mIsInterval | |||
| 6590 | ? DebuggerNotificationType::SetIntervalCallback | |||
| 6591 | : DebuggerNotificationType::SetTimeoutCallback); | |||
| 6592 | abortIntervalHandler = !handler->Call(reason); | |||
| 6593 | } | |||
| 6594 | ||||
| 6595 | // If we received an uncatchable exception, do not schedule the timeout again. | |||
| 6596 | // This allows the slow script dialog to break easy DoS attacks like | |||
| 6597 | // setInterval(function() { while(1); }, 100); | |||
| 6598 | if (abortIntervalHandler) { | |||
| 6599 | // If it wasn't an interval timer to begin with, this does nothing. If it | |||
| 6600 | // was, we'll treat it as a timeout that we just ran and discard it when | |||
| 6601 | // we return. | |||
| 6602 | timeout->mIsInterval = false; | |||
| 6603 | } | |||
| 6604 | ||||
| 6605 | // We ignore any failures from calling EvaluateString() on the context or | |||
| 6606 | // Call() on a Function here since we're in a loop | |||
| 6607 | // where we're likely to be running timeouts whose OS timers | |||
| 6608 | // didn't fire in time and we don't want to not fire those timers | |||
| 6609 | // now just because execution of one timer failed. We can't | |||
| 6610 | // propagate the error to anyone who cares about it from this | |||
| 6611 | // point anyway, and the script context should have already reported | |||
| 6612 | // the script error in the usual way - so we just drop it. | |||
| 6613 | ||||
| 6614 | mTimeoutManager->SetNestingLevelForWindow(nestingLevel); | |||
| 6615 | ||||
| 6616 | mTimeoutManager->EndRunningTimeout(last_running_timeout); | |||
| 6617 | timeout->mRunning = false; | |||
| 6618 | ||||
| 6619 | return timeout->mCleared; | |||
| 6620 | } | |||
| 6621 | ||||
| 6622 | //***************************************************************************** | |||
| 6623 | // nsGlobalWindowInner: Helper Functions | |||
| 6624 | //***************************************************************************** | |||
| 6625 | ||||
| 6626 | already_AddRefed<nsIDocShellTreeOwner> nsGlobalWindowInner::GetTreeOwner() { | |||
| 6627 | FORWARD_TO_OUTER(GetTreeOwner, (), nullptr); | |||
| 6628 | } | |||
| 6629 | ||||
| 6630 | already_AddRefed<nsIWebBrowserChrome> | |||
| 6631 | nsGlobalWindowInner::GetWebBrowserChrome() { | |||
| 6632 | nsCOMPtr<nsIDocShellTreeOwner> treeOwner = GetTreeOwner(); | |||
| 6633 | ||||
| 6634 | nsCOMPtr<nsIWebBrowserChrome> browserChrome = do_GetInterface(treeOwner); | |||
| 6635 | return browserChrome.forget(); | |||
| 6636 | } | |||
| 6637 | ||||
| 6638 | ScrollContainerFrame* nsGlobalWindowInner::GetScrollContainerFrame() { | |||
| 6639 | FORWARD_TO_OUTER(GetScrollContainerFrame, (), nullptr); | |||
| 6640 | } | |||
| 6641 | ||||
| 6642 | bool nsGlobalWindowInner::IsPrivateBrowsing() { | |||
| 6643 | nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(GetDocShell()); | |||
| 6644 | return loadContext && loadContext->UsePrivateBrowsing(); | |||
| 6645 | } | |||
| 6646 | ||||
| 6647 | void nsGlobalWindowInner::FlushPendingNotifications(FlushType aType) { | |||
| 6648 | if (mDoc) { | |||
| 6649 | mDoc->FlushPendingNotifications(aType); | |||
| 6650 | } | |||
| 6651 | } | |||
| 6652 | ||||
| 6653 | void nsGlobalWindowInner::EnableDeviceSensor(uint32_t aType) { | |||
| 6654 | bool alreadyEnabled = false; | |||
| 6655 | for (uint32_t i = 0; i < mEnabledSensors.Length(); i++) { | |||
| 6656 | if (mEnabledSensors[i] == aType) { | |||
| 6657 | alreadyEnabled = true; | |||
| 6658 | break; | |||
| 6659 | } | |||
| 6660 | } | |||
| 6661 | ||||
| 6662 | mEnabledSensors.AppendElement(aType); | |||
| 6663 | ||||
| 6664 | if (alreadyEnabled) { | |||
| 6665 | return; | |||
| 6666 | } | |||
| 6667 | ||||
| 6668 | nsCOMPtr<nsIDeviceSensors> ac = do_GetService(NS_DEVICE_SENSORS_CONTRACTID"@mozilla.org/devicesensors;1"); | |||
| 6669 | if (ac) { | |||
| 6670 | ac->AddWindowListener(aType, this); | |||
| 6671 | } | |||
| 6672 | } | |||
| 6673 | ||||
| 6674 | void nsGlobalWindowInner::DisableDeviceSensor(uint32_t aType) { | |||
| 6675 | int32_t doomedElement = -1; | |||
| 6676 | int32_t listenerCount = 0; | |||
| 6677 | for (uint32_t i = 0; i < mEnabledSensors.Length(); i++) { | |||
| 6678 | if (mEnabledSensors[i] == aType) { | |||
| 6679 | doomedElement = i; | |||
| 6680 | listenerCount++; | |||
| 6681 | } | |||
| 6682 | } | |||
| 6683 | ||||
| 6684 | if (doomedElement == -1) { | |||
| 6685 | return; | |||
| 6686 | } | |||
| 6687 | ||||
| 6688 | mEnabledSensors.RemoveElementAt(doomedElement); | |||
| 6689 | ||||
| 6690 | if (listenerCount > 1) { | |||
| 6691 | return; | |||
| 6692 | } | |||
| 6693 | ||||
| 6694 | nsCOMPtr<nsIDeviceSensors> ac = do_GetService(NS_DEVICE_SENSORS_CONTRACTID"@mozilla.org/devicesensors;1"); | |||
| 6695 | if (ac) { | |||
| 6696 | ac->RemoveWindowListener(aType, this); | |||
| 6697 | } | |||
| 6698 | } | |||
| 6699 | ||||
| 6700 | #if defined(MOZ_WIDGET_ANDROID) | |||
| 6701 | void nsGlobalWindowInner::EnableOrientationChangeListener() { | |||
| 6702 | if (!ShouldResistFingerprinting(RFPTarget::ScreenOrientation)) { | |||
| 6703 | mHasOrientationChangeListeners = true; | |||
| 6704 | mOrientationAngle = Orientation(CallerType::System); | |||
| 6705 | } | |||
| 6706 | } | |||
| 6707 | ||||
| 6708 | void nsGlobalWindowInner::DisableOrientationChangeListener() { | |||
| 6709 | mHasOrientationChangeListeners = false; | |||
| 6710 | } | |||
| 6711 | #endif | |||
| 6712 | ||||
| 6713 | void nsGlobalWindowInner::SetHasGamepadEventListener( | |||
| 6714 | bool aHasGamepad /* = true*/) { | |||
| 6715 | mHasGamepad = aHasGamepad; | |||
| 6716 | if (aHasGamepad) { | |||
| 6717 | EnableGamepadUpdates(); | |||
| 6718 | } | |||
| 6719 | } | |||
| 6720 | ||||
| 6721 | void nsGlobalWindowInner::NotifyDetectXRRuntimesCompleted() { | |||
| 6722 | if (!mXRRuntimeDetectionInFlight) { | |||
| 6723 | return; | |||
| 6724 | } | |||
| 6725 | mXRRuntimeDetectionInFlight = false; | |||
| 6726 | if (mXRPermissionRequestInFlight) { | |||
| 6727 | return; | |||
| 6728 | } | |||
| 6729 | gfx::VRManagerChild* vm = gfx::VRManagerChild::Get(); | |||
| 6730 | bool supported = vm->RuntimeSupportsVR(); | |||
| 6731 | if (!supported) { | |||
| 6732 | // A VR runtime was not installed; we can suppress | |||
| 6733 | // the permission prompt | |||
| 6734 | OnXRPermissionRequestCancel(); | |||
| 6735 | return; | |||
| 6736 | } | |||
| 6737 | // A VR runtime was found. Display a permission prompt before | |||
| 6738 | // allowing it to be accessed. | |||
| 6739 | // Connect to the VRManager in order to receive the runtime | |||
| 6740 | // detection results. | |||
| 6741 | mXRPermissionRequestInFlight = true; | |||
| 6742 | RefPtr request = MakeRefPtr<XRPermissionRequest>(this, WindowID()); | |||
| 6743 | (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" , 6743); | |||
| 6744 | } | |||
| 6745 | ||||
| 6746 | void nsGlobalWindowInner::RequestXRPermission() { | |||
| 6747 | if (IsDying()) { | |||
| 6748 | // Do not proceed if the window is dying, as that will result | |||
| 6749 | // in leaks of objects that get re-allocated after FreeInnerObjects | |||
| 6750 | // has been called, including mVREventObserver. | |||
| 6751 | return; | |||
| 6752 | } | |||
| 6753 | if (mXRPermissionGranted) { | |||
| 6754 | // Don't prompt redundantly once permission to | |||
| 6755 | // access XR devices has been granted. | |||
| 6756 | OnXRPermissionRequestAllow(); | |||
| 6757 | return; | |||
| 6758 | } | |||
| 6759 | if (mXRRuntimeDetectionInFlight || mXRPermissionRequestInFlight) { | |||
| 6760 | // Don't allow multiple simultaneous permissions requests; | |||
| 6761 | return; | |||
| 6762 | } | |||
| 6763 | // Before displaying a permission prompt, detect | |||
| 6764 | // if there is any VR runtime installed. | |||
| 6765 | gfx::VRManagerChild* vm = gfx::VRManagerChild::Get(); | |||
| 6766 | mXRRuntimeDetectionInFlight = true; | |||
| 6767 | EnableVRUpdates(); | |||
| 6768 | vm->DetectRuntimes(); | |||
| 6769 | } | |||
| 6770 | ||||
| 6771 | void nsGlobalWindowInner::OnXRPermissionRequestAllow() { | |||
| 6772 | mXRPermissionRequestInFlight = false; | |||
| 6773 | if (IsDying()) { | |||
| 6774 | // The window may have started dying while the permission request | |||
| 6775 | // is in flight. | |||
| 6776 | // Do not proceed if the window is dying, as that will result | |||
| 6777 | // in leaks of objects that get re-allocated after FreeInnerObjects | |||
| 6778 | // has been called, including mNavigator. | |||
| 6779 | return; | |||
| 6780 | } | |||
| 6781 | mXRPermissionGranted = true; | |||
| 6782 | ||||
| 6783 | NotifyHasXRSession(); | |||
| 6784 | ||||
| 6785 | dom::Navigator* nav = Navigator(); | |||
| 6786 | 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", 6786 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "nav != nullptr" ")" ); do { MOZ_CrashSequence(__null, 6786); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 6787 | nav->OnXRPermissionRequestAllow(); | |||
| 6788 | } | |||
| 6789 | ||||
| 6790 | void nsGlobalWindowInner::OnXRPermissionRequestCancel() { | |||
| 6791 | mXRPermissionRequestInFlight = false; | |||
| 6792 | if (IsDying()) { | |||
| 6793 | // The window may have started dying while the permission request | |||
| 6794 | // is in flight. | |||
| 6795 | // Do not proceed if the window is dying, as that will result | |||
| 6796 | // in leaks of objects that get re-allocated after FreeInnerObjects | |||
| 6797 | // has been called, including mNavigator. | |||
| 6798 | return; | |||
| 6799 | } | |||
| 6800 | dom::Navigator* nav = Navigator(); | |||
| 6801 | 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", 6801 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "nav != nullptr" ")" ); do { MOZ_CrashSequence(__null, 6801); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 6802 | nav->OnXRPermissionRequestCancel(); | |||
| 6803 | } | |||
| 6804 | ||||
| 6805 | void nsGlobalWindowInner::EventListenerAdded(nsAtom* aType) { | |||
| 6806 | if (aType == nsGkAtoms::onvrdisplayactivate || | |||
| 6807 | aType == nsGkAtoms::onvrdisplayconnect || | |||
| 6808 | aType == nsGkAtoms::onvrdisplaydeactivate || | |||
| 6809 | aType == nsGkAtoms::onvrdisplaydisconnect || | |||
| 6810 | aType == nsGkAtoms::onvrdisplaypresentchange) { | |||
| 6811 | RequestXRPermission(); | |||
| 6812 | } | |||
| 6813 | ||||
| 6814 | if (aType == nsGkAtoms::onvrdisplayactivate) { | |||
| 6815 | mHasVRDisplayActivateEvents = true; | |||
| 6816 | } | |||
| 6817 | ||||
| 6818 | if (aType == nsGkAtoms::onunload && mWindowGlobalChild) { | |||
| 6819 | if (++mUnloadOrBeforeUnloadListenerCount == 1) { | |||
| 6820 | mWindowGlobalChild->BlockBFCacheFor(BFCacheStatus::UNLOAD_LISTENER); | |||
| 6821 | } | |||
| 6822 | } | |||
| 6823 | ||||
| 6824 | if (aType == nsGkAtoms::onbeforeunload && mWindowGlobalChild) { | |||
| 6825 | if (!StaticPrefs:: | |||
| 6826 | docshell_shistory_bfcache_ship_allow_beforeunload_listeners()) { | |||
| 6827 | if (++mUnloadOrBeforeUnloadListenerCount == 1) { | |||
| 6828 | mWindowGlobalChild->BlockBFCacheFor( | |||
| 6829 | BFCacheStatus::BEFOREUNLOAD_LISTENER); | |||
| 6830 | } | |||
| 6831 | } | |||
| 6832 | if (!mDoc || !(mDoc->GetSandboxFlags() & SANDBOXED_MODALS)) { | |||
| 6833 | mWindowGlobalChild->BeforeUnloadAdded(); | |||
| 6834 | 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" , 6834); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mWindowGlobalChild->BeforeUnloadListeners() > 0" ")"); do { MOZ_CrashSequence(__null, 6834); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 6835 | } | |||
| 6836 | } | |||
| 6837 | ||||
| 6838 | // We need to initialize localStorage in order to receive notifications. | |||
| 6839 | if (aType == nsGkAtoms::onstorage) { | |||
| 6840 | ErrorResult rv; | |||
| 6841 | GetLocalStorage(rv); | |||
| 6842 | rv.SuppressException(); | |||
| 6843 | ||||
| 6844 | if (NextGenLocalStorageEnabled() && mLocalStorage && | |||
| 6845 | mLocalStorage->Type() == Storage::eLocalStorage) { | |||
| 6846 | auto object = static_cast<LSObject*>(mLocalStorage.get()); | |||
| 6847 | ||||
| 6848 | (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", 6848 ); | |||
| 6849 | } | |||
| 6850 | } | |||
| 6851 | } | |||
| 6852 | ||||
| 6853 | void nsGlobalWindowInner::EventListenerRemoved(nsAtom* aType) { | |||
| 6854 | if (aType == nsGkAtoms::onunload && mWindowGlobalChild) { | |||
| 6855 | 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", 6855 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mUnloadOrBeforeUnloadListenerCount > 0" ")"); do { MOZ_CrashSequence(__null, 6855); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 6856 | if (--mUnloadOrBeforeUnloadListenerCount == 0) { | |||
| 6857 | mWindowGlobalChild->UnblockBFCacheFor(BFCacheStatus::UNLOAD_LISTENER); | |||
| 6858 | } | |||
| 6859 | } | |||
| 6860 | ||||
| 6861 | if (aType == nsGkAtoms::onbeforeunload && mWindowGlobalChild) { | |||
| 6862 | if (!StaticPrefs:: | |||
| 6863 | docshell_shistory_bfcache_ship_allow_beforeunload_listeners()) { | |||
| 6864 | if (--mUnloadOrBeforeUnloadListenerCount == 0) { | |||
| 6865 | mWindowGlobalChild->UnblockBFCacheFor( | |||
| 6866 | BFCacheStatus::BEFOREUNLOAD_LISTENER); | |||
| 6867 | } | |||
| 6868 | } | |||
| 6869 | if (!mDoc || !(mDoc->GetSandboxFlags() & SANDBOXED_MODALS)) { | |||
| 6870 | mWindowGlobalChild->BeforeUnloadRemoved(); | |||
| 6871 | 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" , 6871); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mWindowGlobalChild->BeforeUnloadListeners() >= 0" ")"); do { MOZ_CrashSequence(__null, 6871); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 6872 | } | |||
| 6873 | } | |||
| 6874 | ||||
| 6875 | if (aType == nsGkAtoms::onstorage) { | |||
| 6876 | if (NextGenLocalStorageEnabled() && mLocalStorage && | |||
| 6877 | mLocalStorage->Type() == Storage::eLocalStorage && | |||
| 6878 | // The remove event is fired even if this isn't the last listener, so | |||
| 6879 | // only remove if there are no other listeners left. | |||
| 6880 | mListenerManager && | |||
| 6881 | !mListenerManager->HasListenersFor(nsGkAtoms::onstorage)) { | |||
| 6882 | auto object = static_cast<LSObject*>(mLocalStorage.get()); | |||
| 6883 | ||||
| 6884 | object->DropObserver(); | |||
| 6885 | } | |||
| 6886 | } | |||
| 6887 | } | |||
| 6888 | ||||
| 6889 | void nsGlobalWindowInner::NotifyHasXRSession() { | |||
| 6890 | if (IsDying()) { | |||
| 6891 | // Do not proceed if the window is dying, as that will result | |||
| 6892 | // in leaks of objects that get re-allocated after FreeInnerObjects | |||
| 6893 | // has been called, including mVREventObserver. | |||
| 6894 | return; | |||
| 6895 | } | |||
| 6896 | if (mWindowGlobalChild && !mHasXRSession) { | |||
| 6897 | mWindowGlobalChild->BlockBFCacheFor(BFCacheStatus::HAS_USED_VR); | |||
| 6898 | } | |||
| 6899 | mHasXRSession = true; | |||
| 6900 | EnableVRUpdates(); | |||
| 6901 | } | |||
| 6902 | ||||
| 6903 | bool nsGlobalWindowInner::HasUsedVR() const { | |||
| 6904 | // Returns true only if content has enumerated and activated | |||
| 6905 | // XR devices. Detection of XR runtimes without activation | |||
| 6906 | // will not cause true to be returned. | |||
| 6907 | return mHasXRSession; | |||
| 6908 | } | |||
| 6909 | ||||
| 6910 | bool nsGlobalWindowInner::IsVRContentDetected() const { | |||
| 6911 | // Returns true only if the content will respond to | |||
| 6912 | // the VRDisplayActivate event. | |||
| 6913 | return mHasVRDisplayActivateEvents; | |||
| 6914 | } | |||
| 6915 | ||||
| 6916 | bool nsGlobalWindowInner::IsVRContentPresenting() const { | |||
| 6917 | for (const auto& display : mVRDisplays) { | |||
| 6918 | if (display->IsAnyPresenting(gfx::kVRGroupAll)) { | |||
| 6919 | return true; | |||
| 6920 | } | |||
| 6921 | } | |||
| 6922 | return false; | |||
| 6923 | } | |||
| 6924 | ||||
| 6925 | void nsGlobalWindowInner::AddSizeOfIncludingThis( | |||
| 6926 | nsWindowSizes& aWindowSizes) const { | |||
| 6927 | aWindowSizes.mDOMSizes.mDOMOtherSize += | |||
| 6928 | aWindowSizes.mState.mMallocSizeOf(this); | |||
| 6929 | aWindowSizes.mDOMSizes.mDOMOtherSize += | |||
| 6930 | nsIGlobalObject::ShallowSizeOfExcludingThis( | |||
| 6931 | aWindowSizes.mState.mMallocSizeOf); | |||
| 6932 | ||||
| 6933 | EventListenerManager* elm = GetExistingListenerManager(); | |||
| 6934 | if (elm) { | |||
| 6935 | aWindowSizes.mDOMSizes.mDOMOtherSize += | |||
| 6936 | elm->SizeOfIncludingThis(aWindowSizes.mState.mMallocSizeOf); | |||
| 6937 | aWindowSizes.mDOMEventListenersCount += elm->ListenerCount(); | |||
| 6938 | } | |||
| 6939 | if (mDoc) { | |||
| 6940 | // Multiple global windows can share a document. So only measure the | |||
| 6941 | // document if it (a) doesn't have a global window, or (b) it's the | |||
| 6942 | // primary document for the window. | |||
| 6943 | if (!mDoc->GetInnerWindow() || mDoc->GetInnerWindow() == this) { | |||
| 6944 | mDoc->DocAddSizeOfIncludingThis(aWindowSizes); | |||
| 6945 | } | |||
| 6946 | } | |||
| 6947 | ||||
| 6948 | if (mNavigation) { | |||
| 6949 | aWindowSizes.mDOMSizes.mDOMOtherSize += | |||
| 6950 | aWindowSizes.mState.mMallocSizeOf(mNavigation.get()); | |||
| 6951 | } | |||
| 6952 | if (mNavigator) { | |||
| 6953 | aWindowSizes.mDOMSizes.mDOMOtherSize += | |||
| 6954 | mNavigator->SizeOfIncludingThis(aWindowSizes.mState.mMallocSizeOf); | |||
| 6955 | } | |||
| 6956 | ||||
| 6957 | ForEachGlobalTeardownObserver([&](GlobalTeardownObserver* et, | |||
| 6958 | bool* aDoneOut) { | |||
| 6959 | if (nsCOMPtr<nsISizeOfEventTarget> iSizeOf = do_QueryObject(et)) { | |||
| 6960 | aWindowSizes.mDOMSizes.mDOMEventTargetsSize += | |||
| 6961 | iSizeOf->SizeOfEventTargetIncludingThis( | |||
| 6962 | aWindowSizes.mState.mMallocSizeOf); | |||
| 6963 | } | |||
| 6964 | if (nsCOMPtr<DOMEventTargetHelper> helper = do_QueryObject(et)) { | |||
| 6965 | if (EventListenerManager* elm = helper->GetExistingListenerManager()) { | |||
| 6966 | aWindowSizes.mDOMEventListenersCount += elm->ListenerCount(); | |||
| 6967 | } | |||
| 6968 | } | |||
| 6969 | ++aWindowSizes.mDOMEventTargetsCount; | |||
| 6970 | }); | |||
| 6971 | ||||
| 6972 | if (mPerformance) { | |||
| 6973 | aWindowSizes.mDOMSizes.mDOMPerformanceUserEntries = | |||
| 6974 | mPerformance->SizeOfUserEntries(aWindowSizes.mState.mMallocSizeOf); | |||
| 6975 | aWindowSizes.mDOMSizes.mDOMPerformanceResourceEntries = | |||
| 6976 | mPerformance->SizeOfResourceEntries(aWindowSizes.mState.mMallocSizeOf); | |||
| 6977 | aWindowSizes.mDOMSizes.mDOMPerformanceEventEntries = | |||
| 6978 | mPerformance->SizeOfEventEntries(aWindowSizes.mState.mMallocSizeOf); | |||
| 6979 | } | |||
| 6980 | ||||
| 6981 | aWindowSizes.mMediaSourceURLsCount = mMediaSourceURLs.Length(); | |||
| 6982 | } | |||
| 6983 | ||||
| 6984 | void nsGlobalWindowInner::RegisterDataDocumentForMemoryReporting( | |||
| 6985 | Document* aDocument) { | |||
| 6986 | aDocument->SetAddedToMemoryReportAsDataDocument(); | |||
| 6987 | mDataDocumentsForMemoryReporting.AppendElement(aDocument); | |||
| 6988 | } | |||
| 6989 | ||||
| 6990 | void nsGlobalWindowInner::UnregisterDataDocumentForMemoryReporting( | |||
| 6991 | Document* aDocument) { | |||
| 6992 | DebugOnly<bool> found = | |||
| 6993 | mDataDocumentsForMemoryReporting.RemoveElement(aDocument); | |||
| 6994 | 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" , 6994); AnnotateMozCrashReason("MOZ_ASSERT" "(" "found" ")") ; do { MOZ_CrashSequence(__null, 6994); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 6995 | } | |||
| 6996 | ||||
| 6997 | void nsGlobalWindowInner::CollectDOMSizesForDataDocuments( | |||
| 6998 | nsWindowSizes& aSize) const { | |||
| 6999 | for (Document* doc : mDataDocumentsForMemoryReporting) { | |||
| 7000 | if (doc) { | |||
| 7001 | doc->DocAddSizeOfIncludingThis(aSize); | |||
| 7002 | } | |||
| 7003 | } | |||
| 7004 | } | |||
| 7005 | ||||
| 7006 | void nsGlobalWindowInner::AddGamepad(GamepadHandle aHandle, Gamepad* aGamepad) { | |||
| 7007 | // Create the index we will present to content based on which indices are | |||
| 7008 | // already taken, as required by the spec. | |||
| 7009 | // https://w3c.github.io/gamepad/gamepad.html#widl-Gamepad-index | |||
| 7010 | int index = 0; | |||
| 7011 | while (mGamepadIndexSet.Contains(index)) { | |||
| 7012 | ++index; | |||
| 7013 | } | |||
| 7014 | mGamepadIndexSet.Put(index); | |||
| 7015 | aGamepad->SetIndex(index); | |||
| 7016 | mGamepads.InsertOrUpdate(aHandle, RefPtr{aGamepad}); | |||
| 7017 | } | |||
| 7018 | ||||
| 7019 | void nsGlobalWindowInner::RemoveGamepad(GamepadHandle aHandle) { | |||
| 7020 | RefPtr<Gamepad> gamepad; | |||
| 7021 | if (!mGamepads.Get(aHandle, getter_AddRefs(gamepad))) { | |||
| 7022 | return; | |||
| 7023 | } | |||
| 7024 | // Free up the index we were using so it can be reused | |||
| 7025 | mGamepadIndexSet.Remove(gamepad->Index()); | |||
| 7026 | mGamepads.Remove(aHandle); | |||
| 7027 | } | |||
| 7028 | ||||
| 7029 | void nsGlobalWindowInner::GetGamepads(nsTArray<RefPtr<Gamepad>>& aGamepads) { | |||
| 7030 | aGamepads.Clear(); | |||
| 7031 | ||||
| 7032 | // navigator.getGamepads() always returns an empty array when | |||
| 7033 | // privacy.resistFingerprinting is true. | |||
| 7034 | if (ShouldResistFingerprinting(RFPTarget::Gamepad)) { | |||
| 7035 | return; | |||
| 7036 | } | |||
| 7037 | ||||
| 7038 | // mGamepads.Count() may not be sufficient, but it's not harmful. | |||
| 7039 | aGamepads.SetCapacity(mGamepads.Count()); | |||
| 7040 | for (const auto& entry : mGamepads) { | |||
| 7041 | Gamepad* gamepad = entry.GetWeak(); | |||
| 7042 | aGamepads.EnsureLengthAtLeast(gamepad->Index() + 1); | |||
| 7043 | aGamepads[gamepad->Index()] = gamepad; | |||
| 7044 | } | |||
| 7045 | } | |||
| 7046 | ||||
| 7047 | already_AddRefed<mozilla::dom::Promise> nsGlobalWindowInner::RequestAllGamepads( | |||
| 7048 | ErrorResult& aRv) { | |||
| 7049 | RefPtr<GamepadManager> gamepadManager(GamepadManager::GetService()); | |||
| 7050 | ||||
| 7051 | if (!gamepadManager) { | |||
| 7052 | aRv.Throw(NS_ERROR_UNEXPECTED); | |||
| 7053 | return nullptr; | |||
| 7054 | } | |||
| 7055 | ||||
| 7056 | return gamepadManager->RequestAllGamepads(this, aRv); | |||
| 7057 | } | |||
| 7058 | ||||
| 7059 | already_AddRefed<Gamepad> nsGlobalWindowInner::GetGamepad( | |||
| 7060 | GamepadHandle aHandle) { | |||
| 7061 | RefPtr<Gamepad> gamepad; | |||
| 7062 | ||||
| 7063 | if (mGamepads.Get(aHandle, getter_AddRefs(gamepad))) { | |||
| 7064 | return gamepad.forget(); | |||
| 7065 | } | |||
| 7066 | ||||
| 7067 | return nullptr; | |||
| 7068 | } | |||
| 7069 | ||||
| 7070 | void nsGlobalWindowInner::SetHasSeenGamepadInput(bool aHasSeen) { | |||
| 7071 | mHasSeenGamepadInput = aHasSeen; | |||
| 7072 | } | |||
| 7073 | ||||
| 7074 | bool nsGlobalWindowInner::HasSeenGamepadInput() { return mHasSeenGamepadInput; } | |||
| 7075 | ||||
| 7076 | void nsGlobalWindowInner::SyncGamepadState() { | |||
| 7077 | if (mHasSeenGamepadInput) { | |||
| 7078 | RefPtr<GamepadManager> gamepadManager(GamepadManager::GetService()); | |||
| 7079 | for (const auto& entry : mGamepads) { | |||
| 7080 | gamepadManager->SyncGamepadState(entry.GetKey(), this, entry.GetWeak()); | |||
| 7081 | } | |||
| 7082 | } | |||
| 7083 | } | |||
| 7084 | ||||
| 7085 | void nsGlobalWindowInner::StopGamepadHaptics() { | |||
| 7086 | if (mHasSeenGamepadInput) { | |||
| 7087 | RefPtr<GamepadManager> gamepadManager(GamepadManager::GetService()); | |||
| 7088 | gamepadManager->StopHaptics(); | |||
| 7089 | } | |||
| 7090 | } | |||
| 7091 | ||||
| 7092 | bool nsGlobalWindowInner::UpdateVRDisplays( | |||
| 7093 | nsTArray<RefPtr<mozilla::dom::VRDisplay>>& aDevices) { | |||
| 7094 | VRDisplay::UpdateVRDisplays(mVRDisplays, this); | |||
| 7095 | aDevices = mVRDisplays.Clone(); | |||
| 7096 | return true; | |||
| 7097 | } | |||
| 7098 | ||||
| 7099 | void nsGlobalWindowInner::NotifyActiveVRDisplaysChanged() { | |||
| 7100 | if (mNavigator) { | |||
| 7101 | mNavigator->NotifyActiveVRDisplaysChanged(); | |||
| 7102 | } | |||
| 7103 | } | |||
| 7104 | ||||
| 7105 | void nsGlobalWindowInner::NotifyPresentationGenerationChanged( | |||
| 7106 | uint32_t aDisplayID) { | |||
| 7107 | for (const auto& display : mVRDisplays) { | |||
| 7108 | if (display->DisplayId() == aDisplayID) { | |||
| 7109 | display->OnPresentationGenerationChanged(); | |||
| 7110 | } | |||
| 7111 | } | |||
| 7112 | } | |||
| 7113 | ||||
| 7114 | void nsGlobalWindowInner::DispatchVRDisplayActivate( | |||
| 7115 | uint32_t aDisplayID, mozilla::dom::VRDisplayEventReason aReason) { | |||
| 7116 | // Ensure that our list of displays is up to date | |||
| 7117 | VRDisplay::UpdateVRDisplays(mVRDisplays, this); | |||
| 7118 | ||||
| 7119 | // Search for the display identified with aDisplayID and fire the | |||
| 7120 | // event if found. | |||
| 7121 | for (const auto& display : mVRDisplays) { | |||
| 7122 | if (display->DisplayId() == aDisplayID) { | |||
| 7123 | if (aReason != VRDisplayEventReason::Navigation && | |||
| 7124 | display->IsAnyPresenting(gfx::kVRGroupContent)) { | |||
| 7125 | // We only want to trigger this event if nobody is presenting to the | |||
| 7126 | // display already or when a page is loaded by navigating away | |||
| 7127 | // from a page with an active VR Presentation. | |||
| 7128 | continue; | |||
| 7129 | } | |||
| 7130 | ||||
| 7131 | VRDisplayEventInit init; | |||
| 7132 | init.mBubbles = false; | |||
| 7133 | init.mCancelable = false; | |||
| 7134 | init.mDisplay = display; | |||
| 7135 | init.mReason.Construct(aReason); | |||
| 7136 | ||||
| 7137 | RefPtr<VRDisplayEvent> event = | |||
| 7138 | VRDisplayEvent::Constructor(this, u"vrdisplayactivate"_ns, init); | |||
| 7139 | // vrdisplayactivate is a trusted event, allowing VRDisplay.requestPresent | |||
| 7140 | // to be used in response to link traversal, user request (chrome UX), and | |||
| 7141 | // HMD mounting detection sensors. | |||
| 7142 | event->SetTrusted(true); | |||
| 7143 | // VRDisplay.requestPresent normally requires a user gesture; however, an | |||
| 7144 | // exception is made to allow it to be called in response to | |||
| 7145 | // vrdisplayactivate during VR link traversal. | |||
| 7146 | display->StartHandlingVRNavigationEvent(); | |||
| 7147 | DispatchEvent(*event); | |||
| 7148 | display->StopHandlingVRNavigationEvent(); | |||
| 7149 | // Once we dispatch the event, we must not access any members as an event | |||
| 7150 | // listener can do anything, including closing windows. | |||
| 7151 | return; | |||
| 7152 | } | |||
| 7153 | } | |||
| 7154 | } | |||
| 7155 | ||||
| 7156 | void nsGlobalWindowInner::DispatchVRDisplayDeactivate( | |||
| 7157 | uint32_t aDisplayID, mozilla::dom::VRDisplayEventReason aReason) { | |||
| 7158 | // Ensure that our list of displays is up to date | |||
| 7159 | VRDisplay::UpdateVRDisplays(mVRDisplays, this); | |||
| 7160 | ||||
| 7161 | // Search for the display identified with aDisplayID and fire the | |||
| 7162 | // event if found. | |||
| 7163 | for (const auto& display : mVRDisplays) { | |||
| 7164 | if (display->DisplayId() == aDisplayID && display->IsPresenting()) { | |||
| 7165 | // We only want to trigger this event to content that is presenting to | |||
| 7166 | // the display already. | |||
| 7167 | ||||
| 7168 | VRDisplayEventInit init; | |||
| 7169 | init.mBubbles = false; | |||
| 7170 | init.mCancelable = false; | |||
| 7171 | init.mDisplay = display; | |||
| 7172 | init.mReason.Construct(aReason); | |||
| 7173 | ||||
| 7174 | RefPtr<VRDisplayEvent> event = | |||
| 7175 | VRDisplayEvent::Constructor(this, u"vrdisplaydeactivate"_ns, init); | |||
| 7176 | event->SetTrusted(true); | |||
| 7177 | DispatchEvent(*event); | |||
| 7178 | // Once we dispatch the event, we must not access any members as an event | |||
| 7179 | // listener can do anything, including closing windows. | |||
| 7180 | return; | |||
| 7181 | } | |||
| 7182 | } | |||
| 7183 | } | |||
| 7184 | ||||
| 7185 | void nsGlobalWindowInner::DispatchVRDisplayConnect(uint32_t aDisplayID) { | |||
| 7186 | // Ensure that our list of displays is up to date | |||
| 7187 | VRDisplay::UpdateVRDisplays(mVRDisplays, this); | |||
| 7188 | ||||
| 7189 | // Search for the display identified with aDisplayID and fire the | |||
| 7190 | // event if found. | |||
| 7191 | for (const auto& display : mVRDisplays) { | |||
| 7192 | if (display->DisplayId() == aDisplayID) { | |||
| 7193 | // Fire event even if not presenting to the display. | |||
| 7194 | VRDisplayEventInit init; | |||
| 7195 | init.mBubbles = false; | |||
| 7196 | init.mCancelable = false; | |||
| 7197 | init.mDisplay = display; | |||
| 7198 | // VRDisplayEvent.reason is not set for vrdisplayconnect | |||
| 7199 | ||||
| 7200 | RefPtr<VRDisplayEvent> event = | |||
| 7201 | VRDisplayEvent::Constructor(this, u"vrdisplayconnect"_ns, init); | |||
| 7202 | event->SetTrusted(true); | |||
| 7203 | DispatchEvent(*event); | |||
| 7204 | // Once we dispatch the event, we must not access any members as an event | |||
| 7205 | // listener can do anything, including closing windows. | |||
| 7206 | return; | |||
| 7207 | } | |||
| 7208 | } | |||
| 7209 | } | |||
| 7210 | ||||
| 7211 | void nsGlobalWindowInner::DispatchVRDisplayDisconnect(uint32_t aDisplayID) { | |||
| 7212 | // Ensure that our list of displays is up to date | |||
| 7213 | VRDisplay::UpdateVRDisplays(mVRDisplays, this); | |||
| 7214 | ||||
| 7215 | // Search for the display identified with aDisplayID and fire the | |||
| 7216 | // event if found. | |||
| 7217 | for (const auto& display : mVRDisplays) { | |||
| 7218 | if (display->DisplayId() == aDisplayID) { | |||
| 7219 | // Fire event even if not presenting to the display. | |||
| 7220 | VRDisplayEventInit init; | |||
| 7221 | init.mBubbles = false; | |||
| 7222 | init.mCancelable = false; | |||
| 7223 | init.mDisplay = display; | |||
| 7224 | // VRDisplayEvent.reason is not set for vrdisplaydisconnect | |||
| 7225 | ||||
| 7226 | RefPtr<VRDisplayEvent> event = | |||
| 7227 | VRDisplayEvent::Constructor(this, u"vrdisplaydisconnect"_ns, init); | |||
| 7228 | event->SetTrusted(true); | |||
| 7229 | DispatchEvent(*event); | |||
| 7230 | // Once we dispatch the event, we must not access any members as an event | |||
| 7231 | // listener can do anything, including closing windows. | |||
| 7232 | return; | |||
| 7233 | } | |||
| 7234 | } | |||
| 7235 | } | |||
| 7236 | ||||
| 7237 | void nsGlobalWindowInner::DispatchVRDisplayPresentChange(uint32_t aDisplayID) { | |||
| 7238 | // Ensure that our list of displays is up to date | |||
| 7239 | VRDisplay::UpdateVRDisplays(mVRDisplays, this); | |||
| 7240 | ||||
| 7241 | // Search for the display identified with aDisplayID and fire the | |||
| 7242 | // event if found. | |||
| 7243 | for (const auto& display : mVRDisplays) { | |||
| 7244 | if (display->DisplayId() == aDisplayID) { | |||
| 7245 | // Fire event even if not presenting to the display. | |||
| 7246 | VRDisplayEventInit init; | |||
| 7247 | init.mBubbles = false; | |||
| 7248 | init.mCancelable = false; | |||
| 7249 | init.mDisplay = display; | |||
| 7250 | // VRDisplayEvent.reason is not set for vrdisplaypresentchange | |||
| 7251 | RefPtr<VRDisplayEvent> event = | |||
| 7252 | VRDisplayEvent::Constructor(this, u"vrdisplaypresentchange"_ns, init); | |||
| 7253 | event->SetTrusted(true); | |||
| 7254 | DispatchEvent(*event); | |||
| 7255 | // Once we dispatch the event, we must not access any members as an event | |||
| 7256 | // listener can do anything, including closing windows. | |||
| 7257 | return; | |||
| 7258 | } | |||
| 7259 | } | |||
| 7260 | } | |||
| 7261 | ||||
| 7262 | enum WindowState { | |||
| 7263 | // These constants need to match the constants in Window.webidl | |||
| 7264 | STATE_MAXIMIZED = 1, | |||
| 7265 | STATE_MINIMIZED = 2, | |||
| 7266 | STATE_NORMAL = 3, | |||
| 7267 | STATE_FULLSCREEN = 4 | |||
| 7268 | }; | |||
| 7269 | ||||
| 7270 | uint16_t nsGlobalWindowInner::WindowState() { | |||
| 7271 | nsCOMPtr<nsIWidget> widget = GetMainWidget(); | |||
| 7272 | ||||
| 7273 | int32_t mode = widget ? widget->SizeMode() : 0; | |||
| 7274 | ||||
| 7275 | switch (mode) { | |||
| 7276 | case nsSizeMode_Minimized: | |||
| 7277 | return STATE_MINIMIZED; | |||
| 7278 | case nsSizeMode_Maximized: | |||
| 7279 | return STATE_MAXIMIZED; | |||
| 7280 | case nsSizeMode_Fullscreen: | |||
| 7281 | return STATE_FULLSCREEN; | |||
| 7282 | case nsSizeMode_Normal: | |||
| 7283 | return STATE_NORMAL; | |||
| 7284 | default: | |||
| 7285 | 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" , 7285); | |||
| 7286 | break; | |||
| 7287 | } | |||
| 7288 | ||||
| 7289 | return STATE_NORMAL; | |||
| 7290 | } | |||
| 7291 | ||||
| 7292 | bool nsGlobalWindowInner::IsFullyOccluded() { | |||
| 7293 | nsCOMPtr<nsIWidget> widget = GetMainWidget(); | |||
| 7294 | return widget && widget->IsFullyOccluded(); | |||
| 7295 | } | |||
| 7296 | ||||
| 7297 | void nsGlobalWindowInner::Maximize() { | |||
| 7298 | if (nsCOMPtr<nsIWidget> widget = GetMainWidget()) { | |||
| 7299 | widget->SetSizeMode(nsSizeMode_Maximized); | |||
| 7300 | } | |||
| 7301 | } | |||
| 7302 | ||||
| 7303 | void nsGlobalWindowInner::Minimize() { | |||
| 7304 | if (nsCOMPtr<nsIWidget> widget = GetMainWidget()) { | |||
| 7305 | widget->SetSizeMode(nsSizeMode_Minimized); | |||
| 7306 | } | |||
| 7307 | } | |||
| 7308 | ||||
| 7309 | void nsGlobalWindowInner::Restore() { | |||
| 7310 | if (nsCOMPtr<nsIWidget> widget = GetMainWidget()) { | |||
| 7311 | widget->SetSizeMode(nsSizeMode_Normal); | |||
| 7312 | } | |||
| 7313 | } | |||
| 7314 | ||||
| 7315 | void nsGlobalWindowInner::GetWorkspaceID(nsAString& workspaceID) { | |||
| 7316 | workspaceID.Truncate(); | |||
| 7317 | if (nsCOMPtr<nsIWidget> widget = GetMainWidget()) { | |||
| 7318 | return widget->GetWorkspaceID(workspaceID); | |||
| 7319 | } | |||
| 7320 | } | |||
| 7321 | ||||
| 7322 | void nsGlobalWindowInner::MoveToWorkspace(const nsAString& workspaceID) { | |||
| 7323 | if (nsCOMPtr<nsIWidget> widget = GetMainWidget()) { | |||
| 7324 | widget->MoveToWorkspace(workspaceID); | |||
| 7325 | } | |||
| 7326 | } | |||
| 7327 | ||||
| 7328 | bool nsGlobalWindowInner::IsCloaked() const { | |||
| 7329 | if (nsCOMPtr<nsIWidget> widget = GetMainWidget()) { | |||
| 7330 | return widget->IsCloaked(); | |||
| 7331 | } | |||
| 7332 | // Assume that it is not, since most windows are not cloaked. | |||
| 7333 | return false; | |||
| 7334 | } | |||
| 7335 | ||||
| 7336 | void nsGlobalWindowInner::GetAttention(ErrorResult& aResult) { | |||
| 7337 | return GetAttentionWithCycleCount(-1, aResult); | |||
| 7338 | } | |||
| 7339 | ||||
| 7340 | void nsGlobalWindowInner::GetAttentionWithCycleCount(int32_t aCycleCount, | |||
| 7341 | ErrorResult& aError) { | |||
| 7342 | nsCOMPtr<nsIWidget> widget = GetMainWidget(); | |||
| 7343 | ||||
| 7344 | if (widget) { | |||
| 7345 | aError = widget->GetAttention(aCycleCount); | |||
| 7346 | } | |||
| 7347 | } | |||
| 7348 | ||||
| 7349 | already_AddRefed<Promise> nsGlobalWindowInner::PromiseDocumentFlushed( | |||
| 7350 | PromiseDocumentFlushedCallback& aCallback, ErrorResult& aError) { | |||
| 7351 | 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", 7351 ); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "IsChromeWindow()" ")"); do { MOZ_CrashSequence(__null, 7351); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 7352 | ||||
| 7353 | if (!IsCurrentInnerWindow()) { | |||
| 7354 | aError.ThrowInvalidStateError("Not the current inner window"); | |||
| 7355 | return nullptr; | |||
| 7356 | } | |||
| 7357 | if (!mDoc) { | |||
| 7358 | aError.ThrowInvalidStateError("No document"); | |||
| 7359 | return nullptr; | |||
| 7360 | } | |||
| 7361 | ||||
| 7362 | if (mIteratingDocumentFlushedResolvers) { | |||
| 7363 | aError.ThrowInvalidStateError("Already iterating through resolvers"); | |||
| 7364 | return nullptr; | |||
| 7365 | } | |||
| 7366 | ||||
| 7367 | PresShell* presShell = mDoc->GetPresShell(); | |||
| 7368 | if (!presShell) { | |||
| 7369 | aError.ThrowInvalidStateError("No pres shell"); | |||
| 7370 | return nullptr; | |||
| 7371 | } | |||
| 7372 | ||||
| 7373 | // We need to associate the lifetime of the Promise to the lifetime | |||
| 7374 | // of the caller's global. That way, if the window we're observing | |||
| 7375 | // refresh driver ticks on goes away before our observer is fired, | |||
| 7376 | // we can still resolve the Promise. | |||
| 7377 | nsIGlobalObject* global = GetIncumbentGlobal(); | |||
| 7378 | if (!global) { | |||
| 7379 | aError.ThrowInvalidStateError("No incumbent global"); | |||
| 7380 | return nullptr; | |||
| 7381 | } | |||
| 7382 | ||||
| 7383 | RefPtr<Promise> resultPromise = Promise::Create(global, aError); | |||
| 7384 | if (aError.Failed()) { | |||
| 7385 | return nullptr; | |||
| 7386 | } | |||
| 7387 | ||||
| 7388 | auto flushResolver = std::make_unique<PromiseDocumentFlushedResolver>( | |||
| 7389 | resultPromise, aCallback); | |||
| 7390 | ||||
| 7391 | if (!presShell->NeedStyleFlush() && !presShell->NeedLayoutFlush()) { | |||
| 7392 | flushResolver->Call(); | |||
| 7393 | return resultPromise.forget(); | |||
| 7394 | } | |||
| 7395 | ||||
| 7396 | if (!TryToObserveRefresh()) { | |||
| 7397 | aError.ThrowInvalidStateError("Couldn't observe refresh"); | |||
| 7398 | return nullptr; | |||
| 7399 | } | |||
| 7400 | ||||
| 7401 | mDocumentFlushedResolvers.AppendElement(std::move(flushResolver)); | |||
| 7402 | return resultPromise.forget(); | |||
| 7403 | } | |||
| 7404 | ||||
| 7405 | bool nsGlobalWindowInner::TryToObserveRefresh() { | |||
| 7406 | if (mObservingRefresh) { | |||
| 7407 | return true; | |||
| 7408 | } | |||
| 7409 | ||||
| 7410 | if (!mDoc) { | |||
| 7411 | return false; | |||
| 7412 | } | |||
| 7413 | ||||
| 7414 | nsPresContext* pc = mDoc->GetPresContext(); | |||
| 7415 | if (!pc) { | |||
| 7416 | return false; | |||
| 7417 | } | |||
| 7418 | ||||
| 7419 | mObservingRefresh = true; | |||
| 7420 | auto observer = MakeRefPtr<ManagedPostRefreshObserver>( | |||
| 7421 | pc, [win = RefPtr{this}](bool aWasCanceled) { | |||
| 7422 | if (win->MaybeCallDocumentFlushedResolvers( | |||
| 7423 | /* aUntilExhaustion = */ aWasCanceled)) { | |||
| 7424 | return ManagedPostRefreshObserver::Unregister::No; | |||
| 7425 | } | |||
| 7426 | win->mObservingRefresh = false; | |||
| 7427 | return ManagedPostRefreshObserver::Unregister::Yes; | |||
| 7428 | }); | |||
| 7429 | pc->RegisterManagedPostRefreshObserver(observer.get()); | |||
| 7430 | return mObservingRefresh; | |||
| 7431 | } | |||
| 7432 | ||||
| 7433 | void nsGlobalWindowInner::CallDocumentFlushedResolvers(bool aUntilExhaustion) { | |||
| 7434 | while (true) { | |||
| 7435 | { | |||
| 7436 | // To coalesce MicroTask checkpoints inside callback call, enclose the | |||
| 7437 | // inner loop with nsAutoMicroTask, and perform a MicroTask checkpoint | |||
| 7438 | // after the loop. | |||
| 7439 | nsAutoMicroTask mt; | |||
| 7440 | ||||
| 7441 | mIteratingDocumentFlushedResolvers = true; | |||
| 7442 | ||||
| 7443 | auto resolvers = std::move(mDocumentFlushedResolvers); | |||
| 7444 | for (const auto& resolver : resolvers) { | |||
| 7445 | resolver->Call(); | |||
| 7446 | } | |||
| 7447 | ||||
| 7448 | mIteratingDocumentFlushedResolvers = false; | |||
| 7449 | } | |||
| 7450 | ||||
| 7451 | // Leaving nsAutoMicroTask above will perform MicroTask checkpoint, and | |||
| 7452 | // Promise callbacks there may create mDocumentFlushedResolvers items. | |||
| 7453 | ||||
| 7454 | // If there's no new resolvers, or we're not exhausting the queue, there's | |||
| 7455 | // nothing to do (we'll keep observing if there's any new observer). | |||
| 7456 | // | |||
| 7457 | // Otherwise, keep looping to call all promises. This case can happen while | |||
| 7458 | // destroying the window. This violates the constraint that the | |||
| 7459 | // promiseDocumentFlushed callback only ever run when no flush is needed, | |||
| 7460 | // but it's necessary to resolve the Promise returned by that. | |||
| 7461 | if (!aUntilExhaustion || mDocumentFlushedResolvers.IsEmpty()) { | |||
| 7462 | break; | |||
| 7463 | } | |||
| 7464 | } | |||
| 7465 | } | |||
| 7466 | ||||
| 7467 | bool nsGlobalWindowInner::MaybeCallDocumentFlushedResolvers( | |||
| 7468 | bool aUntilExhaustion) { | |||
| 7469 | 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" , 7469); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mDoc" ")"); do { MOZ_CrashSequence(__null, 7469); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 7470 | ||||
| 7471 | PresShell* presShell = mDoc->GetPresShell(); | |||
| 7472 | if (!presShell || aUntilExhaustion) { | |||
| 7473 | CallDocumentFlushedResolvers(/* aUntilExhaustion = */ true); | |||
| 7474 | return false; | |||
| 7475 | } | |||
| 7476 | ||||
| 7477 | if (presShell->NeedStyleFlush() || presShell->NeedLayoutFlush()) { | |||
| 7478 | // By the time our observer fired, something has already invalidated | |||
| 7479 | // style or layout - or perhaps we're still in the middle of a flush that | |||
| 7480 | // was interrupted. In either case, we'll wait until the next refresh driver | |||
| 7481 | // tick instead and try again. | |||
| 7482 | return true; | |||
| 7483 | } | |||
| 7484 | ||||
| 7485 | CallDocumentFlushedResolvers(/* aUntilExhaustion = */ false); | |||
| 7486 | return !mDocumentFlushedResolvers.IsEmpty(); | |||
| 7487 | } | |||
| 7488 | ||||
| 7489 | already_AddRefed<nsWindowRoot> nsGlobalWindowInner::GetWindowRoot( | |||
| 7490 | mozilla::ErrorResult& aError) { | |||
| 7491 | FORWARD_TO_OUTER_OR_THROW(GetWindowRootOuter, (), aError, nullptr); | |||
| 7492 | } | |||
| 7493 | ||||
| 7494 | void nsGlobalWindowInner::SetCursor(const nsACString& aCursor, | |||
| 7495 | ErrorResult& aError) { | |||
| 7496 | FORWARD_TO_OUTER_OR_THROW(SetCursorOuter, (aCursor, aError), aError, ); | |||
| 7497 | } | |||
| 7498 | ||||
| 7499 | nsIBrowserDOMWindow* nsGlobalWindowInner::GetBrowserDOMWindow( | |||
| 7500 | ErrorResult& aError) { | |||
| 7501 | FORWARD_TO_OUTER_OR_THROW(GetBrowserDOMWindow, (), aError, nullptr); | |||
| 7502 | } | |||
| 7503 | ||||
| 7504 | void nsGlobalWindowInner::SetBrowserDOMWindow( | |||
| 7505 | nsIBrowserDOMWindow* aBrowserWindow, ErrorResult& aError) { | |||
| 7506 | FORWARD_TO_OUTER_OR_THROW(SetBrowserDOMWindowOuter, (aBrowserWindow), | |||
| 7507 | aError, ); | |||
| 7508 | } | |||
| 7509 | ||||
| 7510 | void nsGlobalWindowInner::NotifyDefaultButtonLoaded(Element& aDefaultButton, | |||
| 7511 | ErrorResult& aError) { | |||
| 7512 | // Don't snap to a disabled button. | |||
| 7513 | nsCOMPtr<nsIDOMXULControlElement> xulControl = aDefaultButton.AsXULControl(); | |||
| 7514 | if (!xulControl) { | |||
| 7515 | aError.Throw(NS_ERROR_FAILURE); | |||
| 7516 | return; | |||
| 7517 | } | |||
| 7518 | bool disabled; | |||
| 7519 | aError = xulControl->GetDisabled(&disabled); | |||
| 7520 | if (aError.Failed() || disabled) { | |||
| 7521 | return; | |||
| 7522 | } | |||
| 7523 | ||||
| 7524 | // Get the button rect in screen coordinates. | |||
| 7525 | nsIFrame* frame = aDefaultButton.GetPrimaryFrame(); | |||
| 7526 | if (!frame) { | |||
| 7527 | aError.Throw(NS_ERROR_FAILURE); | |||
| 7528 | return; | |||
| 7529 | } | |||
| 7530 | LayoutDeviceIntRect buttonRect = LayoutDeviceIntRect::FromAppUnitsToNearest( | |||
| 7531 | frame->GetScreenRectInAppUnits(), | |||
| 7532 | frame->PresContext()->AppUnitsPerDevPixel()); | |||
| 7533 | ||||
| 7534 | // Get the widget rect in screen coordinates. | |||
| 7535 | nsIWidget* widget = GetNearestWidget(); | |||
| 7536 | if (!widget) { | |||
| 7537 | aError.Throw(NS_ERROR_FAILURE); | |||
| 7538 | return; | |||
| 7539 | } | |||
| 7540 | LayoutDeviceIntRect widgetRect = widget->GetScreenBounds(); | |||
| 7541 | ||||
| 7542 | // Convert the buttonRect coordinates from screen to the widget. | |||
| 7543 | buttonRect -= widgetRect.TopLeft(); | |||
| 7544 | nsresult rv = widget->OnDefaultButtonLoaded(buttonRect); | |||
| 7545 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) && rv != NS_ERROR_NOT_IMPLEMENTED) { | |||
| 7546 | aError.Throw(rv); | |||
| 7547 | } | |||
| 7548 | } | |||
| 7549 | ||||
| 7550 | ChromeMessageBroadcaster* nsGlobalWindowInner::MessageManager() { | |||
| 7551 | 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", 7551 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsChromeWindow()" ")"); do { MOZ_CrashSequence(__null, 7551); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 7552 | if (!mChromeFields.mMessageManager) { | |||
| 7553 | RefPtr<ChromeMessageBroadcaster> globalMM = | |||
| 7554 | nsFrameMessageManager::GetGlobalMessageManager(); | |||
| 7555 | mChromeFields.mMessageManager = | |||
| 7556 | MakeRefPtr<ChromeMessageBroadcaster>(globalMM); | |||
| 7557 | } | |||
| 7558 | return mChromeFields.mMessageManager; | |||
| 7559 | } | |||
| 7560 | ||||
| 7561 | ChromeMessageBroadcaster* nsGlobalWindowInner::GetGroupMessageManager( | |||
| 7562 | const nsAString& aGroup) { | |||
| 7563 | 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", 7563 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsChromeWindow()" ")"); do { MOZ_CrashSequence(__null, 7563); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 7564 | ||||
| 7565 | return mChromeFields.mGroupMessageManagers | |||
| 7566 | .LookupOrInsertWith( | |||
| 7567 | aGroup, | |||
| 7568 | [&] { | |||
| 7569 | return MakeAndAddRef<ChromeMessageBroadcaster>(MessageManager()); | |||
| 7570 | }) | |||
| 7571 | .get(); | |||
| 7572 | } | |||
| 7573 | ||||
| 7574 | void nsGlobalWindowInner::InitWasOffline() { mWasOffline = NS_IsOffline(); } | |||
| 7575 | ||||
| 7576 | int16_t nsGlobalWindowInner::Orientation(CallerType aCallerType) { | |||
| 7577 | // GetOrientationAngle() returns 0, 90, 180 or 270. | |||
| 7578 | // window.orientation returns -90, 0, 90 or 180. | |||
| 7579 | uint16_t screenAngle = Screen()->GetOrientationAngle(); | |||
| 7580 | if (nsIGlobalObject::ShouldResistFingerprinting( | |||
| 7581 | aCallerType, RFPTarget::ScreenOrientation)) { | |||
| 7582 | CSSIntSize size = mBrowsingContext->TopInnerSizeSpoofedForRFP(); | |||
| 7583 | screenAngle = nsRFPService::ViewportSizeToAngle(size.width, size.height); | |||
| 7584 | } | |||
| 7585 | int16_t angle = AssertedCast<int16_t>(screenAngle); | |||
| 7586 | return angle <= 180 ? angle : angle - 360; | |||
| 7587 | } | |||
| 7588 | ||||
| 7589 | already_AddRefed<Console> nsGlobalWindowInner::GetConsole(JSContext* aCx, | |||
| 7590 | ErrorResult& aRv) { | |||
| 7591 | if (!mConsole) { | |||
| 7592 | mConsole = Console::Create(aCx, this, aRv); | |||
| 7593 | if (NS_WARN_IF(aRv.Failed())NS_warn_if_impl(aRv.Failed(), "aRv.Failed()", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp" , 7593)) { | |||
| 7594 | return nullptr; | |||
| 7595 | } | |||
| 7596 | } | |||
| 7597 | ||||
| 7598 | RefPtr<Console> console = mConsole; | |||
| 7599 | return console.forget(); | |||
| 7600 | } | |||
| 7601 | ||||
| 7602 | already_AddRefed<CookieStore> nsGlobalWindowInner::CookieStore() { | |||
| 7603 | if (!mCookieStore) { | |||
| 7604 | mCookieStore = CookieStore::Create(this); | |||
| 7605 | } | |||
| 7606 | ||||
| 7607 | return do_AddRef(mCookieStore); | |||
| 7608 | } | |||
| 7609 | ||||
| 7610 | DocumentPictureInPicture* nsGlobalWindowInner::DocumentPictureInPicture() { | |||
| 7611 | if (!mDocumentPiP) { | |||
| 7612 | mDocumentPiP = MakeRefPtr<class DocumentPictureInPicture>(this); | |||
| 7613 | } | |||
| 7614 | ||||
| 7615 | return mDocumentPiP; | |||
| 7616 | } | |||
| 7617 | ||||
| 7618 | mozilla::dom::PushManager* nsGlobalWindowInner::GetPushManager( | |||
| 7619 | JSContext* aCx, ErrorResult& aRv) { | |||
| 7620 | if (!mPushManager) { | |||
| 7621 | mPushManager = PushManager::Create(aCx, this, aRv); | |||
| 7622 | } | |||
| 7623 | return mPushManager; | |||
| 7624 | } | |||
| 7625 | ||||
| 7626 | bool nsGlobalWindowInner::IsSecureContext() const { | |||
| 7627 | JS::Realm* realm = js::GetNonCCWObjectRealm(GetWrapperPreserveColor()); | |||
| 7628 | return JS::GetIsSecureContext(realm); | |||
| 7629 | } | |||
| 7630 | ||||
| 7631 | External* nsGlobalWindowInner::External() { | |||
| 7632 | if (!mExternal) { | |||
| 7633 | mExternal = MakeRefPtr<dom::External>(ToSupports(this)); | |||
| 7634 | } | |||
| 7635 | ||||
| 7636 | return mExternal; | |||
| 7637 | } | |||
| 7638 | ||||
| 7639 | void nsGlobalWindowInner::ClearDocumentDependentSlots(JSContext* aCx) { | |||
| 7640 | // If JSAPI OOMs here, there is basically nothing we can do to recover safely. | |||
| 7641 | if (!Window_Binding::ClearCachedDocumentValue(aCx, this) || | |||
| 7642 | !Window_Binding::ClearCachedPerformanceValue(aCx, this)) { | |||
| 7643 | 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", 7643 ); AnnotateMozCrashReason("MOZ_CRASH(" "Unhandlable OOM while clearing document dependent slots." ")"); do { MOZ_CrashSequence(__null, 7643); __attribute__((nomerge )) ::abort(); } while (false); } while (false); | |||
| 7644 | } | |||
| 7645 | } | |||
| 7646 | ||||
| 7647 | /* static */ | |||
| 7648 | JSObject* nsGlobalWindowInner::CreateNamedPropertiesObject( | |||
| 7649 | JSContext* aCx, JS::Handle<JSObject*> aProto) { | |||
| 7650 | return WindowNamedPropertiesHandler::Create(aCx, aProto); | |||
| 7651 | } | |||
| 7652 | ||||
| 7653 | void nsGlobalWindowInner::RedefineProperty(JSContext* aCx, | |||
| 7654 | const char* aPropName, | |||
| 7655 | JS::Handle<JS::Value> aValue, | |||
| 7656 | ErrorResult& aError) { | |||
| 7657 | JS::Rooted<JSObject*> thisObj(aCx, GetWrapperPreserveColor()); | |||
| 7658 | if (!thisObj) { | |||
| 7659 | aError.Throw(NS_ERROR_UNEXPECTED); | |||
| 7660 | return; | |||
| 7661 | } | |||
| 7662 | ||||
| 7663 | if (!JS_WrapObject(aCx, &thisObj) || | |||
| 7664 | !JS_DefineProperty(aCx, thisObj, aPropName, aValue, JSPROP_ENUMERATE)) { | |||
| 7665 | aError.Throw(NS_ERROR_FAILURE); | |||
| 7666 | } | |||
| 7667 | } | |||
| 7668 | ||||
| 7669 | void nsGlobalWindowInner::FireOnNewGlobalObject() { | |||
| 7670 | // AutoEntryScript required to invoke debugger hook, which is a | |||
| 7671 | // Gecko-specific concept at present. | |||
| 7672 | AutoEntryScript aes(this, "nsGlobalWindowInner report new global"); | |||
| 7673 | JS::Rooted<JSObject*> global(aes.cx(), GetWrapper()); | |||
| 7674 | JS_FireOnNewGlobalObject(aes.cx(), global); | |||
| 7675 | } | |||
| 7676 | ||||
| 7677 | #if defined(_WINDOWS_) && !defined(MOZ_WRAPPED_WINDOWS_H) | |||
| 7678 | # pragma message( \ | |||
| 7679 | "wrapper failure reason: " MOZ_WINDOWS_WRAPPER_DISABLED_REASON) | |||
| 7680 | # error "Never include unwrapped windows.h in this file!" | |||
| 7681 | #endif | |||
| 7682 | ||||
| 7683 | already_AddRefed<Promise> nsGlobalWindowInner::CreateImageBitmap( | |||
| 7684 | const ImageBitmapSource& aImage, const ImageBitmapOptions& aOptions, | |||
| 7685 | ErrorResult& aRv) { | |||
| 7686 | return ImageBitmap::Create(this, aImage, Nothing(), aOptions, aRv); | |||
| 7687 | } | |||
| 7688 | ||||
| 7689 | already_AddRefed<Promise> nsGlobalWindowInner::CreateImageBitmap( | |||
| 7690 | const ImageBitmapSource& aImage, int32_t aSx, int32_t aSy, int32_t aSw, | |||
| 7691 | int32_t aSh, const ImageBitmapOptions& aOptions, ErrorResult& aRv) { | |||
| 7692 | return ImageBitmap::Create( | |||
| 7693 | this, aImage, Some(gfx::IntRect(aSx, aSy, aSw, aSh)), aOptions, aRv); | |||
| 7694 | } | |||
| 7695 | ||||
| 7696 | // https://html.spec.whatwg.org/#structured-cloning | |||
| 7697 | void nsGlobalWindowInner::StructuredClone( | |||
| 7698 | JSContext* aCx, JS::Handle<JS::Value> aValue, | |||
| 7699 | const StructuredSerializeOptions& aOptions, | |||
| 7700 | JS::MutableHandle<JS::Value> aRetval, ErrorResult& aError) { | |||
| 7701 | nsContentUtils::StructuredClone(aCx, this, aValue, aOptions, aRetval, aError); | |||
| 7702 | } | |||
| 7703 | ||||
| 7704 | nsresult nsGlobalWindowInner::Dispatch( | |||
| 7705 | already_AddRefed<nsIRunnable> aRunnable) const { | |||
| 7706 | 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", 7706 ); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence(__null, 7706); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 7707 | return NS_DispatchToCurrentThread(std::move(aRunnable)); | |||
| 7708 | } | |||
| 7709 | ||||
| 7710 | nsISerialEventTarget* nsGlobalWindowInner::SerialEventTarget() const { | |||
| 7711 | 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", 7711 ); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence(__null, 7711); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 7712 | return GetMainThreadSerialEventTarget(); | |||
| 7713 | } | |||
| 7714 | ||||
| 7715 | Worklet* nsGlobalWindowInner::GetPaintWorklet(ErrorResult& aRv) { | |||
| 7716 | if (!mPaintWorklet) { | |||
| 7717 | nsIPrincipal* principal = GetPrincipal(); | |||
| 7718 | if (!principal) { | |||
| 7719 | aRv.Throw(NS_ERROR_FAILURE); | |||
| 7720 | return nullptr; | |||
| 7721 | } | |||
| 7722 | ||||
| 7723 | mPaintWorklet = PaintWorkletImpl::CreateWorklet(this, principal); | |||
| 7724 | } | |||
| 7725 | ||||
| 7726 | return mPaintWorklet; | |||
| 7727 | } | |||
| 7728 | ||||
| 7729 | void nsGlobalWindowInner::GetWebExposedLocales(nsTArray<nsString>& aLocales) { | |||
| 7730 | 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", 7730 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mozilla::intl::LocaleService::GetInstance()" ")"); do { MOZ_CrashSequence(__null, 7730); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 7731 | ||||
| 7732 | AutoTArray<nsCString, 10> rpLocales; | |||
| 7733 | mozilla::intl::LocaleService::GetInstance()->GetWebExposedLocales(rpLocales); | |||
| 7734 | ||||
| 7735 | for (const auto& loc : rpLocales) { | |||
| 7736 | aLocales.AppendElement(NS_ConvertUTF8toUTF16(loc)); | |||
| 7737 | } | |||
| 7738 | } | |||
| 7739 | ||||
| 7740 | IntlUtils* nsGlobalWindowInner::GetIntlUtils(ErrorResult& aError) { | |||
| 7741 | if (!mIntlUtils) { | |||
| 7742 | mIntlUtils = MakeRefPtr<IntlUtils>(this); | |||
| 7743 | } | |||
| 7744 | ||||
| 7745 | return mIntlUtils; | |||
| 7746 | } | |||
| 7747 | ||||
| 7748 | void nsGlobalWindowInner::StoreSharedWorker(SharedWorker* aSharedWorker) { | |||
| 7749 | 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", 7749 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aSharedWorker" ")" ); do { MOZ_CrashSequence(__null, 7749); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 7750 | 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", 7750 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mSharedWorkers.Contains(aSharedWorker)" ")"); do { MOZ_CrashSequence(__null, 7750); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 7751 | ||||
| 7752 | mSharedWorkers.AppendElement(aSharedWorker); | |||
| 7753 | } | |||
| 7754 | ||||
| 7755 | void nsGlobalWindowInner::ForgetSharedWorker(SharedWorker* aSharedWorker) { | |||
| 7756 | 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", 7756 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aSharedWorker" ")" ); do { MOZ_CrashSequence(__null, 7756); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 7757 | 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", 7757 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mSharedWorkers.Contains(aSharedWorker)" ")"); do { MOZ_CrashSequence(__null, 7757); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 7758 | ||||
| 7759 | mSharedWorkers.RemoveElement(aSharedWorker); | |||
| 7760 | } | |||
| 7761 | ||||
| 7762 | void nsGlobalWindowInner::UpdateSharedWorkersLanguageOverride( | |||
| 7763 | const nsCString& aLanguageOverride) { | |||
| 7764 | nsTArray<nsString> resolvedLanguages; | |||
| 7765 | Navigator::GetAcceptLanguages(resolvedLanguages, aLanguageOverride.IsEmpty() | |||
| 7766 | ? nullptr | |||
| 7767 | : &aLanguageOverride); | |||
| 7768 | ||||
| 7769 | for (RefPtr<mozilla::dom::SharedWorker> pinnedWorker : | |||
| 7770 | mSharedWorkers.ForwardRange()) { | |||
| 7771 | pinnedWorker->UpdateLanguageOverride(aLanguageOverride, resolvedLanguages); | |||
| 7772 | } | |||
| 7773 | } | |||
| 7774 | ||||
| 7775 | void nsGlobalWindowInner::UpdateSharedWorkerTimezoneOverride( | |||
| 7776 | const nsAString& aTimezoneOverride) { | |||
| 7777 | for (RefPtr<SharedWorker> pinnedWorker : mSharedWorkers.ForwardRange()) { | |||
| 7778 | pinnedWorker->UpdateTimezoneOverride(aTimezoneOverride); | |||
| 7779 | } | |||
| 7780 | } | |||
| 7781 | ||||
| 7782 | RefPtr<GenericPromise> nsGlobalWindowInner::StorageAccessPermissionChanged( | |||
| 7783 | bool aGranted) { | |||
| 7784 | // Invalidate cached StorageAllowed field so that calls to GetLocalStorage | |||
| 7785 | // give us the updated localStorage object. | |||
| 7786 | ClearStorageAllowedCache(); | |||
| 7787 | ||||
| 7788 | // Just reset the active cookie and storage principals | |||
| 7789 | nsCOMPtr<nsICookieJarSettings> cjs; | |||
| 7790 | if (mDoc) { | |||
| 7791 | cjs = mDoc->CookieJarSettings(); | |||
| 7792 | } | |||
| 7793 | StorageAccess storageAccess = StorageAllowedForWindow(this); | |||
| 7794 | if (ShouldPartitionStorage(storageAccess) && | |||
| 7795 | StoragePartitioningEnabled(storageAccess, cjs)) { | |||
| 7796 | if (mDoc) { | |||
| 7797 | mDoc->ClearActiveCookieAndStoragePrincipals(); | |||
| 7798 | } | |||
| 7799 | // When storage access is granted the content process needs to request the | |||
| 7800 | // updated cookie list from the parent process. Otherwise the site won't | |||
| 7801 | // have access to unpartitioned cookies via document.cookie without a | |||
| 7802 | // reload. | |||
| 7803 | if (aGranted) { | |||
| 7804 | nsIChannel* channel = mDoc->GetChannel(); | |||
| 7805 | if (channel) { | |||
| 7806 | // The promise resolves when the updated cookie list has been received | |||
| 7807 | // from the parent. | |||
| 7808 | return ContentChild::UpdateCookieStatus(channel); | |||
| 7809 | } | |||
| 7810 | } | |||
| 7811 | } | |||
| 7812 | ||||
| 7813 | PropagateStorageAccessPermissionGrantedToWorkers(*this); | |||
| 7814 | ||||
| 7815 | // If we have a partitioned localStorage, it's time to replace it with a real | |||
| 7816 | // one in order to receive notifications. | |||
| 7817 | ||||
| 7818 | if (mLocalStorage) { | |||
| 7819 | IgnoredErrorResult error; | |||
| 7820 | GetLocalStorage(error); | |||
| 7821 | if (NS_WARN_IF(error.Failed())NS_warn_if_impl(error.Failed(), "error.Failed()", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp" , 7821)) { | |||
| 7822 | return MozPromise<bool, nsresult, true>::CreateAndReject( | |||
| 7823 | error.StealNSResult(), __func__); | |||
| 7824 | } | |||
| 7825 | ||||
| 7826 | 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", 7827 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLocalStorage && mLocalStorage->Type() == Storage::eLocalStorage" ")"); do { MOZ_CrashSequence(__null, 7827); __attribute__((nomerge )) ::abort(); } while (false); } } while (false) | |||
| 7827 | 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", 7827 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLocalStorage && mLocalStorage->Type() == Storage::eLocalStorage" ")"); do { MOZ_CrashSequence(__null, 7827); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 7828 | ||||
| 7829 | if (NextGenLocalStorageEnabled() && mListenerManager && | |||
| 7830 | mListenerManager->HasListenersFor(nsGkAtoms::onstorage)) { | |||
| 7831 | auto object = static_cast<LSObject*>(mLocalStorage.get()); | |||
| 7832 | ||||
| 7833 | object->EnsureObserver(); | |||
| 7834 | } | |||
| 7835 | } | |||
| 7836 | ||||
| 7837 | // Reset the IndexedDB factory. | |||
| 7838 | mIndexedDB = nullptr; | |||
| 7839 | ||||
| 7840 | // Reset DOM Cache | |||
| 7841 | mCacheStorage = nullptr; | |||
| 7842 | ||||
| 7843 | // Reset the active cookie and storage principals | |||
| 7844 | if (mDoc) { | |||
| 7845 | mDoc->ClearActiveCookieAndStoragePrincipals(); | |||
| 7846 | if (mWindowGlobalChild) { | |||
| 7847 | // Clearing the cookie principal might make us end up with a new effective | |||
| 7848 | // storage principal on the child side than on the parent side, which | |||
| 7849 | // means that we need to sync it. See bug 1705359. | |||
| 7850 | mWindowGlobalChild->SendUpdatePrincipalPartitioning( | |||
| 7851 | !mDoc->UseRegularPrincipal()); | |||
| 7852 | } | |||
| 7853 | } | |||
| 7854 | ||||
| 7855 | // When storage access is granted the content process needs to request the | |||
| 7856 | // updated cookie list from the parent process. Otherwise the site won't have | |||
| 7857 | // access to unpartitioned cookies via document.cookie without a reload. | |||
| 7858 | if (aGranted) { | |||
| 7859 | nsIChannel* channel = mDoc->GetChannel(); | |||
| 7860 | if (channel) { | |||
| 7861 | // The promise resolves when the updated cookie list has been received | |||
| 7862 | // from the parent. | |||
| 7863 | return ContentChild::UpdateCookieStatus(channel); | |||
| 7864 | } | |||
| 7865 | } | |||
| 7866 | return MozPromise<bool, nsresult, true>::CreateAndResolve(true, __func__); | |||
| 7867 | } | |||
| 7868 | ||||
| 7869 | ContentMediaController* nsGlobalWindowInner::GetContentMediaController() { | |||
| 7870 | if (mContentMediaController) { | |||
| 7871 | return mContentMediaController; | |||
| 7872 | } | |||
| 7873 | if (!mBrowsingContext) { | |||
| 7874 | return nullptr; | |||
| 7875 | } | |||
| 7876 | ||||
| 7877 | mContentMediaController = | |||
| 7878 | MakeRefPtr<ContentMediaController>(mBrowsingContext->Id()); | |||
| 7879 | return mContentMediaController; | |||
| 7880 | } | |||
| 7881 | ||||
| 7882 | void nsGlobalWindowInner::SetScrollMarks(const nsTArray<uint32_t>& aScrollMarks, | |||
| 7883 | bool aOnHScrollbar) { | |||
| 7884 | mScrollMarks.Assign(aScrollMarks); | |||
| 7885 | mScrollMarksOnHScrollbar = aOnHScrollbar; | |||
| 7886 | ||||
| 7887 | // Mark the scrollbar for repainting. | |||
| 7888 | if (mDoc) { | |||
| 7889 | PresShell* presShell = mDoc->GetPresShell(); | |||
| 7890 | if (presShell) { | |||
| 7891 | ScrollContainerFrame* sf = presShell->GetRootScrollContainerFrame(); | |||
| 7892 | if (sf) { | |||
| 7893 | sf->InvalidateScrollbars(); | |||
| 7894 | } | |||
| 7895 | } | |||
| 7896 | } | |||
| 7897 | } | |||
| 7898 | ||||
| 7899 | /* static */ | |||
| 7900 | already_AddRefed<nsGlobalWindowInner> nsGlobalWindowInner::Create( | |||
| 7901 | nsGlobalWindowOuter* aOuterWindow, bool aIsChrome, | |||
| 7902 | WindowGlobalChild* aActor) { | |||
| 7903 | RefPtr<nsGlobalWindowInner> window = | |||
| 7904 | new nsGlobalWindowInner(aOuterWindow, aActor); | |||
| 7905 | if (aIsChrome) { | |||
| 7906 | window->mIsChrome = true; | |||
| 7907 | window->mCleanMessageManager = true; | |||
| 7908 | } | |||
| 7909 | ||||
| 7910 | if (aActor) { | |||
| 7911 | aActor->InitWindowGlobal(window); | |||
| 7912 | } | |||
| 7913 | ||||
| 7914 | window->InitWasOffline(); | |||
| 7915 | return window.forget(); | |||
| 7916 | } | |||
| 7917 | ||||
| 7918 | JS::loader::ModuleLoaderBase* nsGlobalWindowInner::GetModuleLoader( | |||
| 7919 | JSContext* aCx) { | |||
| 7920 | Document* document = GetDocument(); | |||
| 7921 | if (!document) { | |||
| 7922 | return nullptr; | |||
| 7923 | } | |||
| 7924 | ||||
| 7925 | ScriptLoader* loader = document->GetScriptLoader(); | |||
| 7926 | if (!loader) { | |||
| 7927 | return nullptr; | |||
| 7928 | } | |||
| 7929 | ||||
| 7930 | return loader->GetModuleLoader(); | |||
| 7931 | } | |||
| 7932 | ||||
| 7933 | void nsGlobalWindowInner::SetCurrentPasteDataTransfer( | |||
| 7934 | DataTransfer* aDataTransfer) { | |||
| 7935 | 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" , 7935); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aDataTransfer->GetEventMessage() == ePaste" ")"); do { MOZ_CrashSequence(__null, 7935); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); } } while ( false); | |||
| 7936 | 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", 7937 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aDataTransfer->ClipboardType() == Some(nsIClipboard::kGlobalClipboard)" ")"); do { MOZ_CrashSequence(__null, 7937); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); } } while ( false) | |||
| 7937 | 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", 7937 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aDataTransfer->ClipboardType() == Some(nsIClipboard::kGlobalClipboard)" ")"); do { MOZ_CrashSequence(__null, 7937); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); } } while ( false); | |||
| 7938 | 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", 7938 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aDataTransfer->GetClipboardDataSnapshot()" ")"); do { MOZ_CrashSequence(__null, 7938); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); } } while ( false); | |||
| 7939 | mCurrentPasteDataTransfer = aDataTransfer; | |||
| 7940 | } | |||
| 7941 | ||||
| 7942 | DataTransfer* nsGlobalWindowInner::GetCurrentPasteDataTransfer() const { | |||
| 7943 | return mCurrentPasteDataTransfer; | |||
| 7944 | } | |||
| 7945 | ||||
| 7946 | TrustedTypePolicyFactory* nsGlobalWindowInner::TrustedTypes() { | |||
| 7947 | if (!mTrustedTypePolicyFactory) { | |||
| 7948 | mTrustedTypePolicyFactory = MakeRefPtr<TrustedTypePolicyFactory>(this); | |||
| 7949 | } | |||
| 7950 | ||||
| 7951 | return mTrustedTypePolicyFactory; | |||
| 7952 | } | |||
| 7953 | ||||
| 7954 | void nsGlobalWindowInner::NoteMediaSourceURL(const nsACString& aURL) { | |||
| 7955 | 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", 7955); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!IsDying()" ") (" "MediaSourceURL will never be cleaned up" ")"); do { MOZ_CrashSequence (__null, 7955); __attribute__((nomerge)) ::abort(); } while ( false); } } while (false); | |||
| 7956 | mMediaSourceURLs.InsertElementSorted(aURL); | |||
| 7957 | } | |||
| 7958 | ||||
| 7959 | void nsGlobalWindowInner::UnnoteMediaSourceURL(const nsACString& aURL) { | |||
| 7960 | DebugOnly<bool> found = mMediaSourceURLs.RemoveElementSorted(aURL); | |||
| 7961 | 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", 7961); AnnotateMozCrashReason("MOZ_ASSERT" "(" "found" ") (" "MediaSourceURL should have been noted" ")"); do { MOZ_CrashSequence (__null, 7961); __attribute__((nomerge)) ::abort(); } while ( false); } } while (false); | |||
| 7962 | } | |||
| 7963 | ||||
| 7964 | void nsGlobalWindowInner::HoldOldPrincipal(nsIPrincipal* aPrincipal) { | |||
| 7965 | mOldPrincipals.AppendElement(aPrincipal); | |||
| 7966 | Dispatch(NewRunnableMethod( | |||
| 7967 | "nsGlobalWindowInner::ClearOldPrincipalsIfNotNestedEventLoop", this, | |||
| 7968 | &nsGlobalWindowInner::ClearOldPrincipalsIfNotNestedEventLoop)); | |||
| 7969 | } | |||
| 7970 | ||||
| 7971 | void nsGlobalWindowInner::ClearOldPrincipalsIfNotNestedEventLoop() { | |||
| 7972 | 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", 7972 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence(__null, 7972); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 7973 | nsThread* mainThread = nsThreadManager::get().GetCurrentThread(); | |||
| 7974 | if (mainThread && mainThread->RecursionDepth() > 1) { | |||
| 7975 | // Not OK to clear old principals from a nested event loop. In order | |||
| 7976 | // to avoid spamming the nested event loop with runnables, just give | |||
| 7977 | // up and leave the old principals around. | |||
| 7978 | return; | |||
| 7979 | } | |||
| 7980 | mOldPrincipals.Clear(); | |||
| 7981 | } | |||
| 7982 | ||||
| 7983 | void nsPIDOMWindowInner::MaybeSetHasPointerRawUpdateEventListeners() { | |||
| 7984 | if (HasPointerRawUpdateEventListeners() || !IsSecureContext()) { | |||
| 7985 | return; | |||
| 7986 | } | |||
| 7987 | mMayHavePointerRawUpdateEventListener = true; | |||
| 7988 | if (BrowserChild* const browserChild = BrowserChild::GetFrom(this)) { | |||
| 7989 | browserChild->OnPointerRawUpdateEventListenerAdded(this); | |||
| 7990 | } | |||
| 7991 | } | |||
| 7992 | ||||
| 7993 | void nsPIDOMWindowInner::ClearHasPointerRawUpdateEventListeners() { | |||
| 7994 | if (!HasPointerRawUpdateEventListeners()) { | |||
| 7995 | return; | |||
| 7996 | } | |||
| 7997 | mMayHavePointerRawUpdateEventListener = false; | |||
| 7998 | if (BrowserChild* const browserChild = BrowserChild::GetFrom(this)) { | |||
| 7999 | browserChild->OnPointerRawUpdateEventListenerRemoved(this); | |||
| 8000 | } | |||
| 8001 | } | |||
| 8002 | ||||
| 8003 | nsIURI* nsPIDOMWindowInner::GetDocumentURI() const { | |||
| 8004 | return mDoc ? mDoc->GetDocumentURI() : mDocumentURI.get(); | |||
| 8005 | } | |||
| 8006 | ||||
| 8007 | nsIURI* nsPIDOMWindowInner::GetDocBaseURI() const { | |||
| 8008 | return mDoc ? mDoc->GetDocBaseURI() : mDocBaseURI.get(); | |||
| 8009 | } | |||
| 8010 | ||||
| 8011 | mozilla::dom::WindowContext* nsPIDOMWindowInner::GetWindowContext() const { | |||
| 8012 | return mWindowGlobalChild ? mWindowGlobalChild->WindowContext() : nullptr; | |||
| 8013 | } | |||
| 8014 | ||||
| 8015 | bool nsPIDOMWindowInner::RemoveFromBFCacheSync() { | |||
| 8016 | if (Document* doc = GetExtantDoc()) { | |||
| 8017 | return doc->RemoveFromBFCacheSync(); | |||
| 8018 | } | |||
| 8019 | return false; | |||
| 8020 | } | |||
| 8021 | ||||
| 8022 | void nsPIDOMWindowInner::MaybeCreateDoc() { | |||
| 8023 | // XXX: Forward to outer? | |||
| 8024 | 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" , 8024); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mDoc" ")") ; do { MOZ_CrashSequence(__null, 8024); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 8025 | if (nsIDocShell* docShell = GetDocShell()) { | |||
| 8026 | // Note that |document| here is the same thing as our mDoc, but we | |||
| 8027 | // don't have to explicitly set the member variable because the docshell | |||
| 8028 | // has already called SetNewDocument(). | |||
| 8029 | nsCOMPtr<Document> document = docShell->GetDocument(); | |||
| 8030 | (void)document; | |||
| 8031 | } | |||
| 8032 | } | |||
| 8033 | ||||
| 8034 | mozilla::dom::DocGroup* nsPIDOMWindowInner::GetDocGroup() const { | |||
| 8035 | Document* doc = GetExtantDoc(); | |||
| 8036 | if (doc) { | |||
| 8037 | return doc->GetDocGroup(); | |||
| 8038 | } | |||
| 8039 | return nullptr; | |||
| 8040 | } | |||
| 8041 | ||||
| 8042 | mozilla::dom::BrowsingContextGroup* | |||
| 8043 | nsPIDOMWindowInner::GetBrowsingContextGroup() const { | |||
| 8044 | return mBrowsingContext ? mBrowsingContext->Group() : nullptr; | |||
| 8045 | } | |||
| 8046 | ||||
| 8047 | nsIGlobalObject* nsPIDOMWindowInner::AsGlobal() { | |||
| 8048 | return nsGlobalWindowInner::Cast(this); | |||
| 8049 | } | |||
| 8050 | ||||
| 8051 | const nsIGlobalObject* nsPIDOMWindowInner::AsGlobal() const { | |||
| 8052 | return nsGlobalWindowInner::Cast(this); | |||
| 8053 | } | |||
| 8054 | ||||
| 8055 | RefPtr<GenericPromise> | |||
| 8056 | nsPIDOMWindowInner::SaveStorageAccessPermissionGranted() { | |||
| 8057 | WindowContext* wc = GetWindowContext(); | |||
| 8058 | if (wc) { | |||
| 8059 | (void)wc->SetUsingStorageAccess(true); | |||
| 8060 | } | |||
| 8061 | ||||
| 8062 | return nsGlobalWindowInner::Cast(this)->StorageAccessPermissionChanged(true); | |||
| 8063 | } | |||
| 8064 | ||||
| 8065 | RefPtr<GenericPromise> | |||
| 8066 | nsPIDOMWindowInner::SaveStorageAccessPermissionRevoked() { | |||
| 8067 | WindowContext* wc = GetWindowContext(); | |||
| 8068 | if (wc) { | |||
| 8069 | (void)wc->SetUsingStorageAccess(false); | |||
| 8070 | } | |||
| 8071 | ||||
| 8072 | return nsGlobalWindowInner::Cast(this)->StorageAccessPermissionChanged(false); | |||
| 8073 | } | |||
| 8074 | ||||
| 8075 | bool nsPIDOMWindowInner::UsingStorageAccess() { | |||
| 8076 | WindowContext* wc = GetWindowContext(); | |||
| 8077 | if (!wc) { | |||
| 8078 | return false; | |||
| 8079 | } | |||
| 8080 | ||||
| 8081 | return wc->GetUsingStorageAccess(); | |||
| 8082 | } | |||
| 8083 | ||||
| 8084 | WebIdentityHandler* nsPIDOMWindowInner::GetOrCreateWebIdentityHandler() { | |||
| 8085 | if (mWebIdentityHandler) { | |||
| 8086 | return mWebIdentityHandler; | |||
| 8087 | } | |||
| 8088 | mWebIdentityHandler = MakeRefPtr<WebIdentityHandler>(this); | |||
| 8089 | bool success = mWebIdentityHandler->MaybeCreateActor(); | |||
| 8090 | if (!success) { | |||
| 8091 | mWebIdentityHandler = nullptr; | |||
| 8092 | } | |||
| 8093 | return mWebIdentityHandler; | |||
| 8094 | } | |||
| 8095 | ||||
| 8096 | CloseWatcherManager* nsPIDOMWindowInner::EnsureCloseWatcherManager() { | |||
| 8097 | if (!mCloseWatcherManager) { | |||
| 8098 | mCloseWatcherManager = MakeRefPtr<CloseWatcherManager>(); | |||
| 8099 | } | |||
| 8100 | return mCloseWatcherManager; | |||
| 8101 | } | |||
| 8102 | ||||
| 8103 | void nsPIDOMWindowInner::NotifyCloseWatcherAdded() { | |||
| 8104 | 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", 8104 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCloseWatcherManager && !mCloseWatcherManager->IsEmpty()" ")"); do { MOZ_CrashSequence(__null, 8104); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 8105 | if (WindowContext* top = TopWindowContext(*this)) { | |||
| 8106 | (void)top->SetHasActiveCloseWatcher(true); | |||
| 8107 | } | |||
| 8108 | } | |||
| 8109 | ||||
| 8110 | void nsPIDOMWindowInner::NotifyCloseWatcherRemoved() { | |||
| 8111 | 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", 8111 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCloseWatcherManager" ")"); do { MOZ_CrashSequence(__null, 8111); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 8112 | if (WindowContext* top = TopWindowContext(*this)) { | |||
| 8113 | (void)top->SetHasActiveCloseWatcher(!mCloseWatcherManager->IsEmpty()); | |||
| 8114 | } | |||
| 8115 | } | |||
| 8116 | ||||
| 8117 | nsPIDOMWindowInner::nsPIDOMWindowInner(nsPIDOMWindowOuter* aOuterWindow, | |||
| 8118 | WindowGlobalChild* aActor) | |||
| 8119 | : mOuterWindow(aOuterWindow), mWindowGlobalChild(aActor) { | |||
| 8120 | 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" , 8120); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aOuterWindow" ")"); do { MOZ_CrashSequence(__null, 8120); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 8121 | mBrowsingContext = aOuterWindow->GetBrowsingContext(); | |||
| 8122 | ||||
| 8123 | if (mWindowGlobalChild) { | |||
| 8124 | mWindowID = aActor->InnerWindowId(); | |||
| 8125 | ||||
| 8126 | 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", 8126 ); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mWindowGlobalChild->BrowsingContext() == mBrowsingContext" ")"); do { MOZ_CrashSequence(__null, 8126); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); | |||
| 8127 | } else { | |||
| 8128 | mWindowID = nsContentUtils::GenerateWindowId(); | |||
| 8129 | } | |||
| 8130 | } | |||
| 8131 | ||||
| 8132 | nsPIDOMWindowInner::~nsPIDOMWindowInner() = default; | |||
| 8133 | ||||
| 8134 | #undef FORWARD_TO_OUTER | |||
| 8135 | #undef FORWARD_TO_OUTER_OR_THROW | |||
| 8136 | #undef FORWARD_TO_OUTER_VOID |