1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "ImageDocument.h"
7 #include "mozilla/dom/ImageDocumentBinding.h"
9 #include "nsIImageLoadingContent.h"
10 #include "nsGenericHTMLElement.h"
11 #include "nsDocShell.h"
12 #include "nsIDocumentInlines.h"
13 #include "nsDOMTokenList.h"
14 #include "nsIDOMHTMLImageElement.h"
15 #include "nsIDOMEvent.h"
16 #include "nsIDOMKeyEvent.h"
17 #include "nsIDOMMouseEvent.h"
18 #include "nsIDOMEventListener.h"
20 #include "nsGkAtoms.h"
21 #include "imgIRequest.h"
22 #include "imgILoader.h"
23 #include "imgIContainer.h"
24 #include "imgINotificationObserver.h"
25 #include "nsIPresShell.h"
26 #include "nsPresContext.h"
27 #include "nsStyleContext.h"
28 #include "nsAutoPtr.h"
29 #include "nsStyleSet.h"
30 #include "nsIChannel.h"
31 #include "nsIContentPolicy.h"
32 #include "nsContentPolicyUtils.h"
33 #include "nsPIDOMWindow.h"
34 #include "nsIDOMElement.h"
35 #include "nsIDOMHTMLElement.h"
37 #include "nsURILoader.h"
38 #include "nsIDocShell.h"
39 #include "nsIContentViewer.h"
40 #include "nsThreadUtils.h"
41 #include "nsIScrollableFrame.h"
42 #include "nsContentUtils.h"
43 #include "mozilla/dom/Element.h"
44 #include "mozilla/Preferences.h"
47 #define AUTOMATIC_IMAGE_RESIZING_PREF "browser.enable_automatic_image_resizing"
48 #define CLICK_IMAGE_RESIZING_PREF "browser.enable_click_image_resizing"
49 //XXX A hack needed for Firefox's site specific zoom.
50 #define SITE_SPECIFIC_ZOOM "browser.zoom.siteSpecific"
55 class ImageListener
: public MediaDocumentStreamListener
58 NS_DECL_NSIREQUESTOBSERVER
60 explicit ImageListener(ImageDocument
* aDocument
);
61 virtual ~ImageListener();
64 ImageListener::ImageListener(ImageDocument
* aDocument
)
65 : MediaDocumentStreamListener(aDocument
)
69 ImageListener::~ImageListener()
74 ImageListener::OnStartRequest(nsIRequest
* request
, nsISupports
*ctxt
)
76 NS_ENSURE_TRUE(mDocument
, NS_ERROR_FAILURE
);
78 ImageDocument
*imgDoc
= static_cast<ImageDocument
*>(mDocument
.get());
79 nsCOMPtr
<nsIChannel
> channel
= do_QueryInterface(request
);
81 return NS_ERROR_FAILURE
;
84 nsCOMPtr
<nsPIDOMWindow
> domWindow
= imgDoc
->GetWindow();
85 NS_ENSURE_TRUE(domWindow
, NS_ERROR_UNEXPECTED
);
87 // Do a ShouldProcess check to see whether to keep loading the image.
88 nsCOMPtr
<nsIURI
> channelURI
;
89 channel
->GetURI(getter_AddRefs(channelURI
));
91 nsAutoCString mimeType
;
92 channel
->GetContentType(mimeType
);
94 nsIScriptSecurityManager
* secMan
= nsContentUtils::GetSecurityManager();
95 nsCOMPtr
<nsIPrincipal
> channelPrincipal
;
97 secMan
->GetChannelResultPrincipal(channel
, getter_AddRefs(channelPrincipal
));
100 int16_t decision
= nsIContentPolicy::ACCEPT
;
101 nsresult rv
= NS_CheckContentProcessPolicy(nsIContentPolicy::TYPE_IMAGE
,
104 domWindow
->GetFrameElementInternal(),
108 nsContentUtils::GetContentPolicy(),
111 if (NS_FAILED(rv
) || NS_CP_REJECTED(decision
)) {
112 request
->Cancel(NS_ERROR_CONTENT_BLOCKED
);
116 if (!imgDoc
->mObservingImageLoader
) {
117 nsCOMPtr
<nsIImageLoadingContent
> imageLoader
= do_QueryInterface(imgDoc
->mImageContent
);
118 NS_ENSURE_TRUE(imageLoader
, NS_ERROR_UNEXPECTED
);
120 imageLoader
->AddObserver(imgDoc
);
121 imgDoc
->mObservingImageLoader
= true;
122 imageLoader
->LoadImageWithChannel(channel
, getter_AddRefs(mNextStream
));
125 return MediaDocumentStreamListener::OnStartRequest(request
, ctxt
);
129 ImageListener::OnStopRequest(nsIRequest
* aRequest
, nsISupports
* aCtxt
, nsresult aStatus
)
131 ImageDocument
* imgDoc
= static_cast<ImageDocument
*>(mDocument
.get());
132 nsContentUtils::DispatchChromeEvent(imgDoc
, static_cast<nsIDocument
*>(imgDoc
),
133 NS_LITERAL_STRING("ImageContentLoaded"),
135 return MediaDocumentStreamListener::OnStopRequest(aRequest
, aCtxt
, aStatus
);
138 ImageDocument::ImageDocument()
140 mOriginalZoomLevel(1.0)
142 // NOTE! nsDocument::operator new() zeroes out all members, so don't
143 // bother initializing members to 0.
146 ImageDocument::~ImageDocument()
151 NS_IMPL_CYCLE_COLLECTION_INHERITED(ImageDocument
, MediaDocument
,
154 NS_IMPL_ADDREF_INHERITED(ImageDocument
, MediaDocument
)
155 NS_IMPL_RELEASE_INHERITED(ImageDocument
, MediaDocument
)
157 NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(ImageDocument
)
158 NS_INTERFACE_TABLE_INHERITED(ImageDocument
, nsIImageDocument
,
159 imgINotificationObserver
, nsIDOMEventListener
)
160 NS_INTERFACE_TABLE_TAIL_INHERITING(MediaDocument
)
164 ImageDocument::Init()
166 nsresult rv
= MediaDocument::Init();
167 NS_ENSURE_SUCCESS(rv
, rv
);
169 mResizeImageByDefault
= Preferences::GetBool(AUTOMATIC_IMAGE_RESIZING_PREF
);
170 mClickResizingEnabled
= Preferences::GetBool(CLICK_IMAGE_RESIZING_PREF
);
171 mShouldResize
= mResizeImageByDefault
;
178 ImageDocument::WrapNode(JSContext
* aCx
)
180 return ImageDocumentBinding::Wrap(aCx
, this);
184 ImageDocument::StartDocumentLoad(const char* aCommand
,
185 nsIChannel
* aChannel
,
186 nsILoadGroup
* aLoadGroup
,
187 nsISupports
* aContainer
,
188 nsIStreamListener
** aDocListener
,
190 nsIContentSink
* aSink
)
193 MediaDocument::StartDocumentLoad(aCommand
, aChannel
, aLoadGroup
, aContainer
,
194 aDocListener
, aReset
, aSink
);
200 Preferences::GetBool(SITE_SPECIFIC_ZOOM
, false) ? 1.0 : GetZoomLevel();
202 NS_ASSERTION(aDocListener
, "null aDocListener");
203 *aDocListener
= new ImageListener(this);
204 NS_ADDREF(*aDocListener
);
210 ImageDocument::Destroy()
213 // Remove our event listener from the image content.
214 nsCOMPtr
<EventTarget
> target
= do_QueryInterface(mImageContent
);
215 target
->RemoveEventListener(NS_LITERAL_STRING("load"), this, false);
216 target
->RemoveEventListener(NS_LITERAL_STRING("click"), this, false);
218 // Break reference cycle with mImageContent, if we have one
219 if (mObservingImageLoader
) {
220 nsCOMPtr
<nsIImageLoadingContent
> imageLoader
= do_QueryInterface(mImageContent
);
222 imageLoader
->RemoveObserver(this);
226 mImageContent
= nullptr;
229 MediaDocument::Destroy();
233 ImageDocument::SetScriptGlobalObject(nsIScriptGlobalObject
* aScriptGlobalObject
)
235 // If the script global object is changing, we need to unhook our event
236 // listeners on the window.
237 nsCOMPtr
<EventTarget
> target
;
238 if (mScriptGlobalObject
&&
239 aScriptGlobalObject
!= mScriptGlobalObject
) {
240 target
= do_QueryInterface(mScriptGlobalObject
);
241 target
->RemoveEventListener(NS_LITERAL_STRING("resize"), this, false);
242 target
->RemoveEventListener(NS_LITERAL_STRING("keypress"), this,
246 // Set the script global object on the superclass before doing
247 // anything that might require it....
248 MediaDocument::SetScriptGlobalObject(aScriptGlobalObject
);
250 if (aScriptGlobalObject
) {
251 if (!GetRootElement()) {
252 // Create synthetic document
256 CreateSyntheticDocument();
257 NS_ASSERTION(NS_SUCCEEDED(rv
), "failed to create synthetic document");
259 target
= do_QueryInterface(mImageContent
);
260 target
->AddEventListener(NS_LITERAL_STRING("load"), this, false);
261 target
->AddEventListener(NS_LITERAL_STRING("click"), this, false);
264 target
= do_QueryInterface(aScriptGlobalObject
);
265 target
->AddEventListener(NS_LITERAL_STRING("resize"), this, false);
266 target
->AddEventListener(NS_LITERAL_STRING("keypress"), this, false);
268 if (GetReadyStateEnum() != nsIDocument::READYSTATE_COMPLETE
) {
269 LinkStylesheet(NS_LITERAL_STRING("resource://gre/res/ImageDocument.css"));
270 if (!nsContentUtils::IsChildOfSameType(this)) {
271 LinkStylesheet(NS_LITERAL_STRING("resource://gre/res/TopLevelImageDocument.css"));
272 LinkStylesheet(NS_LITERAL_STRING("chrome://global/skin/media/TopLevelImageDocument.css"));
280 ImageDocument::OnPageShow(bool aPersisted
,
281 EventTarget
* aDispatchStartTarget
)
285 Preferences::GetBool(SITE_SPECIFIC_ZOOM
, false) ? 1.0 : GetZoomLevel();
287 MediaDocument::OnPageShow(aPersisted
, aDispatchStartTarget
);
291 ImageDocument::GetImageResizingEnabled(bool* aImageResizingEnabled
)
293 *aImageResizingEnabled
= ImageResizingEnabled();
298 ImageDocument::GetImageIsOverflowing(bool* aImageIsOverflowing
)
300 *aImageIsOverflowing
= ImageIsOverflowing();
305 ImageDocument::GetImageIsResized(bool* aImageIsResized
)
307 *aImageIsResized
= ImageIsResized();
311 already_AddRefed
<imgIRequest
>
312 ImageDocument::GetImageRequest(ErrorResult
& aRv
)
314 nsCOMPtr
<nsIImageLoadingContent
> imageLoader
= do_QueryInterface(mImageContent
);
315 nsCOMPtr
<imgIRequest
> imageRequest
;
317 aRv
= imageLoader
->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST
,
318 getter_AddRefs(imageRequest
));
320 return imageRequest
.forget();
324 ImageDocument::GetImageRequest(imgIRequest
** aImageRequest
)
327 *aImageRequest
= GetImageRequest(rv
).take();
328 return rv
.ErrorCode();
332 ImageDocument::ShrinkToFit()
334 if (!mImageContent
) {
337 if (GetZoomLevel() != mOriginalZoomLevel
&& mImageIsResized
&&
338 !nsContentUtils::IsChildOfSameType(this)) {
342 // Keep image content alive while changing the attributes.
343 nsCOMPtr
<nsIContent
> imageContent
= mImageContent
;
344 nsCOMPtr
<nsIDOMHTMLImageElement
> image
= do_QueryInterface(mImageContent
);
345 image
->SetWidth(std::max(1, NSToCoordFloor(GetRatio() * mImageWidth
)));
346 image
->SetHeight(std::max(1, NSToCoordFloor(GetRatio() * mImageHeight
)));
348 // The view might have been scrolled when zooming in, scroll back to the
349 // origin now that we're showing a shrunk-to-window version.
350 ScrollImageTo(0, 0, false);
352 if (!mImageContent
) {
353 // ScrollImageTo flush destroyed our content.
357 SetModeClass(eShrinkToFit
);
359 mImageIsResized
= true;
361 UpdateTitleAndCharset();
365 ImageDocument::DOMShrinkToFit()
372 ImageDocument::DOMRestoreImageTo(int32_t aX
, int32_t aY
)
374 RestoreImageTo(aX
, aY
);
379 ImageDocument::ScrollImageTo(int32_t aX
, int32_t aY
, bool restoreImage
)
381 float ratio
= GetRatio();
385 FlushPendingNotifications(Flush_Layout
);
388 nsCOMPtr
<nsIPresShell
> shell
= GetShell();
393 nsIScrollableFrame
* sf
= shell
->GetRootScrollFrameAsScrollable();
398 nsRect portRect
= sf
->GetScrollPortRect();
399 sf
->ScrollTo(nsPoint(nsPresContext::CSSPixelsToAppUnits(aX
/ratio
) - portRect
.width
/2,
400 nsPresContext::CSSPixelsToAppUnits(aY
/ratio
) - portRect
.height
/2),
401 nsIScrollableFrame::INSTANT
);
405 ImageDocument::RestoreImage()
407 if (!mImageContent
) {
410 // Keep image content alive while changing the attributes.
411 nsCOMPtr
<nsIContent
> imageContent
= mImageContent
;
412 imageContent
->UnsetAttr(kNameSpaceID_None
, nsGkAtoms::width
, true);
413 imageContent
->UnsetAttr(kNameSpaceID_None
, nsGkAtoms::height
, true);
415 if (mImageIsOverflowing
) {
416 SetModeClass(eOverflowing
);
422 mImageIsResized
= false;
424 UpdateTitleAndCharset();
428 ImageDocument::DOMRestoreImage()
435 ImageDocument::ToggleImageSize()
437 mShouldResize
= true;
438 if (mImageIsResized
) {
439 mShouldResize
= false;
443 else if (mImageIsOverflowing
) {
450 ImageDocument::DOMToggleImageSize()
457 ImageDocument::Notify(imgIRequest
* aRequest
, int32_t aType
, const nsIntRect
* aData
)
459 if (aType
== imgINotificationObserver::SIZE_AVAILABLE
) {
460 nsCOMPtr
<imgIContainer
> image
;
461 aRequest
->GetImage(getter_AddRefs(image
));
462 return OnSizeAvailable(aRequest
, image
);
465 // Run this using a script runner because HAS_TRANSPARENCY notifications can
466 // come during painting and this will trigger invalidation.
467 if (aType
== imgINotificationObserver::HAS_TRANSPARENCY
) {
468 nsCOMPtr
<nsIRunnable
> runnable
=
469 NS_NewRunnableMethod(this, &ImageDocument::OnHasTransparency
);
470 nsContentUtils::AddScriptRunner(runnable
);
473 if (aType
== imgINotificationObserver::LOAD_COMPLETE
) {
475 aRequest
->GetImageStatus(&reqStatus
);
477 reqStatus
& imgIRequest::STATUS_ERROR
? NS_ERROR_FAILURE
: NS_OK
;
478 return OnLoadComplete(aRequest
, status
);
485 ImageDocument::OnHasTransparency()
487 if (!mImageContent
|| nsContentUtils::IsChildOfSameType(this)) {
491 nsDOMTokenList
* classList
= mImageContent
->AsElement()->ClassList();
492 mozilla::ErrorResult rv
;
493 classList
->Add(NS_LITERAL_STRING("transparent"), rv
);
497 ImageDocument::SetModeClass(eModeClasses mode
)
499 nsDOMTokenList
* classList
= mImageContent
->AsElement()->ClassList();
500 mozilla::ErrorResult rv
;
502 if (mode
== eShrinkToFit
) {
503 classList
->Add(NS_LITERAL_STRING("shrinkToFit"), rv
);
505 classList
->Remove(NS_LITERAL_STRING("shrinkToFit"), rv
);
508 if (mode
== eOverflowing
) {
509 classList
->Add(NS_LITERAL_STRING("overflowing"), rv
);
511 classList
->Remove(NS_LITERAL_STRING("overflowing"), rv
);
516 ImageDocument::OnSizeAvailable(imgIRequest
* aRequest
, imgIContainer
* aImage
)
518 // Styles have not yet been applied, so we don't know the final size. For now,
519 // default to the image's intrinsic size.
520 aImage
->GetWidth(&mImageWidth
);
521 aImage
->GetHeight(&mImageHeight
);
523 nsCOMPtr
<nsIRunnable
> runnable
=
524 NS_NewRunnableMethod(this, &ImageDocument::DefaultCheckOverflowing
);
525 nsContentUtils::AddScriptRunner(runnable
);
526 UpdateTitleAndCharset();
532 ImageDocument::OnLoadComplete(imgIRequest
* aRequest
, nsresult aStatus
)
534 UpdateTitleAndCharset();
536 // mImageContent can be null if the document is already destroyed
537 if (NS_FAILED(aStatus
) && mStringBundle
&& mImageContent
) {
539 mDocumentURI
->GetSpec(src
);
540 NS_ConvertUTF8toUTF16
srcString(src
);
541 const char16_t
* formatString
[] = { srcString
.get() };
542 nsXPIDLString errorMsg
;
543 NS_NAMED_LITERAL_STRING(str
, "InvalidImage");
544 mStringBundle
->FormatStringFromName(str
.get(), formatString
, 1,
545 getter_Copies(errorMsg
));
547 mImageContent
->SetAttr(kNameSpaceID_None
, nsGkAtoms::alt
, errorMsg
, false);
554 ImageDocument::HandleEvent(nsIDOMEvent
* aEvent
)
556 nsAutoString eventType
;
557 aEvent
->GetType(eventType
);
558 if (eventType
.EqualsLiteral("resize")) {
559 CheckOverflowing(false);
561 else if (eventType
.EqualsLiteral("click") && mClickResizingEnabled
) {
563 mShouldResize
= true;
564 if (mImageIsResized
) {
565 int32_t x
= 0, y
= 0;
566 nsCOMPtr
<nsIDOMMouseEvent
> event(do_QueryInterface(aEvent
));
568 event
->GetClientX(&x
);
569 event
->GetClientY(&y
);
570 int32_t left
= 0, top
= 0;
571 nsCOMPtr
<nsIDOMHTMLElement
> htmlElement
=
572 do_QueryInterface(mImageContent
);
573 htmlElement
->GetOffsetLeft(&left
);
574 htmlElement
->GetOffsetTop(&top
);
578 mShouldResize
= false;
579 RestoreImageTo(x
, y
);
581 else if (mImageIsOverflowing
) {
584 } else if (eventType
.EqualsLiteral("load")) {
585 UpdateSizeFromLayout();
592 ImageDocument::UpdateSizeFromLayout()
594 // Pull an updated size from the content frame to account for any size
595 // change due to CSS properties like |image-orientation|.
596 Element
* contentElement
= mImageContent
->AsElement();
597 if (!contentElement
) {
601 nsIFrame
* contentFrame
= contentElement
->GetPrimaryFrame(Flush_Frames
);
606 nsIntSize
oldSize(mImageWidth
, mImageHeight
);
607 IntrinsicSize newSize
= contentFrame
->GetIntrinsicSize();
609 if (newSize
.width
.GetUnit() == eStyleUnit_Coord
) {
610 mImageWidth
= nsPresContext::AppUnitsToFloatCSSPixels(newSize
.width
.GetCoordValue());
612 if (newSize
.height
.GetUnit() == eStyleUnit_Coord
) {
613 mImageHeight
= nsPresContext::AppUnitsToFloatCSSPixels(newSize
.height
.GetCoordValue());
616 // Ensure that our information about overflow is up-to-date if needed.
617 if (mImageWidth
!= oldSize
.width
|| mImageHeight
!= oldSize
.height
) {
618 CheckOverflowing(false);
623 ImageDocument::CreateSyntheticDocument()
625 // Synthesize an html document that refers to the image
626 nsresult rv
= MediaDocument::CreateSyntheticDocument();
627 NS_ENSURE_SUCCESS(rv
, rv
);
629 // Add the image element
630 Element
* body
= GetBodyElement();
632 NS_WARNING("no body on image document!");
633 return NS_ERROR_FAILURE
;
636 nsRefPtr
<NodeInfo
> nodeInfo
;
637 nodeInfo
= mNodeInfoManager
->GetNodeInfo(nsGkAtoms::img
, nullptr,
639 nsIDOMNode::ELEMENT_NODE
);
641 mImageContent
= NS_NewHTMLImageElement(nodeInfo
.forget());
642 if (!mImageContent
) {
643 return NS_ERROR_OUT_OF_MEMORY
;
645 nsCOMPtr
<nsIImageLoadingContent
> imageLoader
= do_QueryInterface(mImageContent
);
646 NS_ENSURE_TRUE(imageLoader
, NS_ERROR_UNEXPECTED
);
649 mDocumentURI
->GetSpec(src
);
651 NS_ConvertUTF8toUTF16
srcString(src
);
652 // Make sure not to start the image load from here...
653 imageLoader
->SetLoadingEnabled(false);
654 mImageContent
->SetAttr(kNameSpaceID_None
, nsGkAtoms::src
, srcString
, false);
655 mImageContent
->SetAttr(kNameSpaceID_None
, nsGkAtoms::alt
, srcString
, false);
657 body
->AppendChildTo(mImageContent
, false);
658 imageLoader
->SetLoadingEnabled(true);
664 ImageDocument::CheckOverflowing(bool changeState
)
666 /* Create a scope so that the style context gets destroyed before we might
667 * call RebuildStyleData. Also, holding onto pointers to the
668 * presentation through style resolution is potentially dangerous.
671 nsIPresShell
*shell
= GetShell();
676 nsPresContext
*context
= shell
->GetPresContext();
677 nsRect visibleArea
= context
->GetVisibleArea();
679 mVisibleWidth
= nsPresContext::AppUnitsToFloatCSSPixels(visibleArea
.width
);
680 mVisibleHeight
= nsPresContext::AppUnitsToFloatCSSPixels(visibleArea
.height
);
683 bool imageWasOverflowing
= mImageIsOverflowing
;
684 mImageIsOverflowing
=
685 mImageWidth
> mVisibleWidth
|| mImageHeight
> mVisibleHeight
;
686 bool windowBecameBigEnough
= imageWasOverflowing
&& !mImageIsOverflowing
;
688 if (changeState
|| mShouldResize
|| mFirstResize
||
689 windowBecameBigEnough
) {
690 if (mImageIsOverflowing
&& (changeState
|| mShouldResize
)) {
693 else if (mImageIsResized
|| mFirstResize
|| windowBecameBigEnough
) {
697 mFirstResize
= false;
703 ImageDocument::UpdateTitleAndCharset()
705 nsAutoCString typeStr
;
706 nsCOMPtr
<imgIRequest
> imageRequest
;
707 nsCOMPtr
<nsIImageLoadingContent
> imageLoader
= do_QueryInterface(mImageContent
);
709 imageLoader
->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST
,
710 getter_AddRefs(imageRequest
));
714 nsXPIDLCString mimeType
;
715 imageRequest
->GetMimeType(getter_Copies(mimeType
));
716 ToUpperCase(mimeType
);
717 nsXPIDLCString::const_iterator start
, end
;
718 mimeType
.BeginReading(start
);
719 mimeType
.EndReading(end
);
720 nsXPIDLCString::const_iterator iter
= end
;
721 if (FindInReadable(NS_LITERAL_CSTRING("IMAGE/"), start
, iter
) &&
723 // strip out "X-" if any
726 if (iter
!= end
&& *iter
== '-') {
729 // looks like "IMAGE/X-" is the type?? Bail out of here.
730 mimeType
.BeginReading(iter
);
736 typeStr
= Substring(iter
, end
);
742 nsXPIDLString status
;
743 if (mImageIsResized
) {
744 nsAutoString ratioStr
;
745 ratioStr
.AppendInt(NSToCoordFloor(GetRatio() * 100));
747 const char16_t
* formatString
[1] = { ratioStr
.get() };
748 mStringBundle
->FormatStringFromName(MOZ_UTF16("ScaledImage"),
750 getter_Copies(status
));
753 static const char* const formatNames
[4] =
755 "ImageTitleWithNeitherDimensionsNorFile",
756 "ImageTitleWithoutDimensions",
757 "ImageTitleWithDimensions2",
758 "ImageTitleWithDimensions2AndFile",
761 MediaDocument::UpdateTitleAndCharset(typeStr
, mChannel
, formatNames
,
762 mImageWidth
, mImageHeight
, status
);
766 ImageDocument::ResetZoomLevel()
768 nsCOMPtr
<nsIDocShell
> docShell(mDocumentContainer
);
770 if (nsContentUtils::IsChildOfSameType(this)) {
774 nsCOMPtr
<nsIContentViewer
> cv
;
775 docShell
->GetContentViewer(getter_AddRefs(cv
));
777 cv
->SetFullZoom(mOriginalZoomLevel
);
783 ImageDocument::GetZoomLevel()
785 float zoomLevel
= mOriginalZoomLevel
;
786 nsCOMPtr
<nsIDocShell
> docShell(mDocumentContainer
);
788 nsCOMPtr
<nsIContentViewer
> cv
;
789 docShell
->GetContentViewer(getter_AddRefs(cv
));
791 cv
->GetFullZoom(&zoomLevel
);
798 } // namespace mozilla
801 NS_NewImageDocument(nsIDocument
** aResult
)
803 mozilla::dom::ImageDocument
* doc
= new mozilla::dom::ImageDocument();
806 nsresult rv
= doc
->Init();