Bug Summary

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