diff --git a/content/html/document/public/MANIFEST_IDL b/content/html/document/public/MANIFEST_IDL index b9ae4d67c8e..e69de29bb2d 100644 --- a/content/html/document/public/MANIFEST_IDL +++ b/content/html/document/public/MANIFEST_IDL @@ -1,4 +0,0 @@ -# -# This is a list of local files which get copied to the mozilla:dist:idl directory -# -nsIWyciwygChannel.idl diff --git a/content/html/document/public/Makefile.in b/content/html/document/public/Makefile.in index e1964920203..dde58262620 100644 --- a/content/html/document/public/Makefile.in +++ b/content/html/document/public/Makefile.in @@ -28,8 +28,9 @@ include $(DEPTH)/config/autoconf.mk MODULE = content -XPIDLSRCS = nsIWyciwygChannel.idl \ - $(NULL) +XPIDLSRCS = \ + nsIImageDocument.idl \ + nsIWyciwygChannel.idl \ + $(NULL) include $(topsrcdir)/config/rules.mk - diff --git a/content/html/document/src/nsImageDocument.cpp b/content/html/document/src/nsImageDocument.cpp index 790af353815..d3f9e572aa9 100644 --- a/content/html/document/src/nsImageDocument.cpp +++ b/content/html/document/src/nsImageDocument.cpp @@ -20,9 +20,10 @@ * the Initial Developer. All Rights Reserved. * * Contributor(s): - * Morten Nilsen - * Christian Biesinger - * + * Morten Nilsen + * Christian Biesinger + * Jan Varga + * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), @@ -37,210 +38,157 @@ * * ***** END LICENSE BLOCK ***** */ -#include "nsCOMPtr.h" +#include "nsRect.h" #include "nsHTMLDocument.h" +#include "nsIImageDocument.h" #include "nsGenericHTMLElement.h" +#include "nsIDOMHTMLImageElement.h" +#include "nsIDOMEvent.h" +#include "nsIDOMKeyEvent.h" +#include "nsIDOMEventListener.h" #include "nsHTMLAtoms.h" -#include "nsIHTMLContent.h" #include "imgIRequest.h" #include "imgILoader.h" #include "imgIContainer.h" -#include "nsIStreamListener.h" +#include "imgIDecoderObserver.h" #include "nsIURL.h" -#include "nsHTMLValue.h" -#include "nsIHTMLStyleSheet.h" -#include "nsIHTMLCSSStyleSheet.h" +#include "nsIScrollable.h" #include "nsIPresShell.h" #include "nsIPresContext.h" +#include "nsIStyleContext.h" #include "nsIViewManager.h" -#include "nsIChannel.h" -#include "nsINameSpaceManager.h" -#include "nsINodeInfo.h" -// Needed for Localization -#include "nsXPIDLString.h" #include "nsIStringBundle.h" -// Needed to fetch scrollbar prefs for image documents that are iframes/frameset frames -#include "nsIScrollable.h" -#include "nsWeakReference.h" -#include "nsRect.h" +#include "nsIPrefService.h" #define NSIMAGEDOCUMENT_PROPERTIES_URI "chrome://communicator/locale/layout/ImageDocument.properties" -static NS_DEFINE_CID(kStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID); - -// done L10N - -// XXX TODO: - -// 1. hookup the original stream to the image library directly so that we -// don't have to load the image twice. - -// 2. have a synthetic document url that we load that has patterns in it -// that we replace with the image url (so that we can customize the -// the presentation of the image): we could add script code to set the -// width/height to provide scale buttons, we could show the image -// attributes; etc.; should we have a seperate style sheet? - -// 3. override the save-as methods so that we don't write out our synthetic -// html +#define AUTOMATIC_IMAGE_RESIZING_PREF "browser.enable_automatic_image_resizing" -class nsImageDocument : public nsHTMLDocument { +class nsImageDocument : public nsHTMLDocument, + public nsIImageDocument, + public nsIStreamListener, + public imgIDecoderObserver, + public nsIDOMEventListener +{ public: nsImageDocument(); virtual ~nsImageDocument(); - NS_IMETHOD StartDocumentLoad(const char* aCommand, - nsIChannel* aChannel, - nsILoadGroup* aLoadGroup, - nsISupports* aContainer, - nsIStreamListener **aDocListener, - PRBool aReset = PR_TRUE, - nsIContentSink* aSink = nsnull); + NS_DECL_ISUPPORTS + + // nsIHTMLDocument + nsresult Init(); + + NS_IMETHOD StartDocumentLoad(const char* aCommand, + nsIChannel* aChannel, + nsILoadGroup* aLoadGroup, + nsISupports* aContainer, + nsIStreamListener** aDocListener, + PRBool aReset = PR_TRUE, + nsIContentSink* aSink = nsnull); NS_IMETHOD SetScriptGlobalObject(nsIScriptGlobalObject* aScriptGlobalObject); - nsresult CreateSyntheticDocument(); + NS_DECL_NSIIMAGEDOCUMENT - nsresult EndLayout(nsISupports *ctxt, - nsresult status); - nsresult UpdateTitle( void ); - - void StartLayout(); - nsCOMPtr mImageRequest; - nscolor mBlack; - nsWeakPtr mContainer; -}; - -//---------------------------------------------------------------------- - -class ImageListener : public nsIStreamListener { -public: - ImageListener(nsImageDocument* aDoc); - virtual ~ImageListener(); - - NS_DECL_ISUPPORTS - // nsIRequestObserver methods: NS_DECL_NSIREQUESTOBSERVER - // nsIStreamListener methods: NS_DECL_NSISTREAMLISTENER - nsImageDocument* mDocument; - nsCOMPtr mNextStream; + NS_DECL_IMGIDECODEROBSERVER + + NS_DECL_IMGICONTAINEROBSERVER + + // nsIDOMEventListener + NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent); + +protected: + nsresult CreateSyntheticDocument(); + + nsresult CheckOverflowing(); + + nsresult StartLayout(); + + nsresult UpdateTitle(); + + nsCOMPtr mStringBundle; + nsCOMPtr mImageElement; + nsCOMPtr mImageRequest; + nsCOMPtr mNextStream; + + nscoord mVisibleWidth; + nscoord mVisibleHeight; + nscoord mImageWidth; + nscoord mImageHeight; + + PRPackedBool mImageResizingEnabled; + PRPackedBool mImageIsOverflowing; + PRPackedBool mImageIsResized; }; -ImageListener::ImageListener(nsImageDocument* aDoc) -{ - mDocument = aDoc; - NS_ADDREF(aDoc); -} - -ImageListener::~ImageListener() -{ - NS_RELEASE(mDocument); -} - -NS_IMPL_THREADSAFE_ISUPPORTS1(ImageListener, nsIStreamListener) - -NS_IMETHODIMP -ImageListener::OnStartRequest(nsIRequest* request, nsISupports *ctxt) -{ - nsCOMPtr channel = do_QueryInterface(request); - if (!channel) return NS_ERROR_NULL_POINTER; - - nsCOMPtr shell; - nsCOMPtr context; - mDocument->GetShellAt(0, getter_AddRefs(shell)); - if (shell) { - shell->GetPresContext(getter_AddRefs(context)); - } - - nsCOMPtr kungFuDeathGrip(this); - nsCOMPtr il(do_GetService("@mozilla.org/image/loader;1")); - il->LoadImageWithChannel(channel, nsnull, context, getter_AddRefs(mNextStream), - getter_AddRefs(mDocument->mImageRequest)); - - // XXX - // if we get a cache hit, and we cancel the channel in the above function, - // do we call OnStopRequest before we call StartLayout? - // if so, should LoadImageWithChannel() not call channel->Cancel() ? - - mDocument->StartLayout(); - - if (nsnull == mNextStream) { - return NS_ERROR_FAILURE; - } - return mNextStream->OnStartRequest(request, ctxt); -} - -NS_IMETHODIMP -ImageListener::OnStopRequest(nsIRequest* request, nsISupports *ctxt, - nsresult status) -{ - if(mDocument){ - mDocument->EndLayout(ctxt, status); - } - - if (nsnull == mNextStream) { - return NS_ERROR_FAILURE; - } - return mNextStream->OnStopRequest(request, ctxt, status); -} - -NS_IMETHODIMP -ImageListener::OnDataAvailable(nsIRequest* request, nsISupports *ctxt, - nsIInputStream *inStr, PRUint32 sourceOffset, PRUint32 count) -{ - if (nsnull == mNextStream) { - return NS_ERROR_FAILURE; - } - return mNextStream->OnDataAvailable(request, ctxt, inStr, sourceOffset, count); -} - -//---------------------------------------------------------------------- - -NS_EXPORT nsresult -NS_NewImageDocument(nsIDocument** aInstancePtrResult) -{ - nsImageDocument* doc = new nsImageDocument(); - NS_ENSURE_TRUE(doc, NS_ERROR_OUT_OF_MEMORY); - - nsresult rv = doc->Init(); - - if (NS_FAILED(rv)) { - delete doc; - - return rv; - } - - *aInstancePtrResult = doc; - NS_ADDREF(*aInstancePtrResult); - - return NS_OK; -} nsImageDocument::nsImageDocument() + : mVisibleWidth(0), + mVisibleHeight(0), + mImageWidth(0), + mImageHeight(0), + mImageResizingEnabled(PR_FALSE), + mImageIsOverflowing(PR_FALSE), + mImageIsResized(PR_FALSE) { - mBlack = NS_RGB(0, 0, 0); } nsImageDocument::~nsImageDocument() { } -NS_IMETHODIMP -nsImageDocument::StartDocumentLoad(const char* aCommand, - nsIChannel* aChannel, - nsILoadGroup* aLoadGroup, - nsISupports* aContainer, - nsIStreamListener **aDocListener, - PRBool aReset, - nsIContentSink* aSink) -{ - NS_ASSERTION(aDocListener, "null aDocListener"); - NS_ENSURE_ARG_POINTER(aContainer); - mContainer = dont_AddRef(NS_GetWeakReference(aContainer)); +NS_IMPL_ADDREF_INHERITED(nsImageDocument, nsHTMLDocument) +NS_IMPL_RELEASE_INHERITED(nsImageDocument, nsHTMLDocument) +NS_INTERFACE_MAP_BEGIN(nsImageDocument) + NS_INTERFACE_MAP_ENTRY(nsIImageDocument) + NS_INTERFACE_MAP_ENTRY(nsIRequestObserver) + NS_INTERFACE_MAP_ENTRY(nsIStreamListener) + NS_INTERFACE_MAP_ENTRY(imgIDecoderObserver) + NS_INTERFACE_MAP_ENTRY(imgIContainerObserver) + NS_INTERFACE_MAP_ENTRY(nsIDOMEventListener) + NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(ImageDocument) +NS_INTERFACE_MAP_END_INHERITING(nsHTMLDocument) + + +nsresult +nsImageDocument::Init() +{ + nsresult rv = nsHTMLDocument::Init(); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr prefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID)); + if (prefBranch) { + PRBool temp = PR_FALSE; + prefBranch->GetBoolPref(AUTOMATIC_IMAGE_RESIZING_PREF, &temp); + mImageResizingEnabled = temp; + } + + // Create a bundle for the localization + nsCOMPtr stringService( + do_GetService(NS_STRINGBUNDLE_CONTRACTID)); + if (stringService) { + stringService->CreateBundle(NSIMAGEDOCUMENT_PROPERTIES_URI, + getter_AddRefs(mStringBundle)); + } + + return NS_OK; +} + +NS_IMETHODIMP +nsImageDocument::StartDocumentLoad(const char* aCommand, + nsIChannel* aChannel, + nsILoadGroup* aLoadGroup, + nsISupports* aContainer, + nsIStreamListener** aDocListener, + PRBool aReset, + nsIContentSink* aSink) +{ nsresult rv = nsDocument::StartDocumentLoad(aCommand, aChannel, aLoadGroup, aContainer, aDocListener, aReset, aSink); @@ -262,15 +210,12 @@ nsImageDocument::StartDocumentLoad(const char* aCommand, // Create synthetic document rv = CreateSyntheticDocument(); - if (NS_OK != rv) { + if (NS_FAILED(rv)) { return rv; } - *aDocListener = new ImageListener(this); - if (!*aDocListener) - return NS_ERROR_OUT_OF_MEMORY; - - NS_ADDREF(*aDocListener); + NS_ASSERTION(aDocListener, "null aDocListener"); + NS_ADDREF(*aDocListener = this); return NS_OK; } @@ -283,11 +228,259 @@ nsImageDocument::SetScriptGlobalObject(nsIScriptGlobalObject* aScriptGlobalObjec // going away soon. Drop our ref to imgRequest so that we don't end // up leaking due to cycles through imgLib mImageRequest = nsnull; + + if (mImageResizingEnabled) { + nsCOMPtr target = do_QueryInterface(mImageElement); + target->RemoveEventListener(NS_LITERAL_STRING("click"), this, PR_FALSE); + + target = do_QueryInterface(mScriptGlobalObject); + target->RemoveEventListener(NS_LITERAL_STRING("resize"), this, PR_FALSE); + target->RemoveEventListener(NS_LITERAL_STRING("keypress"), this, PR_FALSE); + } + } + else { + if (mImageResizingEnabled) { + nsCOMPtr target = do_QueryInterface(mImageElement); + target->AddEventListener(NS_LITERAL_STRING("click"), this, PR_FALSE); + + target = do_QueryInterface(aScriptGlobalObject); + target->AddEventListener(NS_LITERAL_STRING("resize"), this, PR_FALSE); + target->AddEventListener(NS_LITERAL_STRING("keypress"), this, PR_FALSE); + } } return nsHTMLDocument::SetScriptGlobalObject(aScriptGlobalObject); } + +NS_IMETHODIMP +nsImageDocument::GetImageResizingEnabled(PRBool* aImageResizingEnabled) +{ + *aImageResizingEnabled = mImageResizingEnabled; + return NS_OK; +} + +NS_IMETHODIMP +nsImageDocument::GetImageIsOverflowing(PRBool* aImageIsOverflowing) +{ + *aImageIsOverflowing = mImageIsOverflowing; + return NS_OK; +} + +NS_IMETHODIMP +nsImageDocument::GetImageIsResized(PRBool* aImageIsResized) +{ + *aImageIsResized = mImageIsResized; + return NS_OK; +} + +NS_IMETHODIMP +nsImageDocument::ShrinkToFit() +{ + if (mImageResizingEnabled) { + nsCOMPtr image = do_QueryInterface(mImageElement); + + float ratio = PR_MIN((float)mVisibleWidth / mImageWidth, + (float)mVisibleHeight / mImageHeight); + image->SetWidth(NSToCoordFloor(mImageWidth * ratio)); + + mImageElement->SetAttribute(NS_LITERAL_STRING("style"), + NS_LITERAL_STRING("cursor: move")); + + mImageIsResized = PR_TRUE; + } + return NS_OK; +} + +NS_IMETHODIMP +nsImageDocument::RestoreImage() +{ + if (mImageResizingEnabled) { + mImageElement->RemoveAttribute(NS_LITERAL_STRING("width")); + + if (!mImageIsOverflowing) { + mImageElement->RemoveAttribute(NS_LITERAL_STRING("style")); + } + + mImageIsResized = PR_FALSE; + } + + return NS_OK; +} + +NS_IMETHODIMP +nsImageDocument::ToggleImageSize() +{ + if (mImageResizingEnabled) { + if (mImageIsResized) { + RestoreImage(); + } + else if (mImageIsOverflowing) { + ShrinkToFit(); + } + } + + return NS_OK; +} + +NS_IMETHODIMP +nsImageDocument::OnStartRequest(nsIRequest* request, nsISupports *ctxt) +{ + nsCOMPtr channel = do_QueryInterface(request); + if (!channel) { + return NS_ERROR_FAILURE; + } + + nsCOMPtr shell; + nsCOMPtr context; + GetShellAt(0, getter_AddRefs(shell)); + if (shell) { + shell->GetPresContext(getter_AddRefs(context)); + } + + nsCOMPtr il(do_GetService("@mozilla.org/image/loader;1")); + il->LoadImageWithChannel(channel, this, context, getter_AddRefs(mNextStream), + getter_AddRefs(mImageRequest)); + + StartLayout(); + + if (mNextStream) { + return mNextStream->OnStartRequest(request, ctxt); + } + + return NS_OK; +} + +NS_IMETHODIMP +nsImageDocument::OnStopRequest(nsIRequest* request, nsISupports *ctxt, + nsresult status) +{ + UpdateTitle(); + + if (mNextStream) { + return mNextStream->OnStopRequest(request, ctxt, status); + } + + return NS_OK; +} + +NS_IMETHODIMP +nsImageDocument::OnDataAvailable(nsIRequest* request, nsISupports *ctxt, + nsIInputStream *inStr, PRUint32 sourceOffset, PRUint32 count) +{ + if (mNextStream) { + return mNextStream->OnDataAvailable(request, ctxt, inStr, sourceOffset, count); + } + + return NS_OK; +} + + +NS_IMETHODIMP +nsImageDocument::OnStartDecode(imgIRequest* aRequest, + nsISupports* aCX) +{ + return NS_OK; +} + +NS_IMETHODIMP +nsImageDocument::OnStartContainer(imgIRequest* aRequest, + nsISupports* aCX, + imgIContainer* aImage) +{ + aImage->GetWidth(&mImageWidth); + aImage->GetHeight(&mImageHeight); + if (mImageResizingEnabled) { + CheckOverflowing(); + } + + return NS_OK; +} + +NS_IMETHODIMP +nsImageDocument::OnStartFrame(imgIRequest* aRequest, + nsISupports* aCX, + gfxIImageFrame* aFrame) +{ + return NS_OK; +} + +NS_IMETHODIMP +nsImageDocument::OnDataAvailable(imgIRequest* aRequest, + nsISupports *aCX, + gfxIImageFrame* aFrame, + const nsRect* aRect) +{ + return NS_OK; +} + +NS_IMETHODIMP +nsImageDocument::OnStopFrame(imgIRequest* aRequest, + nsISupports* aCX, + gfxIImageFrame* aFrame) +{ + return NS_OK; +} + +NS_IMETHODIMP +nsImageDocument::OnStopContainer(imgIRequest* aRequest, + nsISupports* aCX, + imgIContainer* aImage) +{ + return NS_OK; +} + +NS_IMETHODIMP +nsImageDocument::OnStopDecode(imgIRequest* aRequest, + nsISupports* aCX, + nsresult status, + const PRUnichar* statusArg) +{ + return NS_OK; +} + +NS_IMETHODIMP +nsImageDocument::FrameChanged(imgIContainer* aContainer, + nsISupports *aCX, + gfxIImageFrame* aFrame, + nsRect* aDirtyRect) +{ + return NS_OK; +} + + +NS_IMETHODIMP +nsImageDocument::HandleEvent(nsIDOMEvent* aEvent) +{ + nsAutoString eventType; + aEvent->GetType(eventType); + if (eventType.Equals(NS_LITERAL_STRING("resize"))) { + CheckOverflowing(); + } + else if (eventType.Equals(NS_LITERAL_STRING("click"))) { + ToggleImageSize(); + } + else if (eventType.Equals(NS_LITERAL_STRING("keypress"))) { + nsCOMPtr keyEvent = do_QueryInterface(aEvent); + PRUint32 charCode; + keyEvent->GetCharCode(&charCode); + // plus key + if (charCode == 0x2B) { + if (mImageIsResized) { + RestoreImage(); + } + } + // minus key + else if (charCode == 0x2D) { + if (mImageIsOverflowing) { + ShrinkToFit(); + } + } + } + + return NS_OK; +} + nsresult nsImageDocument::CreateSyntheticDocument() { @@ -300,9 +493,9 @@ nsImageDocument::CreateSyntheticDocument() *getter_AddRefs(nodeInfo)); NS_ENSURE_SUCCESS(rv, rv); - nsIHTMLContent* root; - rv = NS_NewHTMLHtmlElement(&root, nodeInfo); - if (NS_OK != rv) { + nsCOMPtr root; + rv = NS_NewHTMLHtmlElement(getter_AddRefs(root), nodeInfo); + if (NS_FAILED(rv)) { return rv; } root->SetDocument(this, PR_FALSE, PR_TRUE); @@ -313,179 +506,155 @@ nsImageDocument::CreateSyntheticDocument() *getter_AddRefs(nodeInfo)); NS_ENSURE_SUCCESS(rv, rv); - nsIHTMLContent* body; - rv = NS_NewHTMLBodyElement(&body, nodeInfo); - if (NS_OK != rv) { + nsCOMPtr body; + rv = NS_NewHTMLBodyElement(getter_AddRefs(body), nodeInfo); + if (NS_FAILED(rv)) { return rv; } body->SetDocument(this, PR_FALSE, PR_TRUE); - - rv = mNodeInfoManager->GetNodeInfo(nsHTMLAtoms::p, nsnull, kNameSpaceID_None, - *getter_AddRefs(nodeInfo)); - NS_ENSURE_SUCCESS(rv, rv); - - nsIHTMLContent* center; - rv = NS_NewHTMLParagraphElement(¢er, nodeInfo); - if (NS_OK != rv) { - return rv; - } - center->SetDocument(this, PR_FALSE, PR_TRUE); + mBodyContent = do_QueryInterface(body); rv = mNodeInfoManager->GetNodeInfo(nsHTMLAtoms::img, nsnull, kNameSpaceID_None, *getter_AddRefs(nodeInfo)); NS_ENSURE_SUCCESS(rv, rv); - nsIHTMLContent* image; - rv = NS_NewHTMLImageElement(&image, nodeInfo); - if (NS_OK != rv) { + nsCOMPtr image; + rv = NS_NewHTMLImageElement(getter_AddRefs(image), nodeInfo); + if (NS_FAILED(rv)) { return rv; } image->SetDocument(this, PR_FALSE, PR_TRUE); + mImageElement = do_QueryInterface(image); nsCAutoString src; mDocumentURL->GetSpec(src); - NS_ConvertUTF8toUCS2 src_string(src); - nsHTMLValue val(src_string); + NS_ConvertUTF8toUCS2 srcString(src); + nsHTMLValue val(srcString); image->SetHTMLAttribute(nsHTMLAtoms::src, val, PR_FALSE); - // Create a stringbundle for localized error message - nsCOMPtr bundle; - nsCOMPtr stringService = - do_GetService(kStringBundleServiceCID, &rv); - if (NS_SUCCEEDED(rv) && stringService) - rv = stringService->CreateBundle(NSIMAGEDOCUMENT_PROPERTIES_URI, getter_AddRefs(bundle)); - if (NS_SUCCEEDED(rv) && bundle) { - const PRUnichar* formatString[1] = { src_string.get() }; + if (mStringBundle) { + const PRUnichar* formatString[1] = { srcString.get() }; nsXPIDLString errorMsg; - rv = bundle->FormatStringFromName(NS_LITERAL_STRING("InvalidImage").get(), formatString, 1, getter_Copies(errorMsg)); + rv = mStringBundle->FormatStringFromName(NS_LITERAL_STRING("InvalidImage").get(), + formatString, 1, getter_Copies(errorMsg)); nsHTMLValue errorText(errorMsg); image->SetHTMLAttribute(nsHTMLAtoms::alt, errorText, PR_FALSE); } root->AppendChildTo(body, PR_FALSE, PR_FALSE); - center->AppendChildTo(image, PR_FALSE, PR_FALSE); - body->AppendChildTo(center, PR_FALSE, PR_FALSE); - - NS_RELEASE(image); - NS_RELEASE(center); - NS_RELEASE(body); - NS_RELEASE(root); + body->AppendChildTo(image, PR_FALSE, PR_FALSE); return NS_OK; } -void +nsresult +nsImageDocument::CheckOverflowing() +{ + nsCOMPtr shell; + GetShellAt(0, getter_AddRefs(shell)); + if (!shell) { + return NS_OK; + } + + nsCOMPtr context; + shell->GetPresContext(getter_AddRefs(context)); + + nsRect visibleArea; + context->GetVisibleArea(visibleArea); + + nsCOMPtr styleContext; + nsCOMPtr content = do_QueryInterface(mBodyContent); + context->ResolveStyleContextFor(content, nsnull, getter_AddRefs(styleContext)); + + const nsStyleMargin* marginData = + (const nsStyleMargin*)styleContext->GetStyleData(eStyleStruct_Margin); + nsMargin margin; + marginData->GetMargin(margin); + visibleArea.Deflate(margin); + + nsStyleBorderPadding bPad; + styleContext->GetBorderPaddingFor(bPad); + bPad.GetBorderPadding(margin); + visibleArea.Deflate(margin); + + float t2p; + context->GetTwipsToPixels(&t2p); + mVisibleWidth = NSTwipsToIntPixels(visibleArea.width, t2p); + mVisibleHeight = NSTwipsToIntPixels(visibleArea.height, t2p); + + mImageIsOverflowing = mImageWidth > mVisibleWidth || mImageHeight > mVisibleHeight; + + if (mImageIsOverflowing) { + ShrinkToFit(); + } + else if (mImageIsResized) { + RestoreImage(); + } + + return NS_OK; +} + +nsresult nsImageDocument::StartLayout() { - // Reset scrolling to default settings for this shell. // This must happen before the initial reflow, when we create the root frame - nsCOMPtr scrollableContainer(do_QueryReferent(mContainer)); + nsCOMPtr scrollableContainer(do_QueryReferent(mDocumentContainer)); if (scrollableContainer) { scrollableContainer->ResetScrollbarPreferences(); } - - PRInt32 i, ns = GetNumberOfShells(); - for (i = 0; i < ns; i++) { + PRInt32 numberOfShells = GetNumberOfShells(); + for (PRInt32 i = 0; i < numberOfShells; i++) { nsCOMPtr shell; GetShellAt(i, getter_AddRefs(shell)); - if (nsnull != shell) { - // Make shell an observer for next time + if (shell) { + // Make shell an observer for next time. shell->BeginObservingDocument(); - // Resize-reflow this time - nsCOMPtr cx; - shell->GetPresContext(getter_AddRefs(cx)); - nsRect r; - cx->GetVisibleArea(r); - shell->InitialReflow(r.width, r.height); + // Initial-reflow this time. + nsCOMPtr context; + shell->GetPresContext(getter_AddRefs(context)); + nsRect visibleArea; + context->GetVisibleArea(visibleArea); + shell->InitialReflow(visibleArea.width, visibleArea.height); - // Now trigger a refresh - // XXX It's unfortunate that this has to be here + // Now trigger a refresh. nsCOMPtr vm; shell->GetViewManager(getter_AddRefs(vm)); if (vm) { vm->EnableRefresh(NS_VMREFRESH_IMMEDIATE); } - } } -} - -nsresult -nsImageDocument::EndLayout(nsISupports *ctxt, - nsresult status) -{ - // Layout has completed: now update the title - UpdateTitle(); return NS_OK; } - -// NOTE: call this AFTER the shell has been installed as an observer of the -// document so the update notification gets processed by the shell -// and it updates the titlebar -nsresult nsImageDocument::UpdateTitle( void ) +nsresult nsImageDocument::UpdateTitle() { -#ifdef USE_EXTENSION_FOR_TYPE - // XXX TEMPORARY XXX - // We want to display the image type, however there is no way to right now - // so instead we just get the image-extension - // - get the URL interface, get the extension, convert to upper-case - // Unless the Imagerequest or Image can tell us the type this is the best we can do. - nsCOMPtr url = do_QueryInterface(mDocumentURL); - if (url) { - nsXPIDLCString extension; - url->GetFileExtension(getter_Copies(extension)); - ToUpperCase(extension); - titleStr.AppendWithConversion(extension); - } -#endif - - nsCOMPtr bundle; - nsresult rv; - // Create a bundle for the localization - nsCOMPtr stringService = - do_GetService(kStringBundleServiceCID, &rv); - if (NS_SUCCEEDED(rv) && stringService) { - rv = stringService->CreateBundle(NSIMAGEDOCUMENT_PROPERTIES_URI, getter_AddRefs(bundle)); - } - if (NS_SUCCEEDED(rv) && bundle) { - nsXPIDLString valUni; + if (mStringBundle) { + nsXPIDLString fileStr; nsAutoString widthStr; nsAutoString heightStr; - nsXPIDLString fileStr; nsAutoString typeStr; - PRUint32 width = 0, height = 0; + nsXPIDLString valUni; nsCOMPtr url = do_QueryInterface(mDocumentURL); if (url) { - nsCAutoString pName; - url->GetFileName(pName); - fileStr.Assign(NS_ConvertUTF8toUCS2(pName)); + nsCAutoString fileName; + url->GetFileName(fileName); + fileStr.Assign(NS_ConvertUTF8toUCS2(fileName)); } + widthStr.AppendInt(mImageWidth); + heightStr.AppendInt(mImageHeight); + if (mImageRequest) { - imgIContainer* imgContainer; - rv = mImageRequest->GetImage(&imgContainer); - if (NS_SUCCEEDED(rv) && imgContainer) { - nscoord w = 0, h = 0; - imgContainer->GetWidth(&w); - imgContainer->GetHeight(&h); - width = w; - height = h; - NS_RELEASE(imgContainer); - } - - widthStr.AppendInt(width); - heightStr.AppendInt(height); - nsXPIDLCString mimeType; mImageRequest->GetMimeType(getter_Copies(mimeType)); ToUpperCase(mimeType); @@ -512,31 +681,54 @@ nsresult nsImageDocument::UpdateTitle( void ) CopyASCIItoUCS2(mimeType, typeStr); } } + // If we got a filename, display it if (!fileStr.IsEmpty()) { // if we got a valid size (sometimes we do not) then display it - if (width != 0 && height != 0){ + if (mImageWidth != 0 && mImageHeight != 0){ const PRUnichar *formatStrings[4] = {fileStr.get(), typeStr.get(), widthStr.get(), heightStr.get()}; - rv = bundle->FormatStringFromName(NS_LITERAL_STRING("ImageTitleWithDimensionsAndFile").get(), formatStrings, 4, getter_Copies(valUni)); + mStringBundle->FormatStringFromName(NS_LITERAL_STRING("ImageTitleWithDimensionsAndFile").get(), formatStrings, 4, getter_Copies(valUni)); } else { const PRUnichar *formatStrings[2] = {fileStr.get(), typeStr.get()}; - rv = bundle->FormatStringFromName(NS_LITERAL_STRING("ImageTitleWithoutDimensions").get(), formatStrings, 2, getter_Copies(valUni)); + mStringBundle->FormatStringFromName(NS_LITERAL_STRING("ImageTitleWithoutDimensions").get(), formatStrings, 2, getter_Copies(valUni)); } } else { // if we got a valid size (sometimes we do not) then display it - if (width != 0 && height != 0){ + if (mImageWidth != 0 && mImageHeight != 0){ const PRUnichar *formatStrings[3] = {typeStr.get(), widthStr.get(), heightStr.get()}; - rv = bundle->FormatStringFromName(NS_LITERAL_STRING("ImageTitleWithDimensions").get(), formatStrings, 3, getter_Copies(valUni)); + mStringBundle->FormatStringFromName(NS_LITERAL_STRING("ImageTitleWithDimensions").get(), formatStrings, 3, getter_Copies(valUni)); } else { const PRUnichar *formatStrings[1] = {typeStr.get()}; - rv = bundle->FormatStringFromName(NS_LITERAL_STRING("ImageTitleWithNeitherDimensionsNorFile").get(), formatStrings, 1, getter_Copies(valUni)); + mStringBundle->FormatStringFromName(NS_LITERAL_STRING("ImageTitleWithNeitherDimensionsNorFile").get(), formatStrings, 1, getter_Copies(valUni)); } } - if (NS_SUCCEEDED(rv) && valUni) { + if (valUni) { // set it on the document SetTitle(valUni); } } + + return NS_OK; +} + + +nsresult +NS_NewImageDocument(nsIDocument** aResult) +{ + nsImageDocument* doc = new nsImageDocument(); + if (!doc) { + return NS_ERROR_OUT_OF_MEMORY; + } + + nsresult rv = doc->Init(); + + if (NS_FAILED(rv)) { + delete doc; + return rv; + } + + NS_ADDREF(*aResult = doc); + return NS_OK; } diff --git a/content/macbuild/contentIDL.xml b/content/macbuild/contentIDL.xml index 26737070a68..2d78f49c23b 100644 --- a/content/macbuild/contentIDL.xml +++ b/content/macbuild/contentIDL.xml @@ -879,6 +879,13 @@ Text + + Name + nsIImageDocument.idl + MacOS + Text + + Name nsIWyciwygChannel.idl @@ -1036,6 +1043,11 @@ nsITextAreaElement.idl MacOS + + Name + nsIImageDocument.idl + MacOS + Name nsIWyciwygChannel.idl @@ -1914,6 +1926,13 @@ Text + + Name + nsIImageDocument.idl + MacOS + Text + + Name nsIWyciwygChannel.idl @@ -2071,6 +2090,11 @@ nsITextAreaElement.idl MacOS + + Name + nsIImageDocument.idl + MacOS + Name nsIWyciwygChannel.idl @@ -2233,6 +2257,12 @@ nsITextAreaElement.idl MacOS + + headers + Name + nsIImageDocument.idl + MacOS + headers Name diff --git a/dom/public/nsIDOMClassInfo.h b/dom/public/nsIDOMClassInfo.h index 1b232be073a..66f3a5a8cfe 100644 --- a/dom/public/nsIDOMClassInfo.h +++ b/dom/public/nsIDOMClassInfo.h @@ -87,6 +87,7 @@ enum nsDOMClassInfoID { eDOMClassInfo_HTMLOptionCollection_id, eDOMClassInfo_HTMLFormControlCollection_id, eDOMClassInfo_HTMLGenericCollection_id, + eDOMClassInfo_ImageDocument_id, // HTML element classes eDOMClassInfo_HTMLAnchorElement_id, diff --git a/dom/src/base/nsDOMClassInfo.cpp b/dom/src/base/nsDOMClassInfo.cpp index d4526ac0b1c..21b7f3f23cd 100644 --- a/dom/src/base/nsDOMClassInfo.cpp +++ b/dom/src/base/nsDOMClassInfo.cpp @@ -110,6 +110,7 @@ #include "nsIDOMNSHTMLFormControlList.h" #include "nsIDOMHTMLCollection.h" #include "nsIHTMLDocument.h" +#include "nsIImageDocument.h" // HTMLSelectElement helper includes #include "nsIDOMHTMLSelectElement.h" @@ -471,6 +472,9 @@ static nsDOMClassInfoData sClassInfoData[] = { NS_DEFINE_CLASSINFO_DATA(HTMLDocument, nsHTMLDocumentSH, DOCUMENT_SCRIPTABLE_FLAGS | nsIXPCScriptable::WANT_ENUMERATE) + NS_DEFINE_CLASSINFO_DATA(ImageDocument, nsHTMLDocumentSH, + DOCUMENT_SCRIPTABLE_FLAGS | + nsIXPCScriptable::WANT_ENUMERATE) NS_DEFINE_CLASSINFO_DATA(HTMLCollection, nsHTMLCollectionSH, ARRAY_SCRIPTABLE_FLAGS) NS_DEFINE_CLASSINFO_DATA(HTMLOptionCollection, @@ -1415,6 +1419,21 @@ nsDOMClassInfo::Init() DOM_CLASSINFO_MAP_ENTRY(nsIDOM3Node) DOM_CLASSINFO_MAP_END_WITH_XPATH + DOM_CLASSINFO_MAP_BEGIN(ImageDocument, nsIImageDocument) + DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLDocument) + DOM_CLASSINFO_MAP_ENTRY(nsIImageDocument) + DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSHTMLDocument) + DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSDocument) + DOM_CLASSINFO_MAP_ENTRY(nsIDOMDocumentEvent) + DOM_CLASSINFO_MAP_ENTRY(nsIDOMDocumentStyle) + DOM_CLASSINFO_MAP_ENTRY(nsIDOMDocumentView) + DOM_CLASSINFO_MAP_ENTRY(nsIDOMDocumentRange) + DOM_CLASSINFO_MAP_ENTRY(nsIDOMDocumentTraversal) + DOM_CLASSINFO_MAP_ENTRY(nsIDOMDocumentXBL) + DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget) + DOM_CLASSINFO_MAP_ENTRY(nsIDOM3Node) + DOM_CLASSINFO_MAP_END + DOM_CLASSINFO_MAP_BEGIN(HTMLCollection, nsIDOMHTMLCollection) DOM_CLASSINFO_MAP_ENTRY(nsIDOMNodeList) DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLCollection) diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js index 911b0e1cb11..0ced59e4787 100644 --- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -93,6 +93,7 @@ pref("browser.anchor_color", "#0000EE"); pref("browser.visited_color", "#551A8B"); pref("browser.underline_anchors", true); pref("browser.blink_allowed", true); +pref("browser.enable_automatic_image_resizing", false); pref("browser.display.use_focus_colors", false); pref("browser.display.focus_background_color", "#117722"); diff --git a/xpfe/communicator/resources/content/contentAreaContextOverlay.xul b/xpfe/communicator/resources/content/contentAreaContextOverlay.xul index 4ccec3c1203..eee73c4bb34 100644 --- a/xpfe/communicator/resources/content/contentAreaContextOverlay.xul +++ b/xpfe/communicator/resources/content/contentAreaContextOverlay.xul @@ -83,6 +83,11 @@ accesskey="©LinkCmd.accesskey;" command="cmd_copyLink"/> + + + diff --git a/xpfe/components/prefwindow/resources/content/pref-appearance.xul b/xpfe/components/prefwindow/resources/content/pref-appearance.xul index c449f915ef0..6d47e840d56 100644 --- a/xpfe/components/prefwindow/resources/content/pref-appearance.xul +++ b/xpfe/components/prefwindow/resources/content/pref-appearance.xul @@ -37,7 +37,10 @@ @@ -71,6 +74,11 @@ accesskey="&useSiteIcons.accesskey;" prefstring="browser.chrome.site_icons"/> + + diff --git a/xpfe/components/prefwindow/resources/locale/en-US/pref-appearance.dtd b/xpfe/components/prefwindow/resources/locale/en-US/pref-appearance.dtd index 19ea2e9eaba..6e7311870d1 100644 --- a/xpfe/components/prefwindow/resources/locale/en-US/pref-appearance.dtd +++ b/xpfe/components/prefwindow/resources/locale/en-US/pref-appearance.dtd @@ -27,6 +27,8 @@ + +