Bug Summary

File:var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp
Warning:line 2116, column 7
Value stored to 'rv' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name Unified_cpp_layout_base1.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/layout/base -fcoverage-compilation-dir=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/layout/base -resource-dir /usr/lib/llvm-20/lib/clang/20 -include /var/lib/jenkins/workspace/firefox-scan-build/config/gcc_hidden.h -include /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D _GLIBCXX_ASSERTIONS -D DEBUG=1 -D MOZ_HAS_MOZGLUE -D MOZILLA_INTERNAL_API -D IMPL_LIBXUL -D MOZ_SUPPORT_LEAKCHECKING -D STATIC_EXPORTABLE_JS_API -I /var/lib/jenkins/workspace/firefox-scan-build/layout/base -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/layout/base -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/ipc/ipdl/_ipdlheaders -I /var/lib/jenkins/workspace/firefox-scan-build/ipc/chromium/src -I /var/lib/jenkins/workspace/firefox-scan-build/layout/forms -I /var/lib/jenkins/workspace/firefox-scan-build/layout/generic -I /var/lib/jenkins/workspace/firefox-scan-build/layout/mathml -I /var/lib/jenkins/workspace/firefox-scan-build/layout/painting -I /var/lib/jenkins/workspace/firefox-scan-build/layout/printing -I /var/lib/jenkins/workspace/firefox-scan-build/layout/style -I /var/lib/jenkins/workspace/firefox-scan-build/layout/tables -I /var/lib/jenkins/workspace/firefox-scan-build/layout/xul -I /var/lib/jenkins/workspace/firefox-scan-build/layout/xul/tree -I /var/lib/jenkins/workspace/firefox-scan-build/docshell/base -I /var/lib/jenkins/workspace/firefox-scan-build/dom/base -I /var/lib/jenkins/workspace/firefox-scan-build/dom/html -I /var/lib/jenkins/workspace/firefox-scan-build/dom/svg -I /var/lib/jenkins/workspace/firefox-scan-build/dom/xul -I /var/lib/jenkins/workspace/firefox-scan-build/view -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/x86_64-linux-gnu/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/backward -internal-isystem /usr/lib/llvm-20/lib/clang/20/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-deprecated-anon-enum-enum-conversion -Wno-deprecated-enum-enum-conversion -Wno-deprecated-this-capture -Wno-inline-new-delete -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-vla-cxx-extension -Wno-unknown-warning-option -fdeprecated-macro -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fno-sized-deallocation -fno-aligned-allocation -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2025-01-20-090804-167946-1 -x c++ Unified_cpp_layout_base1.cpp
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/. */
6
7/* container for a document and its presentation */
8
9#include "gfxContext.h"
10#include "mozilla/PresShell.h"
11#include "mozilla/RestyleManager.h"
12#include "mozilla/ServoStyleSet.h"
13#include "mozilla/StaticPrefs_print.h"
14#include "mozilla/Telemetry.h"
15#include "nsThreadUtils.h"
16#include "nscore.h"
17#include "nsCOMPtr.h"
18#include "nsCRT.h"
19#include "nsFrameSelection.h"
20#include "nsString.h"
21#include "nsReadableUtils.h"
22#include "nsIContent.h"
23#include "nsIDocumentViewer.h"
24#include "nsIDocumentViewerPrint.h"
25#include "nsIScreen.h"
26#include "mozilla/dom/AutoSuppressEventHandlingAndSuspend.h"
27#include "mozilla/dom/BrowsingContext.h"
28#include "mozilla/dom/BeforeUnloadEvent.h"
29#include "mozilla/dom/PopupBlocker.h"
30#include "mozilla/dom/Document.h"
31#include "mozilla/dom/DocumentInlines.h"
32#include "mozilla/dom/DocGroup.h"
33#include "mozilla/dom/FragmentDirective.h"
34#include "mozilla/widget/Screen.h"
35#include "nsPresContext.h"
36#include "nsIFrame.h"
37#include "nsIWritablePropertyBag2.h"
38#include "nsSubDocumentFrame.h"
39#include "nsGenericHTMLElement.h"
40#include "nsStubMutationObserver.h"
41
42#include "nsISelectionListener.h"
43#include "mozilla/dom/Selection.h"
44#include "nsContentUtils.h"
45#ifdef ACCESSIBILITY1
46# include "mozilla/a11y/DocAccessible.h"
47#endif
48#include "mozilla/BasicEvents.h"
49#include "mozilla/Encoding.h"
50#include "mozilla/ErrorResult.h"
51#include "mozilla/Preferences.h"
52#include "mozilla/ScrollContainerFrame.h"
53#include "mozilla/SpinEventLoopUntil.h"
54#include "mozilla/WeakPtr.h"
55#include "mozilla/StaticPrefs_dom.h"
56#include "mozilla/StaticPrefs_javascript.h"
57#include "mozilla/StaticPrefs_fission.h"
58#include "mozilla/StaticPrefs_print.h"
59#include "mozilla/StyleSheet.h"
60#include "mozilla/StyleSheetInlines.h"
61#include "mozilla/Try.h"
62
63#include "nsViewManager.h"
64#include "nsView.h"
65
66#include "nsPageSequenceFrame.h"
67#include "nsNetUtil.h"
68#include "nsIDocumentViewerEdit.h"
69#include "mozilla/css/Loader.h"
70#include "nsIInterfaceRequestor.h"
71#include "nsIInterfaceRequestorUtils.h"
72#include "nsDocShell.h"
73#include "nsIBaseWindow.h"
74#include "nsILayoutHistoryState.h"
75#include "nsCharsetSource.h"
76#include "mozilla/ReflowInput.h"
77#include "nsIImageLoadingContent.h"
78#include "nsCopySupport.h"
79#include "nsXULPopupManager.h"
80
81#include "nsIClipboard.h"
82#include "nsIClipboardHelper.h"
83
84#include "nsPIDOMWindow.h"
85#include "nsGlobalWindowInner.h"
86#include "nsGlobalWindowOuter.h"
87#include "nsDOMNavigationTiming.h"
88#include "nsPIWindowRoot.h"
89#include "nsJSEnvironment.h"
90#include "nsFocusManager.h"
91
92#include "nsStyleSheetService.h"
93#include "nsILoadContext.h"
94#include "mozilla/ThrottledEventQueue.h"
95#include "nsIPromptCollection.h"
96#include "nsIPromptService.h"
97#include "imgIContainer.h" // image animation mode constants
98#include "nsIXULRuntime.h"
99#include "nsSandboxFlags.h"
100
101//--------------------------
102// Printing Include
103//---------------------------
104#ifdef NS_PRINTING1
105
106# include "nsIWebBrowserPrint.h"
107
108# include "nsPrintJob.h"
109# include "nsDeviceContextSpecProxy.h"
110
111// Print Options
112# include "nsIPrintSettings.h"
113# include "nsIPrintSettingsService.h"
114# include "nsISimpleEnumerator.h"
115
116#endif // NS_PRINTING
117
118// focus
119#include "nsIDOMEventListener.h"
120#include "nsISelectionController.h"
121
122#include "mozilla/EventDispatcher.h"
123#include "nsISHEntry.h"
124#include "nsISHistory.h"
125#include "nsIWebNavigation.h"
126#include "mozilla/dom/XMLHttpRequestMainThread.h"
127
128// paint forcing
129#include <stdio.h>
130#include "mozilla/BasePrincipal.h"
131#include "mozilla/dom/Element.h"
132#include "mozilla/dom/Event.h"
133#include "mozilla/Telemetry.h"
134#include "mozilla/dom/ScriptLoader.h"
135#include "mozilla/dom/WindowGlobalChild.h"
136
137namespace mozilla {
138namespace dom {
139class PrintPreviewResultInfo;
140} // namespace dom
141} // namespace mozilla
142
143using namespace mozilla;
144using namespace mozilla::dom;
145
146using mozilla::layout::RemotePrintJobChild;
147using PrintPreviewResolver =
148 std::function<void(const mozilla::dom::PrintPreviewResultInfo&)>;
149
150//-----------------------------------------------------
151// LOGGING
152#include "LayoutLogging.h"
153#include "mozilla/Logging.h"
154
155extern mozilla::LazyLogModule gPageCacheLog;
156
157#ifdef NS_PRINTING1
158mozilla::LazyLogModule gPrintingLog("printing");
159
160# define PR_PL(_p1)do { const ::mozilla::LogModule* moz_real_module = gPrintingLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, MOZ_LOG_EXPAND_ARGS
_p1); } } while (0);
MOZ_LOG(gPrintingLog, mozilla::LogLevel::Debug, _p1)do { const ::mozilla::LogModule* moz_real_module = gPrintingLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, MOZ_LOG_EXPAND_ARGS
_p1); } } while (0)
;
161#endif // NS_PRINTING
162
163#define PRT_YESNO(_p)((_p) ? "YES" : "NO") ((_p) ? "YES" : "NO")
164//-----------------------------------------------------
165
166class nsDocumentViewer;
167
168// a small delegate class used to avoid circular references
169
170class nsDocViewerSelectionListener final : public nsISelectionListener {
171 public:
172 // nsISupports interface...
173 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:
174
175 // nsISelectionListerner interface
176 NS_DECL_NSISELECTIONLISTENERvirtual nsresult NotifySelectionChanged(mozilla::dom::Document
*doc, mozilla::dom::Selection *sel, int16_t reason, int32_t amount
) override;
177
178 explicit nsDocViewerSelectionListener(nsDocumentViewer* aDocViewer)
179 : mDocViewer(aDocViewer), mSelectionWasCollapsed(true) {}
180
181 void Disconnect() { mDocViewer = nullptr; }
182
183 protected:
184 virtual ~nsDocViewerSelectionListener() = default;
185
186 nsDocumentViewer* mDocViewer;
187 bool mSelectionWasCollapsed;
188};
189
190/** editor Implementation of the FocusListener interface */
191class nsDocViewerFocusListener final : public nsIDOMEventListener {
192 public:
193 explicit nsDocViewerFocusListener(nsDocumentViewer* aDocViewer)
194 : mDocViewer(aDocViewer) {}
195
196 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:
197 NS_DECL_NSIDOMEVENTLISTENERvirtual nsresult HandleEvent(mozilla::dom::Event *event) override
;
198
199 void Disconnect() { mDocViewer = nullptr; }
200
201 protected:
202 virtual ~nsDocViewerFocusListener() = default;
203
204 nsDocumentViewer* mDocViewer;
205};
206
207namespace viewer_detail {
208
209/**
210 * Mutation observer for use until we hand ourselves over to our SHEntry.
211 */
212class BFCachePreventionObserver final : public nsStubMutationObserver {
213 public:
214 explicit BFCachePreventionObserver(Document* aDocument)
215 : mDocument(aDocument) {}
216
217 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:
218
219 NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGEDvirtual void CharacterDataChanged( nsIContent* aContent, const
CharacterDataChangeInfo& aInfo) override;
220 NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGEDvirtual void AttributeChanged(mozilla::dom::Element* aElement
, int32_t aNameSpaceID, nsAtom* aAttribute, int32_t aModType,
const nsAttrValue* aOldValue) override;
221 NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDEDvirtual void ContentAppended(nsIContent* aFirstNewContent) override
;
222 NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTEDvirtual void ContentInserted(nsIContent* aChild) override;
223 NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVEDvirtual void ContentWillBeRemoved(nsIContent* aChild, const BatchRemovalState
*) override;
224 NS_DECL_NSIMUTATIONOBSERVER_NODEWILLBEDESTROYEDvirtual void NodeWillBeDestroyed(nsINode* aNode) override;
225
226 // Stop observing the document.
227 void Disconnect();
228
229 private:
230 ~BFCachePreventionObserver() = default;
231
232 // Helper for the work that needs to happen when mutations happen.
233 void MutationHappened();
234
235 Document* mDocument; // Weak; we get notified if it dies
236};
237
238NS_IMPL_ISUPPORTS(BFCachePreventionObserver, nsIMutationObserver)MozExternalRefCountType BFCachePreventionObserver::AddRef(void
) { static_assert(!std::is_destructible_v<BFCachePreventionObserver
>, "Reference-counted class " "BFCachePreventionObserver" " 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 238); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
238; __attribute__((nomerge)) ::abort(); } while (false); } }
while (false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("BFCachePreventionObserver" != nullptr)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!("BFCachePreventionObserver" != nullptr))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("\"BFCachePreventionObserver\" != nullptr"
" (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 238); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"BFCachePreventionObserver\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 238; __attribute__((nomerge)) ::abort(); } while (false);
} } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("BFCachePreventionObserver" " not thread-safe"
); nsrefcnt count = ++mRefCnt; NS_LogAddRef((this), (count), (
"BFCachePreventionObserver"), (uint32_t)(sizeof(*this))); return
count; } MozExternalRefCountType BFCachePreventionObserver::
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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 238); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 238
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("BFCachePreventionObserver" != nullptr)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!("BFCachePreventionObserver" != nullptr))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("\"BFCachePreventionObserver\" != nullptr"
" (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 238); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"BFCachePreventionObserver\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 238; __attribute__((nomerge)) ::abort(); } while (false);
} } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("BFCachePreventionObserver" " not thread-safe"
); const char* const nametmp = "BFCachePreventionObserver"; nsrefcnt
count = --mRefCnt; NS_LogRelease((this), (count), (nametmp))
; if (count == 0) { mRefCnt = 1; delete (this); return 0; } return
count; } nsresult BFCachePreventionObserver::QueryInterface(
const nsIID& aIID, void** aInstancePtr) { do { if (!(aInstancePtr
)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 238); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE
; static_assert(1 > 0, "Need more arguments to NS_INTERFACE_TABLE"
); static const QITableEntry table[] = { {&mozilla::detail
::kImplementedIID<BFCachePreventionObserver, nsIMutationObserver
>, int32_t( reinterpret_cast<char*>(static_cast<nsIMutationObserver
*>((BFCachePreventionObserver*)0x1000)) - reinterpret_cast
<char*>((BFCachePreventionObserver*)0x1000))}, {&mozilla
::detail::kImplementedIID<BFCachePreventionObserver, nsISupports
>, int32_t(reinterpret_cast<char*>(static_cast<nsISupports
*>( static_cast<nsIMutationObserver*>((BFCachePreventionObserver
*)0x1000))) - reinterpret_cast<char*>((BFCachePreventionObserver
*)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; }
239
240void BFCachePreventionObserver::CharacterDataChanged(
241 nsIContent* aContent, const CharacterDataChangeInfo&) {
242 if (aContent->IsInNativeAnonymousSubtree()) {
243 return;
244 }
245 MutationHappened();
246}
247
248void BFCachePreventionObserver::AttributeChanged(Element* aElement,
249 int32_t aNameSpaceID,
250 nsAtom* aAttribute,
251 int32_t aModType,
252 const nsAttrValue* aOldValue) {
253 if (aElement->IsInNativeAnonymousSubtree()) {
254 return;
255 }
256 MutationHappened();
257}
258
259void BFCachePreventionObserver::ContentAppended(nsIContent* aFirstNewContent) {
260 if (aFirstNewContent->IsInNativeAnonymousSubtree()) {
261 return;
262 }
263 MutationHappened();
264}
265
266void BFCachePreventionObserver::ContentInserted(nsIContent* aChild) {
267 if (aChild->IsInNativeAnonymousSubtree()) {
268 return;
269 }
270 MutationHappened();
271}
272
273void BFCachePreventionObserver::ContentWillBeRemoved(nsIContent* aChild,
274 const BatchRemovalState*) {
275 if (aChild->IsInNativeAnonymousSubtree()) {
276 return;
277 }
278 MutationHappened();
279}
280
281void BFCachePreventionObserver::NodeWillBeDestroyed(nsINode* aNode) {
282 mDocument = nullptr;
283}
284
285void BFCachePreventionObserver::Disconnect() {
286 if (mDocument) {
287 mDocument->RemoveMutationObserver(this);
288 // It will no longer tell us when it goes away, so make sure we're
289 // not holding a dangling ref.
290 mDocument = nullptr;
291 }
292}
293
294void BFCachePreventionObserver::MutationHappened() {
295 MOZ_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mDocument)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mDocument))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mDocument" " (" "How can we not have a document but be getting notified for mutations?"
")", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 297); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mDocument" ") ("
"How can we not have a document but be getting notified for mutations?"
")"); do { *((volatile int*)__null) = 297; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
296 mDocument,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mDocument)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mDocument))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mDocument" " (" "How can we not have a document but be getting notified for mutations?"
")", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 297); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mDocument" ") ("
"How can we not have a document but be getting notified for mutations?"
")"); do { *((volatile int*)__null) = 297; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
297 "How can we not have a document but be getting notified for mutations?")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mDocument)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mDocument))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mDocument" " (" "How can we not have a document but be getting notified for mutations?"
")", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 297); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mDocument" ") ("
"How can we not have a document but be getting notified for mutations?"
")"); do { *((volatile int*)__null) = 297; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
298 mDocument->DisallowBFCaching();
299 Disconnect();
300}
301
302} // namespace viewer_detail
303
304using viewer_detail::BFCachePreventionObserver;
305
306//-------------------------------------------------------------
307class nsDocumentViewer final : public nsIDocumentViewer,
308 public nsIDocumentViewerEdit,
309 public nsIDocumentViewerPrint
310#ifdef NS_PRINTING1
311 ,
312 public nsIWebBrowserPrint
313#endif
314
315{
316 friend class nsDocViewerSelectionListener;
317 friend class nsPagePrintTimer;
318 friend class nsPrintJob;
319
320 public:
321 nsDocumentViewer();
322
323 // nsISupports interface...
324 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:
325
326 // nsIDocumentViewer interface...
327 NS_DECL_NSIDOCUMENTVIEWERvirtual nsresult Init(nsIWidget * aParentWidget, const mozilla
::LayoutDeviceIntRect & aBounds, mozilla::dom::WindowGlobalChild
* aWindowActor) override; virtual nsresult GetContainer(nsIDocShell
**aContainer) override; virtual nsresult SetContainer(nsIDocShell
*aContainer) override; virtual void LoadStart(mozilla::dom::
Document *aDoc) override; virtual nsresult LoadComplete(nsresult
aStatus) override; virtual bool GetLoadCompleted() override;
virtual bool GetIsStopped() override; virtual nsresult PermitUnload
(nsIDocumentViewer::PermitUnloadAction aAction, bool *_retval
) override; virtual nsresult GetInPermitUnload(bool *aInPermitUnload
) override; virtual nsIDocumentViewer::PermitUnloadResult DispatchBeforeUnload
(void) override; virtual nsresult GetBeforeUnloadFiring(bool *
aBeforeUnloadFiring) override; virtual nsresult PageHide(bool
isUnload) override; virtual nsresult Close(nsISHEntry *historyEntry
) override; virtual nsresult Destroy(void) override; virtual nsresult
Stop(void) override; virtual nsresult GetDOMDocument(mozilla
::dom::Document **aDOMDocument) override; virtual mozilla::dom
::Document * GetDocument(void) override; virtual nsresult SetDocument
(mozilla::dom::Document *aDocument) override; virtual nsresult
GetBounds(mozilla::LayoutDeviceIntRect & aBounds) override
; virtual nsresult SetBounds(const mozilla::LayoutDeviceIntRect
& aBounds) override; virtual nsresult SetBoundsWithFlags
(const mozilla::LayoutDeviceIntRect & aBounds, uint32_t aFlags
) override; virtual nsIDocumentViewer * GetPreviousViewer() override
; virtual void SetPreviousViewer(nsIDocumentViewer *aPreviousViewer
) override; virtual nsresult Move(int32_t aX, int32_t aY) override
; virtual nsresult Show(void) override; virtual nsresult Hide
(void) override; virtual nsresult GetSticky(bool *aSticky) override
; virtual nsresult SetSticky(bool aSticky) override; virtual nsresult
Open(nsISupports *aState, nsISHEntry *aSHEntry) override; virtual
nsresult ClearHistoryEntry(void) override; virtual nsresult SetPageModeForTesting
(bool aPageMode, nsIPrintSettings *aPrintSettings) override; virtual
nsresult SetPrintSettingsForSubdocument(nsIPrintSettings *aPrintSettings
, mozilla::layout::RemotePrintJobChild * aRemotePrintJob) override
; virtual nsresult GetHistoryEntry(nsISHEntry **aHistoryEntry
) override; virtual nsresult GetIsTabModalPromptAllowed(bool *
aIsTabModalPromptAllowed) override; virtual nsresult GetIsHidden
(bool *aIsHidden) override; virtual nsresult SetIsHidden(bool
aIsHidden) override; virtual mozilla::PresShell * GetPresShell
() override; virtual nsPresContext * GetPresContext() override
; virtual nsresult SetDocumentInternal(mozilla::dom::Document
*aDocument, bool aForceReuseInnerWindow) override; virtual nsView
* FindContainerView(void) override; virtual void SetNavigationTiming
(nsDOMNavigationTiming * aTiming) override; virtual nsresult GetDeviceFullZoomForTest
(float *aDeviceFullZoomForTest) override; virtual nsresult GetAuthorStyleDisabled
(bool *aAuthorStyleDisabled) override; virtual nsresult SetAuthorStyleDisabled
(bool aAuthorStyleDisabled) override; virtual nsresult GetContentSize
(int32_t maxWidth, int32_t maxHeight, int32_t prefWidth, int32_t
*width, int32_t *height) override; virtual const mozilla::Encoding
* GetReloadEncodingAndSource(int32_t *aSource) override; virtual
void SetReloadEncodingAndSource(const mozilla::Encoding * aEncoding
, int32_t aSource) override; virtual void ForgetReloadEncoding
(void) override;
328
329 // nsIDocumentViewerEdit
330 NS_DECL_NSIDOCUMENTVIEWEREDITvirtual nsresult ClearSelection(void) override; virtual nsresult
SelectAll(void) override; virtual nsresult CopySelection(void
) override; virtual nsresult GetCopyable(bool *aCopyable) override
; virtual nsresult CopyLinkLocation(void) override; virtual nsresult
GetInLink(bool *aInLink) override; virtual nsresult CopyImage
(int32_t aCopyFlags) override; virtual nsresult GetInImage(bool
*aInImage) override; virtual nsresult GetContents(const char
* aMimeType, bool aSelectionOnly, nsAString& _retval) override
; virtual nsresult GetCanGetContents(bool *aCanGetContents) override
; virtual nsresult SetCommandNode(nsINode *aNode) override;
331
332#ifdef NS_PRINTING1
333 // nsIWebBrowserPrint
334 NS_DECL_NSIWEBBROWSERPRINTvirtual nsresult GetDoingPrint(bool *aDoingPrint) override; virtual
nsresult GetDoingPrintPreview(bool *aDoingPrintPreview) override
; virtual nsresult GetRawNumPages(int32_t *aRawNumPages) override
; virtual nsresult GetPrintPreviewNumPages(int32_t *aPrintPreviewNumPages
) override; virtual nsresult GetPrintPreviewCurrentPageNumber
(int32_t *aPrintPreviewCurrentPageNumber) override; using nsIWebBrowserPrint
::GetCloseWindowAfterPrint; virtual nsresult GetCloseWindowAfterPrint
(bool *aCloseWindowAfterPrint) override; virtual nsresult SetCloseWindowAfterPrint
(bool aCloseWindowAfterPrint) override; virtual nsresult Print
(nsIPrintSettings *aThePrintSettings, mozilla::layout::RemotePrintJobChild
* aRemotePrintJob, nsIWebProgressListener *aWPListener) override
; virtual nsresult PrintPreview(nsIPrintSettings *aThePrintSettings
, nsIWebProgressListener *aWPListener, std::function<void(
const mozilla::dom::PrintPreviewResultInfo&)>&&
aCallback) override; virtual nsresult PrintPreviewScrollToPage
(int16_t aNavType, int32_t aPageNum) override; virtual nsresult
ExitPrintPreview(void) override;
335#endif
336
337 // nsIDocumentViewerPrint Printing Methods
338 NS_DECL_NSIDOCUMENTVIEWERPRINTbool GetIsPrinting() const override; void SetIsPrintPreview(bool
aIsPrintPreview) override; bool GetIsPrintPreview() const override
; void IncrementDestroyBlockedCount() override; void DecrementDestroyBlockedCount
() override; void OnDonePrinting() override; void SetPrintPreviewPresentation
(nsViewManager* aViewManager, nsPresContext* aPresContext, mozilla
::PresShell* aPresShell) override;
339
340 protected:
341 virtual ~nsDocumentViewer();
342
343 private:
344 /**
345 * Creates a view manager, root view, and widget for the root view, setting
346 * mViewManager and mWindow.
347 * @param aSize the initial size in appunits
348 * @param aContainerView the container view to hook our root view up
349 * to as a child, or null if this will be the root view manager
350 */
351 nsresult MakeWindow(const nsSize& aSize, nsView* aContainerView);
352
353 /**
354 * Create our device context
355 */
356 nsresult CreateDeviceContext(nsView* aContainerView);
357
358 /**
359 * If aDoCreation is true, this creates the device context, creates a
360 * prescontext if necessary, and calls MakeWindow.
361 *
362 * If aForceSetNewDocument is false, then SetNewDocument won't be
363 * called if the window's current document is already mDocument.
364 */
365 nsresult InitInternal(nsIWidget* aParentWidget, nsISupports* aState,
366 mozilla::dom::WindowGlobalChild* aActor,
367 const LayoutDeviceIntRect& aBounds, bool aDoCreation,
368 bool aNeedMakeCX = true,
369 bool aForceSetNewDocument = true);
370 /**
371 * @param aDoInitialReflow set to true if you want to kick off the initial
372 * reflow
373 */
374 MOZ_CAN_RUN_SCRIPT_BOUNDARY
375 nsresult InitPresentationStuff(bool aDoInitialReflow);
376
377 already_AddRefed<nsINode> GetPopupNode();
378 already_AddRefed<nsINode> GetPopupLinkNode();
379 already_AddRefed<nsIImageLoadingContent> GetPopupImageNode();
380
381 void PrepareToStartLoad(void);
382
383 nsresult SyncParentSubDocMap();
384
385 void RemoveFocusListener();
386 void ReinitializeFocusListener();
387
388 mozilla::dom::Selection* GetDocumentSelection();
389
390 void DestroyPresShell();
391 void DestroyPresContext();
392
393 void InvalidatePotentialSubDocDisplayItem();
394
395 // Whether we should attach to the top level widget. This is true if we
396 // are sharing/recycling a single base widget and not creating multiple
397 // child widgets.
398 bool ShouldAttachToTopLevel();
399
400 std::tuple<const nsIFrame*, int32_t> GetCurrentSheetFrameAndNumber() const;
401
402 protected:
403 // Returns the current viewmanager. Might be null.
404 nsViewManager* GetViewManager();
405
406 void DetachFromTopLevelWidget();
407
408 // IMPORTANT: The ownership implicit in the following member
409 // variables has been explicitly checked and set using nsCOMPtr
410 // for owning pointers and raw COM interface pointers for weak
411 // (ie, non owning) references. If you add any members to this
412 // class, please make the ownership explicit (pinkerton, scc).
413
414 WeakPtr<nsDocShell> mContainer; // it owns me!
415 RefPtr<nsDeviceContext> mDeviceContext; // We create and own this baby
416
417 // the following six items are explicitly in this order
418 // so they will be destroyed in the reverse order (pinkerton, scc)
419 nsCOMPtr<Document> mDocument;
420 nsCOMPtr<nsIWidget> mWindow; // may be null
421 RefPtr<nsViewManager> mViewManager;
422 RefPtr<nsPresContext> mPresContext;
423 RefPtr<PresShell> mPresShell;
424
425 RefPtr<nsDocViewerSelectionListener> mSelectionListener;
426 RefPtr<nsDocViewerFocusListener> mFocusListener;
427
428 nsCOMPtr<nsIDocumentViewer> mPreviousViewer;
429 nsCOMPtr<nsISHEntry> mSHEntry;
430 // Observer that will prevent bfcaching if it gets notified. This
431 // is non-null precisely when mSHEntry is non-null.
432 RefPtr<BFCachePreventionObserver> mBFCachePreventionObserver;
433
434 nsIWidget* mParentWidget; // purposely won't be ref counted. May be null
435 bool mAttachedToParent; // view is attached to the parent widget
436
437 LayoutDeviceIntRect mBounds;
438
439 int16_t mNumURLStarts;
440 int16_t mDestroyBlockedCount;
441
442 unsigned mStopped : 1;
443 unsigned mLoaded : 1;
444 unsigned mDeferredWindowClose : 1;
445 // document management data
446 // these items are specific to markup documents (html and xml)
447 // may consider splitting these out into a subclass
448 unsigned mIsSticky : 1;
449 unsigned mInPermitUnload : 1;
450 unsigned mInPermitUnloadPrompt : 1;
451
452#ifdef NS_PRINTING1
453 unsigned mClosingWhilePrinting : 1;
454 unsigned mCloseWindowAfterPrint : 1;
455
456# if NS_PRINT_PREVIEW1
457 RefPtr<nsPrintJob> mPrintJob;
458# endif // NS_PRINT_PREVIEW
459
460#endif // NS_PRINTING
461
462 /* character set member data */
463 int32_t mReloadEncodingSource;
464 const Encoding* mReloadEncoding;
465
466 bool mIsPageMode;
467 bool mInitializedForPrintPreview;
468 bool mHidden;
469};
470
471class nsDocumentShownDispatcher : public Runnable {
472 public:
473 explicit nsDocumentShownDispatcher(nsCOMPtr<Document> aDocument)
474 : Runnable("nsDocumentShownDispatcher"), mDocument(aDocument) {}
475
476 NS_IMETHODvirtual nsresult Run() override;
477
478 private:
479 nsCOMPtr<Document> mDocument;
480};
481
482//------------------------------------------------------------------
483// nsDocumentViewer
484//------------------------------------------------------------------
485
486//------------------------------------------------------------------
487already_AddRefed<nsIDocumentViewer> NS_NewDocumentViewer() {
488 return MakeAndAddRef<nsDocumentViewer>();
489}
490
491void nsDocumentViewer::PrepareToStartLoad() {
492 MOZ_DIAGNOSTIC_ASSERT(!GetIsPrintPreview(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!GetIsPrintPreview())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!GetIsPrintPreview()))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("!GetIsPrintPreview()"
" (" "Print preview tab should never navigate" ")", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 493); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!GetIsPrintPreview()"
") (" "Print preview tab should never navigate" ")"); do { *
((volatile int*)__null) = 493; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
493 "Print preview tab should never navigate")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!GetIsPrintPreview())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!GetIsPrintPreview()))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("!GetIsPrintPreview()"
" (" "Print preview tab should never navigate" ")", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 493); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!GetIsPrintPreview()"
") (" "Print preview tab should never navigate" ")"); do { *
((volatile int*)__null) = 493; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
494
495 mStopped = false;
496 mLoaded = false;
497 mAttachedToParent = false;
498 mDeferredWindowClose = false;
499
500#ifdef NS_PRINTING1
501 mClosingWhilePrinting = false;
502
503 // Make sure we have destroyed it and cleared the data member
504 if (mPrintJob) {
505 mPrintJob->Destroy();
506 mPrintJob = nullptr;
507 }
508
509#endif // NS_PRINTING
510}
511
512nsDocumentViewer::nsDocumentViewer()
513 : mParentWidget(nullptr),
514 mAttachedToParent(false),
515 mNumURLStarts(0),
516 mDestroyBlockedCount(0),
517 mStopped(false),
518 mLoaded(false),
519 mDeferredWindowClose(false),
520 mIsSticky(true),
521 mInPermitUnload(false),
522 mInPermitUnloadPrompt(false),
523#ifdef NS_PRINTING1
524 mClosingWhilePrinting(false),
525 mCloseWindowAfterPrint(false),
526#endif // NS_PRINTING
527 mReloadEncodingSource(kCharsetUninitialized),
528 mReloadEncoding(nullptr),
529 mIsPageMode(false),
530 mInitializedForPrintPreview(false),
531 mHidden(false) {
532 PrepareToStartLoad();
533}
534
535NS_IMPL_ADDREF(nsDocumentViewer)MozExternalRefCountType nsDocumentViewer::AddRef(void) { static_assert
(!std::is_destructible_v<nsDocumentViewer>, "Reference-counted class "
"nsDocumentViewer" " 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 535); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
535; __attribute__((nomerge)) ::abort(); } while (false); } }
while (false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("nsDocumentViewer" != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!("nsDocumentViewer" != nullptr
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"\"nsDocumentViewer\" != nullptr" " (" "Must specify a name" ")"
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 535); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"nsDocumentViewer\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 535; __attribute__((nomerge)) ::abort(); } while (false);
} } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("nsDocumentViewer" " not thread-safe"); nsrefcnt
count = ++mRefCnt; NS_LogAddRef((this), (count), ("nsDocumentViewer"
), (uint32_t)(sizeof(*this))); return count; }
536NS_IMPL_RELEASE(nsDocumentViewer)MozExternalRefCountType nsDocumentViewer::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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 536); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 536
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("nsDocumentViewer" != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!("nsDocumentViewer" != nullptr
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"\"nsDocumentViewer\" != nullptr" " (" "Must specify a name" ")"
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 536); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"nsDocumentViewer\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 536; __attribute__((nomerge)) ::abort(); } while (false);
} } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("nsDocumentViewer" " not thread-safe"); const
char* const nametmp = "nsDocumentViewer"; nsrefcnt count = --
mRefCnt; NS_LogRelease((this), (count), (nametmp)); if (count
== 0) { mRefCnt = 1; delete (this); return 0; } return count
; }
537
538NS_INTERFACE_MAP_BEGIN(nsDocumentViewer)nsresult nsDocumentViewer::QueryInterface(const nsIID& aIID
, void** aInstancePtr) { do { if (!(aInstancePtr)) { NS_DebugBreak
(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 538); MOZ_PretendNoReturn(); } } while (0); nsISupports* foundInterface
;
539 NS_INTERFACE_MAP_ENTRY(nsIDocumentViewer)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIDocumentViewer>)) foundInterface
= static_cast<nsIDocumentViewer*>(this); else
540 NS_INTERFACE_MAP_ENTRY(nsIDocumentViewerEdit)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIDocumentViewerEdit>)) foundInterface
= static_cast<nsIDocumentViewerEdit*>(this); else
541 NS_INTERFACE_MAP_ENTRY(nsIDocumentViewerPrint)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIDocumentViewerPrint>)) foundInterface
= static_cast<nsIDocumentViewerPrint*>(this); else
542 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDocumentViewer)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsISupports>)) foundInterface = static_cast
<nsISupports*>(static_cast<nsIDocumentViewer*>(this
)); else
543#ifdef NS_PRINTING1
544 NS_INTERFACE_MAP_ENTRY(nsIWebBrowserPrint)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIWebBrowserPrint>)) foundInterface
= static_cast<nsIWebBrowserPrint*>(this); else
545#endif
546NS_INTERFACE_MAP_ENDfoundInterface = 0; nsresult status; if (!foundInterface) { do
{ static_assert( mozilla::detail::AssertionConditionType<
decltype(!aIID.Equals((nsISupports::COMTypeInfo<nsISupports
, void>::kIID)))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!aIID.Equals((nsISupports::COMTypeInfo
<nsISupports, void>::kIID))))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("!aIID.Equals((nsISupports::COMTypeInfo<nsISupports, void>::kIID))"
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 546); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aIID.Equals((nsISupports::COMTypeInfo<nsISupports, void>::kIID))"
")"); do { *((volatile int*)__null) = 546; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); status = NS_NOINTERFACE
; } else { (foundInterface)->AddRef(); status = NS_OK; } *
aInstancePtr = foundInterface; return status; }
547
548nsDocumentViewer::~nsDocumentViewer() {
549 if (mDocument) {
550 Close(nullptr);
551 mDocument->Destroy();
552 }
553
554#ifdef NS_PRINTING1
555 if (mPrintJob) {
556 mPrintJob->Destroy();
557 mPrintJob = nullptr;
558 }
559#endif
560
561 MOZ_RELEASE_ASSERT(mDestroyBlockedCount == 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mDestroyBlockedCount == 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mDestroyBlockedCount == 0)))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("mDestroyBlockedCount == 0"
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 561); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "mDestroyBlockedCount == 0"
")"); do { *((volatile int*)__null) = 561; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
562 NS_ASSERTION(!mPresShell && !mPresContext,do { if (!(!mPresShell && !mPresContext)) { NS_DebugBreak
(NS_DEBUG_ASSERTION, "User did not call nsIDocumentViewer::Destroy"
, "!mPresShell && !mPresContext", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 563); MOZ_PretendNoReturn(); } } while (0)
563 "User did not call nsIDocumentViewer::Destroy")do { if (!(!mPresShell && !mPresContext)) { NS_DebugBreak
(NS_DEBUG_ASSERTION, "User did not call nsIDocumentViewer::Destroy"
, "!mPresShell && !mPresContext", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 563); MOZ_PretendNoReturn(); } } while (0)
;
564 if (mPresShell || mPresContext) {
565 // Make sure we don't hand out a reference to the content viewer to
566 // the SHEntry!
567 mSHEntry = nullptr;
568
569 Destroy();
570 }
571
572 if (mSelectionListener) {
573 mSelectionListener->Disconnect();
574 }
575
576 RemoveFocusListener();
577
578 // XXX(?) Revoke pending invalidate events
579}
580
581/*
582 * This method is called by the Document Loader once a document has
583 * been created for a particular data stream... The content viewer
584 * must cache this document for later use when Init(...) is called.
585 *
586 * This method is also called when an out of band document.write() happens.
587 * In that case, the document passed in is the same as the previous document.
588 */
589/* virtual */
590void nsDocumentViewer::LoadStart(Document* aDocument) {
591 MOZ_ASSERT(aDocument)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aDocument)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aDocument))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aDocument", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 591); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aDocument" ")"
); do { *((volatile int*)__null) = 591; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
592
593 if (!mDocument) {
594 mDocument = aDocument;
595 }
596}
597
598void nsDocumentViewer::RemoveFocusListener() {
599 if (RefPtr<nsDocViewerFocusListener> oldListener =
600 std::move(mFocusListener)) {
601 oldListener->Disconnect();
602 if (mDocument) {
603 mDocument->RemoveEventListener(u"focus"_ns, oldListener, false);
604 mDocument->RemoveEventListener(u"blur"_ns, oldListener, false);
605 }
606 }
607}
608
609void nsDocumentViewer::ReinitializeFocusListener() {
610 RemoveFocusListener();
611 mFocusListener = new nsDocViewerFocusListener(this);
612 if (mDocument) {
613 mDocument->AddEventListener(u"focus"_ns, mFocusListener, false, false);
614 mDocument->AddEventListener(u"blur"_ns, mFocusListener, false, false);
615 }
616}
617
618nsresult nsDocumentViewer::SyncParentSubDocMap() {
619 nsCOMPtr<nsIDocShell> docShell(mContainer);
620 if (!docShell) {
621 return NS_OK;
622 }
623
624 nsCOMPtr<nsPIDOMWindowOuter> pwin(docShell->GetWindow());
625 if (!mDocument || !pwin) {
626 return NS_OK;
627 }
628
629 nsCOMPtr<Element> element = pwin->GetFrameElementInternal();
630 if (!element) {
631 return NS_OK;
632 }
633
634 nsCOMPtr<nsIDocShellTreeItem> parent;
635 docShell->GetInProcessParent(getter_AddRefs(parent));
636
637 nsCOMPtr<nsPIDOMWindowOuter> parent_win =
638 parent ? parent->GetWindow() : nullptr;
639 if (!parent_win) {
640 return NS_OK;
641 }
642
643 nsCOMPtr<Document> parent_doc = parent_win->GetDoc();
644 if (!parent_doc) {
645 return NS_OK;
646 }
647
648 if (mDocument && parent_doc->GetSubDocumentFor(element) != mDocument &&
649 parent_doc->EventHandlingSuppressed()) {
650 mDocument->SuppressEventHandling(parent_doc->EventHandlingSuppressed());
651 }
652 return parent_doc->SetSubDocumentFor(element, mDocument);
653}
654
655NS_IMETHODIMPnsresult
656nsDocumentViewer::SetContainer(nsIDocShell* aContainer) {
657 mContainer = static_cast<nsDocShell*>(aContainer);
658
659 // We're loading a new document into the window where this document
660 // viewer lives, sync the parent document's frame element -> sub
661 // document map
662
663 return SyncParentSubDocMap();
664}
665
666NS_IMETHODIMPnsresult
667nsDocumentViewer::GetContainer(nsIDocShell** aResult) {
668 NS_ENSURE_ARG_POINTER(aResult)do { if ((__builtin_expect(!!(!(aResult)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aResult" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 668); return NS_ERROR_INVALID_POINTER; } } while (false)
;
669
670 nsCOMPtr<nsIDocShell> container(mContainer);
671 container.swap(*aResult);
672 return NS_OK;
673}
674
675NS_IMETHODIMPnsresult
676nsDocumentViewer::Init(nsIWidget* aParentWidget,
677 const LayoutDeviceIntRect& aBounds,
678 WindowGlobalChild* aActor) {
679 return InitInternal(aParentWidget, nullptr, aActor, aBounds, true);
680}
681
682nsresult nsDocumentViewer::InitPresentationStuff(bool aDoInitialReflow) {
683 // We assert this because initializing the pres shell could otherwise cause
684 // re-entrancy into nsDocumentViewer methods, which might cause a different
685 // pres shell to be created. Callers of InitPresentationStuff should ensure
686 // the call is appropriately bounded by an nsAutoScriptBlocker to decide
687 // when it is safe for these re-entrant calls to be made.
688 MOZ_ASSERT(!nsContentUtils::IsSafeToRunScript(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!nsContentUtils::IsSafeToRunScript())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!nsContentUtils::IsSafeToRunScript
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!nsContentUtils::IsSafeToRunScript()" " (" "InitPresentationStuff must only be called when scripts are "
"blocked" ")", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 690); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!nsContentUtils::IsSafeToRunScript()"
") (" "InitPresentationStuff must only be called when scripts are "
"blocked" ")"); do { *((volatile int*)__null) = 690; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
689 "InitPresentationStuff must only be called when scripts are "do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!nsContentUtils::IsSafeToRunScript())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!nsContentUtils::IsSafeToRunScript
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!nsContentUtils::IsSafeToRunScript()" " (" "InitPresentationStuff must only be called when scripts are "
"blocked" ")", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 690); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!nsContentUtils::IsSafeToRunScript()"
") (" "InitPresentationStuff must only be called when scripts are "
"blocked" ")"); do { *((volatile int*)__null) = 690; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
690 "blocked")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!nsContentUtils::IsSafeToRunScript())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!nsContentUtils::IsSafeToRunScript
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!nsContentUtils::IsSafeToRunScript()" " (" "InitPresentationStuff must only be called when scripts are "
"blocked" ")", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 690); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!nsContentUtils::IsSafeToRunScript()"
") (" "InitPresentationStuff must only be called when scripts are "
"blocked" ")"); do { *((volatile int*)__null) = 690; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
;
691
692#ifdef NS_PRINTING1
693 // When getting printed, either for print or print preview, the print job
694 // takes care of setting up the presentation of the document.
695 if (mPrintJob) {
696 return NS_OK;
697 }
698#endif
699
700 NS_ASSERTION(!mPresShell, "Someone should have destroyed the presshell!")do { if (!(!mPresShell)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "Someone should have destroyed the presshell!"
, "!mPresShell", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 700); MOZ_PretendNoReturn(); } } while (0)
;
701
702 // Now make the shell for the document
703 nsCOMPtr<Document> doc = mDocument;
704 RefPtr<nsPresContext> presContext = mPresContext;
705 RefPtr<nsViewManager> viewManager = mViewManager;
706 mPresShell = doc->CreatePresShell(presContext, viewManager);
707 if (!mPresShell) {
708 return NS_ERROR_FAILURE;
709 }
710
711 if (aDoInitialReflow) {
712 // Since Initialize() will create frames for *all* items
713 // that are currently in the document tree, we need to flush
714 // any pending notifications to prevent the content sink from
715 // duplicating layout frames for content it has added to the tree
716 // but hasn't notified the document about. (Bug 154018)
717 //
718 // Note that we are flushing before we add mPresShell as an observer
719 // to avoid bogus notifications.
720 mDocument->FlushPendingNotifications(FlushType::ContentAndNotify);
721 }
722
723 mPresShell->BeginObservingDocument();
724
725 // Initialize our view manager
726
727 {
728 int32_t p2a = mPresContext->AppUnitsPerDevPixel();
729 MOZ_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(p2a == mPresContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(p2a == mPresContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("p2a == mPresContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom()"
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 731); AnnotateMozCrashReason("MOZ_ASSERT" "(" "p2a == mPresContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom()"
")"); do { *((volatile int*)__null) = 731; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
730 p2a ==do { static_assert( mozilla::detail::AssertionConditionType<
decltype(p2a == mPresContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(p2a == mPresContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("p2a == mPresContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom()"
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 731); AnnotateMozCrashReason("MOZ_ASSERT" "(" "p2a == mPresContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom()"
")"); do { *((volatile int*)__null) = 731; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
731 mPresContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(p2a == mPresContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(p2a == mPresContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("p2a == mPresContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom()"
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 731); AnnotateMozCrashReason("MOZ_ASSERT" "(" "p2a == mPresContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom()"
")"); do { *((volatile int*)__null) = 731; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
732
733 const nsSize size = LayoutDevicePixel::ToAppUnits(mBounds.Size(), p2a);
734
735 mViewManager->SetWindowDimensions(size.width, size.height);
736 mPresContext->SetInitialVisibleArea(nsRect(nsPoint(), size));
737 // We rely on the default zoom not being initialized until here.
738 mPresContext->RecomputeBrowsingContextDependentData();
739 }
740
741 if (mWindow && mDocument->IsTopLevelContentDocument()) {
742 // Set initial safe area insets
743 LayoutDeviceIntMargin windowSafeAreaInsets;
744 LayoutDeviceIntRect windowRect = mWindow->GetScreenBounds();
745 if (nsCOMPtr<nsIScreen> screen = mWindow->GetWidgetScreen()) {
746 windowSafeAreaInsets = nsContentUtils::GetWindowSafeAreaInsets(
747 screen, mWindow->GetSafeAreaInsets(), windowRect);
748 }
749 mPresContext->SetSafeAreaInsets(windowSafeAreaInsets);
750 }
751
752 if (aDoInitialReflow) {
753 RefPtr<PresShell> presShell = mPresShell;
754 // Initial reflow
755 presShell->Initialize();
756 }
757
758 // now register ourselves as a selection listener, so that we get
759 // called when the selection changes in the window
760 if (!mSelectionListener) {
761 mSelectionListener = new nsDocViewerSelectionListener(this);
762 }
763
764 RefPtr<mozilla::dom::Selection> selection = GetDocumentSelection();
765 if (!selection) {
766 return NS_ERROR_FAILURE;
767 }
768
769 selection->AddSelectionListener(mSelectionListener);
770
771 ReinitializeFocusListener();
772
773 if (aDoInitialReflow && mDocument) {
774 nsCOMPtr<Document> document = mDocument;
775 document->ScrollToRef();
776 }
777
778 return NS_OK;
779}
780
781static already_AddRefed<nsPresContext> CreatePresContext(
782 Document* aDocument, nsPresContext::nsPresContextType aType,
783 nsView* aContainerView) {
784 RefPtr<nsPresContext> result = aContainerView
785 ? new nsPresContext(aDocument, aType)
786 : new nsRootPresContext(aDocument, aType);
787
788 return result.forget();
789}
790
791//-----------------------------------------------
792// This method can be used to initial the "presentation"
793// The aDoCreation indicates whether it should create
794// all the new objects or just initialize the existing ones
795nsresult nsDocumentViewer::InitInternal(
796 nsIWidget* aParentWidget, nsISupports* aState, WindowGlobalChild* aActor,
797 const LayoutDeviceIntRect& aBounds, bool aDoCreation,
798 bool aNeedMakeCX /*= true*/, bool aForceSetNewDocument /* = true*/) {
799 // We don't want any scripts to run here. That can cause flushing,
800 // which can cause reentry into initialization of this document viewer,
801 // which would be disastrous.
802 nsAutoScriptBlocker blockScripts;
803
804 mParentWidget = aParentWidget; // not ref counted
805 mBounds = aBounds;
806
807 nsresult rv = NS_OK;
808 NS_ENSURE_TRUE(mDocument, NS_ERROR_NULL_POINTER)do { if ((__builtin_expect(!!(!(mDocument)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mDocument" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 808); return NS_ERROR_NULL_POINTER; } } while (false)
;
809
810 nsView* containerView = FindContainerView();
811
812 bool makeCX = false;
813 if (aDoCreation) {
814 nsresult rv = CreateDeviceContext(containerView);
815 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, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 815); return rv; } } while (false)
;
816
817 // XXXbz this is a nasty hack to do with the fact that we create
818 // presentations both in Init() and in Show()... Ideally we would only do
819 // it in one place (Show()) and require that callers call init(), open(),
820 // show() in that order or something.
821 if (!mPresContext &&
822 (aParentWidget || containerView || mDocument->IsBeingUsedAsImage() ||
823 (mDocument->GetDisplayDocument() &&
824 mDocument->GetDisplayDocument()->GetPresShell()))) {
825 // Create presentation context
826 if (mIsPageMode) {
827 // Presentation context already created in SetPageModeForTesting which
828 // is calling this method
829 } else {
830 mPresContext = CreatePresContext(
831 mDocument, nsPresContext::eContext_Galley, containerView);
832 }
833 NS_ENSURE_TRUE(mPresContext, NS_ERROR_OUT_OF_MEMORY)do { if ((__builtin_expect(!!(!(mPresContext)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mPresContext" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 833); return NS_ERROR_OUT_OF_MEMORY; } } while (false)
;
834
835 nsresult rv = mPresContext->Init(mDeviceContext);
836 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
837 mPresContext = nullptr;
838 return rv;
839 }
840
841#if defined(NS_PRINTING1) && defined(NS_PRINT_PREVIEW1)
842 makeCX = !GetIsPrintPreview() &&
843 aNeedMakeCX; // needs to be true except when we are already in
844 // PP or we are enabling/disabling paginated mode.
845#else
846 makeCX = true;
847#endif
848 }
849
850 if (mPresContext) {
851 // Create the ViewManager and Root View...
852
853 // We must do this before we tell the script global object about
854 // this new document since doing that will cause us to re-enter
855 // into nsSubDocumentFrame code through reflows caused by
856 // FlushPendingNotifications() calls down the road...
857
858 rv = MakeWindow(nsSize(mPresContext->DevPixelsToAppUnits(aBounds.width),
859 mPresContext->DevPixelsToAppUnits(aBounds.height)),
860 containerView);
861 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, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 861); return rv; } } while (false)
;
862 Hide();
863
864#ifdef NS_PRINT_PREVIEW1
865 if (mIsPageMode) {
866 // I'm leaving this in a broken state for the moment; we should
867 // be measuring/scaling with the print device context, not the
868 // screen device context, but this is good enough to allow
869 // printing reftests to work.
870 double pageWidth = 0, pageHeight = 0;
871 mPresContext->GetPrintSettings()->GetEffectivePageSize(&pageWidth,
872 &pageHeight);
873 mPresContext->SetPageSize(
874 nsSize(mPresContext->CSSTwipsToAppUnits(NSToIntFloor(pageWidth)),
875 mPresContext->CSSTwipsToAppUnits(NSToIntFloor(pageHeight))));
876 mPresContext->SetIsRootPaginatedDocument(true);
877 mPresContext->SetPageScale(1.0f);
878 }
879#endif
880 } else {
881 // Avoid leaking the old viewer.
882 if (mPreviousViewer) {
883 mPreviousViewer->Destroy();
884 mPreviousViewer = nullptr;
885 }
886 }
887 }
888
889 nsCOMPtr<nsIInterfaceRequestor> requestor(mContainer);
890 if (requestor) {
891 // Set script-context-owner in the document
892
893 nsCOMPtr<nsPIDOMWindowOuter> window = do_GetInterface(requestor);
894
895 if (window) {
896 nsCOMPtr<Document> curDoc = window->GetExtantDoc();
897 if (aForceSetNewDocument || curDoc != mDocument) {
898 rv = window->SetNewDocument(mDocument, aState, false, aActor);
899 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
900 Destroy();
901 return rv;
902 }
903 }
904 }
905 }
906
907 if (aDoCreation && mPresContext) {
908 // The ViewManager and Root View was created above (in
909 // MakeWindow())...
910
911 rv = InitPresentationStuff(!makeCX);
912 }
913
914 return rv;
915}
916
917void nsDocumentViewer::SetNavigationTiming(nsDOMNavigationTiming* timing) {
918 NS_ASSERTION(mDocument, "Must have a document to set navigation timing.")do { if (!(mDocument)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "Must have a document to set navigation timing."
, "mDocument", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 918); MOZ_PretendNoReturn(); } } while (0)
;
919 if (mDocument) {
920 mDocument->SetNavigationTiming(timing);
921 }
922}
923
924//
925// LoadComplete(aStatus)
926//
927// aStatus - The status returned from loading the document.
928//
929// This method is called by the container when the document has been
930// completely loaded.
931//
932NS_IMETHODIMPnsresult
933nsDocumentViewer::LoadComplete(nsresult aStatus) {
934 /* We need to protect ourself against auto-destruction in case the
935 window is closed while processing the OnLoad event. See bug
936 http://bugzilla.mozilla.org/show_bug.cgi?id=78445 for more
937 explanation.
938 */
939 RefPtr<nsDocumentViewer> kungFuDeathGrip(this);
940
941 // Flush out layout so it's up-to-date by the time onload is called.
942 // Note that this could destroy the window, so do this before
943 // checking for our mDocument and its window.
944 if (mPresShell && !mStopped) {
945 // Hold strong ref because this could conceivably run script
946 RefPtr<PresShell> presShell = mPresShell;
947 presShell->FlushPendingNotifications(FlushType::Layout);
948 }
949
950 nsresult rv = NS_OK;
951 NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE)do { if ((__builtin_expect(!!(!(mDocument)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mDocument" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 951); return NS_ERROR_NOT_AVAILABLE; } } while (false)
;
952
953 // First, get the window from the document...
954 nsCOMPtr<nsPIDOMWindowOuter> window = mDocument->GetWindow();
955
956 mLoaded = true;
957
958 // Now, fire either an OnLoad or OnError event to the document...
959 bool restoring = false;
960 // XXXbz imagelib kills off the document load for a full-page image with
961 // NS_ERROR_PARSED_DATA_CACHED if it's in the cache. So we want to treat
962 // that one as a success code; otherwise whether we fire onload for the image
963 // will depend on whether it's cached!
964 if (window &&
965 (NS_SUCCEEDED(aStatus)((bool)(__builtin_expect(!!(!NS_FAILED_impl(aStatus)), 1))) || aStatus == NS_ERROR_PARSED_DATA_CACHED)) {
966 // If this code changes, the code in nsDocLoader::DocLoaderIsEmpty
967 // that fires load events for document.open() cases might need to
968 // be updated too.
969 nsEventStatus status = nsEventStatus_eIgnore;
970 WidgetEvent event(true, eLoad);
971 event.mFlags.mBubbles = false;
972 event.mFlags.mCancelable = false;
973 // XXX Dispatching to |window|, but using |document| as the target.
974 event.mTarget = mDocument;
975
976 // If the document presentation is being restored, we don't want to fire
977 // onload to the document content since that would likely confuse scripts
978 // on the page.
979
980 RefPtr<nsDocShell> docShell = nsDocShell::Cast(window->GetDocShell());
981 NS_ENSURE_TRUE(docShell, NS_ERROR_UNEXPECTED)do { if ((__builtin_expect(!!(!(docShell)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "docShell" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 981); return NS_ERROR_UNEXPECTED; } } while (false)
;
982
983 // Unfortunately, docShell->GetRestoringDocument() might no longer be set
984 // correctly. In particular, it can be false by now if someone took it upon
985 // themselves to block onload from inside restoration and unblock it later.
986 // But we can detect the restoring case very simply: by whether our
987 // document's readyState is COMPLETE.
988 restoring =
989 (mDocument->GetReadyStateEnum() == Document::READYSTATE_COMPLETE);
990 if (!restoring) {
991 NS_ASSERTION(do { if (!(mDocument->GetReadyStateEnum() == Document::READYSTATE_INTERACTIVE
|| (mDocument->GetReadyStateEnum() == Document::READYSTATE_UNINITIALIZED
&& NS_IsAboutBlank(mDocument->GetDocumentURI())))
) { NS_DebugBreak(NS_DEBUG_ASSERTION, "Bad readystate", "mDocument->GetReadyStateEnum() == Document::READYSTATE_INTERACTIVE || (mDocument->GetReadyStateEnum() == Document::READYSTATE_UNINITIALIZED && NS_IsAboutBlank(mDocument->GetDocumentURI()))"
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 998); MOZ_PretendNoReturn(); } } while (0)
992 mDocument->GetReadyStateEnum() == Document::READYSTATE_INTERACTIVE ||do { if (!(mDocument->GetReadyStateEnum() == Document::READYSTATE_INTERACTIVE
|| (mDocument->GetReadyStateEnum() == Document::READYSTATE_UNINITIALIZED
&& NS_IsAboutBlank(mDocument->GetDocumentURI())))
) { NS_DebugBreak(NS_DEBUG_ASSERTION, "Bad readystate", "mDocument->GetReadyStateEnum() == Document::READYSTATE_INTERACTIVE || (mDocument->GetReadyStateEnum() == Document::READYSTATE_UNINITIALIZED && NS_IsAboutBlank(mDocument->GetDocumentURI()))"
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 998); MOZ_PretendNoReturn(); } } while (0)
993 // test_stricttransportsecurity.html has old-styledo { if (!(mDocument->GetReadyStateEnum() == Document::READYSTATE_INTERACTIVE
|| (mDocument->GetReadyStateEnum() == Document::READYSTATE_UNINITIALIZED
&& NS_IsAboutBlank(mDocument->GetDocumentURI())))
) { NS_DebugBreak(NS_DEBUG_ASSERTION, "Bad readystate", "mDocument->GetReadyStateEnum() == Document::READYSTATE_INTERACTIVE || (mDocument->GetReadyStateEnum() == Document::READYSTATE_UNINITIALIZED && NS_IsAboutBlank(mDocument->GetDocumentURI()))"
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 998); MOZ_PretendNoReturn(); } } while (0)
994 // docshell-generated about:blank docs reach this code!do { if (!(mDocument->GetReadyStateEnum() == Document::READYSTATE_INTERACTIVE
|| (mDocument->GetReadyStateEnum() == Document::READYSTATE_UNINITIALIZED
&& NS_IsAboutBlank(mDocument->GetDocumentURI())))
) { NS_DebugBreak(NS_DEBUG_ASSERTION, "Bad readystate", "mDocument->GetReadyStateEnum() == Document::READYSTATE_INTERACTIVE || (mDocument->GetReadyStateEnum() == Document::READYSTATE_UNINITIALIZED && NS_IsAboutBlank(mDocument->GetDocumentURI()))"
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 998); MOZ_PretendNoReturn(); } } while (0)
995 (mDocument->GetReadyStateEnum() ==do { if (!(mDocument->GetReadyStateEnum() == Document::READYSTATE_INTERACTIVE
|| (mDocument->GetReadyStateEnum() == Document::READYSTATE_UNINITIALIZED
&& NS_IsAboutBlank(mDocument->GetDocumentURI())))
) { NS_DebugBreak(NS_DEBUG_ASSERTION, "Bad readystate", "mDocument->GetReadyStateEnum() == Document::READYSTATE_INTERACTIVE || (mDocument->GetReadyStateEnum() == Document::READYSTATE_UNINITIALIZED && NS_IsAboutBlank(mDocument->GetDocumentURI()))"
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 998); MOZ_PretendNoReturn(); } } while (0)
996 Document::READYSTATE_UNINITIALIZED &&do { if (!(mDocument->GetReadyStateEnum() == Document::READYSTATE_INTERACTIVE
|| (mDocument->GetReadyStateEnum() == Document::READYSTATE_UNINITIALIZED
&& NS_IsAboutBlank(mDocument->GetDocumentURI())))
) { NS_DebugBreak(NS_DEBUG_ASSERTION, "Bad readystate", "mDocument->GetReadyStateEnum() == Document::READYSTATE_INTERACTIVE || (mDocument->GetReadyStateEnum() == Document::READYSTATE_UNINITIALIZED && NS_IsAboutBlank(mDocument->GetDocumentURI()))"
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 998); MOZ_PretendNoReturn(); } } while (0)
997 NS_IsAboutBlank(mDocument->GetDocumentURI())),do { if (!(mDocument->GetReadyStateEnum() == Document::READYSTATE_INTERACTIVE
|| (mDocument->GetReadyStateEnum() == Document::READYSTATE_UNINITIALIZED
&& NS_IsAboutBlank(mDocument->GetDocumentURI())))
) { NS_DebugBreak(NS_DEBUG_ASSERTION, "Bad readystate", "mDocument->GetReadyStateEnum() == Document::READYSTATE_INTERACTIVE || (mDocument->GetReadyStateEnum() == Document::READYSTATE_UNINITIALIZED && NS_IsAboutBlank(mDocument->GetDocumentURI()))"
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 998); MOZ_PretendNoReturn(); } } while (0)
998 "Bad readystate")do { if (!(mDocument->GetReadyStateEnum() == Document::READYSTATE_INTERACTIVE
|| (mDocument->GetReadyStateEnum() == Document::READYSTATE_UNINITIALIZED
&& NS_IsAboutBlank(mDocument->GetDocumentURI())))
) { NS_DebugBreak(NS_DEBUG_ASSERTION, "Bad readystate", "mDocument->GetReadyStateEnum() == Document::READYSTATE_INTERACTIVE || (mDocument->GetReadyStateEnum() == Document::READYSTATE_UNINITIALIZED && NS_IsAboutBlank(mDocument->GetDocumentURI()))"
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 998); MOZ_PretendNoReturn(); } } while (0)
;
999#ifdef DEBUG1
1000 bool docShellThinksWeAreRestoring;
1001 docShell->GetRestoringDocument(&docShellThinksWeAreRestoring);
1002 MOZ_ASSERT(!docShellThinksWeAreRestoring,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!docShellThinksWeAreRestoring)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!docShellThinksWeAreRestoring
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"!docShellThinksWeAreRestoring" " (" "How can docshell think we are restoring if we don't have a "
"READYSTATE_COMPLETE document?" ")", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 1004); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!docShellThinksWeAreRestoring"
") (" "How can docshell think we are restoring if we don't have a "
"READYSTATE_COMPLETE document?" ")"); do { *((volatile int*)
__null) = 1004; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
1003 "How can docshell think we are restoring if we don't have a "do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!docShellThinksWeAreRestoring)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!docShellThinksWeAreRestoring
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"!docShellThinksWeAreRestoring" " (" "How can docshell think we are restoring if we don't have a "
"READYSTATE_COMPLETE document?" ")", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 1004); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!docShellThinksWeAreRestoring"
") (" "How can docshell think we are restoring if we don't have a "
"READYSTATE_COMPLETE document?" ")"); do { *((volatile int*)
__null) = 1004; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
1004 "READYSTATE_COMPLETE document?")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!docShellThinksWeAreRestoring)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!docShellThinksWeAreRestoring
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"!docShellThinksWeAreRestoring" " (" "How can docshell think we are restoring if we don't have a "
"READYSTATE_COMPLETE document?" ")", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 1004); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!docShellThinksWeAreRestoring"
") (" "How can docshell think we are restoring if we don't have a "
"READYSTATE_COMPLETE document?" ")"); do { *((volatile int*)
__null) = 1004; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
1005#endif // DEBUG
1006 nsCOMPtr<Document> d = mDocument;
1007 mDocument->SetReadyStateInternal(Document::READYSTATE_COMPLETE);
1008
1009 RefPtr<nsDOMNavigationTiming> timing(d->GetNavigationTiming());
1010 if (timing) {
1011 timing->NotifyLoadEventStart();
1012 }
1013
1014 // Dispatch observer notification to notify observers document load is
1015 // complete.
1016 nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
1017 if (os) {
1018 nsIPrincipal* principal = d->NodePrincipal();
1019 os->NotifyObservers(ToSupports(d),
1020 principal->IsSystemPrincipal()
1021 ? "chrome-document-loaded"
1022 : "content-document-loaded",
1023 nullptr);
1024 }
1025
1026 nsPIDOMWindowInner* innerWindow = window->GetCurrentInnerWindow();
1027 d->SetLoadEventFiring(true);
1028 RefPtr<nsPresContext> presContext = mPresContext;
1029 // MOZ_KnownLive due to bug 1506441
1030 EventDispatcher::Dispatch(
1031 MOZ_KnownLive(nsGlobalWindowOuter::Cast(window))(nsGlobalWindowOuter::Cast(window)), presContext, &event,
1032 nullptr, &status);
1033 d->SetLoadEventFiring(false);
1034
1035 if (timing) {
1036 timing->NotifyLoadEventEnd();
1037 }
1038
1039 if (innerWindow) {
1040 innerWindow->QueuePerformanceNavigationTiming();
1041 }
1042 }
1043 } else {
1044 // XXX: Should fire error event to the document...
1045
1046 // If our load was explicitly aborted, then we want to set our
1047 // readyState to COMPLETE, and fire a readystatechange event.
1048 if (aStatus == NS_BINDING_ABORTED && mDocument) {
1049 mDocument->NotifyAbortedLoad();
1050 }
1051 }
1052
1053 // Notify the document that it has been shown (regardless of whether
1054 // it was just loaded). Note: mDocument may be null now if the above
1055 // firing of onload caused the document to unload. Or, mDocument may not be
1056 // the "current active" document, if the above firing of onload caused our
1057 // docshell to navigate away. NOTE: In this latter scenario, it's likely that
1058 // we fired pagehide (when navigating away) without ever having fired
1059 // pageshow, and that's pretty broken... Fortunately, this should be rare.
1060 // (It requires us to spin the event loop in onload handler, e.g. via sync
1061 // XHR, in order for the navigation-away to happen before onload completes.)
1062 // We skip firing pageshow if we're currently handling unload, or if loading
1063 // was explicitly aborted.
1064 if (mDocument && mDocument->IsCurrentActiveDocument() &&
1065 aStatus != NS_BINDING_ABORTED) {
1066 // Re-get window, since it might have changed during above firing of onload
1067 window = mDocument->GetWindow();
1068 if (window) {
1069 nsIDocShell* docShell = window->GetDocShell();
1070 bool isInUnload;
1071 if (docShell && NS_SUCCEEDED(docShell->GetIsInUnload(&isInUnload))((bool)(__builtin_expect(!!(!NS_FAILED_impl(docShell->GetIsInUnload
(&isInUnload))), 1)))
&&
1072 !isInUnload) {
1073 mDocument->OnPageShow(restoring, nullptr);
1074 }
1075 }
1076 }
1077
1078 if (!mStopped) {
1079 if (mDocument) {
1080 // This is the final attempt to scroll to an anchor / text directive.
1081 // This is the last iteration of the algorithm described in the spec for
1082 // trying to scroll to a fragment.
1083 // https://html.spec.whatwg.org/#try-to-scroll-to-the-fragment
1084 nsCOMPtr<Document> document = mDocument;
1085 document->ScrollToRef();
1086 }
1087
1088 // Now that the document has loaded, we can tell the presshell
1089 // to unsuppress painting.
1090 if (mPresShell) {
1091 RefPtr<PresShell> presShell = mPresShell;
1092 presShell->UnsuppressPainting();
1093 // mPresShell could have been removed now, see bug 378682/421432
1094 if (mPresShell) {
1095 mPresShell->LoadComplete();
1096 }
1097 }
1098 }
1099
1100 // https://wicg.github.io/scroll-to-text-fragment/#invoking-text-directives
1101 // Monkeypatching HTML § 7.4.6.3 Scrolling to a fragment:
1102 // 2.1 If the user agent has reason to believe the user is no longer
1103 // interested in scrolling to the fragment, then:
1104 // 2.1.1 Set pending text directives to null.
1105 //
1106 // Gecko's implementation differs from the spec (ie., it implements its
1107 // intention but doesn't follow step by step), therefore the mentioned steps
1108 // are not applied in the same manner.
1109 // However, this should be the right place to do this.
1110 if (mDocument) {
1111 mDocument->FragmentDirective()->ClearUninvokedDirectives();
1112 }
1113 if (mDocument && !restoring) {
1114 mDocument->LoadEventFired();
1115 }
1116
1117 // It's probably a good idea to GC soon since we have finished loading.
1118 nsJSContext::PokeGC(
1119 JS::GCReason::LOAD_END,
1120 mDocument ? mDocument->GetWrapperPreserveColor() : nullptr);
1121
1122#ifdef NS_PRINTING1
1123 // Check to see if someone tried to print during the load
1124 if (window) {
1125 auto* outerWin = nsGlobalWindowOuter::Cast(window);
1126 outerWin->StopDelayingPrintingUntilAfterLoad();
1127 if (outerWin->DelayedPrintUntilAfterLoad()) {
1128 // We call into the inner because it ensures there's an active document
1129 // and such, and it also waits until the whole thing completes, which is
1130 // nice because it allows us to close if needed right here.
1131 if (RefPtr inner =
1132 nsGlobalWindowInner::Cast(window->GetCurrentInnerWindow())) {
1133 inner->Print(IgnoreErrors());
1134 }
1135 if (outerWin->DelayedCloseForPrinting()) {
1136 outerWin->Close();
1137 }
1138 } else {
1139 MOZ_ASSERT(!outerWin->DelayedCloseForPrinting())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!outerWin->DelayedCloseForPrinting())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!outerWin->DelayedCloseForPrinting()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!outerWin->DelayedCloseForPrinting()"
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 1139); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!outerWin->DelayedCloseForPrinting()"
")"); do { *((volatile int*)__null) = 1139; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1140 }
1141 }
1142#endif
1143
1144 return rv;
1145}
1146
1147bool nsDocumentViewer::GetLoadCompleted() { return mLoaded; }
1148
1149bool nsDocumentViewer::GetIsStopped() { return mStopped; }
1150
1151NS_IMETHODIMPnsresult
1152nsDocumentViewer::PermitUnload(PermitUnloadAction aAction,
1153 bool* aPermitUnload) {
1154 // We're going to be running JS and nested event loops, which could cause our
1155 // DocShell to be destroyed. Make sure we stay alive until the end of the
1156 // function.
1157 RefPtr<nsDocumentViewer> kungFuDeathGrip(this);
1158
1159 if (StaticPrefs::dom_disable_beforeunload()) {
1160 aAction = eDontPromptAndUnload;
1161 }
1162
1163 *aPermitUnload = true;
1164
1165 NS_ENSURE_STATE(mContainer)do { if ((__builtin_expect(!!(!(mContainer)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mContainer" ") failed",
nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 1165); return NS_ERROR_UNEXPECTED; } } while (false)
;
1166
1167 RefPtr<BrowsingContext> bc = mContainer->GetBrowsingContext();
1168 if (!bc) {
1169 return NS_OK;
1170 }
1171
1172 // Per spec, we need to increase the ignore-opens-during-unload counter while
1173 // dispatching the "beforeunload" event on both the document we're currently
1174 // dispatching the event to and the document that we explicitly asked to
1175 // unload.
1176 IgnoreOpensDuringUnload ignoreOpens(mDocument);
1177
1178 bool foundBlocker = false;
1179 bool foundOOPListener = false;
1180 bc->PreOrderWalk([&](BrowsingContext* aBC) {
1181 if (!aBC->IsInProcess()) {
1182 WindowContext* wc = aBC->GetCurrentWindowContext();
1183 if (wc && wc->HasBeforeUnload()) {
1184 foundOOPListener = true;
1185 }
1186 } else if (aBC->GetDocShell()) {
1187 nsCOMPtr<nsIDocumentViewer> viewer(aBC->GetDocShell()->GetDocViewer());
1188 if (viewer && viewer->DispatchBeforeUnload() == eRequestBlockNavigation) {
1189 foundBlocker = true;
1190 }
1191 }
1192 });
1193
1194 if (!foundOOPListener) {
1195 if (!foundBlocker) {
1196 return NS_OK;
1197 }
1198 if (aAction != ePrompt) {
1199 *aPermitUnload = aAction == eDontPromptAndUnload;
1200 return NS_OK;
1201 }
1202 }
1203
1204 // NB: we nullcheck mDocument because it might now be dead as a result of
1205 // the event being dispatched.
1206 RefPtr<WindowGlobalChild> wgc(mDocument ? mDocument->GetWindowGlobalChild()
1207 : nullptr);
1208 if (!wgc) {
1209 return NS_OK;
1210 }
1211
1212 nsAutoSyncOperation sync(mDocument, SyncOperationBehavior::eSuspendInput);
1213 AutoSuppressEventHandlingAndSuspend seh(bc->Group());
1214
1215 mInPermitUnloadPrompt = true;
1216
1217 bool done = false;
1218 wgc->SendCheckPermitUnload(
1219 foundBlocker, aAction,
1220 [&](bool aPermit) {
1221 done = true;
1222 *aPermitUnload = aPermit;
1223 },
1224 [&](auto) {
1225 // If the prompt aborted, we tell our consumer that it is not allowed
1226 // to unload the page. One reason that prompts abort is that the user
1227 // performed some action that caused the page to unload while our prompt
1228 // was active. In those cases we don't want our consumer to also unload
1229 // the page.
1230 //
1231 // XXX: Are there other cases where prompts can abort? Is it ok to
1232 // prevent unloading the page in those cases?
1233 done = true;
1234 *aPermitUnload = false;
1235 });
1236
1237 SpinEventLoopUntil("nsDocumentViewer::PermitUnload"_ns,
1238 [&]() { return done; });
1239
1240 mInPermitUnloadPrompt = false;
1241 return NS_OK;
1242}
1243
1244MOZ_CAN_RUN_SCRIPT_BOUNDARY PermitUnloadResult
1245nsDocumentViewer::DispatchBeforeUnload() {
1246 AutoDontWarnAboutSyncXHR disableSyncXHRWarning;
1247
1248 if (!mDocument || mInPermitUnload || mInPermitUnloadPrompt || !mContainer) {
1249 return eAllowNavigation;
1250 }
1251
1252 // First, get the script global object from the document...
1253 RefPtr<nsGlobalWindowOuter> window =
1254 nsGlobalWindowOuter::Cast(mDocument->GetWindow());
1255 if (!window) {
1256 // This is odd, but not fatal
1257 NS_WARNING("window not set for document!")NS_DebugBreak(NS_DEBUG_WARNING, "window not set for document!"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 1257)
;
1258 return eAllowNavigation;
1259 }
1260
1261 NS_ASSERTION(nsContentUtils::IsSafeToRunScript(), "This is unsafe")do { if (!(nsContentUtils::IsSafeToRunScript())) { NS_DebugBreak
(NS_DEBUG_ASSERTION, "This is unsafe", "nsContentUtils::IsSafeToRunScript()"
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 1261); MOZ_PretendNoReturn(); } } while (0)
;
1262
1263 // https://html.spec.whatwg.org/multipage/browsing-the-web.html#prompt-to-unload-a-document
1264 // Create an RAII object on mDocument that will increment the
1265 // should-ignore-opens-during-unload counter on initialization
1266 // and decrement it again when it goes out of score (regardless
1267 // of how we exit this function).
1268 IgnoreOpensDuringUnload ignoreOpens(mDocument);
1269
1270 // Now, fire an BeforeUnload event to the document and see if it's ok
1271 // to unload...
1272 nsPresContext* presContext = mDocument->GetPresContext();
1273 auto event = MakeRefPtr<BeforeUnloadEvent>(mDocument, presContext, nullptr);
1274 event->InitEvent(u"beforeunload"_ns, false, true);
1275
1276 // Dispatching to |window|, but using |document| as the target.
1277 event->SetTarget(mDocument);
1278 event->SetTrusted(true);
1279
1280 // In evil cases we might be destroyed while handling the
1281 // onbeforeunload event, don't let that happen. (see also bug#331040)
1282 RefPtr<nsDocumentViewer> kungFuDeathGrip(this);
1283
1284 {
1285 // Never permit popups from the beforeunload handler, no matter
1286 // how we get here.
1287 AutoPopupStatePusherAutoPopupStatePusherInternal popupStatePusher(PopupBlocker::openAbused, true);
1288
1289 RefPtr<BrowsingContext> bc = mContainer->GetBrowsingContext();
1290 NS_ASSERTION(bc, "should have a browsing context in document viewer")do { if (!(bc)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "should have a browsing context in document viewer"
, "bc", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 1290); MOZ_PretendNoReturn(); } } while (0)
;
1291
1292 // Never permit dialogs from the beforeunload handler
1293 nsGlobalWindowOuter::TemporarilyDisableDialogs disableDialogs(bc);
1294
1295 Document::PageUnloadingEventTimeStamp timestamp(mDocument);
1296
1297 mInPermitUnload = true;
1298 RefPtr<nsPresContext> presContext = mPresContext;
1299 EventDispatcher::DispatchDOMEvent(window, nullptr, event, presContext,
1300 nullptr);
1301 mInPermitUnload = false;
1302 }
1303
1304 nsAutoString text;
1305 event->GetReturnValue(text);
1306
1307 // NB: we nullcheck mDocument because it might now be dead as a result of
1308 // the event being dispatched.
1309 if (window->AreDialogsEnabled() && mDocument &&
1310 !(mDocument->GetSandboxFlags() & SANDBOXED_MODALS) &&
1311 (!StaticPrefs::dom_require_user_interaction_for_beforeunload() ||
1312 mDocument->UserHasInteracted()) &&
1313 (event->WidgetEventPtr()->DefaultPrevented() || !text.IsEmpty())) {
1314 return eRequestBlockNavigation;
1315 }
1316 return eAllowNavigation;
1317}
1318
1319NS_IMETHODIMPnsresult
1320nsDocumentViewer::GetBeforeUnloadFiring(bool* aInEvent) {
1321 *aInEvent = mInPermitUnload;
1322 return NS_OK;
1323}
1324
1325NS_IMETHODIMPnsresult
1326nsDocumentViewer::GetInPermitUnload(bool* aInEvent) {
1327 *aInEvent = mInPermitUnloadPrompt;
1328 return NS_OK;
1329}
1330
1331NS_IMETHODIMPnsresult
1332nsDocumentViewer::PageHide(bool aIsUnload) {
1333 AutoDontWarnAboutSyncXHR disableSyncXHRWarning;
1334
1335 mHidden = true;
1336
1337 if (!mDocument) {
1338 return NS_ERROR_NULL_POINTER;
1339 }
1340
1341 if (aIsUnload) {
1342 // Poke the GC. The window might be collectable garbage now.
1343 nsJSContext::PokeGC(JS::GCReason::PAGE_HIDE,
1344 mDocument->GetWrapperPreserveColor(),
1345 TimeDuration::FromMilliseconds(
1346 StaticPrefs::javascript_options_gc_delay() * 2));
1347 }
1348
1349 mDocument->OnPageHide(!aIsUnload, nullptr);
1350
1351 // inform the window so that the focus state is reset.
1352 NS_ENSURE_STATE(mDocument)do { if ((__builtin_expect(!!(!(mDocument)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mDocument" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 1352); return NS_ERROR_UNEXPECTED; } } while (false)
;
1353 nsPIDOMWindowOuter* window = mDocument->GetWindow();
1354 if (window) {
1355 window->PageHidden(!aIsUnload);
1356 }
1357
1358 if (aIsUnload) {
1359 // if Destroy() was called during OnPageHide(), mDocument is nullptr.
1360 NS_ENSURE_STATE(mDocument)do { if ((__builtin_expect(!!(!(mDocument)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mDocument" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 1360); return NS_ERROR_UNEXPECTED; } } while (false)
;
1361
1362 // First, get the window from the document...
1363 RefPtr<nsPIDOMWindowOuter> window = mDocument->GetWindow();
1364
1365 if (!window) {
1366 // Fail if no window is available...
1367 NS_WARNING("window not set for document!")NS_DebugBreak(NS_DEBUG_WARNING, "window not set for document!"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 1367)
;
1368 return NS_ERROR_NULL_POINTER;
1369 }
1370
1371 // https://html.spec.whatwg.org/multipage/browsing-the-web.html#unload-a-document
1372 // Create an RAII object on mDocument that will increment the
1373 // should-ignore-opens-during-unload counter on initialization
1374 // and decrement it again when it goes out of scope.
1375 IgnoreOpensDuringUnload ignoreOpens(mDocument);
1376
1377 // Now, fire an Unload event to the document...
1378 nsEventStatus status = nsEventStatus_eIgnore;
1379 WidgetEvent event(true, eUnload);
1380 event.mFlags.mBubbles = false;
1381 // XXX Dispatching to |window|, but using |document| as the target.
1382 event.mTarget = mDocument;
1383
1384 // Never permit popups from the unload handler, no matter how we get
1385 // here.
1386 AutoPopupStatePusherAutoPopupStatePusherInternal popupStatePusher(PopupBlocker::openAbused, true);
1387
1388 Document::PageUnloadingEventTimeStamp timestamp(mDocument);
1389
1390 RefPtr<nsPresContext> presContext = mPresContext;
1391 // MOZ_KnownLive due to bug 1506441
1392 EventDispatcher::Dispatch(MOZ_KnownLive(nsGlobalWindowOuter::Cast(window))(nsGlobalWindowOuter::Cast(window)),
1393 presContext, &event, nullptr, &status);
1394 }
1395
1396 // look for open menupopups and close them after the unload event, in case
1397 // the unload event listeners open any new popups
1398 nsContentUtils::HidePopupsInDocument(mDocument);
1399
1400 return NS_OK;
1401}
1402
1403static void AttachContainerRecurse(nsIDocShell* aShell) {
1404 nsCOMPtr<nsIDocumentViewer> viewer;
1405 aShell->GetDocViewer(getter_AddRefs(viewer));
1406 if (viewer) {
1407 viewer->SetIsHidden(false);
1408 Document* doc = viewer->GetDocument();
1409 if (doc) {
1410 doc->SetContainer(static_cast<nsDocShell*>(aShell));
1411 }
1412 if (PresShell* presShell = viewer->GetPresShell()) {
1413 presShell->SetForwardingContainer(WeakPtr<nsDocShell>());
1414 }
1415 }
1416
1417 // Now recurse through the children
1418 int32_t childCount;
1419 aShell->GetInProcessChildCount(&childCount);
1420 for (int32_t i = 0; i < childCount; ++i) {
1421 nsCOMPtr<nsIDocShellTreeItem> childItem;
1422 aShell->GetInProcessChildAt(i, getter_AddRefs(childItem));
1423 nsCOMPtr<nsIDocShell> shell = do_QueryInterface(childItem);
1424 AttachContainerRecurse(shell);
1425 }
1426}
1427
1428NS_IMETHODIMPnsresult
1429nsDocumentViewer::Open(nsISupports* aState, nsISHEntry* aSHEntry) {
1430 NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_INITIALIZED)do { if ((__builtin_expect(!!(!(mPresShell)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mPresShell" ") failed",
nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 1430); return NS_ERROR_NOT_INITIALIZED; } } while (false)
;
1431
1432 if (mDocument) {
1433 mDocument->SetContainer(mContainer);
1434 }
1435
1436 nsresult rv = InitInternal(mParentWidget, aState, nullptr, mBounds, false);
1437 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, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 1437); return rv; } } while (false)
;
1438
1439 mHidden = false;
1440
1441 if (mPresShell) {
1442 mPresShell->SetForwardingContainer(WeakPtr<nsDocShell>());
1443 }
1444
1445 // Rehook the child presentations. The child shells are still in
1446 // session history, so get them from there.
1447
1448 if (aSHEntry) {
1449 nsCOMPtr<nsIDocShellTreeItem> item;
1450 int32_t itemIndex = 0;
1451 while (NS_SUCCEEDED(((bool)(__builtin_expect(!!(!NS_FAILED_impl(aSHEntry->ChildShellAt
(itemIndex++, getter_AddRefs(item)))), 1)))
1452 aSHEntry->ChildShellAt(itemIndex++, getter_AddRefs(item)))((bool)(__builtin_expect(!!(!NS_FAILED_impl(aSHEntry->ChildShellAt
(itemIndex++, getter_AddRefs(item)))), 1)))
&&
1453 item) {
1454 nsCOMPtr<nsIDocShell> shell = do_QueryInterface(item);
1455 AttachContainerRecurse(shell);
1456 }
1457 }
1458
1459 SyncParentSubDocMap();
1460
1461 ReinitializeFocusListener();
1462
1463 // XXX re-enable image animations once that works correctly
1464
1465 PrepareToStartLoad();
1466
1467 // When loading a page from the bfcache with puppet widgets, we do the
1468 // widget attachment here (it is otherwise done in MakeWindow, which is
1469 // called for non-bfcache pages in the history, but not bfcache pages).
1470 // Attachment is necessary, since we get detached when another page
1471 // is browsed to. That is, if we are one page A, then when we go to
1472 // page B, we detach. So page A's view has no widget. If we then go
1473 // back to it, and it is in the bfcache, we will use that view, which
1474 // doesn't have a widget. The attach call here will properly attach us.
1475 if (nsIWidget::UsePuppetWidgets() && mPresContext &&
1476 ShouldAttachToTopLevel()) {
1477 // If the old view is already attached to our parent, detach
1478 DetachFromTopLevelWidget();
1479
1480 nsViewManager* vm = GetViewManager();
1481 MOZ_ASSERT(vm, "no view manager")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(vm)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(vm))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("vm" " (" "no view manager" ")"
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 1481); AnnotateMozCrashReason("MOZ_ASSERT" "(" "vm" ") (" "no view manager"
")"); do { *((volatile int*)__null) = 1481; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1482 nsView* v = vm->GetRootView();
1483 MOZ_ASSERT(v, "no root view")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(v)>::isValid, "invalid assertion condition"); if (
(__builtin_expect(!!(!(!!(v))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("v" " (" "no root view" ")", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 1483); AnnotateMozCrashReason("MOZ_ASSERT" "(" "v" ") (" "no root view"
")"); do { *((volatile int*)__null) = 1483; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1484 MOZ_ASSERT(mParentWidget, "no mParentWidget to set")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mParentWidget)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mParentWidget))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("mParentWidget" " ("
"no mParentWidget to set" ")", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 1484); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mParentWidget"
") (" "no mParentWidget to set" ")"); do { *((volatile int*)
__null) = 1484; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
1485 v->AttachToTopLevelWidget(mParentWidget);
1486
1487 mAttachedToParent = true;
1488 }
1489
1490 return NS_OK;
1491}
1492
1493NS_IMETHODIMPnsresult
1494nsDocumentViewer::Close(nsISHEntry* aSHEntry) {
1495 // All callers are supposed to call close to break circular
1496 // references. If we do this stuff in the destructor, the
1497 // destructor might never be called (especially if we're being
1498 // used from JS.
1499
1500 mSHEntry = aSHEntry;
1501
1502 // Close is also needed to disable scripts during paint suppression,
1503 // since we transfer the existing global object to the new document
1504 // that is loaded. In the future, the global object may become a proxy
1505 // for an object that can be switched in and out so that we don't need
1506 // to disable scripts during paint suppression.
1507
1508 if (!mDocument) {
1509 return NS_OK;
1510 }
1511
1512 if (mSHEntry) {
1513 if (mBFCachePreventionObserver) {
1514 mBFCachePreventionObserver->Disconnect();
1515 }
1516 mBFCachePreventionObserver = new BFCachePreventionObserver(mDocument);
1517 mDocument->AddMutationObserver(mBFCachePreventionObserver);
1518 }
1519
1520#ifdef NS_PRINTING1
1521 // A Close was called while we were printing
1522 // so don't clear the ScriptGlobalObject
1523 // or clear the mDocument below
1524 if (mPrintJob && !mClosingWhilePrinting) {
1525 mClosingWhilePrinting = true;
1526 } else
1527#endif
1528 {
1529 // out of band cleanup of docshell
1530 mDocument->SetScriptGlobalObject(nullptr);
1531
1532 if (!mSHEntry && mDocument) {
1533 mDocument->RemovedFromDocShell();
1534 }
1535 }
1536
1537 RemoveFocusListener();
1538 return NS_OK;
1539}
1540
1541static void DetachContainerRecurse(nsIDocShell* aShell) {
1542 // Unhook this docshell's presentation
1543 aShell->SynchronizeLayoutHistoryState();
1544 nsCOMPtr<nsIDocumentViewer> viewer;
1545 aShell->GetDocViewer(getter_AddRefs(viewer));
1546 if (viewer) {
1547 if (Document* doc = viewer->GetDocument()) {
1548 doc->SetContainer(nullptr);
1549 }
1550 if (PresShell* presShell = viewer->GetPresShell()) {
1551 auto weakShell = static_cast<nsDocShell*>(aShell);
1552 presShell->SetForwardingContainer(weakShell);
1553 }
1554 }
1555
1556 // Now recurse through the children
1557 int32_t childCount;
1558 aShell->GetInProcessChildCount(&childCount);
1559 for (int32_t i = 0; i < childCount; ++i) {
1560 nsCOMPtr<nsIDocShellTreeItem> childItem;
1561 aShell->GetInProcessChildAt(i, getter_AddRefs(childItem));
1562 nsCOMPtr<nsIDocShell> shell = do_QueryInterface(childItem);
1563 DetachContainerRecurse(shell);
1564 }
1565}
1566
1567NS_IMETHODIMPnsresult
1568nsDocumentViewer::Destroy() {
1569 // Don't let the document get unloaded while we are printing.
1570 // this could happen if we hit the back button during printing.
1571 // We also keep the viewer from being cached in session history, since
1572 // we require all documents there to be sanitized.
1573 if (mDestroyBlockedCount != 0) {
1574 return NS_OK;
1575 }
1576
1577#ifdef NS_PRINTING1
1578 // Here is where we check to see if the document was still being prepared
1579 // for printing when it was asked to be destroy from someone externally
1580 // This usually happens if the document is unloaded while the user is in the
1581 // Print Dialog
1582 //
1583 // So we flip the bool to remember that the document is going away
1584 // and we can clean up and abort later after returning from the Print Dialog
1585 if (mPrintJob && mPrintJob->CheckBeforeDestroy()) {
1586 return NS_OK;
1587 }
1588#endif
1589
1590 // We want to make sure to disconnect mBFCachePreventionObserver before we
1591 // Sanitize() below.
1592 if (mBFCachePreventionObserver) {
1593 mBFCachePreventionObserver->Disconnect();
1594 mBFCachePreventionObserver = nullptr;
1595 }
1596
1597 if (mSHEntry && mDocument && !mDocument->IsBFCachingAllowed()) {
1598 // Just drop the SHEntry now and pretend like we never even tried to bfcache
1599 // this viewer. This should only happen when someone calls
1600 // DisallowBFCaching() after CanSavePresentation() already ran. Ensure that
1601 // the SHEntry has no viewer and its state is synced up. We want to do this
1602 // via a stack reference, in case those calls mess with our members.
1603 MOZ_LOG(gPageCacheLog, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gPageCacheLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "BFCache not allowed, dropping SHEntry"); }
} while (0)
1604 ("BFCache not allowed, dropping SHEntry"))do { const ::mozilla::LogModule* moz_real_module = gPageCacheLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "BFCache not allowed, dropping SHEntry"); }
} while (0)
;
1605 nsCOMPtr<nsISHEntry> shEntry = std::move(mSHEntry);
1606 shEntry->SetDocumentViewer(nullptr);
1607 shEntry->SyncPresentationState();
1608 }
1609
1610 // If we were told to put ourselves into session history instead of destroy
1611 // the presentation, do that now.
1612 if (mSHEntry) {
1613 if (mPresShell) {
1614 mPresShell->Freeze();
1615 }
1616
1617 // Make sure the presentation isn't torn down by Hide().
1618 mSHEntry->SetSticky(mIsSticky);
1619 mIsSticky = true;
1620
1621 // Remove our root view from the view hierarchy.
1622 if (mPresShell) {
1623 nsViewManager* vm = mPresShell->GetViewManager();
1624 if (vm) {
1625 nsView* rootView = vm->GetRootView();
1626
1627 if (rootView) {
1628 nsView* rootViewParent = rootView->GetParent();
1629 if (rootViewParent) {
1630 nsView* subdocview = rootViewParent->GetParent();
1631 if (subdocview) {
1632 nsIFrame* f = subdocview->GetFrame();
1633 if (f) {
1634 nsSubDocumentFrame* s = do_QueryFrame(f);
1635 if (s) {
1636 s->ClearDisplayItems();
1637 }
1638 }
1639 }
1640 nsViewManager* parentVM = rootViewParent->GetViewManager();
1641 if (parentVM) {
1642 parentVM->RemoveChild(rootView);
1643 }
1644 }
1645 }
1646 }
1647 }
1648
1649 Hide();
1650
1651 // This is after Hide() so that the user doesn't see the inputs clear.
1652 if (mDocument) {
1653 mDocument->Sanitize();
1654 }
1655
1656 // Reverse ownership. Do this *after* calling sanitize so that sanitize
1657 // doesn't cause mutations that make the SHEntry drop the presentation
1658
1659 // Grab a reference to mSHEntry before calling into things like
1660 // SyncPresentationState that might mess with our members.
1661 nsCOMPtr<nsISHEntry> shEntry =
1662 std::move(mSHEntry); // we'll need this below
1663
1664 MOZ_LOG(gPageCacheLog, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gPageCacheLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "Storing content viewer into cache entry")
; } } while (0)
1665 ("Storing content viewer into cache entry"))do { const ::mozilla::LogModule* moz_real_module = gPageCacheLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "Storing content viewer into cache entry")
; } } while (0)
;
1666 shEntry->SetDocumentViewer(this);
1667
1668 // Always sync the presentation state. That way even if someone screws up
1669 // and shEntry has no window state at this point we'll be ok; we just won't
1670 // cache ourselves.
1671 shEntry->SyncPresentationState();
1672 // XXX Synchronize layout history state to parent once bfcache is supported
1673 // in session-history-in-parent.
1674
1675 // Shut down accessibility for the document before we start to tear it down.
1676#ifdef ACCESSIBILITY1
1677 if (mPresShell) {
1678 a11y::DocAccessible* docAcc = mPresShell->GetDocAccessible();
1679 if (docAcc) {
1680 docAcc->Shutdown();
1681 }
1682 }
1683#endif
1684
1685 // Break the link from the document/presentation to the docshell, so that
1686 // link traversals cannot affect the currently-loaded document.
1687 // When the presentation is restored, Open() and InitInternal() will reset
1688 // these pointers to their original values.
1689
1690 if (mDocument) {
1691 mDocument->SetContainer(nullptr);
1692 }
1693 if (mPresShell) {
1694 mPresShell->SetForwardingContainer(mContainer);
1695 }
1696
1697 // Do the same for our children. Note that we need to get the child
1698 // docshells from the SHEntry now; the docshell will have cleared them.
1699 nsCOMPtr<nsIDocShellTreeItem> item;
1700 int32_t itemIndex = 0;
1701 while (NS_SUCCEEDED(((bool)(__builtin_expect(!!(!NS_FAILED_impl(shEntry->ChildShellAt
(itemIndex++, getter_AddRefs(item)))), 1)))
1702 shEntry->ChildShellAt(itemIndex++, getter_AddRefs(item)))((bool)(__builtin_expect(!!(!NS_FAILED_impl(shEntry->ChildShellAt
(itemIndex++, getter_AddRefs(item)))), 1)))
&&
1703 item) {
1704 nsCOMPtr<nsIDocShell> shell = do_QueryInterface(item);
1705 DetachContainerRecurse(shell);
1706 }
1707
1708 return NS_OK;
1709 }
1710
1711 // The document was not put in the bfcache
1712
1713 // Protect against pres shell destruction running scripts and re-entrantly
1714 // creating a new presentation.
1715 nsAutoScriptBlocker scriptBlocker;
1716
1717 if (mPresShell) {
1718 DestroyPresShell();
1719 }
1720 if (mDocument) {
1721 mDocument->Destroy();
1722 mDocument = nullptr;
1723 }
1724
1725 // All callers are supposed to call destroy to break circular
1726 // references. If we do this stuff in the destructor, the
1727 // destructor might never be called (especially if we're being
1728 // used from JS.
1729
1730#ifdef NS_PRINTING1
1731 if (mPrintJob) {
1732 RefPtr<nsPrintJob> printJob = std::move(mPrintJob);
1733# ifdef NS_PRINT_PREVIEW1
1734 if (printJob->CreatedForPrintPreview()) {
1735 printJob->FinishPrintPreview();
1736 }
1737# endif
1738 printJob->Destroy();
1739 MOZ_ASSERT(!mPrintJob,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mPrintJob)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mPrintJob))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("!mPrintJob" " (" "mPrintJob shouldn't be recreated while destroying it"
")", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 1740); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mPrintJob"
") (" "mPrintJob shouldn't be recreated while destroying it"
")"); do { *((volatile int*)__null) = 1740; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1740 "mPrintJob shouldn't be recreated while destroying it")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mPrintJob)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mPrintJob))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("!mPrintJob" " (" "mPrintJob shouldn't be recreated while destroying it"
")", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 1740); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mPrintJob"
") (" "mPrintJob shouldn't be recreated while destroying it"
")"); do { *((volatile int*)__null) = 1740; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1741 }
1742#endif
1743
1744 // Avoid leaking the old viewer.
1745 if (mPreviousViewer) {
1746 mPreviousViewer->Destroy();
1747 mPreviousViewer = nullptr;
1748 }
1749
1750 mDeviceContext = nullptr;
1751
1752 if (mPresContext) {
1753 DestroyPresContext();
1754 }
1755
1756 mWindow = nullptr;
1757 mViewManager = nullptr;
1758 mContainer = WeakPtr<nsDocShell>();
1759
1760 return NS_OK;
1761}
1762
1763NS_IMETHODIMPnsresult
1764nsDocumentViewer::Stop(void) {
1765 NS_ASSERTION(mDocument, "Stop called too early or too late")do { if (!(mDocument)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "Stop called too early or too late"
, "mDocument", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 1765); MOZ_PretendNoReturn(); } } while (0)
;
1766 if (mDocument) {
1767 mDocument->StopDocumentLoad();
1768 }
1769
1770 mStopped = true;
1771
1772 if (!mLoaded && mPresShell) {
1773 // Well, we might as well paint what we have so far.
1774 RefPtr<PresShell> presShell = mPresShell; // bug 378682
1775 presShell->UnsuppressPainting();
1776 }
1777
1778 return NS_OK;
1779}
1780
1781NS_IMETHODIMPnsresult
1782nsDocumentViewer::GetDOMDocument(Document** aResult) {
1783 NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE)do { if ((__builtin_expect(!!(!(mDocument)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mDocument" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 1783); return NS_ERROR_NOT_AVAILABLE; } } while (false)
;
1784 nsCOMPtr<Document> document = mDocument;
1785 document.forget(aResult);
1786 return NS_OK;
1787}
1788
1789Document* nsDocumentViewer::GetDocument() { return mDocument; }
1790
1791nsresult nsDocumentViewer::SetDocument(Document* aDocument) {
1792 // Assumptions:
1793 //
1794 // 1) this document viewer has been initialized with a call to Init().
1795 // 2) the stylesheets associated with the document have been added
1796 // to the document.
1797
1798 // XXX Right now, this method assumes that the layout of the current
1799 // document hasn't started yet. More cleanup will probably be
1800 // necessary to make this method work for the case when layout *has*
1801 // occurred for the current document.
1802 // That work can happen when and if it is needed.
1803
1804 if (!aDocument) {
1805 return NS_ERROR_NULL_POINTER;
1806 }
1807
1808 return SetDocumentInternal(aDocument, false);
1809}
1810
1811NS_IMETHODIMPnsresult
1812nsDocumentViewer::SetDocumentInternal(Document* aDocument,
1813 bool aForceReuseInnerWindow) {
1814 MOZ_ASSERT(aDocument)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aDocument)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aDocument))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aDocument", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 1814); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aDocument" ")"
); do { *((volatile int*)__null) = 1814; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1815
1816 // Set new container
1817 aDocument->SetContainer(mContainer);
1818
1819 if (mDocument != aDocument) {
1820 if (aForceReuseInnerWindow) {
1821 // Transfer the navigation timing information to the new document, since
1822 // we're keeping the same inner and hence should really have the same
1823 // timing information.
1824 aDocument->SetNavigationTiming(mDocument->GetNavigationTiming());
1825 }
1826
1827 if (mDocument &&
1828 (mDocument->IsStaticDocument() || aDocument->IsStaticDocument())) {
1829 nsContentUtils::AddScriptRunner(NewRunnableMethod(
1830 "Document::Destroy", mDocument, &Document::Destroy));
1831 }
1832
1833 // Clear the list of old child docshells. Child docshells for the new
1834 // document will be constructed as frames are created.
1835 if (!aDocument->IsStaticDocument()) {
1836 nsCOMPtr<nsIDocShell> node(mContainer);
1837 if (node) {
1838 int32_t count;
1839 node->GetInProcessChildCount(&count);
1840 for (int32_t i = 0; i < count; ++i) {
1841 nsCOMPtr<nsIDocShellTreeItem> child;
1842 node->GetInProcessChildAt(0, getter_AddRefs(child));
1843 node->RemoveChild(child);
1844 }
1845 }
1846 }
1847
1848 // Replace the old document with the new one. Do this only when
1849 // the new document really is a new document.
1850 mDocument = aDocument;
1851
1852 // Set the script global object on the new document
1853 nsCOMPtr<nsPIDOMWindowOuter> window =
1854 mContainer ? mContainer->GetWindow() : nullptr;
1855 if (window) {
1856 nsresult rv =
1857 window->SetNewDocument(aDocument, nullptr, aForceReuseInnerWindow);
1858 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1859 Destroy();
1860 return rv;
1861 }
1862 }
1863 }
1864
1865 nsresult rv = SyncParentSubDocMap();
1866 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, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 1866); return rv; } } while (false)
;
1867
1868 // Replace the current pres shell with a new shell for the new document
1869
1870 // Protect against pres shell destruction running scripts and re-entrantly
1871 // creating a new presentation.
1872 nsAutoScriptBlocker scriptBlocker;
1873
1874 if (mPresShell) {
1875 DestroyPresShell();
1876 }
1877
1878 if (mPresContext) {
1879 DestroyPresContext();
1880
1881 mWindow = nullptr;
1882 rv = InitInternal(mParentWidget, nullptr, nullptr, mBounds, true, true,
1883 false);
1884 }
1885
1886 return rv;
1887}
1888
1889PresShell* nsDocumentViewer::GetPresShell() { return mPresShell; }
1890
1891nsPresContext* nsDocumentViewer::GetPresContext() { return mPresContext; }
1892
1893nsViewManager* nsDocumentViewer::GetViewManager() { return mViewManager; }
1894
1895NS_IMETHODIMPnsresult
1896nsDocumentViewer::GetBounds(LayoutDeviceIntRect& aResult) {
1897 NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE)do { if ((__builtin_expect(!!(!(mDocument)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mDocument" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 1897); return NS_ERROR_NOT_AVAILABLE; } } while (false)
;
1898 aResult = mBounds;
1899 return NS_OK;
1900}
1901
1902nsIDocumentViewer* nsDocumentViewer::GetPreviousViewer() {
1903 return mPreviousViewer;
1904}
1905
1906void nsDocumentViewer::SetPreviousViewer(nsIDocumentViewer* aViewer) {
1907 // NOTE: |Show| sets |mPreviousViewer| to null without calling this
1908 // function.
1909
1910 if (aViewer) {
1911 NS_ASSERTION(!mPreviousViewer,do { if (!(!mPreviousViewer)) { NS_DebugBreak(NS_DEBUG_ASSERTION
, "can't set previous viewer when there already is one", "!mPreviousViewer"
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 1912); MOZ_PretendNoReturn(); } } while (0)
1912 "can't set previous viewer when there already is one")do { if (!(!mPreviousViewer)) { NS_DebugBreak(NS_DEBUG_ASSERTION
, "can't set previous viewer when there already is one", "!mPreviousViewer"
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 1912); MOZ_PretendNoReturn(); } } while (0)
;
1913
1914 // In a multiple chaining situation (which occurs when running a thrashing
1915 // test like i-bench or jrgm's tests with no delay), we can build up a
1916 // whole chain of viewers. In order to avoid this, we always set our
1917 // previous viewer to the MOST previous viewer in the chain, and then dump
1918 // the intermediate link from the chain. This ensures that at most only 2
1919 // documents are alive and undestroyed at any given time (the one that is
1920 // showing and the one that is loading with painting suppressed). It's very
1921 // important that if this ever gets changed the code before the
1922 // RestorePresentation call in nsDocShell::InternalLoad be changed
1923 // accordingly.
1924 //
1925 // Make sure we hold a strong ref to prevViewer here, since we'll
1926 // tell aViewer to drop it.
1927 nsCOMPtr<nsIDocumentViewer> prevViewer = aViewer->GetPreviousViewer();
1928 if (prevViewer) {
1929 aViewer->SetPreviousViewer(nullptr);
1930 aViewer->Destroy();
1931 return SetPreviousViewer(prevViewer);
1932 }
1933 }
1934
1935 mPreviousViewer = aViewer;
1936}
1937
1938NS_IMETHODIMPnsresult
1939nsDocumentViewer::SetBoundsWithFlags(const LayoutDeviceIntRect& aBounds,
1940 uint32_t aFlags) {
1941 NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE)do { if ((__builtin_expect(!!(!(mDocument)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mDocument" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 1941); return NS_ERROR_NOT_AVAILABLE; } } while (false)
;
1942
1943 bool boundsChanged = !mBounds.IsEqualEdges(aBounds);
1944 mBounds = aBounds;
1945
1946 if (mWindow && !mAttachedToParent) {
1947 // Resize the widget, but don't trigger repaint. Layout will generate
1948 // repaint requests during reflow.
1949 mWindow->Resize(aBounds.x, aBounds.y, aBounds.width, aBounds.height, false);
1950 } else if (mPresContext && mViewManager) {
1951 // Ensure presContext's deviceContext is up to date, as we sometimes get
1952 // here before a resolution-change notification has been fully handled
1953 // during display configuration changes, especially when there are lots
1954 // of windows/widgets competing to handle the notifications.
1955 // (See bug 1154125.)
1956 if (mPresContext->DeviceContext()->CheckDPIChange()) {
1957 mPresContext->UIResolutionChangedSync();
1958 }
1959
1960 int32_t p2a = mPresContext->AppUnitsPerDevPixel();
1961 nscoord width = NSIntPixelsToAppUnits(mBounds.width, p2a);
1962 nscoord height = NSIntPixelsToAppUnits(mBounds.height, p2a);
1963 nsView* rootView = mViewManager->GetRootView();
1964 if (boundsChanged && rootView) {
1965 nsRect viewDims = rootView->GetDimensions();
1966 // If the view/frame tree and prescontext visible area already has the new
1967 // size but we did not, then it's likely that we got reflowed in response
1968 // to a call to GetContentSize. Thus there is a disconnect between the
1969 // size on the document viewer/docshell/containing widget and view
1970 // tree/frame tree/prescontext visible area). SetWindowDimensions compares
1971 // to the root view dimenstions to determine if it needs to do anything;
1972 // if they are the same as the new size it won't do anything, but we still
1973 // need to invalidate because what we want to draw to the screen has
1974 // changed.
1975 if (viewDims.width == width && viewDims.height == height) {
1976 if (nsIFrame* f = rootView->GetFrame()) {
1977 f->InvalidateFrame();
1978
1979 // Forcibly refresh the viewport sizes even if the view size is not
1980 // changed since it is possible that the |mBounds| change means that
1981 // the software keyboard appeared/disappeared. In such cases we might
1982 // need to fire visual viewport events.
1983 mPresShell->RefreshViewportSize();
1984 }
1985 }
1986 }
1987
1988 mViewManager->SetWindowDimensions(
1989 width, height, !!(aFlags & nsIDocumentViewer::eDelayResize));
1990 }
1991
1992 // If there's a previous viewer, it's the one that's actually showing,
1993 // so be sure to resize it as well so it paints over the right area.
1994 // This may slow down the performance of the new page load, but resize
1995 // during load is also probably a relatively unusual condition
1996 // relating to things being hidden while something is loaded. It so
1997 // happens that Firefox does this a good bit with its infobar, and it
1998 // looks ugly if we don't do this.
1999 if (mPreviousViewer) {
2000 nsCOMPtr<nsIDocumentViewer> previousViewer = mPreviousViewer;
2001 previousViewer->SetBounds(aBounds);
2002 }
2003
2004 return NS_OK;
2005}
2006
2007NS_IMETHODIMPnsresult
2008nsDocumentViewer::SetBounds(const LayoutDeviceIntRect& aBounds) {
2009 return SetBoundsWithFlags(aBounds, 0);
2010}
2011
2012NS_IMETHODIMPnsresult
2013nsDocumentViewer::Move(int32_t aX, int32_t aY) {
2014 NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE)do { if ((__builtin_expect(!!(!(mDocument)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mDocument" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2014); return NS_ERROR_NOT_AVAILABLE; } } while (false)
;
2015 mBounds.MoveTo(aX, aY);
2016 if (mWindow) {
2017 mWindow->Move(aX, aY);
2018 }
2019 return NS_OK;
2020}
2021
2022NS_IMETHODIMPnsresult
2023nsDocumentViewer::Show() {
2024 NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE)do { if ((__builtin_expect(!!(!(mDocument)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mDocument" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2024); return NS_ERROR_NOT_AVAILABLE; } } while (false)
;
2025
2026 // We don't need the previous viewer anymore since we're not
2027 // displaying it.
2028 if (mPreviousViewer) {
2029 // This little dance *may* only be to keep
2030 // PresShell::EndObservingDocument happy, but I'm not sure.
2031 nsCOMPtr<nsIDocumentViewer> prevViewer(mPreviousViewer);
2032 mPreviousViewer = nullptr;
2033 prevViewer->Destroy();
2034
2035 // Make sure we don't have too many cached DocumentViewers
2036 nsCOMPtr<nsIDocShellTreeItem> treeItem(mContainer);
2037 if (treeItem) {
2038 // We need to find the root DocShell since only that object has an
2039 // SHistory and we need the SHistory to evict content viewers
2040 nsCOMPtr<nsIDocShellTreeItem> root;
2041 treeItem->GetInProcessSameTypeRootTreeItem(getter_AddRefs(root));
2042 nsCOMPtr<nsIWebNavigation> webNav = do_QueryInterface(root);
2043 RefPtr<ChildSHistory> history = webNav->GetSessionHistory();
2044 if (!mozilla::SessionHistoryInParent() && history) {
2045 int32_t prevIndex, loadedIndex;
2046 nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(treeItem);
2047 docShell->GetPreviousEntryIndex(&prevIndex);
2048 docShell->GetLoadedEntryIndex(&loadedIndex);
2049 MOZ_LOG(gPageCacheLog, LogLevel::Verbose,do { const ::mozilla::LogModule* moz_real_module = gPageCacheLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "About to evict content viewers: prev=%d, loaded=%d"
, prevIndex, loadedIndex); } } while (0)
2050 ("About to evict content viewers: prev=%d, loaded=%d",do { const ::mozilla::LogModule* moz_real_module = gPageCacheLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "About to evict content viewers: prev=%d, loaded=%d"
, prevIndex, loadedIndex); } } while (0)
2051 prevIndex, loadedIndex))do { const ::mozilla::LogModule* moz_real_module = gPageCacheLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "About to evict content viewers: prev=%d, loaded=%d"
, prevIndex, loadedIndex); } } while (0)
;
2052 history->LegacySHistory()->EvictOutOfRangeDocumentViewers(loadedIndex);
2053 }
2054 }
2055 }
2056
2057 if (mWindow) {
2058 // When attached to a top level xul window, we do not need to call
2059 // Show on the widget. Underlying window management code handles
2060 // this when the window is initialized.
2061 if (!mAttachedToParent) {
2062 mWindow->Show(true);
2063 }
2064 }
2065
2066 // Hold on to the document so we can use it after the script blocker below
2067 // has been released (which might re-entrantly call into other
2068 // nsDocumentViewer methods).
2069 nsCOMPtr<Document> document = mDocument;
2070
2071 if (mDocument && !mPresShell) {
2072 // The InitPresentationStuff call below requires a script blocker, because
2073 // its PresShell::Initialize call can cause scripts to run and therefore
2074 // re-entrant calls to nsDocumentViewer methods to be made.
2075 nsAutoScriptBlocker scriptBlocker;
2076
2077 NS_ASSERTION(!mWindow, "Window already created but no presshell?")do { if (!(!mWindow)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "Window already created but no presshell?"
, "!mWindow", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2077); MOZ_PretendNoReturn(); } } while (0)
;
2078
2079 nsCOMPtr<nsIBaseWindow> base_win(mContainer);
2080 if (base_win) {
2081 base_win->GetParentWidget(&mParentWidget);
2082 if (mParentWidget) {
2083 // GetParentWidget AddRefs, but mParentWidget is weak
2084 mParentWidget->Release();
2085 }
2086 }
2087
2088 nsView* containerView = FindContainerView();
2089
2090 nsresult rv = CreateDeviceContext(containerView);
2091 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, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2091); return rv; } } while (false)
;
2092
2093 // Create presentation context
2094 NS_ASSERTION(!mPresContext,do { if (!(!mPresContext)) { NS_DebugBreak(NS_DEBUG_ASSERTION
, "Shouldn't have a prescontext if we have no shell!", "!mPresContext"
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2095); MOZ_PretendNoReturn(); } } while (0)
2095 "Shouldn't have a prescontext if we have no shell!")do { if (!(!mPresContext)) { NS_DebugBreak(NS_DEBUG_ASSERTION
, "Shouldn't have a prescontext if we have no shell!", "!mPresContext"
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2095); MOZ_PretendNoReturn(); } } while (0)
;
2096 mPresContext = CreatePresContext(mDocument, nsPresContext::eContext_Galley,
2097 containerView);
2098 NS_ENSURE_TRUE(mPresContext, NS_ERROR_OUT_OF_MEMORY)do { if ((__builtin_expect(!!(!(mPresContext)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mPresContext" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2098); return NS_ERROR_OUT_OF_MEMORY; } } while (false)
;
2099
2100 rv = mPresContext->Init(mDeviceContext);
2101 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2102 mPresContext = nullptr;
2103 return rv;
2104 }
2105
2106 rv = MakeWindow(nsSize(mPresContext->DevPixelsToAppUnits(mBounds.width),
2107 mPresContext->DevPixelsToAppUnits(mBounds.height)),
2108 containerView);
2109 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2110 return rv;
2111 }
2112
2113 if (mPresContext) {
2114 Hide();
2115
2116 rv = InitPresentationStuff(mDocument->MayStartLayout());
Value stored to 'rv' is never read
2117 }
2118
2119 // If we get here the document load has already started and the
2120 // window is shown because some JS on the page caused it to be
2121 // shown...
2122
2123 if (mPresShell) {
2124 RefPtr<PresShell> presShell = mPresShell; // bug 378682
2125 presShell->UnsuppressPainting();
2126 }
2127 }
2128
2129 // Notify observers that a new page has been shown. This will get run
2130 // from the event loop after we actually draw the page.
2131 auto event = MakeRefPtr<nsDocumentShownDispatcher>(document);
2132 document->Dispatch(event.forget());
2133
2134 return NS_OK;
2135}
2136
2137NS_IMETHODIMPnsresult
2138nsDocumentViewer::Hide() {
2139 if (!mAttachedToParent && mWindow) {
2140 mWindow->Show(false);
2141 }
2142
2143 if (!mPresShell) {
2144 return NS_OK;
2145 }
2146
2147 NS_ASSERTION(mPresContext, "Can't have a presshell and no prescontext!")do { if (!(mPresContext)) { NS_DebugBreak(NS_DEBUG_ASSERTION,
"Can't have a presshell and no prescontext!", "mPresContext"
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2147); MOZ_PretendNoReturn(); } } while (0)
;
2148
2149 // Avoid leaking the old viewer.
2150 if (mPreviousViewer) {
2151 mPreviousViewer->Destroy();
2152 mPreviousViewer = nullptr;
2153 }
2154
2155 if (mIsSticky) {
2156 // This window is sticky, that means that it might be shown again
2157 // and we don't want the presshell n' all that to be thrown away
2158 // just because the window is hidden.
2159
2160 return NS_OK;
2161 }
2162
2163 nsCOMPtr<nsIDocShell> docShell(mContainer);
2164 if (docShell) {
2165#ifdef DEBUG1
2166 nsCOMPtr<nsIDocumentViewer> currentViewer;
2167 docShell->GetDocViewer(getter_AddRefs(currentViewer));
2168 MOZ_ASSERT(currentViewer == this)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(currentViewer == this)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(currentViewer == this))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("currentViewer == this"
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2168); AnnotateMozCrashReason("MOZ_ASSERT" "(" "currentViewer == this"
")"); do { *((volatile int*)__null) = 2168; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2169#endif
2170 nsCOMPtr<nsILayoutHistoryState> layoutState;
2171 mPresShell->CaptureHistoryState(getter_AddRefs(layoutState));
2172 }
2173
2174 // Do not run ScriptRunners queued by DestroyPresShell() in the intermediate
2175 // state before we're done destroying PresShell, PresContext, ViewManager,
2176 // etc.
2177 nsAutoScriptBlocker scriptBlocker;
2178
2179 DestroyPresShell();
2180
2181 DestroyPresContext();
2182
2183 mViewManager = nullptr;
2184 mWindow = nullptr;
2185 mDeviceContext = nullptr;
2186 mParentWidget = nullptr;
2187
2188 nsCOMPtr<nsIBaseWindow> base_win(mContainer);
2189
2190 if (base_win && !mAttachedToParent) {
2191 base_win->SetParentWidget(nullptr);
2192 }
2193
2194 return NS_OK;
2195}
2196
2197NS_IMETHODIMPnsresult
2198nsDocumentViewer::GetSticky(bool* aSticky) {
2199 *aSticky = mIsSticky;
2200
2201 return NS_OK;
2202}
2203
2204NS_IMETHODIMPnsresult
2205nsDocumentViewer::SetSticky(bool aSticky) {
2206 mIsSticky = aSticky;
2207
2208 return NS_OK;
2209}
2210
2211NS_IMETHODIMPnsresult
2212nsDocumentViewer::ClearHistoryEntry() {
2213 if (mDocument) {
2214 nsJSContext::PokeGC(JS::GCReason::PAGE_HIDE,
2215 mDocument->GetWrapperPreserveColor(),
2216 TimeDuration::FromMilliseconds(
2217 StaticPrefs::javascript_options_gc_delay() * 2));
2218 }
2219
2220 mSHEntry = nullptr;
2221 return NS_OK;
2222}
2223
2224//-------------------------------------------------------
2225
2226nsresult nsDocumentViewer::MakeWindow(const nsSize& aSize,
2227 nsView* aContainerView) {
2228 if (GetIsPrintPreview()) {
2229 return NS_OK;
2230 }
2231
2232 const bool shouldAttach = ShouldAttachToTopLevel();
2233 if (shouldAttach) {
2234 // If the old view is already attached to our parent, detach
2235 DetachFromTopLevelWidget();
2236 }
2237
2238 mViewManager = new nsViewManager();
2239
2240 nsDeviceContext* dx = mPresContext->DeviceContext();
2241
2242 nsresult rv = mViewManager->Init(dx);
2243 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2244 return rv;
2245 }
2246
2247 // The root view is always at 0,0.
2248 nsRect tbounds(nsPoint(0, 0), aSize);
2249 // Create a view
2250 nsView* view = mViewManager->CreateView(tbounds, aContainerView);
2251 if (!view) {
2252 return NS_ERROR_OUT_OF_MEMORY;
2253 }
2254
2255 // Create a widget if we were given a parent widget or don't have a
2256 // container view that we can hook up to without a widget.
2257 // Don't create widgets for ResourceDocs (external resources & svg images),
2258 // because when they're displayed, they're painted into *another* document's
2259 // widget.
2260 if (!mDocument->IsResourceDoc() && (mParentWidget || !aContainerView)) {
2261 if (shouldAttach) {
2262 // Reuse the top level parent widget.
2263 rv = view->AttachToTopLevelWidget(mParentWidget);
2264 mAttachedToParent = true;
2265 } else {
2266 rv = view->CreateWidget(mParentWidget, true, false);
2267 }
2268 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2269 return rv;
2270 }
2271 }
2272
2273 // Setup hierarchical relationship in view manager
2274 mViewManager->SetRootView(view);
2275
2276 mWindow = view->GetWidget();
2277
2278 // This SetFocus is necessary so the Arrow Key and Page Key events
2279 // go to the scrolled view as soon as the Window is created instead of going
2280 // to the browser window (this enables keyboard scrolling of the document)
2281 // mWindow->SetFocus();
2282
2283 return rv;
2284}
2285
2286void nsDocumentViewer::DetachFromTopLevelWidget() {
2287 if (mViewManager) {
2288 nsView* oldView = mViewManager->GetRootView();
2289 if (oldView && oldView->IsAttachedToTopLevel()) {
2290 oldView->DetachFromTopLevelWidget();
2291 }
2292 }
2293 mAttachedToParent = false;
2294}
2295
2296nsView* nsDocumentViewer::FindContainerView() {
2297 if (!mContainer) {
2298 return nullptr;
2299 }
2300
2301 nsCOMPtr<nsIDocShell> docShell(mContainer);
2302 nsCOMPtr<nsPIDOMWindowOuter> pwin(docShell->GetWindow());
2303 if (!pwin) {
2304 return nullptr;
2305 }
2306
2307 nsCOMPtr<Element> containerElement = pwin->GetFrameElementInternal();
2308 if (!containerElement) {
2309 return nullptr;
2310 }
2311
2312 nsIFrame* subdocFrame = containerElement->GetPrimaryFrame();
2313 if (!subdocFrame) {
2314 // XXX Silenced by default in bug 1175289
2315 LAYOUT_WARNING("Subdocument container has no frame")do { if ((__builtin_expect(!!(mozilla::detail::log_test(sLayoutLog
, mozilla::LogLevel::Warning)), 0))) { mozilla::detail::LayoutLogWarning
("Subdocument container has no frame", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2315); } } while (0)
;
2316 return nullptr;
2317 }
2318
2319 // Check subdocFrame just to be safe. If this somehow fails we treat that as
2320 // display:none, the document is not displayed.
2321 if (!subdocFrame->IsSubDocumentFrame()) {
2322 NS_WARNING_ASSERTION(subdocFrame->Type() == LayoutFrameType::None,do { if (!(subdocFrame->Type() == LayoutFrameType::None)) {
NS_DebugBreak(NS_DEBUG_WARNING, "Subdocument container has non-subdocument frame"
, "subdocFrame->Type() == LayoutFrameType::None", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2323); } } while (false)
2323 "Subdocument container has non-subdocument frame")do { if (!(subdocFrame->Type() == LayoutFrameType::None)) {
NS_DebugBreak(NS_DEBUG_WARNING, "Subdocument container has non-subdocument frame"
, "subdocFrame->Type() == LayoutFrameType::None", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2323); } } while (false)
;
2324 return nullptr;
2325 }
2326
2327 NS_ASSERTION(subdocFrame->GetView(), "Subdoc frames must have views")do { if (!(subdocFrame->GetView())) { NS_DebugBreak(NS_DEBUG_ASSERTION
, "Subdoc frames must have views", "subdocFrame->GetView()"
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2327); MOZ_PretendNoReturn(); } } while (0)
;
2328 return static_cast<nsSubDocumentFrame*>(subdocFrame)->EnsureInnerView();
2329}
2330
2331nsresult nsDocumentViewer::CreateDeviceContext(nsView* aContainerView) {
2332 MOZ_ASSERT(!mPresShell && !mWindow,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mPresShell && !mWindow)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mPresShell && !mWindow
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"!mPresShell && !mWindow" " (" "This will screw up our existing presentation"
")", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2333); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mPresShell && !mWindow"
") (" "This will screw up our existing presentation" ")"); do
{ *((volatile int*)__null) = 2333; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
2333 "This will screw up our existing presentation")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mPresShell && !mWindow)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mPresShell && !mWindow
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"!mPresShell && !mWindow" " (" "This will screw up our existing presentation"
")", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2333); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mPresShell && !mWindow"
") (" "This will screw up our existing presentation" ")"); do
{ *((volatile int*)__null) = 2333; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
2334 MOZ_ASSERT(mDocument, "Gotta have a document here")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mDocument)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mDocument))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mDocument" " (" "Gotta have a document here"
")", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2334); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mDocument" ") ("
"Gotta have a document here" ")"); do { *((volatile int*)__null
) = 2334; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false)
;
2335
2336 Document* doc = mDocument->GetDisplayDocument();
2337 if (doc) {
2338 NS_ASSERTION(!aContainerView,do { if (!(!aContainerView)) { NS_DebugBreak(NS_DEBUG_ASSERTION
, "External resource document embedded somewhere?", "!aContainerView"
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2339); MOZ_PretendNoReturn(); } } while (0)
2339 "External resource document embedded somewhere?")do { if (!(!aContainerView)) { NS_DebugBreak(NS_DEBUG_ASSERTION
, "External resource document embedded somewhere?", "!aContainerView"
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2339); MOZ_PretendNoReturn(); } } while (0)
;
2340 // We want to use our display document's device context if possible
2341 nsPresContext* ctx = doc->GetPresContext();
2342 if (ctx) {
2343 mDeviceContext = ctx->DeviceContext();
2344 return NS_OK;
2345 }
2346 }
2347
2348 // Create a device context even if we already have one, since our widget
2349 // might have changed.
2350 nsIWidget* widget = nullptr;
2351 if (aContainerView) {
2352 widget = aContainerView->GetNearestWidget(nullptr);
2353 }
2354 if (!widget) {
2355 widget = mParentWidget;
2356 }
2357 if (widget) {
2358 widget = widget->GetTopLevelWidget();
2359 }
2360
2361 mDeviceContext = new nsDeviceContext();
2362 mDeviceContext->Init(widget);
2363 return NS_OK;
2364}
2365
2366// Return the selection for the document. Note that text fields have their
2367// own selection, which cannot be accessed with this method.
2368mozilla::dom::Selection* nsDocumentViewer::GetDocumentSelection() {
2369 if (!mPresShell) {
2370 return nullptr;
2371 }
2372
2373 return mPresShell->GetCurrentSelection(SelectionType::eNormal);
2374}
2375
2376/* ============================================================================
2377 * nsIDocumentViewerEdit
2378 * ============================================================================
2379 */
2380
2381MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMPnsresult nsDocumentViewer::ClearSelection() {
2382 // use nsCopySupport::GetSelectionForCopy() ?
2383 RefPtr<mozilla::dom::Selection> selection = GetDocumentSelection();
2384 if (!selection) {
2385 return NS_ERROR_FAILURE;
2386 }
2387
2388 ErrorResult rv;
2389 selection->CollapseToStart(rv);
2390 return rv.StealNSResult();
2391}
2392
2393MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMPnsresult nsDocumentViewer::SelectAll() {
2394 // XXX this is a temporary implementation copied from nsWebShell
2395 // for now. I think Document and friends should have some helper
2396 // functions to make this easier.
2397
2398 // use nsCopySupport::GetSelectionForCopy() ?
2399 RefPtr<mozilla::dom::Selection> selection = GetDocumentSelection();
2400 if (!selection) {
2401 return NS_ERROR_FAILURE;
2402 }
2403
2404 if (!mDocument) {
2405 return NS_ERROR_FAILURE;
2406 }
2407
2408 nsCOMPtr<nsINode> bodyNode;
2409 if (mDocument->IsHTMLOrXHTML()) {
2410 // XXXbz why not just do GetBody() for all documents, then GetRootElement()
2411 // if GetBody() is null?
2412 bodyNode = mDocument->GetBody();
2413 } else {
2414 bodyNode = mDocument->GetRootElement();
2415 }
2416 if (!bodyNode) {
2417 return NS_ERROR_FAILURE;
2418 }
2419
2420 ErrorResult err;
2421 selection->RemoveAllRanges(err);
2422 if (err.Failed()) {
2423 return err.StealNSResult();
2424 }
2425
2426 mozilla::dom::Selection::AutoUserInitiated userSelection(selection);
2427 selection->SelectAllChildren(*bodyNode, err);
2428 return err.StealNSResult();
2429}
2430
2431NS_IMETHODIMPnsresult nsDocumentViewer::CopySelection() {
2432 RefPtr<PresShell> presShell = mPresShell;
2433 nsCopySupport::FireClipboardEvent(eCopy, Some(nsIClipboard::kGlobalClipboard),
2434 presShell, nullptr, nullptr);
2435 return NS_OK;
2436}
2437
2438NS_IMETHODIMPnsresult nsDocumentViewer::CopyLinkLocation() {
2439 NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_INITIALIZED)do { if ((__builtin_expect(!!(!(mPresShell)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mPresShell" ") failed",
nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2439); return NS_ERROR_NOT_INITIALIZED; } } while (false)
;
2440 nsCOMPtr<nsINode> node = GetPopupLinkNode();
2441 // make noise if we're not in a link
2442 NS_ENSURE_TRUE(node, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(node)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "node" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2442); return NS_ERROR_FAILURE; } } while (false)
;
2443
2444 nsCOMPtr<dom::Element> elm(do_QueryInterface(node));
2445 NS_ENSURE_TRUE(elm, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(elm)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "elm" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2445); return NS_ERROR_FAILURE; } } while (false)
;
2446
2447 nsAutoString locationText;
2448 nsContentUtils::GetLinkLocation(elm, locationText);
2449 if (locationText.IsEmpty()) {
2450 return NS_ERROR_FAILURE;
2451 }
2452
2453 nsresult rv = NS_OK;
2454 nsCOMPtr<nsIClipboardHelper> clipboard(
2455 do_GetService("@mozilla.org/widget/clipboardhelper;1", &rv));
2456 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, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2456); return rv; } } while (false)
;
2457
2458 // copy the href onto the clipboard
2459 return clipboard->CopyString(locationText, mDocument->GetWindowContext());
2460}
2461
2462NS_IMETHODIMPnsresult nsDocumentViewer::CopyImage(int32_t aCopyFlags) {
2463 NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_INITIALIZED)do { if ((__builtin_expect(!!(!(mPresShell)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mPresShell" ") failed",
nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2463); return NS_ERROR_NOT_INITIALIZED; } } while (false)
;
2464 nsCOMPtr<nsIImageLoadingContent> node = GetPopupImageNode();
2465 // make noise if we're not in an image
2466 NS_ENSURE_TRUE(node, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(node)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "node" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2466); return NS_ERROR_FAILURE; } } while (false)
;
2467
2468 nsCOMPtr<nsILoadContext> loadContext(mContainer);
2469 return nsCopySupport::ImageCopy(node, loadContext, aCopyFlags,
2470 mDocument->GetWindowContext());
2471}
2472
2473NS_IMETHODIMPnsresult nsDocumentViewer::GetCopyable(bool* aCopyable) {
2474 NS_ENSURE_ARG_POINTER(aCopyable)do { if ((__builtin_expect(!!(!(aCopyable)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aCopyable" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2474); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2475 *aCopyable = nsCopySupport::CanCopy(mDocument);
2476 return NS_OK;
2477}
2478
2479NS_IMETHODIMPnsresult nsDocumentViewer::GetContents(const char* mimeType,
2480 bool selectionOnly,
2481 nsAString& aOutValue) {
2482 aOutValue.Truncate();
2483
2484 NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_INITIALIZED)do { if ((__builtin_expect(!!(!(mPresShell)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mPresShell" ") failed",
nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2484); return NS_ERROR_NOT_INITIALIZED; } } while (false)
;
2485 NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_INITIALIZED)do { if ((__builtin_expect(!!(!(mDocument)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mDocument" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2485); return NS_ERROR_NOT_INITIALIZED; } } while (false)
;
2486
2487 // Now we have the selection. Make sure it's nonzero:
2488 RefPtr<Selection> sel;
2489 if (selectionOnly) {
2490 sel = nsCopySupport::GetSelectionForCopy(mDocument);
2491 NS_ENSURE_TRUE(sel, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(sel)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "sel" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2491); return NS_ERROR_FAILURE; } } while (false)
;
2492
2493 if (NS_WARN_IF(sel->IsCollapsed())NS_warn_if_impl(sel->IsCollapsed(), "sel->IsCollapsed()"
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2493)
) {
2494 return NS_OK;
2495 }
2496 }
2497
2498 // call the copy code
2499 return nsCopySupport::GetContents(nsDependentCString(mimeType), 0, sel,
2500 mDocument, aOutValue);
2501}
2502
2503NS_IMETHODIMPnsresult nsDocumentViewer::GetCanGetContents(bool* aCanGetContents) {
2504 NS_ENSURE_ARG_POINTER(aCanGetContents)do { if ((__builtin_expect(!!(!(aCanGetContents)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aCanGetContents" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2504); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2505 *aCanGetContents = false;
2506 NS_ENSURE_STATE(mDocument)do { if ((__builtin_expect(!!(!(mDocument)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mDocument" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2506); return NS_ERROR_UNEXPECTED; } } while (false)
;
2507 *aCanGetContents = nsCopySupport::CanCopy(mDocument);
2508 return NS_OK;
2509}
2510
2511NS_IMETHODIMPnsresult nsDocumentViewer::SetCommandNode(nsINode* aNode) {
2512 Document* document = GetDocument();
2513 NS_ENSURE_STATE(document)do { if ((__builtin_expect(!!(!(document)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "document" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2513); return NS_ERROR_UNEXPECTED; } } while (false)
;
2514
2515 nsCOMPtr<nsPIDOMWindowOuter> window(document->GetWindow());
2516 NS_ENSURE_TRUE(window, NS_ERROR_NOT_AVAILABLE)do { if ((__builtin_expect(!!(!(window)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "window" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2516); return NS_ERROR_NOT_AVAILABLE; } } while (false)
;
2517
2518 nsCOMPtr<nsPIWindowRoot> root = window->GetTopWindowRoot();
2519 NS_ENSURE_STATE(root)do { if ((__builtin_expect(!!(!(root)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "root" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2519); return NS_ERROR_UNEXPECTED; } } while (false)
;
2520
2521 root->SetPopupNode(aNode);
2522 return NS_OK;
2523}
2524
2525NS_IMETHODIMPnsresult
2526nsDocumentViewer::GetDeviceFullZoomForTest(float* aDeviceFullZoom) {
2527 NS_ENSURE_ARG_POINTER(aDeviceFullZoom)do { if ((__builtin_expect(!!(!(aDeviceFullZoom)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aDeviceFullZoom" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2527); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2528 nsPresContext* pc = GetPresContext();
2529 *aDeviceFullZoom = pc ? pc->GetDeviceFullZoom() : 1.0;
2530 return NS_OK;
2531}
2532
2533NS_IMETHODIMPnsresult
2534nsDocumentViewer::SetAuthorStyleDisabled(bool aStyleDisabled) {
2535 if (mPresShell) {
2536 mPresShell->SetAuthorStyleDisabled(aStyleDisabled);
2537 }
2538 return NS_OK;
2539}
2540
2541NS_IMETHODIMPnsresult
2542nsDocumentViewer::GetAuthorStyleDisabled(bool* aStyleDisabled) {
2543 if (mPresShell) {
2544 *aStyleDisabled = mPresShell->GetAuthorStyleDisabled();
2545 } else {
2546 *aStyleDisabled = false;
2547 }
2548 return NS_OK;
2549}
2550
2551/* [noscript,notxpcom] Encoding getHintCharset (); */
2552NS_IMETHODIMP_(const Encoding*)const Encoding*
2553nsDocumentViewer::GetReloadEncodingAndSource(int32_t* aSource) {
2554 *aSource = mReloadEncodingSource;
2555 if (kCharsetUninitialized == mReloadEncodingSource) {
2556 return nullptr;
2557 }
2558 return mReloadEncoding;
2559}
2560
2561NS_IMETHODIMP_(void)void
2562nsDocumentViewer::SetReloadEncodingAndSource(const Encoding* aEncoding,
2563 int32_t aSource) {
2564 MOZ_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aSource == kCharsetUninitialized || (aSource >= kCharsetFromFinalAutoDetectionWouldHaveBeenUTF8InitialWasASCII
&& aSource <= kCharsetFromFinalAutoDetectionWouldNotHaveBeenUTF8DependedOnTLDInitialWasASCII
) || aSource == kCharsetFromFinalUserForcedAutoDetection)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(aSource == kCharsetUninitialized || (aSource >= kCharsetFromFinalAutoDetectionWouldHaveBeenUTF8InitialWasASCII
&& aSource <= kCharsetFromFinalAutoDetectionWouldNotHaveBeenUTF8DependedOnTLDInitialWasASCII
) || aSource == kCharsetFromFinalUserForcedAutoDetection))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("aSource == kCharsetUninitialized || (aSource >= kCharsetFromFinalAutoDetectionWouldHaveBeenUTF8InitialWasASCII && aSource <= kCharsetFromFinalAutoDetectionWouldNotHaveBeenUTF8DependedOnTLDInitialWasASCII) || aSource == kCharsetFromFinalUserForcedAutoDetection"
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2570); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aSource == kCharsetUninitialized || (aSource >= kCharsetFromFinalAutoDetectionWouldHaveBeenUTF8InitialWasASCII && aSource <= kCharsetFromFinalAutoDetectionWouldNotHaveBeenUTF8DependedOnTLDInitialWasASCII) || aSource == kCharsetFromFinalUserForcedAutoDetection"
")"); do { *((volatile int*)__null) = 2570; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2565 aSource == kCharsetUninitialized ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aSource == kCharsetUninitialized || (aSource >= kCharsetFromFinalAutoDetectionWouldHaveBeenUTF8InitialWasASCII
&& aSource <= kCharsetFromFinalAutoDetectionWouldNotHaveBeenUTF8DependedOnTLDInitialWasASCII
) || aSource == kCharsetFromFinalUserForcedAutoDetection)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(aSource == kCharsetUninitialized || (aSource >= kCharsetFromFinalAutoDetectionWouldHaveBeenUTF8InitialWasASCII
&& aSource <= kCharsetFromFinalAutoDetectionWouldNotHaveBeenUTF8DependedOnTLDInitialWasASCII
) || aSource == kCharsetFromFinalUserForcedAutoDetection))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("aSource == kCharsetUninitialized || (aSource >= kCharsetFromFinalAutoDetectionWouldHaveBeenUTF8InitialWasASCII && aSource <= kCharsetFromFinalAutoDetectionWouldNotHaveBeenUTF8DependedOnTLDInitialWasASCII) || aSource == kCharsetFromFinalUserForcedAutoDetection"
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2570); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aSource == kCharsetUninitialized || (aSource >= kCharsetFromFinalAutoDetectionWouldHaveBeenUTF8InitialWasASCII && aSource <= kCharsetFromFinalAutoDetectionWouldNotHaveBeenUTF8DependedOnTLDInitialWasASCII) || aSource == kCharsetFromFinalUserForcedAutoDetection"
")"); do { *((volatile int*)__null) = 2570; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2566 (aSource >=do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aSource == kCharsetUninitialized || (aSource >= kCharsetFromFinalAutoDetectionWouldHaveBeenUTF8InitialWasASCII
&& aSource <= kCharsetFromFinalAutoDetectionWouldNotHaveBeenUTF8DependedOnTLDInitialWasASCII
) || aSource == kCharsetFromFinalUserForcedAutoDetection)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(aSource == kCharsetUninitialized || (aSource >= kCharsetFromFinalAutoDetectionWouldHaveBeenUTF8InitialWasASCII
&& aSource <= kCharsetFromFinalAutoDetectionWouldNotHaveBeenUTF8DependedOnTLDInitialWasASCII
) || aSource == kCharsetFromFinalUserForcedAutoDetection))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("aSource == kCharsetUninitialized || (aSource >= kCharsetFromFinalAutoDetectionWouldHaveBeenUTF8InitialWasASCII && aSource <= kCharsetFromFinalAutoDetectionWouldNotHaveBeenUTF8DependedOnTLDInitialWasASCII) || aSource == kCharsetFromFinalUserForcedAutoDetection"
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2570); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aSource == kCharsetUninitialized || (aSource >= kCharsetFromFinalAutoDetectionWouldHaveBeenUTF8InitialWasASCII && aSource <= kCharsetFromFinalAutoDetectionWouldNotHaveBeenUTF8DependedOnTLDInitialWasASCII) || aSource == kCharsetFromFinalUserForcedAutoDetection"
")"); do { *((volatile int*)__null) = 2570; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2567 kCharsetFromFinalAutoDetectionWouldHaveBeenUTF8InitialWasASCII &&do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aSource == kCharsetUninitialized || (aSource >= kCharsetFromFinalAutoDetectionWouldHaveBeenUTF8InitialWasASCII
&& aSource <= kCharsetFromFinalAutoDetectionWouldNotHaveBeenUTF8DependedOnTLDInitialWasASCII
) || aSource == kCharsetFromFinalUserForcedAutoDetection)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(aSource == kCharsetUninitialized || (aSource >= kCharsetFromFinalAutoDetectionWouldHaveBeenUTF8InitialWasASCII
&& aSource <= kCharsetFromFinalAutoDetectionWouldNotHaveBeenUTF8DependedOnTLDInitialWasASCII
) || aSource == kCharsetFromFinalUserForcedAutoDetection))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("aSource == kCharsetUninitialized || (aSource >= kCharsetFromFinalAutoDetectionWouldHaveBeenUTF8InitialWasASCII && aSource <= kCharsetFromFinalAutoDetectionWouldNotHaveBeenUTF8DependedOnTLDInitialWasASCII) || aSource == kCharsetFromFinalUserForcedAutoDetection"
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2570); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aSource == kCharsetUninitialized || (aSource >= kCharsetFromFinalAutoDetectionWouldHaveBeenUTF8InitialWasASCII && aSource <= kCharsetFromFinalAutoDetectionWouldNotHaveBeenUTF8DependedOnTLDInitialWasASCII) || aSource == kCharsetFromFinalUserForcedAutoDetection"
")"); do { *((volatile int*)__null) = 2570; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2568 aSource <=do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aSource == kCharsetUninitialized || (aSource >= kCharsetFromFinalAutoDetectionWouldHaveBeenUTF8InitialWasASCII
&& aSource <= kCharsetFromFinalAutoDetectionWouldNotHaveBeenUTF8DependedOnTLDInitialWasASCII
) || aSource == kCharsetFromFinalUserForcedAutoDetection)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(aSource == kCharsetUninitialized || (aSource >= kCharsetFromFinalAutoDetectionWouldHaveBeenUTF8InitialWasASCII
&& aSource <= kCharsetFromFinalAutoDetectionWouldNotHaveBeenUTF8DependedOnTLDInitialWasASCII
) || aSource == kCharsetFromFinalUserForcedAutoDetection))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("aSource == kCharsetUninitialized || (aSource >= kCharsetFromFinalAutoDetectionWouldHaveBeenUTF8InitialWasASCII && aSource <= kCharsetFromFinalAutoDetectionWouldNotHaveBeenUTF8DependedOnTLDInitialWasASCII) || aSource == kCharsetFromFinalUserForcedAutoDetection"
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2570); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aSource == kCharsetUninitialized || (aSource >= kCharsetFromFinalAutoDetectionWouldHaveBeenUTF8InitialWasASCII && aSource <= kCharsetFromFinalAutoDetectionWouldNotHaveBeenUTF8DependedOnTLDInitialWasASCII) || aSource == kCharsetFromFinalUserForcedAutoDetection"
")"); do { *((volatile int*)__null) = 2570; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2569 kCharsetFromFinalAutoDetectionWouldNotHaveBeenUTF8DependedOnTLDInitialWasASCII) ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aSource == kCharsetUninitialized || (aSource >= kCharsetFromFinalAutoDetectionWouldHaveBeenUTF8InitialWasASCII
&& aSource <= kCharsetFromFinalAutoDetectionWouldNotHaveBeenUTF8DependedOnTLDInitialWasASCII
) || aSource == kCharsetFromFinalUserForcedAutoDetection)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(aSource == kCharsetUninitialized || (aSource >= kCharsetFromFinalAutoDetectionWouldHaveBeenUTF8InitialWasASCII
&& aSource <= kCharsetFromFinalAutoDetectionWouldNotHaveBeenUTF8DependedOnTLDInitialWasASCII
) || aSource == kCharsetFromFinalUserForcedAutoDetection))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("aSource == kCharsetUninitialized || (aSource >= kCharsetFromFinalAutoDetectionWouldHaveBeenUTF8InitialWasASCII && aSource <= kCharsetFromFinalAutoDetectionWouldNotHaveBeenUTF8DependedOnTLDInitialWasASCII) || aSource == kCharsetFromFinalUserForcedAutoDetection"
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2570); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aSource == kCharsetUninitialized || (aSource >= kCharsetFromFinalAutoDetectionWouldHaveBeenUTF8InitialWasASCII && aSource <= kCharsetFromFinalAutoDetectionWouldNotHaveBeenUTF8DependedOnTLDInitialWasASCII) || aSource == kCharsetFromFinalUserForcedAutoDetection"
")"); do { *((volatile int*)__null) = 2570; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2570 aSource == kCharsetFromFinalUserForcedAutoDetection)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aSource == kCharsetUninitialized || (aSource >= kCharsetFromFinalAutoDetectionWouldHaveBeenUTF8InitialWasASCII
&& aSource <= kCharsetFromFinalAutoDetectionWouldNotHaveBeenUTF8DependedOnTLDInitialWasASCII
) || aSource == kCharsetFromFinalUserForcedAutoDetection)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(aSource == kCharsetUninitialized || (aSource >= kCharsetFromFinalAutoDetectionWouldHaveBeenUTF8InitialWasASCII
&& aSource <= kCharsetFromFinalAutoDetectionWouldNotHaveBeenUTF8DependedOnTLDInitialWasASCII
) || aSource == kCharsetFromFinalUserForcedAutoDetection))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("aSource == kCharsetUninitialized || (aSource >= kCharsetFromFinalAutoDetectionWouldHaveBeenUTF8InitialWasASCII && aSource <= kCharsetFromFinalAutoDetectionWouldNotHaveBeenUTF8DependedOnTLDInitialWasASCII) || aSource == kCharsetFromFinalUserForcedAutoDetection"
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2570); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aSource == kCharsetUninitialized || (aSource >= kCharsetFromFinalAutoDetectionWouldHaveBeenUTF8InitialWasASCII && aSource <= kCharsetFromFinalAutoDetectionWouldNotHaveBeenUTF8DependedOnTLDInitialWasASCII) || aSource == kCharsetFromFinalUserForcedAutoDetection"
")"); do { *((volatile int*)__null) = 2570; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2571 mReloadEncoding = aEncoding;
2572 mReloadEncodingSource = aSource;
2573}
2574
2575NS_IMETHODIMP_(void)void
2576nsDocumentViewer::ForgetReloadEncoding() {
2577 mReloadEncoding = nullptr;
2578 mReloadEncodingSource = kCharsetUninitialized;
2579}
2580
2581MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMPnsresult nsDocumentViewer::GetContentSize(
2582 int32_t aMaxWidth, int32_t aMaxHeight, int32_t aPrefWidth, int32_t* aWidth,
2583 int32_t* aHeight) {
2584 NS_ENSURE_STATE(mContainer)do { if ((__builtin_expect(!!(!(mContainer)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mContainer" ") failed",
nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2584); return NS_ERROR_UNEXPECTED; } } while (false)
;
2585
2586 RefPtr<BrowsingContext> bc = mContainer->GetBrowsingContext();
2587 NS_ENSURE_TRUE(bc, NS_ERROR_NOT_AVAILABLE)do { if ((__builtin_expect(!!(!(bc)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "bc" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2587); return NS_ERROR_NOT_AVAILABLE; } } while (false)
;
2588
2589 // It's only valid to access this from a top frame. Doesn't work from
2590 // sub-frames.
2591 NS_ENSURE_TRUE(bc->IsTop(), NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(bc->IsTop())), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "bc->IsTop()" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2591); return NS_ERROR_FAILURE; } } while (false)
;
2592
2593 // Convert max-width/height and pref-width to app units.
2594 if (aMaxWidth > 0) {
2595 aMaxWidth = CSSPixel::ToAppUnits(aMaxWidth);
2596 } else {
2597 aMaxWidth = NS_UNCONSTRAINEDSIZE;
2598 }
2599 if (aMaxHeight > 0) {
2600 aMaxHeight = CSSPixel::ToAppUnits(aMaxHeight);
2601 } else {
2602 aMaxHeight = NS_UNCONSTRAINEDSIZE;
2603 }
2604 if (aPrefWidth > 0) {
2605 aPrefWidth = CSSPixel::ToAppUnits(aPrefWidth);
2606 } else {
2607 aPrefWidth = 0;
2608 }
2609
2610 RefPtr<PresShell> presShell = GetPresShell();
2611 NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(presShell)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "presShell" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2611); return NS_ERROR_FAILURE; } } while (false)
;
2612
2613 // Flush out all content and style updates. We can't use a resize reflow
2614 // because it won't change some sizes that a style change reflow will.
2615 mDocument->FlushPendingNotifications(FlushType::Layout);
2616
2617 nsIFrame* root = presShell->GetRootFrame();
2618 NS_ENSURE_TRUE(root, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(root)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "root" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2618); return NS_ERROR_FAILURE; } } while (false)
;
2619
2620 WritingMode wm = root->GetWritingMode();
2621
2622 nscoord prefISize;
2623 {
2624 const auto& constraints = presShell->GetWindowSizeConstraints();
2625 aMaxHeight = std::min(aMaxHeight, constraints.mMaxSize.height);
2626 aMaxWidth = std::min(aMaxWidth, constraints.mMaxSize.width);
2627
2628 UniquePtr<gfxContext> rcx(presShell->CreateReferenceRenderingContext());
2629 const nscoord minISize = wm.IsVertical() ? constraints.mMinSize.height
2630 : constraints.mMinSize.width;
2631 const nscoord maxISize = wm.IsVertical() ? aMaxHeight : aMaxWidth;
2632 const IntrinsicSizeInput input(rcx.get(), Nothing(), Nothing());
2633 if (aPrefWidth) {
2634 prefISize = std::max(root->GetMinISize(input), aPrefWidth);
2635 } else {
2636 prefISize = root->GetPrefISize(input);
2637 }
2638 prefISize = nsPresContext::RoundUpAppUnitsToCSSPixel(
2639 CSSMinMax(prefISize, minISize, maxISize));
2640 }
2641
2642 // We should never intentionally get here with this sentinel value, but it's
2643 // possible that a document with huge sizes might inadvertently have a
2644 // prefISize that exactly matches NS_UNCONSTRAINEDSIZE.
2645 // Just bail if that happens.
2646 NS_ENSURE_TRUE(prefISize != NS_UNCONSTRAINEDSIZE, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(prefISize != NS_UNCONSTRAINEDSIZE
)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "prefISize != NS_UNCONSTRAINEDSIZE"
") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2646); return NS_ERROR_FAILURE; } } while (false)
;
2647
2648 nscoord height = wm.IsVertical() ? prefISize : aMaxHeight;
2649 nscoord width = wm.IsVertical() ? aMaxWidth : prefISize;
2650
2651 presShell->ResizeReflow(width, height, ResizeReflowOptions::BSizeLimit);
2652
2653 RefPtr<nsPresContext> presContext = GetPresContext();
2654 NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(presContext)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "presContext" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2654); return NS_ERROR_FAILURE; } } while (false)
;
2655
2656 // Protect against bogus returns here
2657 nsRect shellArea = presContext->GetVisibleArea();
2658 NS_ENSURE_TRUE(shellArea.width != NS_UNCONSTRAINEDSIZE &&do { if ((__builtin_expect(!!(!(shellArea.width != NS_UNCONSTRAINEDSIZE
&& shellArea.height != NS_UNCONSTRAINEDSIZE)), 0))) {
NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "shellArea.width != NS_UNCONSTRAINEDSIZE && shellArea.height != NS_UNCONSTRAINEDSIZE"
") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2660); return NS_ERROR_FAILURE; } } while (false)
2659 shellArea.height != NS_UNCONSTRAINEDSIZE,do { if ((__builtin_expect(!!(!(shellArea.width != NS_UNCONSTRAINEDSIZE
&& shellArea.height != NS_UNCONSTRAINEDSIZE)), 0))) {
NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "shellArea.width != NS_UNCONSTRAINEDSIZE && shellArea.height != NS_UNCONSTRAINEDSIZE"
") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2660); return NS_ERROR_FAILURE; } } while (false)
2660 NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(shellArea.width != NS_UNCONSTRAINEDSIZE
&& shellArea.height != NS_UNCONSTRAINEDSIZE)), 0))) {
NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "shellArea.width != NS_UNCONSTRAINEDSIZE && shellArea.height != NS_UNCONSTRAINEDSIZE"
") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2660); return NS_ERROR_FAILURE; } } while (false)
;
2661
2662 // Leave our viewport in a consistent state.
2663 {
2664 auto newBounds = LayoutDeviceIntRect::FromAppUnitsToOutside(
2665 shellArea, presContext->AppUnitsPerDevPixel());
2666 newBounds.MoveTo(mBounds.TopLeft());
2667 SetBounds(newBounds);
2668 }
2669
2670 // Ceil instead of rounding here, so we can actually guarantee showing all the
2671 // content.
2672 *aWidth = std::ceil(CSSPixel::FromAppUnits(shellArea.width));
2673 *aHeight = std::ceil(CSSPixel::FromAppUnits(shellArea.height));
2674
2675 return NS_OK;
2676}
2677
2678NS_IMPL_ISUPPORTS(nsDocViewerSelectionListener, nsISelectionListener)MozExternalRefCountType nsDocViewerSelectionListener::AddRef(
void) { static_assert(!std::is_destructible_v<nsDocViewerSelectionListener
>, "Reference-counted class " "nsDocViewerSelectionListener"
" 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2678); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
2678; __attribute__((nomerge)) ::abort(); } while (false); }
} while (false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("nsDocViewerSelectionListener" != nullptr)>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!("nsDocViewerSelectionListener" != nullptr))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("\"nsDocViewerSelectionListener\" != nullptr"
" (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2678); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"nsDocViewerSelectionListener\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 2678; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("nsDocViewerSelectionListener" " not thread-safe"
); nsrefcnt count = ++mRefCnt; NS_LogAddRef((this), (count), (
"nsDocViewerSelectionListener"), (uint32_t)(sizeof(*this))); return
count; } MozExternalRefCountType nsDocViewerSelectionListener
::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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2678); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 2678
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("nsDocViewerSelectionListener" != nullptr)>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!("nsDocViewerSelectionListener" != nullptr))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("\"nsDocViewerSelectionListener\" != nullptr"
" (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2678); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"nsDocViewerSelectionListener\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 2678; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("nsDocViewerSelectionListener" " not thread-safe"
); const char* const nametmp = "nsDocViewerSelectionListener"
; nsrefcnt count = --mRefCnt; NS_LogRelease((this), (count), (
nametmp)); if (count == 0) { mRefCnt = 1; delete (this); return
0; } return count; } nsresult nsDocViewerSelectionListener::
QueryInterface(const nsIID& aIID, void** aInstancePtr) { do
{ if (!(aInstancePtr)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2678); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE
; static_assert(1 > 0, "Need more arguments to NS_INTERFACE_TABLE"
); static const QITableEntry table[] = { {&mozilla::detail
::kImplementedIID<nsDocViewerSelectionListener, nsISelectionListener
>, int32_t( reinterpret_cast<char*>(static_cast<nsISelectionListener
*>((nsDocViewerSelectionListener*)0x1000)) - reinterpret_cast
<char*>((nsDocViewerSelectionListener*)0x1000))}, {&
mozilla::detail::kImplementedIID<nsDocViewerSelectionListener
, nsISupports>, int32_t(reinterpret_cast<char*>(static_cast
<nsISupports*>( static_cast<nsISelectionListener*>
((nsDocViewerSelectionListener*)0x1000))) - reinterpret_cast<
char*>((nsDocViewerSelectionListener*)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; }
2679
2680/*
2681 * GetPopupNode, GetPopupLinkNode and GetPopupImageNode are helpers
2682 * for the cmd_copyLink / cmd_copyImageLocation / cmd_copyImageContents family
2683 * of commands. The focus controller stores the popup node, these retrieve
2684 * them and munge appropriately. Note that we have to store the popup node
2685 * rather than retrieving it from EventStateManager::GetFocusedContent because
2686 * not all content (images included) can receive focus.
2687 */
2688
2689already_AddRefed<nsINode> nsDocumentViewer::GetPopupNode() {
2690 // get the document
2691 Document* document = GetDocument();
2692 NS_ENSURE_TRUE(document, nullptr)do { if ((__builtin_expect(!!(!(document)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "document" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2692); return nullptr; } } while (false)
;
2693
2694 // get the private dom window
2695 nsCOMPtr<nsPIDOMWindowOuter> window(document->GetWindow());
2696 NS_ENSURE_TRUE(window, nullptr)do { if ((__builtin_expect(!!(!(window)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "window" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2696); return nullptr; } } while (false)
;
2697 if (window) {
2698 nsCOMPtr<nsPIWindowRoot> root = window->GetTopWindowRoot();
2699 NS_ENSURE_TRUE(root, nullptr)do { if ((__builtin_expect(!!(!(root)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "root" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2699); return nullptr; } } while (false)
;
2700
2701 // get the popup node
2702 nsCOMPtr<nsINode> node = root->GetPopupNode();
2703 if (!node) {
2704 nsPIDOMWindowOuter* rootWindow = root->GetWindow();
2705 if (rootWindow) {
2706 nsCOMPtr<Document> rootDoc = rootWindow->GetExtantDoc();
2707 if (rootDoc) {
2708 nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
2709 if (pm) {
2710 node = pm->GetLastTriggerPopupNode(rootDoc);
2711 }
2712 }
2713 }
2714 }
2715 return node.forget();
2716 }
2717
2718 return nullptr;
2719}
2720
2721// GetPopupLinkNode: return popup link node or fail
2722already_AddRefed<nsINode> nsDocumentViewer::GetPopupLinkNode() {
2723 // find popup node
2724 nsCOMPtr<nsINode> node = GetPopupNode();
2725
2726 // find out if we have a link in our ancestry
2727 while (node) {
2728 if (const auto* element = Element::FromNode(*node)) {
2729 if (element->IsLink()) {
2730 return node.forget();
2731 }
2732 }
2733
2734 // get our parent and keep trying...
2735 node = node->GetParentNode();
2736 }
2737
2738 // if we have no node, fail
2739 return nullptr;
2740}
2741
2742// GetPopupLinkNode: return popup image node or fail
2743already_AddRefed<nsIImageLoadingContent> nsDocumentViewer::GetPopupImageNode() {
2744 // find popup node
2745 nsCOMPtr<nsINode> node = GetPopupNode();
2746 nsCOMPtr<nsIImageLoadingContent> img = do_QueryInterface(node);
2747 return img.forget();
2748}
2749
2750/*
2751 * XXX dr
2752 * ------
2753 * These two functions -- GetInLink and GetInImage -- are kind of annoying
2754 * in that they only get called from the controller (in
2755 * nsDOMWindowController::IsCommandEnabled). The actual construction of the
2756 * context menus in communicator (nsContextMenu.js) has its own, redundant
2757 * tests. No big deal, but good to keep in mind if we ever clean context
2758 * menus.
2759 */
2760
2761NS_IMETHODIMPnsresult nsDocumentViewer::GetInLink(bool* aInLink) {
2762#ifdef DEBUG_dr
2763 printf("dr :: nsDocumentViewer::GetInLink\n");
2764#endif
2765
2766 NS_ENSURE_ARG_POINTER(aInLink)do { if ((__builtin_expect(!!(!(aInLink)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aInLink" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2766); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2767
2768 // we're not in a link unless i say so
2769 *aInLink = false;
2770
2771 // get the popup link
2772 nsCOMPtr<nsINode> node = GetPopupLinkNode();
2773 if (!node) {
2774 return NS_ERROR_FAILURE;
2775 }
2776
2777 // if we made it here, we're in a link
2778 *aInLink = true;
2779 return NS_OK;
2780}
2781
2782NS_IMETHODIMPnsresult nsDocumentViewer::GetInImage(bool* aInImage) {
2783#ifdef DEBUG_dr
2784 printf("dr :: nsDocumentViewer::GetInImage\n");
2785#endif
2786
2787 NS_ENSURE_ARG_POINTER(aInImage)do { if ((__builtin_expect(!!(!(aInImage)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aInImage" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2787); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2788
2789 // we're not in an image unless i say so
2790 *aInImage = false;
2791
2792 // get the popup image
2793 nsCOMPtr<nsIImageLoadingContent> node = GetPopupImageNode();
2794 if (!node) {
2795 return NS_ERROR_FAILURE;
2796 }
2797
2798 // Make sure there is a URI assigned. This allows <input type="image"> to
2799 // be an image but rejects other <input> types. This matches what
2800 // nsContextMenu.js does.
2801 nsCOMPtr<nsIURI> uri;
2802 node->GetCurrentURI(getter_AddRefs(uri));
2803 if (uri) {
2804 // if we made it here, we're in an image
2805 *aInImage = true;
2806 }
2807
2808 return NS_OK;
2809}
2810
2811NS_IMETHODIMPnsresult nsDocViewerSelectionListener::NotifySelectionChanged(
2812 Document*, Selection*, int16_t aReason, int32_t aAmount) {
2813 if (!mDocViewer) {
2814 return NS_OK;
2815 }
2816
2817 // get the selection state
2818 RefPtr<mozilla::dom::Selection> selection =
2819 mDocViewer->GetDocumentSelection();
2820 if (!selection) {
2821 return NS_ERROR_FAILURE;
2822 }
2823
2824 Document* theDoc = mDocViewer->GetDocument();
2825 if (!theDoc) {
2826 return NS_ERROR_FAILURE;
2827 }
2828
2829 nsCOMPtr<nsPIDOMWindowOuter> domWindow = theDoc->GetWindow();
2830 if (!domWindow) {
2831 return NS_ERROR_FAILURE;
2832 }
2833
2834 bool selectionCollapsed = selection->IsCollapsed();
2835 // We only call UpdateCommands when the selection changes from collapsed to
2836 // non-collapsed or vice versa, however we skip the initializing collapse. We
2837 // might need another update string for simple selection changes, but that
2838 // would be expenseive.
2839 if (mSelectionWasCollapsed != selectionCollapsed) {
2840 domWindow->UpdateCommands(u"select"_ns);
2841 mSelectionWasCollapsed = selectionCollapsed;
2842 }
2843
2844 return NS_OK;
2845}
2846
2847// nsDocViewerFocusListener
2848NS_IMPL_ISUPPORTS(nsDocViewerFocusListener, nsIDOMEventListener)MozExternalRefCountType nsDocViewerFocusListener::AddRef(void
) { static_assert(!std::is_destructible_v<nsDocViewerFocusListener
>, "Reference-counted class " "nsDocViewerFocusListener" " 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2848); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
2848; __attribute__((nomerge)) ::abort(); } while (false); }
} while (false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("nsDocViewerFocusListener" != nullptr)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!("nsDocViewerFocusListener" != nullptr))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("\"nsDocViewerFocusListener\" != nullptr"
" (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2848); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"nsDocViewerFocusListener\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 2848; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("nsDocViewerFocusListener" " not thread-safe"
); nsrefcnt count = ++mRefCnt; NS_LogAddRef((this), (count), (
"nsDocViewerFocusListener"), (uint32_t)(sizeof(*this))); return
count; } MozExternalRefCountType nsDocViewerFocusListener::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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2848); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 2848
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("nsDocViewerFocusListener" != nullptr)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!("nsDocViewerFocusListener" != nullptr))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("\"nsDocViewerFocusListener\" != nullptr"
" (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2848); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"nsDocViewerFocusListener\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 2848; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("nsDocViewerFocusListener" " not thread-safe"
); const char* const nametmp = "nsDocViewerFocusListener"; nsrefcnt
count = --mRefCnt; NS_LogRelease((this), (count), (nametmp))
; if (count == 0) { mRefCnt = 1; delete (this); return 0; } return
count; } nsresult nsDocViewerFocusListener::QueryInterface(const
nsIID& aIID, void** aInstancePtr) { do { if (!(aInstancePtr
)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2848); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE
; static_assert(1 > 0, "Need more arguments to NS_INTERFACE_TABLE"
); static const QITableEntry table[] = { {&mozilla::detail
::kImplementedIID<nsDocViewerFocusListener, nsIDOMEventListener
>, int32_t( reinterpret_cast<char*>(static_cast<nsIDOMEventListener
*>((nsDocViewerFocusListener*)0x1000)) - reinterpret_cast<
char*>((nsDocViewerFocusListener*)0x1000))}, {&mozilla
::detail::kImplementedIID<nsDocViewerFocusListener, nsISupports
>, int32_t(reinterpret_cast<char*>(static_cast<nsISupports
*>( static_cast<nsIDOMEventListener*>((nsDocViewerFocusListener
*)0x1000))) - reinterpret_cast<char*>((nsDocViewerFocusListener
*)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; }
2849
2850nsresult nsDocViewerFocusListener::HandleEvent(Event* aEvent) {
2851 NS_ENSURE_STATE(mDocViewer)do { if ((__builtin_expect(!!(!(mDocViewer)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mDocViewer" ") failed",
nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2851); return NS_ERROR_UNEXPECTED; } } while (false)
;
2852
2853 RefPtr<PresShell> presShell = mDocViewer->GetPresShell();
2854 NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(presShell)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "presShell" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2854); return NS_ERROR_FAILURE; } } while (false)
;
2855
2856 RefPtr<nsFrameSelection> selection =
2857 presShell->GetLastFocusedFrameSelection();
2858 NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(selection)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "selection" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2858); return NS_ERROR_FAILURE; } } while (false)
;
2859 auto selectionStatus = selection->GetDisplaySelection();
2860 nsAutoString eventType;
2861 aEvent->GetType(eventType);
2862 if (eventType.EqualsLiteral("focus")) {
2863 // If selection was disabled, re-enable it.
2864 if (selectionStatus == nsISelectionController::SELECTION_DISABLED ||
2865 selectionStatus == nsISelectionController::SELECTION_HIDDEN) {
2866 selection->SetDisplaySelection(nsISelectionController::SELECTION_ON);
2867 selection->RepaintSelection(SelectionType::eNormal);
2868 }
2869 // See EditorBase::FinalizeSelection. This fixes up the case where focus
2870 // left the editor's selection but returned to something else.
2871 if (selection != presShell->ConstFrameSelection()) {
2872 RefPtr<Document> doc = presShell->GetDocument();
2873 const bool selectionMatchesFocus =
2874 selection->GetLimiter() &&
2875 selection->GetLimiter()->GetChromeOnlyAccessSubtreeRootParent() ==
2876 doc->GetUnretargetedFocusedContent();
2877 if (NS_WARN_IF(!selectionMatchesFocus)NS_warn_if_impl(!selectionMatchesFocus, "!selectionMatchesFocus"
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2877)
) {
2878 presShell->FrameSelectionWillLoseFocus(*selection);
2879 presShell->SelectionWillTakeFocus();
2880 }
2881 }
2882 } else {
2883 MOZ_ASSERT(eventType.EqualsLiteral("blur"), "Unexpected event type")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(eventType.EqualsLiteral("blur"))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(eventType.EqualsLiteral("blur"
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("eventType.EqualsLiteral(\"blur\")" " (" "Unexpected event type"
")", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2883); AnnotateMozCrashReason("MOZ_ASSERT" "(" "eventType.EqualsLiteral(\"blur\")"
") (" "Unexpected event type" ")"); do { *((volatile int*)__null
) = 2883; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false)
;
2884 // If selection was on, disable it.
2885 if (selectionStatus == nsISelectionController::SELECTION_ON ||
2886 selectionStatus == nsISelectionController::SELECTION_ATTENTION) {
2887 selection->SetDisplaySelection(
2888 nsISelectionController::SELECTION_DISABLED);
2889 selection->RepaintSelection(SelectionType::eNormal);
2890 }
2891 }
2892
2893 return NS_OK;
2894}
2895
2896/** ---------------------------------------------------
2897 * From nsIWebBrowserPrint
2898 */
2899
2900#ifdef NS_PRINTING1
2901
2902NS_IMETHODIMPnsresult
2903nsDocumentViewer::Print(nsIPrintSettings* aPrintSettings,
2904 RemotePrintJobChild* aRemotePrintJob,
2905 nsIWebProgressListener* aWebProgressListener) {
2906 if (NS_WARN_IF(!mContainer)NS_warn_if_impl(!mContainer, "!mContainer", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2906)
) {
2907 PR_PL(("Container was destroyed yet we are still trying to use it!"))do { const ::mozilla::LogModule* moz_real_module = gPrintingLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, "Container was destroyed yet we are still trying to use it!"
); } } while (0);
;
2908 return NS_ERROR_FAILURE;
2909 }
2910
2911 if (NS_WARN_IF(!mDocument)NS_warn_if_impl(!mDocument, "!mDocument", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2911)
|| NS_WARN_IF(!mDeviceContext)NS_warn_if_impl(!mDeviceContext, "!mDeviceContext", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2911)
) {
2912 PR_PL(("Can't Print without a document and a device context"))do { const ::mozilla::LogModule* moz_real_module = gPrintingLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, "Can't Print without a document and a device context"
); } } while (0);
;
2913 return NS_ERROR_FAILURE;
2914 }
2915
2916 if (NS_WARN_IF(mPrintJob && mPrintJob->GetIsPrinting())NS_warn_if_impl(mPrintJob && mPrintJob->GetIsPrinting
(), "mPrintJob && mPrintJob->GetIsPrinting()", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2916)
) {
2917 // If we are printing another URL, then exit.
2918 // The reason we check here is because this method can be called while
2919 // another is still in here (the printing dialog is a good example). the
2920 // only time we can print more than one job at a time is the regression
2921 // tests.
2922 nsresult rv = NS_ERROR_NOT_AVAILABLE;
2923 RefPtr<nsPrintJob>(mPrintJob)->FirePrintingErrorEvent(rv);
2924 return rv;
2925 }
2926
2927 OnDonePrinting();
2928
2929 // Note: mContainer and mDocument are known to be non-null via null-checks
2930 // earlier in this function.
2931 // TODO(dholbert) Do we need to bother with this stack-owned local RefPtr?
2932 // (Is there an edge case where it's needed to keep the nsPrintJob alive?)
2933 auto printJob =
2934 MakeRefPtr<nsPrintJob>(*this, *mContainer, *mDocument,
2935 float(AppUnitsPerCSSInch()) /
2936 float(mDeviceContext->AppUnitsPerDevPixel()));
2937 mPrintJob = printJob;
2938
2939 nsresult rv = printJob->Print(*mDocument, aPrintSettings, aRemotePrintJob,
2940 aWebProgressListener);
2941 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2941)
) {
2942 OnDonePrinting();
2943 }
2944 return rv;
2945}
2946
2947NS_IMETHODIMPnsresult
2948nsDocumentViewer::PrintPreview(nsIPrintSettings* aPrintSettings,
2949 nsIWebProgressListener* aWebProgressListener,
2950 PrintPreviewResolver&& aCallback) {
2951# ifdef NS_PRINT_PREVIEW1
2952 RefPtr<Document> doc = mDocument.get();
2953 NS_ENSURE_STATE(doc)do { if ((__builtin_expect(!!(!(doc)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "doc" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2953); return NS_ERROR_UNEXPECTED; } } while (false)
;
2954
2955 if (NS_WARN_IF(GetIsPrinting())NS_warn_if_impl(GetIsPrinting(), "GetIsPrinting()", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2955)
) {
2956 return NS_ERROR_FAILURE;
2957 }
2958
2959 nsCOMPtr<nsIDocShell> docShell(mContainer);
2960 if (NS_WARN_IF(!docShell)NS_warn_if_impl(!docShell, "!docShell", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2960)
|| NS_WARN_IF(!mDeviceContext)NS_warn_if_impl(!mDeviceContext, "!mDeviceContext", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2960)
) {
2961 PR_PL(("Can't Print Preview without device context and docshell"))do { const ::mozilla::LogModule* moz_real_module = gPrintingLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, "Can't Print Preview without device context and docshell"
); } } while (0);
;
2962 return NS_ERROR_FAILURE;
2963 }
2964
2965 NS_ENSURE_STATE(!GetIsPrinting())do { if ((__builtin_expect(!!(!(!GetIsPrinting())), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "!GetIsPrinting()" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2965); return NS_ERROR_UNEXPECTED; } } while (false)
;
2966 // beforeprint event may have caused DocumentViewer to be shutdown.
2967 NS_ENSURE_STATE(mContainer)do { if ((__builtin_expect(!!(!(mContainer)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mContainer" ") failed",
nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2967); return NS_ERROR_UNEXPECTED; } } while (false)
;
2968 NS_ENSURE_STATE(mDeviceContext)do { if ((__builtin_expect(!!(!(mDeviceContext)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mDeviceContext" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2968); return NS_ERROR_UNEXPECTED; } } while (false)
;
2969
2970 OnDonePrinting();
2971
2972 // Note: mContainer and doc are known to be non-null via null-checks earlier
2973 // in this function.
2974 // TODO(dholbert) Do we need to bother with this stack-owned local RefPtr?
2975 // (Is there an edge case where it's needed to keep the nsPrintJob alive?)
2976 auto printJob =
2977 MakeRefPtr<nsPrintJob>(*this, *mContainer, *doc,
2978 float(AppUnitsPerCSSInch()) /
2979 float(mDeviceContext->AppUnitsPerDevPixel()));
2980 mPrintJob = printJob;
2981
2982 nsresult rv = printJob->PrintPreview(
2983 *doc, aPrintSettings, aWebProgressListener, std::move(aCallback));
2984 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2984)
) {
2985 OnDonePrinting();
2986 }
2987 return rv;
2988# else
2989 return NS_ERROR_FAILURE;
2990# endif // NS_PRINT_PREVIEW
2991}
2992
2993static const nsIFrame* GetTargetPageFrame(int32_t aTargetPageNum,
2994 nsPageSequenceFrame* aSequenceFrame) {
2995 MOZ_ASSERT(aTargetPageNum > 0 &&do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aTargetPageNum > 0 && aTargetPageNum <=
aSequenceFrame->PrincipalChildList().GetLength())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(aTargetPageNum > 0 && aTargetPageNum <= aSequenceFrame
->PrincipalChildList().GetLength()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aTargetPageNum > 0 && aTargetPageNum <= aSequenceFrame->PrincipalChildList().GetLength()"
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2997); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aTargetPageNum > 0 && aTargetPageNum <= aSequenceFrame->PrincipalChildList().GetLength()"
")"); do { *((volatile int*)__null) = 2997; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2996 aTargetPageNum <=do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aTargetPageNum > 0 && aTargetPageNum <=
aSequenceFrame->PrincipalChildList().GetLength())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(aTargetPageNum > 0 && aTargetPageNum <= aSequenceFrame
->PrincipalChildList().GetLength()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aTargetPageNum > 0 && aTargetPageNum <= aSequenceFrame->PrincipalChildList().GetLength()"
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2997); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aTargetPageNum > 0 && aTargetPageNum <= aSequenceFrame->PrincipalChildList().GetLength()"
")"); do { *((volatile int*)__null) = 2997; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2997 aSequenceFrame->PrincipalChildList().GetLength())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aTargetPageNum > 0 && aTargetPageNum <=
aSequenceFrame->PrincipalChildList().GetLength())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(aTargetPageNum > 0 && aTargetPageNum <= aSequenceFrame
->PrincipalChildList().GetLength()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aTargetPageNum > 0 && aTargetPageNum <= aSequenceFrame->PrincipalChildList().GetLength()"
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 2997); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aTargetPageNum > 0 && aTargetPageNum <= aSequenceFrame->PrincipalChildList().GetLength()"
")"); do { *((volatile int*)__null) = 2997; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2998 return aSequenceFrame->PrincipalChildList().FrameAt(aTargetPageNum - 1);
2999}
3000
3001// Calculate the scroll position where the center of |aFrame| is positioned at
3002// the center of |aScrollContainerFrame|'s scroll port for the print preview.
3003// So what we do for that is;
3004// 1) Calculate the position of the center of |aFrame| in the print preview
3005// coordinates.
3006// 2) Reduce the half height of the scroll port from the result of 1.
3007static nscoord ScrollPositionForFrame(
3008 const nsIFrame* aFrame, ScrollContainerFrame* aScrollContainerFrame,
3009 float aPreviewScale) {
3010 // Note that even if the computed scroll position is out of the range of
3011 // the scroll port, it gets clamped in ScrollContainerFrame::ScrollTo.
3012 return nscoord(aPreviewScale * aFrame->GetRect().Center().y -
3013 float(aScrollContainerFrame->GetScrollPortRect().height) /
3014 2.0f);
3015}
3016
3017//----------------------------------------------------------------------
3018NS_IMETHODIMPnsresult
3019nsDocumentViewer::PrintPreviewScrollToPage(int16_t aType, int32_t aPageNum) {
3020 if (!GetIsPrintPreview() || mPrintJob->GetIsCreatingPrintPreview()) {
3021 return NS_ERROR_FAILURE;
3022 }
3023
3024 ScrollContainerFrame* sf = mPresShell->GetRootScrollContainerFrame();
3025 if (!sf) {
3026 return NS_OK;
3027 }
3028
3029 auto [seqFrame, sheetCount] = mPrintJob->GetSeqFrameAndCountSheets();
3030 Unused << sheetCount;
3031 if (!seqFrame) {
3032 return NS_ERROR_FAILURE;
3033 }
3034
3035 float previewScale = seqFrame->GetPrintPreviewScale();
3036
3037 nsPoint dest = sf->GetScrollPosition();
3038
3039 switch (aType) {
3040 case nsIWebBrowserPrint::PRINTPREVIEW_HOME:
3041 dest.y = 0;
3042 break;
3043 case nsIWebBrowserPrint::PRINTPREVIEW_END:
3044 dest.y = sf->GetScrollRange().YMost();
3045 break;
3046 case nsIWebBrowserPrint::PRINTPREVIEW_PREV_PAGE:
3047 case nsIWebBrowserPrint::PRINTPREVIEW_NEXT_PAGE: {
3048 auto [currentFrame, currentSheetNumber] = GetCurrentSheetFrameAndNumber();
3049 Unused << currentSheetNumber;
3050 if (!currentFrame) {
3051 return NS_OK;
3052 }
3053
3054 const nsIFrame* targetFrame = nullptr;
3055 if (aType == nsIWebBrowserPrint::PRINTPREVIEW_PREV_PAGE) {
3056 targetFrame = currentFrame->GetPrevInFlow();
3057 } else {
3058 targetFrame = currentFrame->GetNextInFlow();
3059 }
3060 if (!targetFrame) {
3061 return NS_OK;
3062 }
3063
3064 dest.y = ScrollPositionForFrame(targetFrame, sf, previewScale);
3065 break;
3066 }
3067 case nsIWebBrowserPrint::PRINTPREVIEW_GOTO_PAGENUM: {
3068 if (aPageNum <= 0 || aPageNum > sheetCount) {
3069 return NS_ERROR_INVALID_ARG;
3070 }
3071
3072 const nsIFrame* targetFrame = GetTargetPageFrame(aPageNum, seqFrame);
3073 MOZ_ASSERT(targetFrame)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(targetFrame)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(targetFrame))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("targetFrame", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 3073); AnnotateMozCrashReason("MOZ_ASSERT" "(" "targetFrame"
")"); do { *((volatile int*)__null) = 3073; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3074
3075 dest.y = ScrollPositionForFrame(targetFrame, sf, previewScale);
3076 break;
3077 }
3078 default:
3079 return NS_ERROR_INVALID_ARG;
3080 break;
3081 }
3082
3083 sf->ScrollTo(dest, ScrollMode::Instant);
3084
3085 return NS_OK;
3086}
3087
3088std::tuple<const nsIFrame*, int32_t>
3089nsDocumentViewer::GetCurrentSheetFrameAndNumber() const {
3090 MOZ_ASSERT(mPrintJob)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mPrintJob)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mPrintJob))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mPrintJob", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 3090); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mPrintJob" ")"
); do { *((volatile int*)__null) = 3090; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3091 MOZ_ASSERT(GetIsPrintPreview() && !mPrintJob->GetIsCreatingPrintPreview())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(GetIsPrintPreview() && !mPrintJob->GetIsCreatingPrintPreview
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(GetIsPrintPreview() && !mPrintJob->GetIsCreatingPrintPreview
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("GetIsPrintPreview() && !mPrintJob->GetIsCreatingPrintPreview()"
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 3091); AnnotateMozCrashReason("MOZ_ASSERT" "(" "GetIsPrintPreview() && !mPrintJob->GetIsCreatingPrintPreview()"
")"); do { *((volatile int*)__null) = 3091; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3092
3093 // in PP mPrtPreview->mPrintObject->mSeqFrame is null
3094 auto [seqFrame, sheetCount] = mPrintJob->GetSeqFrameAndCountSheets();
3095 Unused << sheetCount;
3096 if (!seqFrame) {
3097 return {nullptr, 0};
3098 }
3099
3100 ScrollContainerFrame* sf = mPresShell->GetRootScrollContainerFrame();
3101 if (!sf) {
3102 // No scrollable contents, returns 1 even if there are multiple sheets.
3103 return {seqFrame->PrincipalChildList().FirstChild(), 1};
3104 }
3105
3106 nsPoint currentScrollPosition = sf->GetScrollPosition();
3107 float halfwayPoint =
3108 currentScrollPosition.y + float(sf->GetScrollPortRect().height) / 2.0f;
3109 float lastDistanceFromHalfwayPoint = std::numeric_limits<float>::max();
3110 int32_t sheetNumber = 0;
3111 const nsIFrame* currentSheet = nullptr;
3112 float previewScale = seqFrame->GetPrintPreviewScale();
3113 for (const nsIFrame* sheetFrame : seqFrame->PrincipalChildList()) {
3114 nsRect sheetRect = sheetFrame->GetRect();
3115 sheetNumber++;
3116 currentSheet = sheetFrame;
3117
3118 float bottomOfSheet = sheetRect.YMost() * previewScale;
3119 if (bottomOfSheet < halfwayPoint) {
3120 // If the bottom of the sheet is not yet over the halfway point, iterate
3121 // the next frame to see if the next frame is over the halfway point and
3122 // compare the distance from the halfway point.
3123 lastDistanceFromHalfwayPoint = halfwayPoint - bottomOfSheet;
3124 continue;
3125 }
3126
3127 float topOfSheet = sheetRect.Y() * previewScale;
3128 if (topOfSheet <= halfwayPoint) {
3129 // If the top of the sheet is not yet over the halfway point or on the
3130 // point, it's the current sheet.
3131 break;
3132 }
3133
3134 // Now the sheet rect is completely over the halfway point, compare the
3135 // distances from the halfway point.
3136 if ((topOfSheet - halfwayPoint) >= lastDistanceFromHalfwayPoint) {
3137 // If the previous sheet distance is less than or equal to the current
3138 // sheet distance, choose the previous one as the current.
3139 sheetNumber--;
3140 MOZ_ASSERT(sheetNumber > 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(sheetNumber > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(sheetNumber > 0))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("sheetNumber > 0"
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 3140); AnnotateMozCrashReason("MOZ_ASSERT" "(" "sheetNumber > 0"
")"); do { *((volatile int*)__null) = 3140; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3141 currentSheet = currentSheet->GetPrevInFlow();
3142 MOZ_ASSERT(currentSheet)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(currentSheet)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(currentSheet))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("currentSheet", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 3142); AnnotateMozCrashReason("MOZ_ASSERT" "(" "currentSheet"
")"); do { *((volatile int*)__null) = 3142; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3143 }
3144 break;
3145 }
3146
3147 MOZ_ASSERT(sheetNumber <= sheetCount)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(sheetNumber <= sheetCount)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(sheetNumber <= sheetCount
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"sheetNumber <= sheetCount", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 3147); AnnotateMozCrashReason("MOZ_ASSERT" "(" "sheetNumber <= sheetCount"
")"); do { *((volatile int*)__null) = 3147; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3148 return {currentSheet, sheetNumber};
3149}
3150
3151// XXXdholbert As noted in nsIWebBrowserPrint.idl, this API (the IDL attr
3152// 'printPreviewCurrentPageNumber') is misnamed and needs s/Page/Sheet/. See
3153// bug 1669762.
3154NS_IMETHODIMPnsresult
3155nsDocumentViewer::GetPrintPreviewCurrentPageNumber(int32_t* aNumber) {
3156 NS_ENSURE_ARG_POINTER(aNumber)do { if ((__builtin_expect(!!(!(aNumber)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aNumber" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 3156); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3157 NS_ENSURE_TRUE(mPrintJob, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(mPrintJob)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mPrintJob" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 3157); return NS_ERROR_FAILURE; } } while (false)
;
3158 if (!GetIsPrintPreview() || mPrintJob->GetIsCreatingPrintPreview()) {
3159 return NS_ERROR_FAILURE;
3160 }
3161
3162 auto [currentFrame, currentSheetNumber] = GetCurrentSheetFrameAndNumber();
3163 Unused << currentFrame;
3164 if (!currentSheetNumber) {
3165 return NS_ERROR_FAILURE;
3166 }
3167
3168 *aNumber = currentSheetNumber;
3169
3170 return NS_OK;
3171}
3172
3173// XXX This always returns false for subdocuments
3174NS_IMETHODIMPnsresult
3175nsDocumentViewer::GetDoingPrint(bool* aDoingPrint) {
3176 NS_ENSURE_ARG_POINTER(aDoingPrint)do { if ((__builtin_expect(!!(!(aDoingPrint)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aDoingPrint" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 3176); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3177
3178 // XXX shouldn't this be GetDoingPrint() ?
3179 *aDoingPrint = mPrintJob ? mPrintJob->CreatedForPrintPreview() : false;
3180 return NS_OK;
3181}
3182
3183// XXX This always returns false for subdocuments
3184NS_IMETHODIMPnsresult
3185nsDocumentViewer::GetDoingPrintPreview(bool* aDoingPrintPreview) {
3186 NS_ENSURE_ARG_POINTER(aDoingPrintPreview)do { if ((__builtin_expect(!!(!(aDoingPrintPreview)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aDoingPrintPreview" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 3186); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3187
3188 *aDoingPrintPreview = mPrintJob ? mPrintJob->CreatedForPrintPreview() : false;
3189 return NS_OK;
3190}
3191
3192NS_IMETHODIMPnsresult
3193nsDocumentViewer::GetCloseWindowAfterPrint(bool* aCloseWindowAfterPrint) {
3194 NS_ENSURE_ARG_POINTER(aCloseWindowAfterPrint)do { if ((__builtin_expect(!!(!(aCloseWindowAfterPrint)), 0))
) { NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aCloseWindowAfterPrint"
") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 3194); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3195
3196 *aCloseWindowAfterPrint = mCloseWindowAfterPrint;
3197 return NS_OK;
3198}
3199
3200NS_IMETHODIMPnsresult
3201nsDocumentViewer::SetCloseWindowAfterPrint(bool aCloseWindowAfterPrint) {
3202 mCloseWindowAfterPrint = aCloseWindowAfterPrint;
3203 return NS_OK;
3204}
3205
3206NS_IMETHODIMPnsresult
3207nsDocumentViewer::ExitPrintPreview() {
3208 NS_ENSURE_TRUE(mPrintJob, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(mPrintJob)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mPrintJob" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 3208); return NS_ERROR_FAILURE; } } while (false)
;
3209
3210 if (GetIsPrinting()) {
3211 // Block exiting the print preview window if we're in the middle of an
3212 // actual print.
3213 return NS_ERROR_FAILURE;
3214 }
3215
3216 if (!GetIsPrintPreview()) {
3217 NS_ERROR("Wow, we should never get here!")do { NS_DebugBreak(NS_DEBUG_ASSERTION, "Wow, we should never get here!"
, "Error", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 3217); MOZ_PretendNoReturn(); } while (0)
;
3218 return NS_OK;
3219 }
3220
3221# ifdef NS_PRINT_PREVIEW1
3222 mPrintJob->Destroy();
3223 mPrintJob = nullptr;
3224
3225 // Since the print preview implementation discards the window that was used
3226 // to show the print preview, we skip certain cleanup that we would otherwise
3227 // want to do. Specifically, we do not call `SetIsPrintPreview(false)` to
3228 // unblock navigation, we do not call `SetOverrideDPPX` to reset the
3229 // devicePixelRatio, and we do not call `Show` to make such changes take
3230 // affect.
3231# endif // NS_PRINT_PREVIEW
3232
3233 return NS_OK;
3234}
3235
3236NS_IMETHODIMPnsresult
3237nsDocumentViewer::GetRawNumPages(int32_t* aRawNumPages) {
3238 NS_ENSURE_ARG_POINTER(aRawNumPages)do { if ((__builtin_expect(!!(!(aRawNumPages)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aRawNumPages" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 3238); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3239 NS_ENSURE_TRUE(mPrintJob, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(mPrintJob)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mPrintJob" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 3239); return NS_ERROR_FAILURE; } } while (false)
;
3240
3241 *aRawNumPages = mPrintJob->GetRawNumPages();
3242 return *aRawNumPages > 0 ? NS_OK : NS_ERROR_FAILURE;
3243}
3244
3245// XXXdholbert As noted in nsIWebBrowserPrint.idl, this API (the IDL attr
3246// 'printPreviewNumPages') is misnamed and needs s/Page/Sheet/.
3247// See bug 1669762.
3248NS_IMETHODIMPnsresult
3249nsDocumentViewer::GetPrintPreviewNumPages(int32_t* aPrintPreviewNumPages) {
3250 NS_ENSURE_ARG_POINTER(aPrintPreviewNumPages)do { if ((__builtin_expect(!!(!(aPrintPreviewNumPages)), 0)))
{ NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aPrintPreviewNumPages"
") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 3250); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3251 NS_ENSURE_TRUE(mPrintJob, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(mPrintJob)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mPrintJob" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 3251); return NS_ERROR_FAILURE; } } while (false)
;
3252 *aPrintPreviewNumPages = mPrintJob->GetPrintPreviewNumSheets();
3253 return *aPrintPreviewNumPages > 0 ? NS_OK : NS_ERROR_FAILURE;
3254}
3255
3256//----------------------------------------------------------------------------------
3257// Printing/Print Preview Helpers
3258//----------------------------------------------------------------------------------
3259
3260//----------------------------------------------------------------------------------
3261// Walks the document tree and tells each DocShell whether Printing/PP is
3262// happening
3263#endif // NS_PRINTING
3264
3265bool nsDocumentViewer::ShouldAttachToTopLevel() {
3266 if (!mParentWidget) {
3267 return false;
3268 }
3269
3270 // We always attach when using puppet widgets
3271 if (nsIWidget::UsePuppetWidgets() || mParentWidget->IsPuppetWidget()) {
3272 return true;
3273 }
3274
3275 // TODO(emilio, bug 1919165): Unify this between macOS and other platforms?
3276#ifdef XP_MACOSX
3277 return false;
3278#else
3279# ifdef DEBUG1
3280 nsIWidgetListener* parentListener = mParentWidget->GetWidgetListener();
3281 MOZ_ASSERT(!parentListener || !parentListener->GetView(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!parentListener || !parentListener->GetView())>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!parentListener || !parentListener->GetView()))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("!parentListener || !parentListener->GetView()"
" (" "Expect a top level widget" ")", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 3282); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!parentListener || !parentListener->GetView()"
") (" "Expect a top level widget" ")"); do { *((volatile int
*)__null) = 3282; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
3282 "Expect a top level widget")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!parentListener || !parentListener->GetView())>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!parentListener || !parentListener->GetView()))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("!parentListener || !parentListener->GetView()"
" (" "Expect a top level widget" ")", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 3282); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!parentListener || !parentListener->GetView()"
") (" "Expect a top level widget" ")"); do { *((volatile int
*)__null) = 3282; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
3283# endif
3284 return true;
3285#endif
3286}
3287
3288//------------------------------------------------------------
3289// XXX this always returns false for subdocuments
3290bool nsDocumentViewer::GetIsPrinting() const {
3291#ifdef NS_PRINTING1
3292 if (mPrintJob) {
3293 return mPrintJob->GetIsPrinting();
3294 }
3295#endif
3296 return false;
3297}
3298
3299//------------------------------------------------------------
3300// The PrintJob holds the current value
3301// this called from inside the DocViewer.
3302// XXX it always returns false for subdocuments
3303bool nsDocumentViewer::GetIsPrintPreview() const {
3304#ifdef NS_PRINTING1
3305 return mPrintJob && mPrintJob->CreatedForPrintPreview();
3306#else
3307 return false;
3308#endif
3309}
3310
3311//------------------------------------------------------------
3312// Notification from the PrintJob of the current PP status
3313void nsDocumentViewer::SetIsPrintPreview(bool aIsPrintPreview) {
3314 // Protect against pres shell destruction running scripts.
3315 nsAutoScriptBlocker scriptBlocker;
3316
3317 if (!aIsPrintPreview) {
3318 InvalidatePotentialSubDocDisplayItem();
3319 if (mPresShell) {
3320 DestroyPresShell();
3321 }
3322 mWindow = nullptr;
3323 mViewManager = nullptr;
3324 mPresContext = nullptr;
3325 mPresShell = nullptr;
3326 }
3327}
3328
3329//----------------------------------------------------------------------------------
3330// nsIDocumentViewerPrint IFace
3331//----------------------------------------------------------------------------------
3332
3333//------------------------------------------------------------
3334void nsDocumentViewer::IncrementDestroyBlockedCount() {
3335 ++mDestroyBlockedCount;
3336}
3337
3338void nsDocumentViewer::DecrementDestroyBlockedCount() {
3339 --mDestroyBlockedCount;
3340}
3341
3342//------------------------------------------------------------
3343// This called ONLY when printing has completed and the DV
3344// is being notified that it should get rid of the nsPrintJob.
3345//
3346// BUT, if we are in Print Preview then we want to ignore the
3347// notification (we do not get rid of the nsPrintJob)
3348//
3349// One small caveat:
3350// This IS called from two places in this module for cleaning
3351// up when an error occurred during the start up printing
3352// and print preview
3353//
3354void nsDocumentViewer::OnDonePrinting() {
3355#if defined(NS_PRINTING1) && defined(NS_PRINT_PREVIEW1)
3356 // If Destroy() has been called during calling nsPrintJob::Print() or
3357 // nsPrintJob::PrintPreview(), mPrintJob is already nullptr here.
3358 // So, the following clean up does nothing in such case.
3359 // (Do we need some of this for that case?)
3360 if (mPrintJob) {
3361 RefPtr<nsPrintJob> printJob = std::move(mPrintJob);
3362 if (GetIsPrintPreview()) {
3363 printJob->DestroyPrintingData();
3364 } else {
3365 printJob->Destroy();
3366 }
3367
3368// We are done printing, now clean up.
3369//
3370// If the original document to print was not a static clone, we opened a new
3371// window and are responsible for cleaning up the whole <browser> or window
3372// (see the OPEN_PRINT_BROWSER code, specifically
3373// handleStaticCloneCreatedForPrint()), so gotta run window.close(), which
3374// will take care of this.
3375//
3376// Otherwise the front-end code is responsible for cleaning the UI.
3377# ifdef ANDROID
3378 // Android doesn't support Content Analysis and prints in a different way,
3379 // so use different logic to clean up.
3380 bool closeWindowAfterPrint = !printJob->CreatedForPrintPreview();
3381# else
3382 bool closeWindowAfterPrint = GetCloseWindowAfterPrint();
3383# endif
3384 if (closeWindowAfterPrint) {
3385 if (mContainer) {
3386 if (nsCOMPtr<nsPIDOMWindowOuter> win = mContainer->GetWindow()) {
3387 win->Close();
3388 }
3389 }
3390 } else if (mClosingWhilePrinting) {
3391 if (mDocument) {
3392 mDocument->Destroy();
3393 mDocument = nullptr;
3394 }
3395 mClosingWhilePrinting = false;
3396 }
3397 }
3398#endif // NS_PRINTING && NS_PRINT_PREVIEW
3399}
3400
3401NS_IMETHODIMPnsresult nsDocumentViewer::SetPrintSettingsForSubdocument(
3402 nsIPrintSettings* aPrintSettings, RemotePrintJobChild* aRemotePrintJob) {
3403#ifdef NS_PRINTING1
3404 {
3405 nsAutoScriptBlocker scriptBlocker;
3406
3407 if (mPresShell) {
3408 DestroyPresShell();
3409 }
3410
3411 if (mPresContext) {
3412 DestroyPresContext();
3413 }
3414
3415 MOZ_ASSERT(!mPresContext)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mPresContext)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mPresContext))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("!mPresContext",
"/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 3415); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mPresContext"
")"); do { *((volatile int*)__null) = 3415; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3416 MOZ_ASSERT(!mPresShell)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mPresShell)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mPresShell))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("!mPresShell", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 3416); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mPresShell"
")"); do { *((volatile int*)__null) = 3416; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3417
3418 if (MOZ_UNLIKELY(!mDocument)(__builtin_expect(!!(!mDocument), 0))) {
3419 return NS_ERROR_NOT_AVAILABLE;
3420 }
3421
3422 auto devspec = MakeRefPtr<nsDeviceContextSpecProxy>(aRemotePrintJob);
3423 nsresult rv = devspec->Init(aPrintSettings, /* aIsPrintPreview = */ true);
3424 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, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 3424); return rv; } } while (false)
;
3425
3426 mDeviceContext = new nsDeviceContext();
3427 rv = mDeviceContext->InitForPrinting(devspec);
3428
3429 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, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 3429); return rv; } } while (false)
;
3430
3431 mPresContext = CreatePresContext(
3432 mDocument, nsPresContext::eContext_PrintPreview, FindContainerView());
3433 mPresContext->SetPrintSettings(aPrintSettings);
3434 rv = mPresContext->Init(mDeviceContext);
3435 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, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 3435); return rv; } } while (false)
;
3436
3437 rv = MakeWindow(nsSize(mPresContext->DevPixelsToAppUnits(mBounds.width),
3438 mPresContext->DevPixelsToAppUnits(mBounds.height)),
3439 FindContainerView());
3440 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, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 3440); return rv; } } while (false)
;
3441
3442 MOZ_TRY(InitPresentationStuff(true))do { auto mozTryTempResult_ = ::mozilla::ToResult(InitPresentationStuff
(true)); if ((__builtin_expect(!!(mozTryTempResult_.isErr()),
0))) { return mozTryTempResult_.propagateErr(); } } while (0
)
;
3443 }
3444
3445 RefPtr<PresShell> shell = mPresShell;
3446 shell->FlushPendingNotifications(FlushType::Layout);
3447#endif
3448 return NS_OK;
3449}
3450
3451NS_IMETHODIMPnsresult nsDocumentViewer::SetPageModeForTesting(
3452 bool aPageMode, nsIPrintSettings* aPrintSettings) {
3453 // XXX Page mode is only partially working; it's currently used for
3454 // reftests that require a paginated context
3455 mIsPageMode = aPageMode;
3456
3457 // The DestroyPresShell call requires a script blocker, since the
3458 // PresShell::Destroy call it does can cause scripts to run, which could
3459 // re-entrantly call methods on the nsDocumentViewer.
3460 nsAutoScriptBlocker scriptBlocker;
3461
3462 if (mPresShell) {
3463 DestroyPresShell();
3464 }
3465
3466 if (mPresContext) {
3467 DestroyPresContext();
3468 }
3469
3470 mViewManager = nullptr;
3471 mWindow = nullptr;
3472
3473 NS_ENSURE_STATE(mDocument)do { if ((__builtin_expect(!!(!(mDocument)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mDocument" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 3473); return NS_ERROR_UNEXPECTED; } } while (false)
;
3474 if (aPageMode) {
3475 mPresContext = CreatePresContext(
3476 mDocument, nsPresContext::eContext_PageLayout, FindContainerView());
3477 NS_ENSURE_TRUE(mPresContext, NS_ERROR_OUT_OF_MEMORY)do { if ((__builtin_expect(!!(!(mPresContext)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mPresContext" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 3477); return NS_ERROR_OUT_OF_MEMORY; } } while (false)
;
3478 mPresContext->SetPaginatedScrolling(true);
3479 mPresContext->SetPrintSettings(aPrintSettings);
3480 nsresult rv = mPresContext->Init(mDeviceContext);
3481 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, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 3481); return rv; } } while (false)
;
3482 }
3483 NS_ENSURE_SUCCESS(InitInternal(mParentWidget, nullptr, nullptr, mBounds, true,do { nsresult __rv = InitInternal(mParentWidget, nullptr, nullptr
, mBounds, true, false, false); 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", "InitInternal(mParentWidget, nullptr, nullptr, mBounds, true, false, false)"
, "NS_ERROR_FAILURE", static_cast<uint32_t>(__rv), name
? " (" : "", name ? name : "", name ? ")" : ""); NS_DebugBreak
(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 3485); return NS_ERROR_FAILURE; } } while (false)
3484 false, false),do { nsresult __rv = InitInternal(mParentWidget, nullptr, nullptr
, mBounds, true, false, false); 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", "InitInternal(mParentWidget, nullptr, nullptr, mBounds, true, false, false)"
, "NS_ERROR_FAILURE", static_cast<uint32_t>(__rv), name
? " (" : "", name ? name : "", name ? ")" : ""); NS_DebugBreak
(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 3485); return NS_ERROR_FAILURE; } } while (false)
3485 NS_ERROR_FAILURE)do { nsresult __rv = InitInternal(mParentWidget, nullptr, nullptr
, mBounds, true, false, false); 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", "InitInternal(mParentWidget, nullptr, nullptr, mBounds, true, false, false)"
, "NS_ERROR_FAILURE", static_cast<uint32_t>(__rv), name
? " (" : "", name ? name : "", name ? ")" : ""); NS_DebugBreak
(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 3485); return NS_ERROR_FAILURE; } } while (false)
;
3486
3487 Show();
3488 return NS_OK;
3489}
3490
3491NS_IMETHODIMPnsresult
3492nsDocumentViewer::GetHistoryEntry(nsISHEntry** aHistoryEntry) {
3493 NS_IF_ADDREF(*aHistoryEntry = mSHEntry)ns_if_addref(*aHistoryEntry = mSHEntry);
3494 return NS_OK;
3495}
3496
3497NS_IMETHODIMPnsresult
3498nsDocumentViewer::GetIsTabModalPromptAllowed(bool* aAllowed) {
3499 *aAllowed = !mHidden;
3500 return NS_OK;
3501}
3502
3503NS_IMETHODIMPnsresult
3504nsDocumentViewer::GetIsHidden(bool* aHidden) {
3505 *aHidden = mHidden;
3506 return NS_OK;
3507}
3508
3509NS_IMETHODIMPnsresult
3510nsDocumentViewer::SetIsHidden(bool aHidden) {
3511 mHidden = aHidden;
3512 return NS_OK;
3513}
3514
3515void nsDocumentViewer::DestroyPresShell() {
3516 // We assert this because destroying the pres shell could otherwise cause
3517 // re-entrancy into nsDocumentViewer methods, and all callers of
3518 // DestroyPresShell need to do other cleanup work afterwards before it
3519 // is safe for those re-entrant method calls to be made.
3520 MOZ_ASSERT(!nsContentUtils::IsSafeToRunScript(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!nsContentUtils::IsSafeToRunScript())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!nsContentUtils::IsSafeToRunScript
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!nsContentUtils::IsSafeToRunScript()" " (" "DestroyPresShell must only be called when scripts are blocked"
")", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 3521); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!nsContentUtils::IsSafeToRunScript()"
") (" "DestroyPresShell must only be called when scripts are blocked"
")"); do { *((volatile int*)__null) = 3521; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
3521 "DestroyPresShell must only be called when scripts are blocked")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!nsContentUtils::IsSafeToRunScript())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!nsContentUtils::IsSafeToRunScript
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!nsContentUtils::IsSafeToRunScript()" " (" "DestroyPresShell must only be called when scripts are blocked"
")", "/var/lib/jenkins/workspace/firefox-scan-build/layout/base/nsDocumentViewer.cpp"
, 3521); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!nsContentUtils::IsSafeToRunScript()"
") (" "DestroyPresShell must only be called when scripts are blocked"
")"); do { *((volatile int*)__null) = 3521; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3522
3523 // Break circular reference (or something)
3524 mPresShell->EndObservingDocument();
3525
3526 RefPtr<mozilla::dom::Selection> selection = GetDocumentSelection();
3527 if (selection && mSelectionListener) {
3528 selection->RemoveSelectionListener(mSelectionListener);
3529 }
3530
3531 mPresShell->Destroy();
3532 mPresShell = nullptr;
3533}
3534
3535void nsDocumentViewer::InvalidatePotentialSubDocDisplayItem() {
3536 if (mViewManager) {
3537 if (nsView* rootView = mViewManager->GetRootView()) {
3538 if (nsView* rootViewParent = rootView->GetParent()) {
3539 if (nsView* subdocview = rootViewParent->GetParent()) {
3540 if (nsIFrame* f = subdocview->GetFrame()) {
3541 if (nsSubDocumentFrame* s = do_QueryFrame(f)) {
3542 s->MarkNeedsDisplayItemRebuild();
3543 }
3544 }
3545 }
3546 }
3547 }
3548 }
3549}
3550
3551void nsDocumentViewer::DestroyPresContext() {
3552 InvalidatePotentialSubDocDisplayItem();
3553 mPresContext = nullptr;
3554}
3555
3556void nsDocumentViewer::SetPrintPreviewPresentation(nsViewManager* aViewManager,
3557 nsPresContext* aPresContext,
3558 PresShell* aPresShell) {
3559 // Protect against pres shell destruction running scripts and re-entrantly
3560 // creating a new presentation.
3561 nsAutoScriptBlocker scriptBlocker;
3562
3563 if (mPresShell) {
3564 DestroyPresShell();
3565 }
3566
3567 mWindow = nullptr;
3568 mViewManager = aViewManager;
3569 mPresContext = aPresContext;
3570 mPresShell = aPresShell;
3571
3572 if (ShouldAttachToTopLevel()) {
3573 DetachFromTopLevelWidget();
3574 nsView* rootView = mViewManager->GetRootView();
3575 rootView->AttachToTopLevelWidget(mParentWidget);
3576 mAttachedToParent = true;
3577 }
3578}
3579
3580// Fires the "document-shown" event so that interested parties are aware of it.
3581NS_IMETHODIMPnsresult
3582nsDocumentShownDispatcher::Run() {
3583 nsCOMPtr<nsIObserverService> observerService =
3584 mozilla::services::GetObserverService();
3585 if (observerService) {
3586 observerService->NotifyObservers(ToSupports(mDocument), "document-shown",
3587 nullptr);
3588 }
3589 return NS_OK;
3590}