Bug 1769952 - Fix running raptor on a Win10-64 VM r=sparky
[gecko.git] / dom / xul / XULFrameElement.cpp
blob2825a610e752f8507eceaf77d5dded5eee89ab86
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "nsCOMPtr.h"
8 #include "nsIBrowser.h"
9 #include "nsIContent.h"
10 #include "nsIOpenWindowInfo.h"
11 #include "nsFrameLoader.h"
12 #include "mozilla/AsyncEventDispatcher.h"
13 #include "mozilla/dom/HTMLIFrameElement.h"
14 #include "mozilla/dom/WindowProxyHolder.h"
15 #include "mozilla/dom/XULFrameElement.h"
16 #include "mozilla/dom/XULFrameElementBinding.h"
18 namespace mozilla::dom {
20 NS_IMPL_CYCLE_COLLECTION_CLASS(XULFrameElement)
22 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(XULFrameElement, nsXULElement)
23 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFrameLoader)
24 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOpenWindowInfo)
25 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
27 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(XULFrameElement, nsXULElement)
28 if (tmp->mFrameLoader) {
29 tmp->mFrameLoader->Destroy();
31 NS_IMPL_CYCLE_COLLECTION_UNLINK(mOpenWindowInfo)
32 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
34 NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED(XULFrameElement, nsXULElement,
35 nsFrameLoaderOwner)
37 JSObject* XULFrameElement::WrapNode(JSContext* aCx,
38 JS::Handle<JSObject*> aGivenProto) {
39 return XULFrameElement_Binding::Wrap(aCx, this, aGivenProto);
42 nsDocShell* XULFrameElement::GetDocShell() {
43 RefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
44 return frameLoader ? frameLoader->GetDocShell(IgnoreErrors()) : nullptr;
47 already_AddRefed<nsIWebNavigation> XULFrameElement::GetWebNavigation() {
48 nsCOMPtr<nsIDocShell> docShell = GetDocShell();
49 nsCOMPtr<nsIWebNavigation> webnav = do_QueryInterface(docShell);
50 return webnav.forget();
53 Nullable<WindowProxyHolder> XULFrameElement::GetContentWindow() {
54 RefPtr<nsDocShell> docShell = GetDocShell();
55 if (docShell) {
56 return docShell->GetWindowProxy();
59 return nullptr;
62 Document* XULFrameElement::GetContentDocument() {
63 nsCOMPtr<nsIDocShell> docShell = GetDocShell();
64 if (docShell) {
65 nsCOMPtr<nsPIDOMWindowOuter> win = docShell->GetWindow();
66 if (win) {
67 return win->GetDoc();
70 return nullptr;
73 uint64_t XULFrameElement::BrowserId() {
74 if (mFrameLoader) {
75 if (auto* bc = mFrameLoader->GetExtantBrowsingContext()) {
76 return bc->GetBrowserId();
79 return 0;
82 nsIOpenWindowInfo* XULFrameElement::GetOpenWindowInfo() const {
83 return mOpenWindowInfo;
86 void XULFrameElement::SetOpenWindowInfo(nsIOpenWindowInfo* aInfo) {
87 mOpenWindowInfo = aInfo;
90 void XULFrameElement::LoadSrc() {
91 if (!IsInUncomposedDoc() || !OwnerDoc()->GetRootElement()) {
92 return;
94 RefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
95 if (!frameLoader) {
96 // We may have had a nsIOpenWindowInfo set on us by browser chrome, due to
97 // being used as the target for a `window.open` call. Fetch that information
98 // if it's available, and clear it out so we don't read it again.
99 nsCOMPtr<nsIOpenWindowInfo> openWindowInfo = mOpenWindowInfo.forget();
101 // false as the networkCreated parameter so that xul:iframe/browser/editor
102 // session history handling works like dynamic html:iframes. Usually xul
103 // elements are used in chrome, which doesn't have session history at all.
104 mFrameLoader = nsFrameLoader::Create(this, false, openWindowInfo);
105 if (NS_WARN_IF(!mFrameLoader)) {
106 return;
109 (new AsyncEventDispatcher(this, u"XULFrameLoaderCreated"_ns,
110 CanBubble::eYes))
111 ->RunDOMEventWhenSafe();
114 mFrameLoader->LoadFrame(false);
117 void XULFrameElement::SwapFrameLoaders(HTMLIFrameElement& aOtherLoaderOwner,
118 ErrorResult& rv) {
119 aOtherLoaderOwner.SwapFrameLoaders(this, rv);
122 void XULFrameElement::SwapFrameLoaders(XULFrameElement& aOtherLoaderOwner,
123 ErrorResult& rv) {
124 if (&aOtherLoaderOwner == this) {
125 // nothing to do
126 return;
129 aOtherLoaderOwner.SwapFrameLoaders(this, rv);
132 void XULFrameElement::SwapFrameLoaders(nsFrameLoaderOwner* aOtherLoaderOwner,
133 mozilla::ErrorResult& rv) {
134 if (RefPtr<Document> doc = GetComposedDoc()) {
135 // SwapWithOtherLoader relies on frames being up-to-date.
136 doc->FlushPendingNotifications(FlushType::Frames);
139 RefPtr<nsFrameLoader> loader = GetFrameLoader();
140 RefPtr<nsFrameLoader> otherLoader = aOtherLoaderOwner->GetFrameLoader();
141 if (!loader || !otherLoader) {
142 rv.Throw(NS_ERROR_NOT_IMPLEMENTED);
143 return;
146 rv = loader->SwapWithOtherLoader(otherLoader, this, aOtherLoaderOwner);
149 nsresult XULFrameElement::BindToTree(BindContext& aContext, nsINode& aParent) {
150 nsresult rv = nsXULElement::BindToTree(aContext, aParent);
151 NS_ENSURE_SUCCESS(rv, rv);
153 if (IsInUncomposedDoc()) {
154 NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(),
155 "Missing a script blocker!");
156 // We're in a document now. Kick off the frame load.
157 LoadSrc();
160 return NS_OK;
163 void XULFrameElement::UnbindFromTree(bool aNullParent) {
164 if (RefPtr<nsFrameLoader> frameLoader = GetFrameLoader()) {
165 frameLoader->Destroy();
167 mFrameLoader = nullptr;
169 nsXULElement::UnbindFromTree(aNullParent);
172 void XULFrameElement::DestroyContent() {
173 RefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
174 if (frameLoader) {
175 frameLoader->Destroy();
177 mFrameLoader = nullptr;
179 nsXULElement::DestroyContent();
182 nsresult XULFrameElement::AfterSetAttr(int32_t aNamespaceID, nsAtom* aName,
183 const nsAttrValue* aValue,
184 const nsAttrValue* aOldValue,
185 nsIPrincipal* aSubjectPrincipal,
186 bool aNotify) {
187 if (aNamespaceID == kNameSpaceID_None) {
188 if (aName == nsGkAtoms::src && aValue) {
189 LoadSrc();
190 } else if (aName == nsGkAtoms::disablefullscreen && mFrameLoader) {
191 if (auto* bc = mFrameLoader->GetExtantBrowsingContext()) {
192 MOZ_ALWAYS_SUCCEEDS(bc->SetFullscreenAllowedByOwner(!aValue));
197 return nsXULElement::AfterSetAttr(aNamespaceID, aName, aValue, aOldValue,
198 aSubjectPrincipal, aNotify);
201 } // namespace mozilla::dom