2007-03-22 10:30:00 -07:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=2 sw=2 et tw=80: */
|
|
|
|
/* ***** BEGIN LICENSE BLOCK *****
|
|
|
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
|
|
*
|
|
|
|
* The contents of this file are subject to the Mozilla Public License Version
|
|
|
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
|
|
|
* the License. You may obtain a copy of the License at
|
|
|
|
* http://www.mozilla.org/MPL/
|
|
|
|
*
|
|
|
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
|
|
* for the specific language governing rights and limitations under the
|
|
|
|
* License.
|
|
|
|
*
|
|
|
|
* The Original Code is Mozilla Communicator client code.
|
|
|
|
*
|
|
|
|
* The Initial Developer of the Original Code is
|
|
|
|
* Netscape Communications Corporation.
|
|
|
|
* Portions created by the Initial Developer are Copyright (C) 1998
|
|
|
|
* the Initial Developer. All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s):
|
|
|
|
* Dan Rosen <dr@netscape.com>
|
|
|
|
* Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
|
2011-08-24 13:54:30 -07:00
|
|
|
* Mats Palmgren <matspal@gmail.com>
|
2007-03-22 10:30:00 -07:00
|
|
|
*
|
|
|
|
* Alternatively, the contents of this file may be used under the terms of
|
|
|
|
* either of 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"),
|
|
|
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
|
|
* of those above. If you wish to allow use of your version of this file only
|
|
|
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|
|
|
* use your version of this file under the terms of the MPL, indicate your
|
|
|
|
* decision by deleting the provisions above and replace them with the notice
|
|
|
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
|
|
* the provisions above, a recipient may use your version of this file under
|
|
|
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
|
|
|
*
|
|
|
|
* ***** END LICENSE BLOCK ***** */
|
|
|
|
|
|
|
|
/* container for a document and its presentation */
|
|
|
|
|
|
|
|
#include "nscore.h"
|
|
|
|
#include "nsCOMPtr.h"
|
|
|
|
#include "nsCRT.h"
|
|
|
|
#include "nsString.h"
|
|
|
|
#include "nsReadableUtils.h"
|
|
|
|
#include "nsISupports.h"
|
|
|
|
#include "nsIContent.h"
|
|
|
|
#include "nsIContentViewerContainer.h"
|
2011-10-15 00:33:26 -07:00
|
|
|
#include "nsIContentViewer.h"
|
2010-04-30 12:40:59 -07:00
|
|
|
#include "mozilla/FunctionTimer.h"
|
2007-03-22 10:30:00 -07:00
|
|
|
#include "nsIDocumentViewerPrint.h"
|
2009-06-24 01:42:00 -07:00
|
|
|
#include "nsIPrivateDOMEvent.h"
|
|
|
|
#include "nsIDOMBeforeUnloadEvent.h"
|
2007-03-22 10:30:00 -07:00
|
|
|
#include "nsIDocument.h"
|
|
|
|
#include "nsPresContext.h"
|
|
|
|
#include "nsIPresShell.h"
|
|
|
|
#include "nsStyleSet.h"
|
|
|
|
#include "nsIStyleSheet.h"
|
2010-05-11 13:41:47 -07:00
|
|
|
#include "nsCSSStyleSheet.h"
|
2007-03-22 10:30:00 -07:00
|
|
|
#include "nsIFrame.h"
|
2010-09-18 04:28:50 -07:00
|
|
|
#include "nsSubDocumentFrame.h"
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
#include "nsILinkHandler.h"
|
|
|
|
#include "nsIDOMDocument.h"
|
|
|
|
#include "nsISelectionListener.h"
|
|
|
|
#include "nsISelectionPrivate.h"
|
|
|
|
#include "nsIDOMHTMLDocument.h"
|
|
|
|
#include "nsIDOMHTMLCollection.h"
|
|
|
|
#include "nsIDOMHTMLElement.h"
|
|
|
|
#include "nsIDOMRange.h"
|
|
|
|
#include "nsContentCID.h"
|
|
|
|
#include "nsLayoutCID.h"
|
|
|
|
#include "nsContentUtils.h"
|
|
|
|
#include "nsLayoutStylesheetCache.h"
|
2011-05-28 00:03:00 -07:00
|
|
|
#include "mozilla/Preferences.h"
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
#include "nsViewsCID.h"
|
|
|
|
#include "nsIDeviceContextSpec.h"
|
|
|
|
#include "nsIViewManager.h"
|
|
|
|
#include "nsIView.h"
|
|
|
|
|
|
|
|
#include "nsIPageSequenceFrame.h"
|
|
|
|
#include "nsIURL.h"
|
|
|
|
#include "nsNetUtil.h"
|
|
|
|
#include "nsIContentViewerEdit.h"
|
|
|
|
#include "nsIContentViewerFile.h"
|
2010-06-28 15:49:35 -07:00
|
|
|
#include "mozilla/css/Loader.h"
|
2007-03-22 10:30:00 -07:00
|
|
|
#include "nsIMarkupDocumentViewer.h"
|
|
|
|
#include "nsIInterfaceRequestor.h"
|
|
|
|
#include "nsIInterfaceRequestorUtils.h"
|
|
|
|
#include "nsIDocShellTreeItem.h"
|
|
|
|
#include "nsIDocShellTreeNode.h"
|
|
|
|
#include "nsIDocShellTreeOwner.h"
|
|
|
|
#include "nsIDocShell.h"
|
|
|
|
#include "nsIBaseWindow.h"
|
|
|
|
#include "nsILayoutHistoryState.h"
|
|
|
|
#include "nsIParser.h"
|
|
|
|
#include "nsGUIEvent.h"
|
|
|
|
#include "nsHTMLReflowState.h"
|
|
|
|
#include "nsIDOMHTMLAnchorElement.h"
|
|
|
|
#include "nsIDOMHTMLAreaElement.h"
|
|
|
|
#include "nsIDOMHTMLLinkElement.h"
|
|
|
|
#include "nsIImageLoadingContent.h"
|
|
|
|
#include "nsCopySupport.h"
|
|
|
|
#include "nsIDOMHTMLFrameSetElement.h"
|
|
|
|
#ifdef MOZ_XUL
|
|
|
|
#include "nsIXULDocument.h"
|
2007-07-04 08:49:38 -07:00
|
|
|
#include "nsXULPopupManager.h"
|
2007-07-23 17:04:36 -07:00
|
|
|
#endif
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
#include "nsIClipboardHelper.h"
|
|
|
|
|
|
|
|
#include "nsPIDOMWindow.h"
|
2011-06-23 03:39:48 -07:00
|
|
|
#include "nsDOMNavigationTiming.h"
|
2010-02-20 08:07:03 -08:00
|
|
|
#include "nsPIWindowRoot.h"
|
2007-03-22 10:30:00 -07:00
|
|
|
#include "nsJSEnvironment.h"
|
Bug 178324, refactor focus by moving all focus handling into one place and simplifying it, add many tests, fixes many other bugs too numerous to mention in this small checkin comment, r=josh,smichaud,ere,dbaron,marco,neil,gavin,smaug,sr=smaug (CLOSED TREE)
2009-06-10 11:00:39 -07:00
|
|
|
#include "nsFocusManager.h"
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2009-09-02 21:26:00 -07:00
|
|
|
#include "nsIScrollableFrame.h"
|
2007-03-22 10:30:00 -07:00
|
|
|
#include "nsIHTMLDocument.h"
|
|
|
|
#include "nsGfxCIID.h"
|
|
|
|
#include "nsStyleSheetService.h"
|
2009-02-16 03:27:22 -08:00
|
|
|
#include "nsURILoader.h"
|
2011-04-07 18:04:40 -07:00
|
|
|
#include "nsRenderingContext.h"
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
#include "nsIPrompt.h"
|
|
|
|
#include "imgIContainer.h" // image animation mode constants
|
|
|
|
|
|
|
|
//--------------------------
|
|
|
|
// Printing Include
|
|
|
|
//---------------------------
|
|
|
|
#ifdef NS_PRINTING
|
|
|
|
|
|
|
|
#include "nsIWebBrowserPrint.h"
|
|
|
|
|
|
|
|
#include "nsPrintEngine.h"
|
|
|
|
|
|
|
|
// Print Options
|
|
|
|
#include "nsIPrintSettings.h"
|
|
|
|
#include "nsIPrintSettingsService.h"
|
|
|
|
#include "nsIPrintOptions.h"
|
|
|
|
#include "nsIServiceManager.h"
|
|
|
|
#include "nsISimpleEnumerator.h"
|
|
|
|
#include "nsXPCOM.h"
|
|
|
|
#include "nsISupportsPrimitives.h"
|
|
|
|
|
|
|
|
// PrintOptions is now implemented by PrintSettingsService
|
|
|
|
static const char sPrintOptionsContractID[] = "@mozilla.org/gfx/printsettings-service;1";
|
|
|
|
|
|
|
|
// Printing Events
|
|
|
|
#include "nsPrintPreviewListener.h"
|
|
|
|
|
|
|
|
#include "nsIDOMHTMLFrameElement.h"
|
|
|
|
#include "nsIDOMHTMLIFrameElement.h"
|
|
|
|
#include "nsIDOMHTMLObjectElement.h"
|
|
|
|
#include "nsIPluginDocument.h"
|
|
|
|
|
|
|
|
// Print Progress
|
|
|
|
#include "nsIPrintProgress.h"
|
|
|
|
#include "nsIPrintProgressParams.h"
|
|
|
|
|
|
|
|
// Print error dialog
|
|
|
|
#include "nsIWindowWatcher.h"
|
|
|
|
|
|
|
|
// Printing
|
|
|
|
#include "nsPrintEngine.h"
|
|
|
|
#include "nsPagePrintTimer.h"
|
|
|
|
|
|
|
|
#endif // NS_PRINTING
|
|
|
|
|
|
|
|
// FrameSet
|
|
|
|
#include "nsIDocument.h"
|
|
|
|
|
|
|
|
//focus
|
2007-05-14 02:11:38 -07:00
|
|
|
#include "nsIDOMEventTarget.h"
|
2011-06-28 10:59:14 -07:00
|
|
|
#include "nsIDOMEventListener.h"
|
2007-03-22 10:30:00 -07:00
|
|
|
#include "nsISelectionController.h"
|
|
|
|
|
|
|
|
#include "nsBidiUtils.h"
|
|
|
|
#include "nsISHEntry.h"
|
|
|
|
#include "nsISHistory.h"
|
|
|
|
#include "nsISHistoryInternal.h"
|
|
|
|
#include "nsIWebNavigation.h"
|
|
|
|
#include "nsWeakPtr.h"
|
|
|
|
#include "nsEventDispatcher.h"
|
|
|
|
|
|
|
|
//paint forcing
|
|
|
|
#include "prenv.h"
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
//switch to page layout
|
|
|
|
#include "nsGfxCIID.h"
|
|
|
|
|
2011-07-20 12:18:54 -07:00
|
|
|
#include "mozilla/dom/Element.h"
|
|
|
|
|
2011-05-28 00:03:00 -07:00
|
|
|
using namespace mozilla;
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
#ifdef NS_DEBUG
|
|
|
|
|
|
|
|
#undef NOISY_VIEWER
|
|
|
|
#else
|
|
|
|
#undef NOISY_VIEWER
|
|
|
|
#endif
|
|
|
|
|
|
|
|
//-----------------------------------------------------
|
|
|
|
// PR LOGGING
|
|
|
|
#ifdef MOZ_LOGGING
|
|
|
|
#define FORCE_PR_LOG /* Allow logging in the release build */
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "prlog.h"
|
|
|
|
|
|
|
|
#ifdef PR_LOGGING
|
|
|
|
|
|
|
|
static PRLogModuleInfo * kPrintingLogMod = PR_NewLogModule("printing");
|
|
|
|
#define PR_PL(_p1) PR_LOG(kPrintingLogMod, PR_LOG_DEBUG, _p1);
|
|
|
|
|
|
|
|
#define PRT_YESNO(_p) ((_p)?"YES":"NO")
|
|
|
|
#else
|
|
|
|
#define PRT_YESNO(_p)
|
|
|
|
#define PR_PL(_p1)
|
|
|
|
#endif
|
|
|
|
//-----------------------------------------------------
|
|
|
|
|
|
|
|
class DocumentViewerImpl;
|
|
|
|
|
|
|
|
// a small delegate class used to avoid circular references
|
|
|
|
|
|
|
|
class nsDocViewerSelectionListener : public nsISelectionListener
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
// nsISupports interface...
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
|
|
|
|
// nsISelectionListerner interface
|
|
|
|
NS_DECL_NSISELECTIONLISTENER
|
|
|
|
|
|
|
|
nsDocViewerSelectionListener()
|
|
|
|
: mDocViewer(NULL)
|
|
|
|
, mGotSelectionState(PR_FALSE)
|
|
|
|
, mSelectionWasCollapsed(PR_FALSE)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual ~nsDocViewerSelectionListener() {}
|
|
|
|
|
|
|
|
nsresult Init(DocumentViewerImpl *aDocViewer);
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
|
|
|
DocumentViewerImpl* mDocViewer;
|
2011-09-28 23:19:26 -07:00
|
|
|
bool mGotSelectionState;
|
|
|
|
bool mSelectionWasCollapsed;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/** editor Implementation of the FocusListener interface
|
|
|
|
*/
|
2011-06-28 10:59:14 -07:00
|
|
|
class nsDocViewerFocusListener : public nsIDOMEventListener
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
/** default constructor
|
|
|
|
*/
|
|
|
|
nsDocViewerFocusListener();
|
|
|
|
/** default destructor
|
|
|
|
*/
|
|
|
|
virtual ~nsDocViewerFocusListener();
|
|
|
|
|
|
|
|
NS_DECL_ISUPPORTS
|
2011-06-28 10:59:14 -07:00
|
|
|
NS_DECL_NSIDOMEVENTLISTENER
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
nsresult Init(DocumentViewerImpl *aDocViewer);
|
|
|
|
|
|
|
|
private:
|
|
|
|
DocumentViewerImpl* mDocViewer;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
2011-10-15 00:33:26 -07:00
|
|
|
class DocumentViewerImpl : public nsIContentViewer,
|
2007-03-22 10:30:00 -07:00
|
|
|
public nsIContentViewerEdit,
|
|
|
|
public nsIContentViewerFile,
|
2011-05-30 09:36:23 -07:00
|
|
|
public nsIMarkupDocumentViewer,
|
2007-03-22 10:30:00 -07:00
|
|
|
public nsIDocumentViewerPrint
|
|
|
|
|
|
|
|
#ifdef NS_PRINTING
|
|
|
|
, public nsIWebBrowserPrint
|
|
|
|
#endif
|
|
|
|
|
|
|
|
{
|
|
|
|
friend class nsDocViewerSelectionListener;
|
|
|
|
friend class nsPagePrintTimer;
|
|
|
|
friend class nsPrintEngine;
|
|
|
|
|
|
|
|
public:
|
|
|
|
DocumentViewerImpl();
|
|
|
|
|
|
|
|
NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
|
|
|
|
|
|
|
|
// nsISupports interface...
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
|
|
|
|
// nsIContentViewer interface...
|
|
|
|
NS_DECL_NSICONTENTVIEWER
|
|
|
|
|
|
|
|
// nsIContentViewerEdit
|
|
|
|
NS_DECL_NSICONTENTVIEWEREDIT
|
|
|
|
|
|
|
|
// nsIContentViewerFile
|
|
|
|
NS_DECL_NSICONTENTVIEWERFILE
|
|
|
|
|
|
|
|
// nsIMarkupDocumentViewer
|
|
|
|
NS_DECL_NSIMARKUPDOCUMENTVIEWER
|
|
|
|
|
|
|
|
#ifdef NS_PRINTING
|
|
|
|
// nsIWebBrowserPrint
|
|
|
|
NS_DECL_NSIWEBBROWSERPRINT
|
|
|
|
#endif
|
|
|
|
|
|
|
|
typedef void (*CallChildFunc)(nsIMarkupDocumentViewer* aViewer,
|
|
|
|
void* aClosure);
|
|
|
|
void CallChildren(CallChildFunc aFunc, void* aClosure);
|
|
|
|
|
|
|
|
// nsIDocumentViewerPrint Printing Methods
|
|
|
|
NS_DECL_NSIDOCUMENTVIEWERPRINT
|
|
|
|
|
2011-05-14 05:03:58 -07:00
|
|
|
|
|
|
|
static void DispatchBeforePrint(nsIDocument* aTop)
|
|
|
|
{
|
|
|
|
DispatchEventToWindowTree(aTop, NS_LITERAL_STRING("beforeprint"));
|
|
|
|
}
|
|
|
|
static void DispatchAfterPrint(nsIDocument* aTop)
|
|
|
|
{
|
|
|
|
DispatchEventToWindowTree(aTop, NS_LITERAL_STRING("afterprint"));
|
|
|
|
}
|
|
|
|
static void DispatchEventToWindowTree(nsIDocument* aTop,
|
|
|
|
const nsAString& aEvent);
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
protected:
|
|
|
|
virtual ~DocumentViewerImpl();
|
|
|
|
|
|
|
|
private:
|
2007-12-01 02:42:12 -08:00
|
|
|
/**
|
|
|
|
* Creates a view manager, root view, and widget for the root view, setting
|
|
|
|
* mViewManager and mWindow.
|
|
|
|
* @param aSize the initial size in appunits
|
2009-07-21 17:44:53 -07:00
|
|
|
* @param aContainerView the container view to hook our root view up
|
|
|
|
* to as a child, or null if this will be the root view manager
|
2007-12-01 02:42:12 -08:00
|
|
|
*/
|
2009-07-21 17:44:53 -07:00
|
|
|
nsresult MakeWindow(const nsSize& aSize, nsIView* aContainerView);
|
|
|
|
|
2008-08-18 12:22:19 -07:00
|
|
|
/**
|
|
|
|
* Create our device context
|
|
|
|
*/
|
2009-07-21 17:45:10 -07:00
|
|
|
nsresult CreateDeviceContext(nsIView* aContainerView);
|
2008-08-18 12:22:19 -07:00
|
|
|
|
|
|
|
/**
|
2009-07-21 17:45:10 -07:00
|
|
|
* If aDoCreation is true, this creates the device context, creates a
|
|
|
|
* prescontext if necessary, and calls MakeWindow.
|
2011-01-21 11:09:11 -08:00
|
|
|
*
|
|
|
|
* If aForceSetNewDocument is false, then SetNewDocument won't be
|
|
|
|
* called if the window's current document is already mDocument.
|
2008-08-18 12:22:19 -07:00
|
|
|
*/
|
2007-03-22 10:30:00 -07:00
|
|
|
nsresult InitInternal(nsIWidget* aParentWidget,
|
|
|
|
nsISupports *aState,
|
2009-01-14 19:27:09 -08:00
|
|
|
const nsIntRect& aBounds,
|
2011-09-28 23:19:26 -07:00
|
|
|
bool aDoCreation,
|
|
|
|
bool aNeedMakeCX = true,
|
|
|
|
bool aForceSetNewDocument = true);
|
2008-01-09 14:41:43 -08:00
|
|
|
/**
|
|
|
|
* @param aDoInitialReflow set to true if you want to kick off the initial
|
|
|
|
* reflow
|
|
|
|
*/
|
2011-09-28 23:19:26 -07:00
|
|
|
nsresult InitPresentationStuff(bool aDoInitialReflow);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
nsresult GetPopupNode(nsIDOMNode** aNode);
|
|
|
|
nsresult GetPopupLinkNode(nsIDOMNode** aNode);
|
|
|
|
nsresult GetPopupImageNode(nsIImageLoadingContent** aNode);
|
|
|
|
|
|
|
|
void PrepareToStartLoad(void);
|
|
|
|
|
|
|
|
nsresult SyncParentSubDocMap();
|
|
|
|
|
|
|
|
nsresult GetDocumentSelection(nsISelection **aSelection);
|
|
|
|
|
2009-01-14 04:24:10 -08:00
|
|
|
void DestroyPresShell();
|
2011-01-21 11:09:11 -08:00
|
|
|
void DestroyPresContext();
|
2009-01-14 04:24:10 -08:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
#ifdef NS_PRINTING
|
|
|
|
// Called when the DocViewer is notified that the state
|
|
|
|
// of Printing or PP has changed
|
|
|
|
void SetIsPrintingInDocShellTree(nsIDocShellTreeNode* aParentNode,
|
2011-09-28 23:19:26 -07:00
|
|
|
bool aIsPrintingOrPP,
|
|
|
|
bool aStartAtTop);
|
2007-03-22 10:30:00 -07:00
|
|
|
#endif // NS_PRINTING
|
|
|
|
|
2011-02-09 12:13:18 -08:00
|
|
|
// Whether we should attach to the top level widget. This is true if we
|
|
|
|
// are sharing/recycling a single base widget and not creating multiple
|
|
|
|
// child widgets.
|
2011-09-28 23:19:26 -07:00
|
|
|
bool ShouldAttachToTopLevel();
|
2011-02-09 12:13:18 -08:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
protected:
|
2007-11-09 02:19:12 -08:00
|
|
|
// These return the current shell/prescontext etc.
|
|
|
|
nsIPresShell* GetPresShell();
|
|
|
|
nsPresContext* GetPresContext();
|
|
|
|
nsIViewManager* GetViewManager();
|
|
|
|
|
2010-06-24 19:01:06 -07:00
|
|
|
void DetachFromTopLevelWidget();
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
// IMPORTANT: The ownership implicit in the following member
|
|
|
|
// variables has been explicitly checked and set using nsCOMPtr
|
|
|
|
// for owning pointers and raw COM interface pointers for weak
|
|
|
|
// (ie, non owning) references. If you add any members to this
|
|
|
|
// class, please make the ownership explicit (pinkerton, scc).
|
|
|
|
|
|
|
|
nsWeakPtr mContainer; // it owns me!
|
2011-03-24 04:42:54 -07:00
|
|
|
nsWeakPtr mTopContainerWhilePrinting;
|
2011-04-16 18:22:44 -07:00
|
|
|
nsRefPtr<nsDeviceContext> mDeviceContext; // We create and own this baby
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
// the following six items are explicitly in this order
|
|
|
|
// so they will be destroyed in the reverse order (pinkerton, scc)
|
|
|
|
nsCOMPtr<nsIDocument> mDocument;
|
2009-07-21 17:45:10 -07:00
|
|
|
nsCOMPtr<nsIWidget> mWindow; // may be null
|
2007-03-22 10:30:00 -07:00
|
|
|
nsCOMPtr<nsIViewManager> mViewManager;
|
2010-03-25 06:17:11 -07:00
|
|
|
nsRefPtr<nsPresContext> mPresContext;
|
2007-03-22 10:30:00 -07:00
|
|
|
nsCOMPtr<nsIPresShell> mPresShell;
|
|
|
|
|
|
|
|
nsCOMPtr<nsISelectionListener> mSelectionListener;
|
2011-06-28 10:59:14 -07:00
|
|
|
nsRefPtr<nsDocViewerFocusListener> mFocusListener;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
nsCOMPtr<nsIContentViewer> mPreviousViewer;
|
|
|
|
nsCOMPtr<nsISHEntry> mSHEntry;
|
|
|
|
|
2008-09-28 12:14:28 -07:00
|
|
|
nsIWidget* mParentWidget; // purposely won't be ref counted. May be null
|
2011-09-28 23:19:26 -07:00
|
|
|
bool mAttachedToParent; // view is attached to the parent widget
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2009-07-21 17:45:10 -07:00
|
|
|
nsIntRect mBounds;
|
|
|
|
|
2007-11-09 14:29:43 -08:00
|
|
|
// mTextZoom/mPageZoom record the textzoom/pagezoom of the first (galley)
|
|
|
|
// presshell only.
|
2007-03-22 10:30:00 -07:00
|
|
|
float mTextZoom; // Text zoom, defaults to 1.0
|
2007-08-27 18:20:17 -07:00
|
|
|
float mPageZoom;
|
2011-03-10 20:33:43 -08:00
|
|
|
int mMinFontSize;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
PRInt16 mNumURLStarts;
|
|
|
|
PRInt16 mDestroyRefCount; // a second "refcount" for the document viewer's "destroy"
|
|
|
|
|
|
|
|
unsigned mStopped : 1;
|
|
|
|
unsigned mLoaded : 1;
|
|
|
|
unsigned mDeferredWindowClose : 1;
|
|
|
|
// document management data
|
|
|
|
// these items are specific to markup documents (html and xml)
|
|
|
|
// may consider splitting these out into a subclass
|
|
|
|
unsigned mIsSticky : 1;
|
|
|
|
unsigned mInPermitUnload : 1;
|
|
|
|
|
|
|
|
#ifdef NS_PRINTING
|
|
|
|
unsigned mClosingWhilePrinting : 1;
|
|
|
|
|
|
|
|
#if NS_PRINT_PREVIEW
|
2009-03-08 12:01:02 -07:00
|
|
|
unsigned mPrintPreviewZoomed : 1;
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
// These data members support delayed printing when the document is loading
|
|
|
|
unsigned mPrintIsPending : 1;
|
|
|
|
unsigned mPrintDocIsFullyLoaded : 1;
|
|
|
|
nsCOMPtr<nsIPrintSettings> mCachedPrintSettings;
|
|
|
|
nsCOMPtr<nsIWebProgressListener> mCachedPrintWebProgressListner;
|
|
|
|
|
|
|
|
nsCOMPtr<nsPrintEngine> mPrintEngine;
|
2009-03-08 12:01:02 -07:00
|
|
|
float mOriginalPrintPreviewScale;
|
|
|
|
float mPrintPreviewZoom;
|
2007-03-22 10:30:00 -07:00
|
|
|
#endif // NS_PRINT_PREVIEW
|
|
|
|
|
|
|
|
#ifdef NS_DEBUG
|
|
|
|
FILE* mDebugFile;
|
|
|
|
#endif // NS_DEBUG
|
|
|
|
#endif // NS_PRINTING
|
|
|
|
|
|
|
|
/* character set member data */
|
|
|
|
PRInt32 mHintCharsetSource;
|
|
|
|
nsCString mHintCharset;
|
|
|
|
nsCString mDefaultCharacterSet;
|
|
|
|
nsCString mForceCharacterSet;
|
|
|
|
nsCString mPrevDocCharacterSet;
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
bool mIsPageMode;
|
|
|
|
bool mCallerIsClosingWindow;
|
|
|
|
bool mInitializedForPrintPreview;
|
|
|
|
bool mHidden;
|
2007-03-22 10:30:00 -07:00
|
|
|
};
|
|
|
|
|
2011-05-14 05:03:58 -07:00
|
|
|
class nsPrintEventDispatcher
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
nsPrintEventDispatcher(nsIDocument* aTop) : mTop(aTop)
|
|
|
|
{
|
|
|
|
DocumentViewerImpl::DispatchBeforePrint(mTop);
|
|
|
|
}
|
|
|
|
~nsPrintEventDispatcher()
|
|
|
|
{
|
|
|
|
DocumentViewerImpl::DispatchAfterPrint(mTop);
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDocument> mTop;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
//------------------------------------------------------------------
|
|
|
|
// DocumentViewerImpl
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
// Class IDs
|
|
|
|
static NS_DEFINE_CID(kViewManagerCID, NS_VIEW_MANAGER_CID);
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
nsresult
|
2011-10-15 00:33:26 -07:00
|
|
|
NS_NewContentViewer(nsIContentViewer** aResult)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
*aResult = new DocumentViewerImpl();
|
|
|
|
|
|
|
|
NS_ADDREF(*aResult);
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
void DocumentViewerImpl::PrepareToStartLoad()
|
|
|
|
{
|
|
|
|
mStopped = PR_FALSE;
|
|
|
|
mLoaded = PR_FALSE;
|
2010-06-24 19:01:06 -07:00
|
|
|
mAttachedToParent = PR_FALSE;
|
2007-03-22 10:30:00 -07:00
|
|
|
mDeferredWindowClose = PR_FALSE;
|
2009-10-20 07:19:43 -07:00
|
|
|
mCallerIsClosingWindow = PR_FALSE;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
#ifdef NS_PRINTING
|
|
|
|
mPrintIsPending = PR_FALSE;
|
|
|
|
mPrintDocIsFullyLoaded = PR_FALSE;
|
|
|
|
mClosingWhilePrinting = PR_FALSE;
|
|
|
|
|
|
|
|
// Make sure we have destroyed it and cleared the data member
|
|
|
|
if (mPrintEngine) {
|
|
|
|
mPrintEngine->Destroy();
|
|
|
|
mPrintEngine = nsnull;
|
|
|
|
#ifdef NS_PRINT_PREVIEW
|
2009-12-10 20:02:13 -08:00
|
|
|
SetIsPrintPreview(PR_FALSE);
|
2007-03-22 10:30:00 -07:00
|
|
|
#endif
|
2009-12-10 20:02:13 -08:00
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
#ifdef NS_DEBUG
|
|
|
|
mDebugFile = nsnull;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif // NS_PRINTING
|
|
|
|
}
|
|
|
|
|
|
|
|
// Note: operator new zeros our memory, so no need to init things to null.
|
|
|
|
DocumentViewerImpl::DocumentViewerImpl()
|
2011-03-10 20:33:43 -08:00
|
|
|
: mTextZoom(1.0), mPageZoom(1.0), mMinFontSize(0),
|
2007-03-22 10:30:00 -07:00
|
|
|
mIsSticky(PR_TRUE),
|
2009-03-08 12:01:02 -07:00
|
|
|
#ifdef NS_PRINT_PREVIEW
|
|
|
|
mPrintPreviewZoom(1.0),
|
|
|
|
#endif
|
2009-12-10 20:02:13 -08:00
|
|
|
mHintCharsetSource(kCharsetUninitialized),
|
2010-02-18 11:23:23 -08:00
|
|
|
mInitializedForPrintPreview(PR_FALSE),
|
|
|
|
mHidden(PR_FALSE)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
PrepareToStartLoad();
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMPL_ADDREF(DocumentViewerImpl)
|
|
|
|
NS_IMPL_RELEASE(DocumentViewerImpl)
|
|
|
|
|
|
|
|
NS_INTERFACE_MAP_BEGIN(DocumentViewerImpl)
|
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIContentViewer)
|
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIMarkupDocumentViewer)
|
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIContentViewerFile)
|
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIContentViewerEdit)
|
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIDocumentViewerPrint)
|
|
|
|
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIContentViewer)
|
|
|
|
#ifdef NS_PRINTING
|
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIWebBrowserPrint)
|
|
|
|
#endif
|
|
|
|
NS_INTERFACE_MAP_END
|
|
|
|
|
|
|
|
DocumentViewerImpl::~DocumentViewerImpl()
|
|
|
|
{
|
|
|
|
if (mDocument) {
|
|
|
|
Close(nsnull);
|
|
|
|
mDocument->Destroy();
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_ASSERTION(!mPresShell && !mPresContext,
|
|
|
|
"User did not call nsIContentViewer::Destroy");
|
|
|
|
if (mPresShell || mPresContext) {
|
|
|
|
// Make sure we don't hand out a reference to the content viewer to
|
|
|
|
// the SHEntry!
|
|
|
|
mSHEntry = nsnull;
|
|
|
|
|
|
|
|
Destroy();
|
|
|
|
}
|
|
|
|
|
|
|
|
// XXX(?) Revoke pending invalidate events
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This method is called by the Document Loader once a document has
|
|
|
|
* been created for a particular data stream... The content viewer
|
|
|
|
* must cache this document for later use when Init(...) is called.
|
|
|
|
*
|
|
|
|
* This method is also called when an out of band document.write() happens.
|
|
|
|
* In that case, the document passed in is the same as the previous document.
|
|
|
|
*/
|
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::LoadStart(nsISupports *aDoc)
|
|
|
|
{
|
|
|
|
#ifdef NOISY_VIEWER
|
|
|
|
printf("DocumentViewerImpl::LoadStart\n");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
if (!mDocument) {
|
|
|
|
mDocument = do_QueryInterface(aDoc, &rv);
|
|
|
|
}
|
|
|
|
else if (mDocument == aDoc) {
|
|
|
|
// Reset the document viewer's state back to what it was
|
|
|
|
// when the document load started.
|
|
|
|
PrepareToStartLoad();
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
DocumentViewerImpl::SyncParentSubDocMap()
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem> item(do_QueryReferent(mContainer));
|
|
|
|
nsCOMPtr<nsPIDOMWindow> pwin(do_GetInterface(item));
|
|
|
|
nsCOMPtr<nsIContent> content;
|
|
|
|
|
|
|
|
if (mDocument && pwin) {
|
|
|
|
content = do_QueryInterface(pwin->GetFrameElementInternal());
|
|
|
|
}
|
|
|
|
|
|
|
|
if (content) {
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem> parent;
|
|
|
|
item->GetParent(getter_AddRefs(parent));
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMWindow> parent_win(do_GetInterface(parent));
|
|
|
|
|
|
|
|
if (parent_win) {
|
|
|
|
nsCOMPtr<nsIDOMDocument> dom_doc;
|
|
|
|
parent_win->GetDocument(getter_AddRefs(dom_doc));
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDocument> parent_doc(do_QueryInterface(dom_doc));
|
|
|
|
|
|
|
|
if (parent_doc) {
|
2009-03-03 12:11:14 -08:00
|
|
|
if (mDocument && parent_doc->GetSubDocumentFor(content) != mDocument) {
|
|
|
|
mDocument->SuppressEventHandling(parent_doc->EventHandlingSuppressed());
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
return parent_doc->SetSubDocumentFor(content, mDocument);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::SetContainer(nsISupports* aContainer)
|
|
|
|
{
|
|
|
|
mContainer = do_GetWeakReference(aContainer);
|
|
|
|
if (mPresContext) {
|
|
|
|
mPresContext->SetContainer(aContainer);
|
|
|
|
}
|
|
|
|
|
|
|
|
// We're loading a new document into the window where this document
|
|
|
|
// viewer lives, sync the parent document's frame element -> sub
|
|
|
|
// document map
|
|
|
|
|
|
|
|
return SyncParentSubDocMap();
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::GetContainer(nsISupports** aResult)
|
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aResult);
|
|
|
|
|
|
|
|
*aResult = nsnull;
|
|
|
|
nsCOMPtr<nsISupports> container = do_QueryReferent(mContainer);
|
|
|
|
container.swap(*aResult);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::Init(nsIWidget* aParentWidget,
|
2009-01-14 19:27:09 -08:00
|
|
|
const nsIntRect& aBounds)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2010-08-27 16:15:08 -07:00
|
|
|
return InitInternal(aParentWidget, nsnull, aBounds, PR_TRUE);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2011-09-28 23:19:26 -07:00
|
|
|
DocumentViewerImpl::InitPresentationStuff(bool aDoInitialReflow)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2009-12-10 20:02:13 -08:00
|
|
|
if (GetIsPrintPreview())
|
|
|
|
return NS_OK;
|
|
|
|
|
2009-01-14 04:24:10 -08:00
|
|
|
NS_ASSERTION(!mPresShell,
|
|
|
|
"Someone should have destroyed the presshell!");
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
// Create the style set...
|
|
|
|
nsStyleSet *styleSet;
|
|
|
|
nsresult rv = CreateStyleSet(mDocument, &styleSet);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
// Now make the shell for the document
|
|
|
|
rv = mDocument->CreateShell(mPresContext, mViewManager, styleSet,
|
|
|
|
getter_AddRefs(mPresShell));
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
delete styleSet;
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// We're done creating the style set
|
|
|
|
styleSet->EndUpdate();
|
|
|
|
|
|
|
|
if (aDoInitialReflow) {
|
|
|
|
// Since InitialReflow() will create frames for *all* items
|
|
|
|
// that are currently in the document tree, we need to flush
|
|
|
|
// any pending notifications to prevent the content sink from
|
|
|
|
// duplicating layout frames for content it has added to the tree
|
|
|
|
// but hasn't notified the document about. (Bug 154018)
|
|
|
|
//
|
|
|
|
// Note that we are flushing before we add mPresShell as an observer
|
|
|
|
// to avoid bogus notifications.
|
|
|
|
|
|
|
|
mDocument->FlushPendingNotifications(Flush_ContentAndNotify);
|
|
|
|
}
|
|
|
|
|
|
|
|
mPresShell->BeginObservingDocument();
|
|
|
|
|
|
|
|
// Initialize our view manager
|
2009-07-21 17:45:10 -07:00
|
|
|
nscoord width = mPresContext->DeviceContext()->UnscaledAppUnitsPerDevPixel() * mBounds.width;
|
|
|
|
nscoord height = mPresContext->DeviceContext()->UnscaledAppUnitsPerDevPixel() * mBounds.height;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
mViewManager->SetWindowDimensions(width, height);
|
|
|
|
mPresContext->SetTextZoom(mTextZoom);
|
2007-08-27 18:20:17 -07:00
|
|
|
mPresContext->SetFullZoom(mPageZoom);
|
2011-03-10 20:33:43 -08:00
|
|
|
mPresContext->SetMinFontSize(mMinFontSize);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
if (aDoInitialReflow) {
|
|
|
|
nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(mDocument);
|
|
|
|
if (htmlDoc) {
|
|
|
|
nsCOMPtr<nsIDOMHTMLFrameSetElement> frameset =
|
2010-04-30 06:12:05 -07:00
|
|
|
do_QueryInterface(mDocument->GetRootElement());
|
2007-03-22 10:30:00 -07:00
|
|
|
htmlDoc->SetIsFrameset(frameset != nsnull);
|
|
|
|
}
|
|
|
|
|
2007-05-13 20:52:48 -07:00
|
|
|
nsCOMPtr<nsIPresShell> shellGrip = mPresShell;
|
2007-03-22 10:30:00 -07:00
|
|
|
// Initial reflow
|
|
|
|
mPresShell->InitialReflow(width, height);
|
|
|
|
} else {
|
|
|
|
// Store the visible area so it's available for other callers of
|
|
|
|
// InitialReflow, like nsContentSink::StartLayout.
|
|
|
|
mPresContext->SetVisibleArea(nsRect(0, 0, width, height));
|
|
|
|
}
|
|
|
|
|
|
|
|
// now register ourselves as a selection listener, so that we get
|
|
|
|
// called when the selection changes in the window
|
2009-01-14 04:24:10 -08:00
|
|
|
if (!mSelectionListener) {
|
|
|
|
nsDocViewerSelectionListener *selectionListener =
|
|
|
|
new nsDocViewerSelectionListener();
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2009-01-14 04:24:10 -08:00
|
|
|
selectionListener->Init(this);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2009-01-14 04:24:10 -08:00
|
|
|
// mSelectionListener is a owning reference
|
|
|
|
mSelectionListener = selectionListener;
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
nsCOMPtr<nsISelection> selection;
|
|
|
|
rv = GetDocumentSelection(getter_AddRefs(selection));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
nsCOMPtr<nsISelectionPrivate> selPrivate(do_QueryInterface(selection));
|
|
|
|
rv = selPrivate->AddSelectionListener(mSelectionListener);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
// Save old listener so we can unregister it
|
2011-06-28 10:59:14 -07:00
|
|
|
nsRefPtr<nsDocViewerFocusListener> oldFocusListener = mFocusListener;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
// focus listener
|
|
|
|
//
|
|
|
|
// now register ourselves as a focus listener, so that we get called
|
|
|
|
// when the focus changes in the window
|
2010-07-05 02:42:18 -07:00
|
|
|
nsDocViewerFocusListener *focusListener = new nsDocViewerFocusListener();
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
focusListener->Init(this);
|
|
|
|
|
|
|
|
// mFocusListener is a strong reference
|
|
|
|
mFocusListener = focusListener;
|
|
|
|
|
2007-05-14 02:11:38 -07:00
|
|
|
if (mDocument) {
|
2011-06-28 10:59:14 -07:00
|
|
|
mDocument->AddEventListener(NS_LITERAL_STRING("focus"),
|
|
|
|
mFocusListener,
|
|
|
|
PR_FALSE, PR_FALSE);
|
|
|
|
mDocument->AddEventListener(NS_LITERAL_STRING("blur"),
|
|
|
|
mFocusListener,
|
|
|
|
PR_FALSE, PR_FALSE);
|
|
|
|
|
2008-01-09 14:41:43 -08:00
|
|
|
if (oldFocusListener) {
|
2011-06-28 10:59:14 -07:00
|
|
|
mDocument->RemoveEventListener(NS_LITERAL_STRING("focus"),
|
|
|
|
oldFocusListener, PR_FALSE);
|
|
|
|
mDocument->RemoveEventListener(NS_LITERAL_STRING("blur"),
|
|
|
|
oldFocusListener, PR_FALSE);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-05-11 17:30:40 -07:00
|
|
|
if (aDoInitialReflow && mDocument) {
|
|
|
|
mDocument->ScrollToRef();
|
|
|
|
}
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2009-07-21 17:44:54 -07:00
|
|
|
static nsPresContext*
|
|
|
|
CreatePresContext(nsIDocument* aDocument,
|
|
|
|
nsPresContext::nsPresContextType aType,
|
|
|
|
nsIView* aContainerView)
|
|
|
|
{
|
|
|
|
if (aContainerView)
|
|
|
|
return new nsPresContext(aDocument, aType);
|
|
|
|
return new nsRootPresContext(aDocument, aType);
|
|
|
|
}
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
//-----------------------------------------------
|
|
|
|
// This method can be used to initial the "presentation"
|
|
|
|
// The aDoCreation indicates whether it should create
|
|
|
|
// all the new objects or just initialize the existing ones
|
|
|
|
nsresult
|
|
|
|
DocumentViewerImpl::InitInternal(nsIWidget* aParentWidget,
|
|
|
|
nsISupports *aState,
|
2009-01-14 19:27:09 -08:00
|
|
|
const nsIntRect& aBounds,
|
2011-09-28 23:19:26 -07:00
|
|
|
bool aDoCreation,
|
|
|
|
bool aNeedMakeCX /*= true*/,
|
|
|
|
bool aForceSetNewDocument /* = true*/)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2011-01-21 11:09:11 -08:00
|
|
|
if (mIsPageMode) {
|
|
|
|
// XXXbz should the InitInternal in SetPageMode just pass PR_FALSE
|
|
|
|
// here itself?
|
|
|
|
aForceSetNewDocument = PR_FALSE;
|
|
|
|
}
|
|
|
|
|
2009-11-18 15:40:31 -08:00
|
|
|
// We don't want any scripts to run here. That can cause flushing,
|
|
|
|
// which can cause reentry into initialization of this document viewer,
|
|
|
|
// which would be disastrous.
|
|
|
|
nsAutoScriptBlocker blockScripts;
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
mParentWidget = aParentWidget; // not ref counted
|
2009-07-21 17:45:10 -07:00
|
|
|
mBounds = aBounds;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
NS_ENSURE_TRUE(mDocument, NS_ERROR_NULL_POINTER);
|
|
|
|
|
2009-07-21 17:44:53 -07:00
|
|
|
nsIView* containerView = FindContainerView();
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
bool makeCX = false;
|
2007-03-22 10:30:00 -07:00
|
|
|
if (aDoCreation) {
|
2009-07-21 17:45:10 -07:00
|
|
|
nsresult rv = CreateDeviceContext(containerView);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
2008-10-04 13:00:09 -07:00
|
|
|
// XXXbz this is a nasty hack to do with the fact that we create
|
|
|
|
// presentations both in Init() and in Show()... Ideally we would only do
|
|
|
|
// it in one place (Show()) and require that callers call init(), open(),
|
|
|
|
// show() in that order or something.
|
2009-07-21 17:45:10 -07:00
|
|
|
if (!mPresContext &&
|
2010-09-08 13:40:39 -07:00
|
|
|
(aParentWidget || containerView || mDocument->IsBeingUsedAsImage() ||
|
2010-08-11 14:05:26 -07:00
|
|
|
(mDocument->GetDisplayDocument() &&
|
|
|
|
mDocument->GetDisplayDocument()->GetShell()))) {
|
2007-03-22 10:30:00 -07:00
|
|
|
// Create presentation context
|
|
|
|
if (mIsPageMode) {
|
|
|
|
//Presentation context already created in SetPageMode which is calling this method
|
2009-07-21 17:44:54 -07:00
|
|
|
} else {
|
|
|
|
mPresContext = CreatePresContext(mDocument,
|
|
|
|
nsPresContext::eContext_Galley, containerView);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
NS_ENSURE_TRUE(mPresContext, NS_ERROR_OUT_OF_MEMORY);
|
|
|
|
|
2008-08-18 12:22:19 -07:00
|
|
|
nsresult rv = mPresContext->Init(mDeviceContext);
|
2007-03-22 10:30:00 -07:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
mPresContext = nsnull;
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if defined(NS_PRINTING) && defined(NS_PRINT_PREVIEW)
|
|
|
|
makeCX = !GetIsPrintPreview() && aNeedMakeCX; // needs to be true except when we are already in PP or we are enabling/disabling paginated mode.
|
|
|
|
#else
|
|
|
|
makeCX = PR_TRUE;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mPresContext) {
|
|
|
|
// Create the ViewManager and Root View...
|
|
|
|
|
|
|
|
// We must do this before we tell the script global object about
|
|
|
|
// this new document since doing that will cause us to re-enter
|
|
|
|
// into nsSubDocumentFrame code through reflows caused by
|
|
|
|
// FlushPendingNotifications() calls down the road...
|
|
|
|
|
2007-12-01 02:42:12 -08:00
|
|
|
rv = MakeWindow(nsSize(mPresContext->DevPixelsToAppUnits(aBounds.width),
|
2009-07-21 17:44:53 -07:00
|
|
|
mPresContext->DevPixelsToAppUnits(aBounds.height)),
|
|
|
|
containerView);
|
2007-03-22 10:30:00 -07:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
Hide();
|
|
|
|
|
|
|
|
#ifdef NS_PRINT_PREVIEW
|
|
|
|
if (mIsPageMode) {
|
|
|
|
// I'm leaving this in a broken state for the moment; we should
|
|
|
|
// be measuring/scaling with the print device context, not the
|
|
|
|
// screen device context, but this is good enough to allow
|
|
|
|
// printing reftests to work.
|
2007-07-16 16:16:48 -07:00
|
|
|
double pageWidth = 0, pageHeight = 0;
|
|
|
|
mPresContext->GetPrintSettings()->GetEffectivePageSize(&pageWidth,
|
|
|
|
&pageHeight);
|
2007-03-22 10:30:00 -07:00
|
|
|
mPresContext->SetPageSize(
|
2010-08-13 02:58:04 -07:00
|
|
|
nsSize(mPresContext->CSSTwipsToAppUnits(NSToIntFloor(pageWidth)),
|
|
|
|
mPresContext->CSSTwipsToAppUnits(NSToIntFloor(pageHeight))));
|
2007-03-22 10:30:00 -07:00
|
|
|
mPresContext->SetIsRootPaginatedDocument(PR_TRUE);
|
|
|
|
mPresContext->SetPageScale(1.0f);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIInterfaceRequestor> requestor(do_QueryReferent(mContainer));
|
|
|
|
if (requestor) {
|
|
|
|
if (mPresContext) {
|
|
|
|
nsCOMPtr<nsILinkHandler> linkHandler;
|
|
|
|
requestor->GetInterface(NS_GET_IID(nsILinkHandler),
|
|
|
|
getter_AddRefs(linkHandler));
|
|
|
|
|
|
|
|
mPresContext->SetContainer(requestor);
|
|
|
|
mPresContext->SetLinkHandler(linkHandler);
|
|
|
|
}
|
|
|
|
|
2010-08-27 16:15:08 -07:00
|
|
|
// Set script-context-owner in the document
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2010-08-27 16:15:08 -07:00
|
|
|
nsCOMPtr<nsPIDOMWindow> window;
|
|
|
|
requestor->GetInterface(NS_GET_IID(nsPIDOMWindow),
|
|
|
|
getter_AddRefs(window));
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2010-08-27 16:15:08 -07:00
|
|
|
if (window) {
|
|
|
|
nsCOMPtr<nsIDocument> curDoc =
|
|
|
|
do_QueryInterface(window->GetExtantDocument());
|
2011-01-21 11:09:11 -08:00
|
|
|
if (aForceSetNewDocument || curDoc != mDocument) {
|
2010-09-15 15:54:00 -07:00
|
|
|
window->SetNewDocument(mDocument, aState, PR_FALSE);
|
2010-08-27 16:15:08 -07:00
|
|
|
nsJSContext::LoadStart();
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aDoCreation && mPresContext) {
|
|
|
|
// The ViewManager and Root View was created above (in
|
|
|
|
// MakeWindow())...
|
|
|
|
|
2010-02-18 11:23:23 -08:00
|
|
|
rv = InitPresentationStuff(!makeCX);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2011-06-23 03:39:48 -07:00
|
|
|
void DocumentViewerImpl::SetNavigationTiming(nsDOMNavigationTiming* timing)
|
|
|
|
{
|
|
|
|
NS_ASSERTION(mDocument, "Must have a document to set navigation timing.");
|
|
|
|
if (mDocument) {
|
|
|
|
mDocument->SetNavigationTiming(timing);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
//
|
|
|
|
// LoadComplete(aStatus)
|
|
|
|
//
|
|
|
|
// aStatus - The status returned from loading the document.
|
|
|
|
//
|
|
|
|
// This method is called by the container when the document has been
|
|
|
|
// completely loaded.
|
|
|
|
//
|
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::LoadComplete(nsresult aStatus)
|
|
|
|
{
|
2010-04-30 12:40:59 -07:00
|
|
|
NS_TIME_FUNCTION;
|
2007-03-22 10:30:00 -07:00
|
|
|
/* We need to protect ourself against auto-destruction in case the
|
|
|
|
window is closed while processing the OnLoad event. See bug
|
|
|
|
http://bugzilla.mozilla.org/show_bug.cgi?id=78445 for more
|
|
|
|
explanation.
|
|
|
|
*/
|
2011-10-15 00:33:26 -07:00
|
|
|
nsRefPtr<DocumentViewerImpl> kungFuDeathGrip(this);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2007-05-01 12:11:28 -07:00
|
|
|
// Flush out layout so it's up-to-date by the time onload is called.
|
|
|
|
// Note that this could destroy the window, so do this before
|
|
|
|
// checking for our mDocument and its window.
|
2007-04-29 20:09:55 -07:00
|
|
|
if (mPresShell && !mStopped) {
|
|
|
|
// Hold strong ref because this could conceivably run script
|
|
|
|
nsCOMPtr<nsIPresShell> shell = mPresShell;
|
|
|
|
shell->FlushPendingNotifications(Flush_Layout);
|
|
|
|
}
|
2009-09-01 09:45:05 -07:00
|
|
|
|
2011-02-28 23:08:56 -08:00
|
|
|
nsresult rv = NS_OK;
|
2007-05-01 12:11:28 -07:00
|
|
|
NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE);
|
|
|
|
|
|
|
|
// First, get the window from the document...
|
|
|
|
nsPIDOMWindow *window = mDocument->GetWindow();
|
|
|
|
|
|
|
|
mLoaded = PR_TRUE;
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
// Now, fire either an OnLoad or OnError event to the document...
|
2011-09-28 23:19:26 -07:00
|
|
|
bool restoring = false;
|
2008-11-18 14:54:36 -08:00
|
|
|
// XXXbz imagelib kills off the document load for a full-page image with
|
2009-02-16 03:27:22 -08:00
|
|
|
// NS_ERROR_PARSED_DATA_CACHED if it's in the cache. So we want to treat
|
2008-11-18 14:54:36 -08:00
|
|
|
// that one as a success code; otherwise whether we fire onload for the image
|
|
|
|
// will depend on whether it's cached!
|
|
|
|
if(window &&
|
2009-02-16 03:27:22 -08:00
|
|
|
(NS_SUCCEEDED(aStatus) || aStatus == NS_ERROR_PARSED_DATA_CACHED)) {
|
2009-01-09 09:12:09 -08:00
|
|
|
if (mDocument)
|
|
|
|
mDocument->SetReadyStateInternal(nsIDocument::READYSTATE_COMPLETE);
|
2007-03-22 10:30:00 -07:00
|
|
|
nsEventStatus status = nsEventStatus_eIgnore;
|
|
|
|
nsEvent event(PR_TRUE, NS_LOAD);
|
|
|
|
event.flags |= NS_EVENT_FLAG_CANT_BUBBLE;
|
|
|
|
// XXX Dispatching to |window|, but using |document| as the target.
|
|
|
|
event.target = mDocument;
|
|
|
|
|
|
|
|
// If the document presentation is being restored, we don't want to fire
|
|
|
|
// onload to the document content since that would likely confuse scripts
|
|
|
|
// on the page.
|
|
|
|
|
|
|
|
nsIDocShell *docShell = window->GetDocShell();
|
|
|
|
NS_ENSURE_TRUE(docShell, NS_ERROR_UNEXPECTED);
|
|
|
|
|
|
|
|
docShell->GetRestoringDocument(&restoring);
|
|
|
|
if (!restoring) {
|
2011-06-23 03:39:48 -07:00
|
|
|
nsRefPtr<nsDOMNavigationTiming> timing(mDocument->GetNavigationTiming());
|
|
|
|
if (timing) {
|
|
|
|
timing->NotifyLoadEventStart();
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
nsEventDispatcher::Dispatch(window, mPresContext, &event, nsnull,
|
|
|
|
&status);
|
2011-06-23 03:39:48 -07:00
|
|
|
if (timing) {
|
|
|
|
timing->NotifyLoadEventEnd();
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// XXX: Should fire error event to the document...
|
|
|
|
}
|
|
|
|
|
|
|
|
// Notify the document that it has been shown (regardless of whether
|
|
|
|
// it was just loaded). Note: mDocument may be null now if the above
|
|
|
|
// firing of onload caused the document to unload.
|
2009-10-31 17:06:47 -07:00
|
|
|
if (mDocument) {
|
|
|
|
// Re-get window, since it might have changed during above firing of onload
|
|
|
|
window = mDocument->GetWindow();
|
|
|
|
if (window) {
|
|
|
|
nsIDocShell *docShell = window->GetDocShell();
|
2011-09-28 23:19:26 -07:00
|
|
|
bool isInUnload;
|
2009-12-26 15:11:04 -08:00
|
|
|
if (docShell && NS_SUCCEEDED(docShell->GetIsInUnload(&isInUnload)) &&
|
|
|
|
!isInUnload) {
|
2009-10-31 17:06:47 -07:00
|
|
|
mDocument->OnPageShow(restoring, nsnull);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
// Now that the document has loaded, we can tell the presshell
|
|
|
|
// to unsuppress painting.
|
|
|
|
if (mPresShell && !mStopped) {
|
2008-04-10 15:42:03 -07:00
|
|
|
nsCOMPtr<nsIPresShell> shellDeathGrip(mPresShell);
|
2007-03-22 10:30:00 -07:00
|
|
|
mPresShell->UnsuppressPainting();
|
2008-04-10 15:42:03 -07:00
|
|
|
// mPresShell could have been removed now, see bug 378682/421432
|
|
|
|
if (mPresShell) {
|
|
|
|
mPresShell->ScrollToAnchor();
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2007-10-21 09:46:54 -07:00
|
|
|
nsJSContext::LoadEnd();
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
#ifdef NS_PRINTING
|
|
|
|
// Check to see if someone tried to print during the load
|
|
|
|
if (mPrintIsPending) {
|
|
|
|
mPrintIsPending = PR_FALSE;
|
|
|
|
mPrintDocIsFullyLoaded = PR_TRUE;
|
|
|
|
Print(mCachedPrintSettings, mCachedPrintWebProgressListner);
|
|
|
|
mCachedPrintSettings = nsnull;
|
|
|
|
mCachedPrintWebProgressListner = nsnull;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2011-02-28 23:08:56 -08:00
|
|
|
return rv;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2011-09-28 23:19:26 -07:00
|
|
|
DocumentViewerImpl::PermitUnload(bool aCallerClosesWindow, bool *aPermitUnload)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
*aPermitUnload = PR_TRUE;
|
|
|
|
|
2009-10-20 07:19:43 -07:00
|
|
|
if (!mDocument || mInPermitUnload || mCallerIsClosingWindow) {
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// First, get the script global object from the document...
|
|
|
|
nsPIDOMWindow *window = mDocument->GetWindow();
|
|
|
|
|
|
|
|
if (!window) {
|
|
|
|
// This is odd, but not fatal
|
|
|
|
NS_WARNING("window not set for document!");
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2008-03-14 16:08:57 -07:00
|
|
|
NS_ASSERTION(nsContentUtils::IsSafeToRunScript(), "This is unsafe");
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
// Now, fire an BeforeUnload event to the document and see if it's ok
|
|
|
|
// to unload...
|
2011-05-23 09:46:36 -07:00
|
|
|
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(mDocument);
|
2009-06-24 01:42:00 -07:00
|
|
|
nsCOMPtr<nsIDOMEvent> event;
|
2011-05-23 09:46:36 -07:00
|
|
|
domDoc->CreateEvent(NS_LITERAL_STRING("beforeunloadevent"),
|
|
|
|
getter_AddRefs(event));
|
2009-06-24 01:42:00 -07:00
|
|
|
nsCOMPtr<nsIDOMBeforeUnloadEvent> beforeUnload = do_QueryInterface(event);
|
|
|
|
nsCOMPtr<nsIPrivateDOMEvent> pEvent = do_QueryInterface(beforeUnload);
|
|
|
|
NS_ENSURE_STATE(pEvent);
|
|
|
|
nsresult rv = event->InitEvent(NS_LITERAL_STRING("beforeunload"),
|
|
|
|
PR_FALSE, PR_TRUE);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
// XXX Dispatching to |window|, but using |document| as the target.
|
2009-06-24 01:42:00 -07:00
|
|
|
nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(mDocument);
|
|
|
|
pEvent->SetTarget(target);
|
|
|
|
pEvent->SetTrusted(PR_TRUE);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
// In evil cases we might be destroyed while handling the
|
|
|
|
// onbeforeunload event, don't let that happen. (see also bug#331040)
|
|
|
|
nsRefPtr<DocumentViewerImpl> kungFuDeathGrip(this);
|
|
|
|
|
|
|
|
{
|
|
|
|
// Never permit popups from the beforeunload handler, no matter
|
|
|
|
// how we get here.
|
|
|
|
nsAutoPopupStatePusher popupStatePusher(openAbused, PR_TRUE);
|
|
|
|
|
|
|
|
mInPermitUnload = PR_TRUE;
|
2009-06-24 01:42:00 -07:00
|
|
|
nsEventDispatcher::DispatchDOMEvent(window, nsnull, event, mPresContext,
|
|
|
|
nsnull);
|
2007-03-22 10:30:00 -07:00
|
|
|
mInPermitUnload = PR_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDocShellTreeNode> docShellNode(do_QueryReferent(mContainer));
|
2009-06-24 01:42:00 -07:00
|
|
|
nsAutoString text;
|
|
|
|
beforeUnload->GetReturnValue(text);
|
|
|
|
if (pEvent->GetInternalNSEvent()->flags & NS_EVENT_FLAG_NO_DEFAULT ||
|
|
|
|
!text.IsEmpty()) {
|
2007-03-22 10:30:00 -07:00
|
|
|
// Ask the user if it's ok to unload the current page
|
|
|
|
|
|
|
|
nsCOMPtr<nsIPrompt> prompt = do_GetInterface(docShellNode);
|
|
|
|
|
|
|
|
if (prompt) {
|
2010-09-16 00:51:24 -07:00
|
|
|
nsXPIDLString title, message, stayLabel, leaveLabel;
|
|
|
|
rv = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
|
|
|
|
"OnBeforeUnloadTitle",
|
|
|
|
title);
|
2007-03-22 10:30:00 -07:00
|
|
|
rv |= nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
|
2010-09-16 00:51:24 -07:00
|
|
|
"OnBeforeUnloadMessage",
|
|
|
|
message);
|
|
|
|
rv |= nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
|
|
|
|
"OnBeforeUnloadLeaveButton",
|
|
|
|
leaveLabel);
|
|
|
|
rv |= nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
|
|
|
|
"OnBeforeUnloadStayButton",
|
|
|
|
stayLabel);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2010-09-16 00:51:24 -07:00
|
|
|
if (NS_FAILED(rv) || !title || !message || !stayLabel || !leaveLabel) {
|
2007-03-22 10:30:00 -07:00
|
|
|
NS_ERROR("Failed to get strings from dom.properties!");
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2011-05-31 11:17:57 -07:00
|
|
|
// Although the exact value is ignored, we must not pass invalid
|
2011-09-28 23:19:26 -07:00
|
|
|
// bool values through XPConnect.
|
|
|
|
bool dummy = false;
|
2010-09-16 00:51:24 -07:00
|
|
|
PRInt32 buttonPressed = 0;
|
|
|
|
PRUint32 buttonFlags = (nsIPrompt::BUTTON_POS_0_DEFAULT |
|
|
|
|
(nsIPrompt::BUTTON_TITLE_IS_STRING * nsIPrompt::BUTTON_POS_0) |
|
|
|
|
(nsIPrompt::BUTTON_TITLE_IS_STRING * nsIPrompt::BUTTON_POS_1));
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2010-09-16 00:51:24 -07:00
|
|
|
rv = prompt->ConfirmEx(title, message, buttonFlags,
|
|
|
|
leaveLabel, stayLabel, nsnull, nsnull,
|
|
|
|
&dummy, &buttonPressed);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
// Button 0 == leave, button 1 == stay
|
|
|
|
*aPermitUnload = (buttonPressed == 0);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (docShellNode) {
|
|
|
|
PRInt32 childCount;
|
|
|
|
docShellNode->GetChildCount(&childCount);
|
|
|
|
|
|
|
|
for (PRInt32 i = 0; i < childCount && *aPermitUnload; ++i) {
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem> item;
|
|
|
|
docShellNode->GetChildAt(i, getter_AddRefs(item));
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(item));
|
|
|
|
|
|
|
|
if (docShell) {
|
|
|
|
nsCOMPtr<nsIContentViewer> cv;
|
2009-10-20 07:19:43 -07:00
|
|
|
docShell->GetContentViewer(getter_AddRefs(cv));
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2009-10-20 07:19:43 -07:00
|
|
|
if (cv) {
|
|
|
|
cv->PermitUnload(aCallerClosesWindow, aPermitUnload);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-10-20 07:19:43 -07:00
|
|
|
if (aCallerClosesWindow && *aPermitUnload)
|
|
|
|
mCallerIsClosingWindow = PR_TRUE;
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::ResetCloseWindow()
|
|
|
|
{
|
|
|
|
mCallerIsClosingWindow = PR_FALSE;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDocShellTreeNode> docShellNode(do_QueryReferent(mContainer));
|
|
|
|
if (docShellNode) {
|
|
|
|
PRInt32 childCount;
|
|
|
|
docShellNode->GetChildCount(&childCount);
|
|
|
|
|
|
|
|
for (PRInt32 i = 0; i < childCount; ++i) {
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem> item;
|
|
|
|
docShellNode->GetChildAt(i, getter_AddRefs(item));
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(item));
|
|
|
|
|
|
|
|
if (docShell) {
|
|
|
|
nsCOMPtr<nsIContentViewer> cv;
|
|
|
|
docShell->GetContentViewer(getter_AddRefs(cv));
|
|
|
|
|
|
|
|
if (cv) {
|
|
|
|
cv->ResetCloseWindow();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2011-09-28 23:19:26 -07:00
|
|
|
DocumentViewerImpl::PageHide(bool aIsUnload)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2010-02-18 11:23:23 -08:00
|
|
|
mHidden = PR_TRUE;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
if (!mDocument) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
|
|
|
|
2009-02-26 14:05:42 -08:00
|
|
|
mDocument->OnPageHide(!aIsUnload, nsnull);
|
Bug 178324, refactor focus by moving all focus handling into one place and simplifying it, add many tests, fixes many other bugs too numerous to mention in this small checkin comment, r=josh,smichaud,ere,dbaron,marco,neil,gavin,smaug,sr=smaug (CLOSED TREE)
2009-06-10 11:00:39 -07:00
|
|
|
|
|
|
|
// inform the window so that the focus state is reset.
|
|
|
|
NS_ENSURE_STATE(mDocument);
|
|
|
|
nsPIDOMWindow *window = mDocument->GetWindow();
|
|
|
|
if (window)
|
|
|
|
window->PageHidden();
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
if (aIsUnload) {
|
2011-02-16 15:47:12 -08:00
|
|
|
// Poke the GC. The window might be collectable garbage now.
|
|
|
|
nsJSContext::PokeGC();
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
// if Destroy() was called during OnPageHide(), mDocument is nsnull.
|
|
|
|
NS_ENSURE_STATE(mDocument);
|
|
|
|
|
|
|
|
// First, get the window from the document...
|
|
|
|
nsPIDOMWindow *window = mDocument->GetWindow();
|
|
|
|
|
|
|
|
if (!window) {
|
|
|
|
// Fail if no window is available...
|
2010-03-21 15:06:12 -07:00
|
|
|
NS_WARNING("window not set for document!");
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now, fire an Unload event to the document...
|
|
|
|
nsEventStatus status = nsEventStatus_eIgnore;
|
|
|
|
nsEvent event(PR_TRUE, NS_PAGE_UNLOAD);
|
|
|
|
event.flags |= NS_EVENT_FLAG_CANT_BUBBLE;
|
|
|
|
// XXX Dispatching to |window|, but using |document| as the target.
|
|
|
|
event.target = mDocument;
|
|
|
|
|
|
|
|
// Never permit popups from the unload handler, no matter how we get
|
|
|
|
// here.
|
|
|
|
nsAutoPopupStatePusher popupStatePusher(openAbused, PR_TRUE);
|
|
|
|
|
|
|
|
nsEventDispatcher::Dispatch(window, mPresContext, &event, nsnull, &status);
|
|
|
|
}
|
|
|
|
|
2007-07-23 17:04:36 -07:00
|
|
|
#ifdef MOZ_XUL
|
2007-04-20 11:20:03 -07:00
|
|
|
// look for open menupopups and close them after the unload event, in case
|
|
|
|
// the unload event listeners open any new popups
|
2009-10-23 13:24:47 -07:00
|
|
|
nsContentUtils::HidePopupsInDocument(mDocument);
|
2007-07-23 17:04:36 -07:00
|
|
|
#endif
|
2007-04-25 19:37:27 -07:00
|
|
|
|
|
|
|
return NS_OK;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
AttachContainerRecurse(nsIDocShell* aShell)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIContentViewer> viewer;
|
|
|
|
aShell->GetContentViewer(getter_AddRefs(viewer));
|
2011-10-15 00:33:26 -07:00
|
|
|
if (viewer) {
|
|
|
|
nsIDocument* doc = viewer->GetDocument();
|
2007-03-22 10:30:00 -07:00
|
|
|
if (doc) {
|
|
|
|
doc->SetContainer(aShell);
|
|
|
|
}
|
2010-03-25 06:17:11 -07:00
|
|
|
nsRefPtr<nsPresContext> pc;
|
2011-10-15 00:33:26 -07:00
|
|
|
viewer->GetPresContext(getter_AddRefs(pc));
|
2007-03-22 10:30:00 -07:00
|
|
|
if (pc) {
|
|
|
|
pc->SetContainer(aShell);
|
|
|
|
pc->SetLinkHandler(nsCOMPtr<nsILinkHandler>(do_QueryInterface(aShell)));
|
|
|
|
}
|
|
|
|
nsCOMPtr<nsIPresShell> presShell;
|
2011-10-15 00:33:26 -07:00
|
|
|
viewer->GetPresShell(getter_AddRefs(presShell));
|
2007-03-22 10:30:00 -07:00
|
|
|
if (presShell) {
|
|
|
|
presShell->SetForwardingContainer(nsnull);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now recurse through the children
|
|
|
|
nsCOMPtr<nsIDocShellTreeNode> node = do_QueryInterface(aShell);
|
|
|
|
NS_ASSERTION(node, "docshells must implement nsIDocShellTreeNode");
|
|
|
|
|
|
|
|
PRInt32 childCount;
|
|
|
|
node->GetChildCount(&childCount);
|
|
|
|
for (PRInt32 i = 0; i < childCount; ++i) {
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem> childItem;
|
|
|
|
node->GetChildAt(i, getter_AddRefs(childItem));
|
|
|
|
AttachContainerRecurse(nsCOMPtr<nsIDocShell>(do_QueryInterface(childItem)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::Open(nsISupports *aState, nsISHEntry *aSHEntry)
|
|
|
|
{
|
|
|
|
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_INITIALIZED);
|
|
|
|
|
2008-09-30 09:51:26 -07:00
|
|
|
if (mDocument)
|
|
|
|
mDocument->SetContainer(nsCOMPtr<nsISupports>(do_QueryReferent(mContainer)));
|
|
|
|
|
2010-08-27 16:15:08 -07:00
|
|
|
nsresult rv = InitInternal(mParentWidget, aState, mBounds, PR_FALSE);
|
2008-10-04 13:00:09 -07:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
2011-04-19 14:18:17 -07:00
|
|
|
mHidden = PR_FALSE;
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
if (mPresShell)
|
|
|
|
mPresShell->SetForwardingContainer(nsnull);
|
|
|
|
|
|
|
|
// Rehook the child presentations. The child shells are still in
|
|
|
|
// session history, so get them from there.
|
|
|
|
|
2008-09-28 12:14:28 -07:00
|
|
|
if (aSHEntry) {
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem> item;
|
|
|
|
PRInt32 itemIndex = 0;
|
|
|
|
while (NS_SUCCEEDED(aSHEntry->ChildShellAt(itemIndex++,
|
|
|
|
getter_AddRefs(item))) && item) {
|
|
|
|
AttachContainerRecurse(nsCOMPtr<nsIDocShell>(do_QueryInterface(item)));
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
SyncParentSubDocMap();
|
|
|
|
|
2007-05-14 02:11:38 -07:00
|
|
|
if (mFocusListener && mDocument) {
|
2011-06-28 10:59:14 -07:00
|
|
|
mDocument->AddEventListener(NS_LITERAL_STRING("focus"), mFocusListener,
|
|
|
|
PR_FALSE, PR_FALSE);
|
|
|
|
mDocument->AddEventListener(NS_LITERAL_STRING("blur"), mFocusListener,
|
|
|
|
PR_FALSE, PR_FALSE);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// XXX re-enable image animations once that works correctly
|
|
|
|
|
|
|
|
PrepareToStartLoad();
|
2011-02-09 12:13:18 -08:00
|
|
|
|
|
|
|
// When loading a page from the bfcache with puppet widgets, we do the
|
|
|
|
// widget attachment here (it is otherwise done in MakeWindow, which is
|
|
|
|
// called for non-bfcache pages in the history, but not bfcache pages).
|
|
|
|
// Attachment is necessary, since we get detached when another page
|
|
|
|
// is browsed to. That is, if we are one page A, then when we go to
|
|
|
|
// page B, we detach. So page A's view has no widget. If we then go
|
|
|
|
// back to it, and it is in the bfcache, we will use that view, which
|
|
|
|
// doesn't have a widget. The attach call here will properly attach us.
|
|
|
|
if (nsIWidget::UsePuppetWidgets() && mPresContext &&
|
|
|
|
ShouldAttachToTopLevel()) {
|
|
|
|
// If the old view is already attached to our parent, detach
|
|
|
|
DetachFromTopLevelWidget();
|
|
|
|
|
|
|
|
nsIViewManager *vm = GetViewManager();
|
|
|
|
NS_ABORT_IF_FALSE(vm, "no view manager");
|
2011-03-29 19:24:54 -07:00
|
|
|
nsIView* v = vm->GetRootView();
|
2011-02-09 12:13:18 -08:00
|
|
|
NS_ABORT_IF_FALSE(v, "no root view");
|
|
|
|
NS_ABORT_IF_FALSE(mParentWidget, "no mParentWidget to set");
|
|
|
|
v->AttachToTopLevelWidget(mParentWidget);
|
|
|
|
|
|
|
|
mAttachedToParent = PR_TRUE;
|
|
|
|
}
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::Close(nsISHEntry *aSHEntry)
|
|
|
|
{
|
|
|
|
// All callers are supposed to call close to break circular
|
|
|
|
// references. If we do this stuff in the destructor, the
|
|
|
|
// destructor might never be called (especially if we're being
|
|
|
|
// used from JS.
|
|
|
|
|
|
|
|
mSHEntry = aSHEntry;
|
|
|
|
|
|
|
|
// Close is also needed to disable scripts during paint suppression,
|
|
|
|
// since we transfer the existing global object to the new document
|
|
|
|
// that is loaded. In the future, the global object may become a proxy
|
|
|
|
// for an object that can be switched in and out so that we don't need
|
|
|
|
// to disable scripts during paint suppression.
|
|
|
|
|
|
|
|
if (!mDocument)
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
#if defined(NS_PRINTING) && defined(NS_PRINT_PREVIEW)
|
|
|
|
// Turn scripting back on
|
|
|
|
// after PrintPreview had turned it off
|
|
|
|
if (GetIsPrintPreview() && mPrintEngine) {
|
|
|
|
mPrintEngine->TurnScriptingOn(PR_TRUE);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef NS_PRINTING
|
|
|
|
// A Close was called while we were printing
|
|
|
|
// so don't clear the ScriptGlobalObject
|
|
|
|
// or clear the mDocument below
|
|
|
|
if (mPrintEngine && !mClosingWhilePrinting) {
|
|
|
|
mClosingWhilePrinting = PR_TRUE;
|
|
|
|
} else
|
|
|
|
#endif
|
|
|
|
{
|
2009-05-07 12:21:53 -07:00
|
|
|
// out of band cleanup of docshell
|
2007-03-22 10:30:00 -07:00
|
|
|
mDocument->SetScriptGlobalObject(nsnull);
|
|
|
|
|
2008-12-19 15:45:56 -08:00
|
|
|
if (!mSHEntry && mDocument)
|
2008-04-18 03:02:03 -07:00
|
|
|
mDocument->RemovedFromDocShell();
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2007-05-14 02:11:38 -07:00
|
|
|
if (mFocusListener && mDocument) {
|
2011-06-28 10:59:14 -07:00
|
|
|
mDocument->RemoveEventListener(NS_LITERAL_STRING("focus"), mFocusListener,
|
|
|
|
PR_FALSE);
|
|
|
|
mDocument->RemoveEventListener(NS_LITERAL_STRING("blur"), mFocusListener,
|
|
|
|
PR_FALSE);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
DetachContainerRecurse(nsIDocShell *aShell)
|
|
|
|
{
|
|
|
|
// Unhook this docshell's presentation
|
|
|
|
nsCOMPtr<nsIContentViewer> viewer;
|
|
|
|
aShell->GetContentViewer(getter_AddRefs(viewer));
|
2011-10-15 00:33:26 -07:00
|
|
|
if (viewer) {
|
|
|
|
nsIDocument* doc = viewer->GetDocument();
|
2007-03-22 10:30:00 -07:00
|
|
|
if (doc) {
|
|
|
|
doc->SetContainer(nsnull);
|
|
|
|
}
|
2010-03-25 06:17:11 -07:00
|
|
|
nsRefPtr<nsPresContext> pc;
|
2011-10-15 00:33:26 -07:00
|
|
|
viewer->GetPresContext(getter_AddRefs(pc));
|
2007-03-22 10:30:00 -07:00
|
|
|
if (pc) {
|
|
|
|
pc->SetContainer(nsnull);
|
|
|
|
pc->SetLinkHandler(nsnull);
|
|
|
|
}
|
|
|
|
nsCOMPtr<nsIPresShell> presShell;
|
2011-10-15 00:33:26 -07:00
|
|
|
viewer->GetPresShell(getter_AddRefs(presShell));
|
2007-03-22 10:30:00 -07:00
|
|
|
if (presShell) {
|
|
|
|
presShell->SetForwardingContainer(nsWeakPtr(do_GetWeakReference(aShell)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now recurse through the children
|
|
|
|
nsCOMPtr<nsIDocShellTreeNode> node = do_QueryInterface(aShell);
|
|
|
|
NS_ASSERTION(node, "docshells must implement nsIDocShellTreeNode");
|
|
|
|
|
|
|
|
PRInt32 childCount;
|
|
|
|
node->GetChildCount(&childCount);
|
|
|
|
for (PRInt32 i = 0; i < childCount; ++i) {
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem> childItem;
|
|
|
|
node->GetChildAt(i, getter_AddRefs(childItem));
|
|
|
|
DetachContainerRecurse(nsCOMPtr<nsIDocShell>(do_QueryInterface(childItem)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::Destroy()
|
|
|
|
{
|
|
|
|
NS_ASSERTION(mDocument, "No document in Destroy()!");
|
|
|
|
|
|
|
|
#ifdef NS_PRINTING
|
2009-01-16 17:35:19 -08:00
|
|
|
// Here is where we check to see if the document was still being prepared
|
2007-03-22 10:30:00 -07:00
|
|
|
// for printing when it was asked to be destroy from someone externally
|
2009-01-16 17:35:19 -08:00
|
|
|
// This usually happens if the document is unloaded while the user is in the
|
|
|
|
// Print Dialog
|
2007-03-22 10:30:00 -07:00
|
|
|
//
|
|
|
|
// So we flip the bool to remember that the document is going away
|
|
|
|
// and we can clean up and abort later after returning from the Print Dialog
|
|
|
|
if (mPrintEngine) {
|
|
|
|
if (mPrintEngine->CheckBeforeDestroy()) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Don't let the document get unloaded while we are printing.
|
|
|
|
// this could happen if we hit the back button during printing.
|
|
|
|
// We also keep the viewer from being cached in session history, since
|
|
|
|
// we require all documents there to be sanitized.
|
|
|
|
if (mDestroyRefCount != 0) {
|
|
|
|
--mDestroyRefCount;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we were told to put ourselves into session history instead of destroy
|
|
|
|
// the presentation, do that now.
|
|
|
|
if (mSHEntry) {
|
|
|
|
if (mPresShell)
|
|
|
|
mPresShell->Freeze();
|
|
|
|
|
|
|
|
// Make sure the presentation isn't torn down by Hide().
|
|
|
|
mSHEntry->SetSticky(mIsSticky);
|
|
|
|
mIsSticky = PR_TRUE;
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
bool savePresentation = true;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
// Remove our root view from the view hierarchy.
|
|
|
|
if (mPresShell) {
|
|
|
|
nsIViewManager *vm = mPresShell->GetViewManager();
|
|
|
|
if (vm) {
|
2011-03-29 19:24:54 -07:00
|
|
|
nsIView *rootView = vm->GetRootView();
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
if (rootView) {
|
2011-02-07 10:51:54 -08:00
|
|
|
// The invalidate that removing this view causes is dropped because
|
|
|
|
// the Freeze call above sets painting to be suppressed for our
|
|
|
|
// document. So we do it ourselves and make it happen.
|
|
|
|
vm->UpdateViewNoSuppression(rootView,
|
|
|
|
rootView->GetBounds() - rootView->GetPosition(),
|
|
|
|
NS_VMREFRESH_NO_SYNC);
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
nsIView *rootViewParent = rootView->GetParent();
|
|
|
|
if (rootViewParent) {
|
|
|
|
nsIViewManager *parentVM = rootViewParent->GetViewManager();
|
|
|
|
if (parentVM) {
|
|
|
|
parentVM->RemoveChild(rootView);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Hide();
|
|
|
|
|
|
|
|
// This is after Hide() so that the user doesn't see the inputs clear.
|
|
|
|
if (mDocument) {
|
|
|
|
nsresult rv = mDocument->Sanitize();
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
// If we failed to sanitize, don't save presentation.
|
2010-11-23 13:24:57 -08:00
|
|
|
// XXX Shouldn't we run all the stuff after the |if (mSHEntry)| then?
|
2007-03-22 10:30:00 -07:00
|
|
|
savePresentation = PR_FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Reverse ownership. Do this *after* calling sanitize so that sanitize
|
|
|
|
// doesn't cause mutations that make the SHEntry drop the presentation
|
2011-02-11 22:12:20 -08:00
|
|
|
|
|
|
|
// Grab a reference to mSHEntry before calling into things like
|
|
|
|
// SyncPresentationState that might mess with our members.
|
2007-03-22 10:30:00 -07:00
|
|
|
nsCOMPtr<nsISHEntry> shEntry = mSHEntry; // we'll need this below
|
|
|
|
mSHEntry = nsnull;
|
|
|
|
|
2011-02-11 22:12:20 -08:00
|
|
|
if (savePresentation) {
|
|
|
|
shEntry->SetContentViewer(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Always sync the presentation state. That way even if someone screws up
|
|
|
|
// and shEntry has no window state at this point we'll be ok; we just won't
|
|
|
|
// cache ourselves.
|
|
|
|
shEntry->SyncPresentationState();
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
// Break the link from the document/presentation to the docshell, so that
|
|
|
|
// link traversals cannot affect the currently-loaded document.
|
|
|
|
// When the presentation is restored, Open() and InitInternal() will reset
|
|
|
|
// these pointers to their original values.
|
|
|
|
|
2010-11-23 13:24:57 -08:00
|
|
|
if (mDocument) {
|
2007-03-22 10:30:00 -07:00
|
|
|
mDocument->SetContainer(nsnull);
|
2010-11-23 13:24:57 -08:00
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
if (mPresContext) {
|
|
|
|
mPresContext->SetLinkHandler(nsnull);
|
|
|
|
mPresContext->SetContainer(nsnull);
|
|
|
|
}
|
|
|
|
if (mPresShell)
|
|
|
|
mPresShell->SetForwardingContainer(mContainer);
|
|
|
|
|
|
|
|
// Do the same for our children. Note that we need to get the child
|
|
|
|
// docshells from the SHEntry now; the docshell will have cleared them.
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem> item;
|
|
|
|
PRInt32 itemIndex = 0;
|
|
|
|
while (NS_SUCCEEDED(shEntry->ChildShellAt(itemIndex++,
|
|
|
|
getter_AddRefs(item))) && item) {
|
|
|
|
DetachContainerRecurse(nsCOMPtr<nsIDocShell>(do_QueryInterface(item)));
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2010-11-23 13:24:57 -08:00
|
|
|
// The document was not put in the bfcache
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
if (mDocument) {
|
|
|
|
mDocument->Destroy();
|
|
|
|
mDocument = nsnull;
|
|
|
|
}
|
|
|
|
|
|
|
|
// All callers are supposed to call destroy to break circular
|
|
|
|
// references. If we do this stuff in the destructor, the
|
|
|
|
// destructor might never be called (especially if we're being
|
|
|
|
// used from JS.
|
|
|
|
|
2008-04-08 22:24:13 -07:00
|
|
|
#ifdef NS_PRINTING
|
|
|
|
if (mPrintEngine) {
|
|
|
|
#ifdef NS_PRINT_PREVIEW
|
2011-09-28 23:19:26 -07:00
|
|
|
bool doingPrintPreview;
|
2008-04-08 22:24:13 -07:00
|
|
|
mPrintEngine->GetDoingPrintPreview(&doingPrintPreview);
|
|
|
|
if (doingPrintPreview) {
|
|
|
|
mPrintEngine->FinishPrintPreview();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
mPrintEngine->Destroy();
|
|
|
|
mPrintEngine = nsnull;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
// Avoid leaking the old viewer.
|
|
|
|
if (mPreviousViewer) {
|
|
|
|
mPreviousViewer->Destroy();
|
|
|
|
mPreviousViewer = nsnull;
|
|
|
|
}
|
|
|
|
|
2008-01-20 18:05:38 -08:00
|
|
|
mDeviceContext = nsnull;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
if (mPresShell) {
|
2009-01-14 04:24:10 -08:00
|
|
|
DestroyPresShell();
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (mPresContext) {
|
2011-01-21 11:09:11 -08:00
|
|
|
DestroyPresContext();
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2010-10-27 09:57:21 -07:00
|
|
|
mWindow = nsnull;
|
|
|
|
mViewManager = nsnull;
|
2007-03-22 10:30:00 -07:00
|
|
|
mContainer = nsnull;
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::Stop(void)
|
|
|
|
{
|
|
|
|
NS_ASSERTION(mDocument, "Stop called too early or too late");
|
|
|
|
if (mDocument) {
|
|
|
|
mDocument->StopDocumentLoad();
|
|
|
|
}
|
|
|
|
|
2010-02-18 11:23:23 -08:00
|
|
|
if (!mHidden && (mLoaded || mStopped) && mPresContext && !mSHEntry)
|
2007-03-22 10:30:00 -07:00
|
|
|
mPresContext->SetImageAnimationMode(imgIContainer::kDontAnimMode);
|
|
|
|
|
|
|
|
mStopped = PR_TRUE;
|
|
|
|
|
|
|
|
if (!mLoaded && mPresShell) {
|
|
|
|
// Well, we might as well paint what we have so far.
|
2007-04-27 04:06:22 -07:00
|
|
|
nsCOMPtr<nsIPresShell> shellDeathGrip(mPresShell); // bug 378682
|
2007-03-22 10:30:00 -07:00
|
|
|
mPresShell->UnsuppressPainting();
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::GetDOMDocument(nsIDOMDocument **aResult)
|
|
|
|
{
|
|
|
|
NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE);
|
|
|
|
return CallQueryInterface(mDocument, aResult);
|
|
|
|
}
|
|
|
|
|
2010-01-23 03:41:41 -08:00
|
|
|
NS_IMETHODIMP_(nsIDocument *)
|
|
|
|
DocumentViewerImpl::GetDocument()
|
|
|
|
{
|
|
|
|
return mDocument;
|
|
|
|
}
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::SetDOMDocument(nsIDOMDocument *aDocument)
|
|
|
|
{
|
|
|
|
// Assumptions:
|
|
|
|
//
|
|
|
|
// 1) this document viewer has been initialized with a call to Init().
|
|
|
|
// 2) the stylesheets associated with the document have been added
|
|
|
|
// to the document.
|
|
|
|
|
|
|
|
// XXX Right now, this method assumes that the layout of the current
|
|
|
|
// document hasn't started yet. More cleanup will probably be
|
|
|
|
// necessary to make this method work for the case when layout *has*
|
|
|
|
// occurred for the current document.
|
|
|
|
// That work can happen when and if it is needed.
|
|
|
|
|
|
|
|
if (!aDocument)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
2010-09-15 15:54:00 -07:00
|
|
|
nsCOMPtr<nsIDocument> newDoc = do_QueryInterface(aDocument);
|
|
|
|
NS_ENSURE_TRUE(newDoc, NS_ERROR_UNEXPECTED);
|
|
|
|
|
|
|
|
return SetDocumentInternal(newDoc, PR_FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::SetDocumentInternal(nsIDocument* aDocument,
|
2011-09-28 23:19:26 -07:00
|
|
|
bool aForceReuseInnerWindow)
|
2010-09-15 15:54:00 -07:00
|
|
|
{
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
// Set new container
|
|
|
|
nsCOMPtr<nsISupports> container = do_QueryReferent(mContainer);
|
2010-09-15 15:54:00 -07:00
|
|
|
aDocument->SetContainer(container);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2010-09-15 15:54:00 -07:00
|
|
|
if (mDocument != aDocument) {
|
2011-06-16 11:20:13 -07:00
|
|
|
if (mDocument->IsStaticDocument()) {
|
|
|
|
mDocument->SetScriptGlobalObject(nsnull);
|
|
|
|
mDocument->Destroy();
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
// Replace the old document with the new one. Do this only when
|
|
|
|
// the new document really is a new document.
|
2010-09-15 15:54:00 -07:00
|
|
|
mDocument = aDocument;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
// Set the script global object on the new document
|
|
|
|
nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(container);
|
|
|
|
if (window) {
|
2010-09-15 15:54:00 -07:00
|
|
|
window->SetNewDocument(aDocument, nsnull, aForceReuseInnerWindow);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2011-01-21 11:09:11 -08:00
|
|
|
// Clear the list of old child docshells. Child docshells for the new
|
2007-03-22 10:30:00 -07:00
|
|
|
// document will be constructed as frames are created.
|
2010-09-15 15:54:00 -07:00
|
|
|
if (!aDocument->IsStaticDocument()) {
|
2009-12-10 20:02:13 -08:00
|
|
|
nsCOMPtr<nsIDocShellTreeNode> node = do_QueryInterface(container);
|
|
|
|
if (node) {
|
|
|
|
PRInt32 count;
|
|
|
|
node->GetChildCount(&count);
|
|
|
|
for (PRInt32 i = 0; i < count; ++i) {
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem> child;
|
|
|
|
node->GetChildAt(0, getter_AddRefs(child));
|
|
|
|
node->RemoveChild(child);
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-09-15 15:54:00 -07:00
|
|
|
nsresult rv = SyncParentSubDocMap();
|
2007-03-22 10:30:00 -07:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
// Replace the current pres shell with a new shell for the new document
|
|
|
|
|
|
|
|
if (mPresShell) {
|
2009-01-14 04:24:10 -08:00
|
|
|
DestroyPresShell();
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (mPresContext) {
|
2011-01-21 11:09:11 -08:00
|
|
|
DestroyPresContext();
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2011-02-15 13:45:02 -08:00
|
|
|
mWindow = nsnull;
|
2011-01-21 11:09:11 -08:00
|
|
|
InitInternal(mParentWidget, nsnull, mBounds, PR_TRUE, PR_TRUE, PR_FALSE);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2007-11-09 02:19:12 -08:00
|
|
|
nsIPresShell*
|
|
|
|
DocumentViewerImpl::GetPresShell()
|
|
|
|
{
|
2009-12-10 20:02:13 -08:00
|
|
|
return mPresShell;
|
2007-11-09 02:19:12 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
nsPresContext*
|
|
|
|
DocumentViewerImpl::GetPresContext()
|
|
|
|
{
|
2009-12-10 20:02:13 -08:00
|
|
|
return mPresContext;
|
2007-11-09 02:19:12 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
nsIViewManager*
|
|
|
|
DocumentViewerImpl::GetViewManager()
|
|
|
|
{
|
2009-12-10 20:02:13 -08:00
|
|
|
return mViewManager;
|
2007-11-09 02:19:12 -08:00
|
|
|
}
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::GetPresShell(nsIPresShell** aResult)
|
|
|
|
{
|
2007-11-09 02:19:12 -08:00
|
|
|
nsIPresShell* shell = GetPresShell();
|
|
|
|
NS_IF_ADDREF(*aResult = shell);
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::GetPresContext(nsPresContext** aResult)
|
|
|
|
{
|
2007-11-09 02:19:12 -08:00
|
|
|
nsPresContext* pc = GetPresContext();
|
|
|
|
NS_IF_ADDREF(*aResult = pc);
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2009-01-14 19:27:09 -08:00
|
|
|
DocumentViewerImpl::GetBounds(nsIntRect& aResult)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE);
|
2009-07-21 17:45:10 -07:00
|
|
|
aResult = mBounds;
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::GetPreviousViewer(nsIContentViewer** aViewer)
|
|
|
|
{
|
|
|
|
*aViewer = mPreviousViewer;
|
|
|
|
NS_IF_ADDREF(*aViewer);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::SetPreviousViewer(nsIContentViewer* aViewer)
|
|
|
|
{
|
|
|
|
// NOTE: |Show| sets |mPreviousViewer| to null without calling this
|
|
|
|
// function.
|
|
|
|
|
|
|
|
if (aViewer) {
|
|
|
|
NS_ASSERTION(!mPreviousViewer,
|
|
|
|
"can't set previous viewer when there already is one");
|
|
|
|
|
|
|
|
// In a multiple chaining situation (which occurs when running a thrashing
|
|
|
|
// test like i-bench or jrgm's tests with no delay), we can build up a
|
|
|
|
// whole chain of viewers. In order to avoid this, we always set our previous
|
|
|
|
// viewer to the MOST previous viewer in the chain, and then dump the intermediate
|
|
|
|
// link from the chain. This ensures that at most only 2 documents are alive
|
|
|
|
// and undestroyed at any given time (the one that is showing and the one that
|
|
|
|
// is loading with painting suppressed).
|
2007-10-05 17:35:00 -07:00
|
|
|
// It's very important that if this ever gets changed the code
|
|
|
|
// before the RestorePresentation call in nsDocShell::InternalLoad
|
|
|
|
// be changed accordingly.
|
2007-03-22 10:30:00 -07:00
|
|
|
nsCOMPtr<nsIContentViewer> prevViewer;
|
|
|
|
aViewer->GetPreviousViewer(getter_AddRefs(prevViewer));
|
|
|
|
if (prevViewer) {
|
|
|
|
aViewer->SetPreviousViewer(nsnull);
|
|
|
|
aViewer->Destroy();
|
|
|
|
return SetPreviousViewer(prevViewer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
mPreviousViewer = aViewer;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2009-01-14 19:27:09 -08:00
|
|
|
DocumentViewerImpl::SetBounds(const nsIntRect& aBounds)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE);
|
|
|
|
|
2009-07-21 17:45:10 -07:00
|
|
|
mBounds = aBounds;
|
2007-03-22 10:30:00 -07:00
|
|
|
if (mWindow) {
|
2010-06-24 19:01:06 -07:00
|
|
|
// When attached to a top level window, change the client area, not the
|
|
|
|
// window frame.
|
2007-03-22 10:30:00 -07:00
|
|
|
// Don't have the widget repaint. Layout will generate repaint requests
|
2010-06-24 19:01:06 -07:00
|
|
|
// during reflow.
|
|
|
|
if (mAttachedToParent)
|
|
|
|
mWindow->ResizeClient(aBounds.x, aBounds.y,
|
|
|
|
aBounds.width, aBounds.height,
|
|
|
|
PR_FALSE);
|
|
|
|
else
|
|
|
|
mWindow->Resize(aBounds.x, aBounds.y,
|
|
|
|
aBounds.width, aBounds.height,
|
|
|
|
PR_FALSE);
|
2009-07-21 17:45:10 -07:00
|
|
|
} else if (mPresContext && mViewManager) {
|
|
|
|
PRInt32 p2a = mPresContext->AppUnitsPerDevPixel();
|
|
|
|
mViewManager->SetWindowDimensions(NSIntPixelsToAppUnits(mBounds.width, p2a),
|
|
|
|
NSIntPixelsToAppUnits(mBounds.height, p2a));
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// If there's a previous viewer, it's the one that's actually showing,
|
|
|
|
// so be sure to resize it as well so it paints over the right area.
|
|
|
|
// This may slow down the performance of the new page load, but resize
|
|
|
|
// during load is also probably a relatively unusual condition
|
|
|
|
// relating to things being hidden while something is loaded. It so
|
|
|
|
// happens that Firefox does this a good bit with its infobar, and it
|
|
|
|
// looks ugly if we don't do this.
|
|
|
|
if (mPreviousViewer)
|
|
|
|
mPreviousViewer->SetBounds(aBounds);
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::Move(PRInt32 aX, PRInt32 aY)
|
|
|
|
{
|
|
|
|
NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE);
|
2009-07-21 17:45:10 -07:00
|
|
|
mBounds.MoveTo(aX, aY);
|
2007-03-22 10:30:00 -07:00
|
|
|
if (mWindow) {
|
|
|
|
mWindow->Move(aX, aY);
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::Show(void)
|
|
|
|
{
|
|
|
|
NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE);
|
|
|
|
|
|
|
|
// We don't need the previous viewer anymore since we're not
|
|
|
|
// displaying it.
|
|
|
|
if (mPreviousViewer) {
|
|
|
|
// This little dance *may* only be to keep
|
|
|
|
// PresShell::EndObservingDocument happy, but I'm not sure.
|
|
|
|
nsCOMPtr<nsIContentViewer> prevViewer(mPreviousViewer);
|
|
|
|
mPreviousViewer = nsnull;
|
|
|
|
prevViewer->Destroy();
|
|
|
|
|
|
|
|
// Make sure we don't have too many cached ContentViewers
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem> treeItem = do_QueryReferent(mContainer);
|
|
|
|
if (treeItem) {
|
|
|
|
// We need to find the root DocShell since only that object has an
|
|
|
|
// SHistory and we need the SHistory to evict content viewers
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem> root;
|
|
|
|
treeItem->GetSameTypeRootTreeItem(getter_AddRefs(root));
|
|
|
|
nsCOMPtr<nsIWebNavigation> webNav = do_QueryInterface(root);
|
|
|
|
nsCOMPtr<nsISHistory> history;
|
|
|
|
webNav->GetSessionHistory(getter_AddRefs(history));
|
|
|
|
nsCOMPtr<nsISHistoryInternal> historyInt = do_QueryInterface(history);
|
|
|
|
if (historyInt) {
|
2008-09-29 11:28:15 -07:00
|
|
|
PRInt32 prevIndex,loadedIndex;
|
|
|
|
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(treeItem);
|
|
|
|
docShell->GetPreviousTransIndex(&prevIndex);
|
|
|
|
docShell->GetLoadedTransIndex(&loadedIndex);
|
2007-03-22 10:30:00 -07:00
|
|
|
#ifdef DEBUG_PAGE_CACHE
|
2008-09-29 11:28:15 -07:00
|
|
|
printf("About to evict content viewers: prev=%d, loaded=%d\n",
|
|
|
|
prevIndex, loadedIndex);
|
2007-03-22 10:30:00 -07:00
|
|
|
#endif
|
2011-05-13 12:42:36 -07:00
|
|
|
historyInt->EvictOutOfRangeContentViewers(loadedIndex);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-07-15 19:47:14 -07:00
|
|
|
if (mWindow) {
|
2010-10-15 06:52:29 -07:00
|
|
|
// When attached to a top level xul window, we do not need to call
|
|
|
|
// Show on the widget. Underlying window management code handles
|
|
|
|
// this when the window is initialized.
|
|
|
|
if (!mAttachedToParent) {
|
2010-08-03 22:36:19 -07:00
|
|
|
mWindow->Show(PR_TRUE);
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2009-07-21 17:45:10 -07:00
|
|
|
if (mDocument && !mPresShell) {
|
|
|
|
NS_ASSERTION(!mWindow, "Window already created but no presshell?");
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
nsCOMPtr<nsIBaseWindow> base_win(do_QueryReferent(mContainer));
|
2008-09-28 12:14:28 -07:00
|
|
|
if (base_win) {
|
|
|
|
base_win->GetParentWidget(&mParentWidget);
|
2009-07-21 17:45:10 -07:00
|
|
|
if (mParentWidget) {
|
|
|
|
mParentWidget->Release(); // GetParentWidget AddRefs, but mParentWidget is weak
|
|
|
|
}
|
2008-09-28 12:14:28 -07:00
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2009-07-21 17:44:53 -07:00
|
|
|
nsIView* containerView = FindContainerView();
|
|
|
|
|
2009-07-21 17:45:10 -07:00
|
|
|
nsresult rv = CreateDeviceContext(containerView);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
// Create presentation context
|
|
|
|
NS_ASSERTION(!mPresContext, "Shouldn't have a prescontext if we have no shell!");
|
2009-07-21 17:44:54 -07:00
|
|
|
mPresContext = CreatePresContext(mDocument,
|
|
|
|
nsPresContext::eContext_Galley, containerView);
|
2007-03-22 10:30:00 -07:00
|
|
|
NS_ENSURE_TRUE(mPresContext, NS_ERROR_OUT_OF_MEMORY);
|
|
|
|
|
|
|
|
rv = mPresContext->Init(mDeviceContext);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
mPresContext = nsnull;
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2009-07-21 17:45:10 -07:00
|
|
|
rv = MakeWindow(nsSize(mPresContext->DevPixelsToAppUnits(mBounds.width),
|
|
|
|
mPresContext->DevPixelsToAppUnits(mBounds.height)),
|
2009-07-21 17:44:53 -07:00
|
|
|
containerView);
|
2007-03-22 10:30:00 -07:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
if (mPresContext && base_win) {
|
|
|
|
nsCOMPtr<nsILinkHandler> linkHandler(do_GetInterface(base_win));
|
|
|
|
|
|
|
|
if (linkHandler) {
|
|
|
|
mPresContext->SetLinkHandler(linkHandler);
|
|
|
|
}
|
|
|
|
|
|
|
|
mPresContext->SetContainer(base_win);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mPresContext) {
|
|
|
|
Hide();
|
|
|
|
|
2010-02-18 11:23:23 -08:00
|
|
|
rv = InitPresentationStuff(mDocument->MayStartLayout());
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// If we get here the document load has already started and the
|
|
|
|
// window is shown because some JS on the page caused it to be
|
|
|
|
// shown...
|
|
|
|
|
2009-12-10 20:02:13 -08:00
|
|
|
if (mPresShell) {
|
|
|
|
nsCOMPtr<nsIPresShell> shellDeathGrip(mPresShell); // bug 378682
|
|
|
|
mPresShell->UnsuppressPainting();
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::Hide(void)
|
|
|
|
{
|
2010-10-21 14:59:26 -07:00
|
|
|
if (!mAttachedToParent && mWindow) {
|
2007-03-22 10:30:00 -07:00
|
|
|
mWindow->Show(PR_FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!mPresShell)
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
NS_ASSERTION(mPresContext, "Can't have a presshell and no prescontext!");
|
|
|
|
|
|
|
|
// Avoid leaking the old viewer.
|
|
|
|
if (mPreviousViewer) {
|
|
|
|
mPreviousViewer->Destroy();
|
|
|
|
mPreviousViewer = nsnull;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mIsSticky) {
|
|
|
|
// This window is sticky, that means that it might be shown again
|
|
|
|
// and we don't want the presshell n' all that to be thrown away
|
|
|
|
// just because the window is hidden.
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDocShell> docShell(do_QueryReferent(mContainer));
|
|
|
|
if (docShell) {
|
2008-12-03 09:55:14 -08:00
|
|
|
nsCOMPtr<nsILayoutHistoryState> layoutState;
|
|
|
|
mPresShell->CaptureHistoryState(getter_AddRefs(layoutState), PR_TRUE);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2009-01-14 04:24:10 -08:00
|
|
|
DestroyPresShell();
|
|
|
|
|
2011-01-21 11:09:11 -08:00
|
|
|
DestroyPresContext();
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
mViewManager = nsnull;
|
|
|
|
mWindow = nsnull;
|
|
|
|
mDeviceContext = nsnull;
|
|
|
|
mParentWidget = nsnull;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIBaseWindow> base_win(do_QueryReferent(mContainer));
|
|
|
|
|
2010-10-21 14:59:26 -07:00
|
|
|
if (base_win && !mAttachedToParent) {
|
2007-03-22 10:30:00 -07:00
|
|
|
base_win->SetParentWidget(nsnull);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2011-09-28 23:19:26 -07:00
|
|
|
DocumentViewerImpl::GetSticky(bool *aSticky)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
*aSticky = mIsSticky;
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2011-09-28 23:19:26 -07:00
|
|
|
DocumentViewerImpl::SetSticky(bool aSticky)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
mIsSticky = aSticky;
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2011-09-28 23:19:26 -07:00
|
|
|
DocumentViewerImpl::RequestWindowClose(bool* aCanClose)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
#ifdef NS_PRINTING
|
|
|
|
if (mPrintIsPending || (mPrintEngine && mPrintEngine->GetIsPrinting())) {
|
|
|
|
*aCanClose = PR_FALSE;
|
|
|
|
mDeferredWindowClose = PR_TRUE;
|
|
|
|
} else
|
|
|
|
#endif
|
|
|
|
*aCanClose = PR_TRUE;
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
static bool
|
2007-03-22 10:30:00 -07:00
|
|
|
AppendAgentSheet(nsIStyleSheet *aSheet, void *aData)
|
|
|
|
{
|
2007-07-08 00:08:04 -07:00
|
|
|
nsStyleSet *styleSet = static_cast<nsStyleSet*>(aData);
|
2007-03-22 10:30:00 -07:00
|
|
|
styleSet->AppendStyleSheet(nsStyleSet::eAgentSheet, aSheet);
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
static bool
|
2007-03-22 10:30:00 -07:00
|
|
|
PrependUserSheet(nsIStyleSheet *aSheet, void *aData)
|
|
|
|
{
|
2007-07-08 00:08:04 -07:00
|
|
|
nsStyleSet *styleSet = static_cast<nsStyleSet*>(aData);
|
2007-03-22 10:30:00 -07:00
|
|
|
styleSet->PrependStyleSheet(nsStyleSet::eUserSheet, aSheet);
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
DocumentViewerImpl::CreateStyleSet(nsIDocument* aDocument,
|
|
|
|
nsStyleSet** aStyleSet)
|
|
|
|
{
|
|
|
|
// Make sure this does the same thing as PresShell::AddSheet wrt ordering.
|
|
|
|
|
|
|
|
// this should eventually get expanded to allow for creating
|
|
|
|
// different sets for different media
|
|
|
|
nsStyleSet *styleSet = new nsStyleSet();
|
|
|
|
|
|
|
|
styleSet->BeginUpdate();
|
|
|
|
|
|
|
|
// The document will fill in the document sheets when we create the presshell
|
|
|
|
|
|
|
|
// Handle the user sheets.
|
2008-10-04 13:00:09 -07:00
|
|
|
#ifdef DEBUG
|
|
|
|
nsCOMPtr<nsISupports> debugDocContainer = aDocument->GetContainer();
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem> debugDocShell(do_QueryReferent(mContainer));
|
|
|
|
NS_ASSERTION(SameCOMIdentity(debugDocContainer, debugDocShell),
|
|
|
|
"Unexpected containers");
|
|
|
|
#endif
|
2010-05-11 13:41:47 -07:00
|
|
|
nsCSSStyleSheet* sheet = nsnull;
|
2008-10-04 13:00:09 -07:00
|
|
|
if (nsContentUtils::IsInChromeDocshell(aDocument)) {
|
2007-03-22 10:30:00 -07:00
|
|
|
sheet = nsLayoutStylesheetCache::UserChromeSheet();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
sheet = nsLayoutStylesheetCache::UserContentSheet();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sheet)
|
|
|
|
styleSet->AppendStyleSheet(nsStyleSet::eUserSheet, sheet);
|
|
|
|
|
|
|
|
// Append chrome sheets (scrollbars + forms).
|
2011-09-28 23:19:26 -07:00
|
|
|
bool shouldOverride = false;
|
2008-10-04 13:00:09 -07:00
|
|
|
// We don't want a docshell here for external resource docs, so just
|
|
|
|
// look at mContainer.
|
|
|
|
nsCOMPtr<nsIDocShell> ds(do_QueryReferent(mContainer));
|
2007-03-22 10:30:00 -07:00
|
|
|
nsCOMPtr<nsIDOMEventTarget> chromeHandler;
|
|
|
|
nsCOMPtr<nsIURI> uri;
|
2010-05-11 13:41:47 -07:00
|
|
|
nsRefPtr<nsCSSStyleSheet> csssheet;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2008-09-28 12:14:28 -07:00
|
|
|
if (ds) {
|
|
|
|
ds->GetChromeEventHandler(getter_AddRefs(chromeHandler));
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
if (chromeHandler) {
|
|
|
|
nsCOMPtr<nsIDOMElement> elt(do_QueryInterface(chromeHandler));
|
|
|
|
nsCOMPtr<nsIContent> content(do_QueryInterface(elt));
|
|
|
|
if (elt && content) {
|
|
|
|
nsCOMPtr<nsIURI> baseURI = content->GetBaseURI();
|
|
|
|
|
|
|
|
nsAutoString sheets;
|
|
|
|
elt->GetAttribute(NS_LITERAL_STRING("usechromesheets"), sheets);
|
|
|
|
if (!sheets.IsEmpty() && baseURI) {
|
2010-03-02 13:00:53 -08:00
|
|
|
nsRefPtr<mozilla::css::Loader> cssLoader = new mozilla::css::Loader();
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
char *str = ToNewCString(sheets);
|
|
|
|
char *newStr = str;
|
|
|
|
char *token;
|
|
|
|
while ( (token = nsCRT::strtok(newStr, ", ", &newStr)) ) {
|
|
|
|
NS_NewURI(getter_AddRefs(uri), nsDependentCString(token), nsnull,
|
|
|
|
baseURI);
|
|
|
|
if (!uri) continue;
|
|
|
|
|
|
|
|
cssLoader->LoadSheetSync(uri, getter_AddRefs(csssheet));
|
2010-04-29 01:37:27 -07:00
|
|
|
if (!csssheet) continue;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, csssheet);
|
|
|
|
shouldOverride = PR_TRUE;
|
|
|
|
}
|
|
|
|
nsMemory::Free(str);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!shouldOverride) {
|
|
|
|
sheet = nsLayoutStylesheetCache::ScrollbarsSheet();
|
|
|
|
if (sheet) {
|
|
|
|
styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, sheet);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sheet = nsLayoutStylesheetCache::FormsSheet();
|
|
|
|
if (sheet) {
|
|
|
|
styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, sheet);
|
|
|
|
}
|
|
|
|
|
2008-11-02 18:29:51 -08:00
|
|
|
// Make sure to clone the quirk sheet so that it can be usefully
|
|
|
|
// enabled/disabled as needed.
|
2010-05-11 13:41:47 -07:00
|
|
|
nsRefPtr<nsCSSStyleSheet> quirkClone;
|
|
|
|
nsCSSStyleSheet* quirkSheet;
|
2008-11-02 18:29:51 -08:00
|
|
|
if (!nsLayoutStylesheetCache::UASheet() ||
|
2010-05-11 13:41:47 -07:00
|
|
|
!(quirkSheet = nsLayoutStylesheetCache::QuirkSheet()) ||
|
|
|
|
!(quirkClone = quirkSheet->Clone(nsnull, nsnull, nsnull, nsnull)) ||
|
2008-11-02 18:29:51 -08:00
|
|
|
!sheet) {
|
|
|
|
delete styleSet;
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
2008-11-02 18:29:51 -08:00
|
|
|
// quirk.css needs to come after the regular UA sheet (or more precisely,
|
|
|
|
// after the html.css and so forth that the UA sheet imports).
|
|
|
|
styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, quirkClone);
|
|
|
|
styleSet->SetQuirkStyleSheet(quirkClone);
|
|
|
|
styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet,
|
|
|
|
nsLayoutStylesheetCache::UASheet());
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
nsCOMPtr<nsIStyleSheetService> dummy =
|
|
|
|
do_GetService(NS_STYLESHEETSERVICE_CONTRACTID);
|
|
|
|
|
|
|
|
nsStyleSheetService *sheetService = nsStyleSheetService::gInstance;
|
|
|
|
if (sheetService) {
|
|
|
|
sheetService->AgentStyleSheets()->EnumerateForwards(AppendAgentSheet,
|
|
|
|
styleSet);
|
|
|
|
sheetService->UserStyleSheets()->EnumerateBackwards(PrependUserSheet,
|
|
|
|
styleSet);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Caller will handle calling EndUpdate, per contract.
|
|
|
|
*aStyleSet = styleSet;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::ClearHistoryEntry()
|
|
|
|
{
|
|
|
|
mSHEntry = nsnull;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------
|
|
|
|
|
|
|
|
nsresult
|
2009-07-21 17:44:53 -07:00
|
|
|
DocumentViewerImpl::MakeWindow(const nsSize& aSize, nsIView* aContainerView)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2009-12-10 20:02:13 -08:00
|
|
|
if (GetIsPrintPreview())
|
|
|
|
return NS_OK;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
bool shouldAttach = ShouldAttachToTopLevel();
|
2011-02-09 12:13:18 -08:00
|
|
|
|
|
|
|
if (shouldAttach) {
|
|
|
|
// If the old view is already attached to our parent, detach
|
|
|
|
DetachFromTopLevelWidget();
|
2010-06-24 19:01:06 -07:00
|
|
|
}
|
|
|
|
|
2009-12-10 20:02:13 -08:00
|
|
|
nsresult rv;
|
2007-03-22 10:30:00 -07:00
|
|
|
mViewManager = do_CreateInstance(kViewManagerCID, &rv);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
2011-04-16 18:22:44 -07:00
|
|
|
nsDeviceContext *dx = mPresContext->DeviceContext();
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
rv = mViewManager->Init(dx);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
2007-12-01 02:42:12 -08:00
|
|
|
// The root view is always at 0,0.
|
|
|
|
nsRect tbounds(nsPoint(0, 0), aSize);
|
2007-03-22 10:30:00 -07:00
|
|
|
// Create a view
|
2009-07-21 17:44:53 -07:00
|
|
|
nsIView* view = mViewManager->CreateView(tbounds, aContainerView);
|
2007-03-22 10:30:00 -07:00
|
|
|
if (!view)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
2010-08-20 12:29:02 -07:00
|
|
|
// Create a widget if we were given a parent widget or don't have a
|
2010-09-08 13:40:39 -07:00
|
|
|
// container view that we can hook up to without a widget.
|
2010-09-08 13:40:39 -07:00
|
|
|
// Don't create widgets for ResourceDocs (external resources & svg images),
|
|
|
|
// because when they're displayed, they're painted into *another* document's
|
|
|
|
// widget.
|
|
|
|
if (!mDocument->IsResourceDoc() &&
|
2010-09-08 13:40:39 -07:00
|
|
|
(mParentWidget || !aContainerView)) {
|
2009-07-21 17:45:10 -07:00
|
|
|
// pass in a native widget to be the parent widget ONLY if the view hierarchy will stand alone.
|
|
|
|
// otherwise the view will find its own parent widget and "do the right thing" to
|
|
|
|
// establish a parent/child widget relationship
|
|
|
|
nsWidgetInitData initData;
|
|
|
|
nsWidgetInitData* initDataPtr;
|
|
|
|
if (!mParentWidget) {
|
|
|
|
initDataPtr = &initData;
|
|
|
|
initData.mWindowType = eWindowType_invisible;
|
|
|
|
} else {
|
|
|
|
initDataPtr = nsnull;
|
|
|
|
}
|
2010-06-24 19:01:06 -07:00
|
|
|
|
2011-02-09 12:13:18 -08:00
|
|
|
if (shouldAttach) {
|
2010-06-24 19:01:06 -07:00
|
|
|
// Reuse the top level parent widget.
|
|
|
|
rv = view->AttachToTopLevelWidget(mParentWidget);
|
2011-02-09 12:13:18 -08:00
|
|
|
mAttachedToParent = PR_TRUE;
|
2010-06-24 19:01:06 -07:00
|
|
|
}
|
2010-08-20 12:29:02 -07:00
|
|
|
else if (!aContainerView && mParentWidget) {
|
2010-08-20 12:29:02 -07:00
|
|
|
rv = view->CreateWidgetForParent(mParentWidget, initDataPtr,
|
2010-08-20 12:29:02 -07:00
|
|
|
PR_TRUE, PR_FALSE);
|
|
|
|
}
|
2010-06-24 19:01:06 -07:00
|
|
|
else {
|
2010-08-20 12:29:02 -07:00
|
|
|
rv = view->CreateWidget(initDataPtr, PR_TRUE, PR_FALSE);
|
2010-06-24 19:01:06 -07:00
|
|
|
}
|
2009-07-21 17:45:10 -07:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2008-09-28 12:14:28 -07:00
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
// Setup hierarchical relationship in view manager
|
|
|
|
mViewManager->SetRootView(view);
|
|
|
|
|
|
|
|
mWindow = view->GetWidget();
|
|
|
|
|
|
|
|
// This SetFocus is necessary so the Arrow Key and Page Key events
|
|
|
|
// go to the scrolled view as soon as the Window is created instead of going to
|
|
|
|
// the browser window (this enables keyboard scrolling of the document)
|
|
|
|
// mWindow->SetFocus();
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2010-06-24 19:01:06 -07:00
|
|
|
void
|
|
|
|
DocumentViewerImpl::DetachFromTopLevelWidget()
|
|
|
|
{
|
|
|
|
if (mViewManager) {
|
2011-03-29 19:24:54 -07:00
|
|
|
nsIView* oldView = mViewManager->GetRootView();
|
2010-06-24 19:01:06 -07:00
|
|
|
if (oldView && oldView->IsAttachedToTopLevel()) {
|
|
|
|
oldView->DetachFromTopLevelWidget();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
mAttachedToParent = PR_FALSE;
|
|
|
|
}
|
|
|
|
|
2009-07-21 17:44:53 -07:00
|
|
|
nsIView*
|
|
|
|
DocumentViewerImpl::FindContainerView()
|
|
|
|
{
|
2009-07-21 17:45:10 -07:00
|
|
|
nsIView* containerView = nsnull;
|
|
|
|
|
2010-08-27 16:15:08 -07:00
|
|
|
if (mContainer) {
|
2010-08-27 16:15:08 -07:00
|
|
|
nsCOMPtr<nsIDocShellTreeItem> docShellItem = do_QueryReferent(mContainer);
|
|
|
|
nsCOMPtr<nsPIDOMWindow> pwin(do_GetInterface(docShellItem));
|
|
|
|
if (pwin) {
|
|
|
|
nsCOMPtr<nsIContent> containerElement = do_QueryInterface(pwin->GetFrameElementInternal());
|
2011-09-25 21:53:30 -07:00
|
|
|
if (!containerElement) {
|
|
|
|
return nsnull;
|
|
|
|
}
|
2009-07-21 17:45:10 -07:00
|
|
|
nsCOMPtr<nsIPresShell> parentPresShell;
|
|
|
|
if (docShellItem) {
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem> parentDocShellItem;
|
|
|
|
docShellItem->GetParent(getter_AddRefs(parentDocShellItem));
|
|
|
|
if (parentDocShellItem) {
|
|
|
|
nsCOMPtr<nsIDocShell> parentDocShell = do_QueryInterface(parentDocShellItem);
|
|
|
|
parentDocShell->GetPresShell(getter_AddRefs(parentPresShell));
|
|
|
|
}
|
|
|
|
}
|
2011-09-25 21:53:30 -07:00
|
|
|
if (!parentPresShell) {
|
2010-08-21 17:55:55 -07:00
|
|
|
nsCOMPtr<nsIDocument> parentDoc = containerElement->GetCurrentDoc();
|
|
|
|
if (parentDoc) {
|
|
|
|
parentPresShell = parentDoc->GetShell();
|
|
|
|
}
|
|
|
|
}
|
2011-09-25 21:53:30 -07:00
|
|
|
if (!parentPresShell) {
|
2009-08-25 12:00:46 -07:00
|
|
|
NS_WARNING("Subdocument container has no presshell");
|
|
|
|
} else {
|
2010-03-04 14:52:59 -08:00
|
|
|
nsIFrame* f = parentPresShell->GetRealPrimaryFrameFor(containerElement);
|
2009-07-21 17:45:10 -07:00
|
|
|
if (f) {
|
|
|
|
nsIFrame* subdocFrame = f->GetContentInsertionFrame();
|
|
|
|
// subdocFrame might not be a subdocument frame; the frame
|
|
|
|
// constructor can treat a <frame> as an inline in some XBL
|
|
|
|
// cases. Treat that as display:none, the document is not
|
|
|
|
// displayed.
|
|
|
|
if (subdocFrame->GetType() == nsGkAtoms::subDocumentFrame) {
|
2010-09-18 04:28:50 -07:00
|
|
|
NS_ASSERTION(subdocFrame->GetView(), "Subdoc frames must have views");
|
|
|
|
nsIView* innerView =
|
|
|
|
static_cast<nsSubDocumentFrame*>(subdocFrame)->EnsureInnerView();
|
2009-07-21 17:45:10 -07:00
|
|
|
containerView = innerView;
|
2009-08-25 12:00:46 -07:00
|
|
|
} else {
|
|
|
|
NS_WARNING("Subdocument container has non-subdocument frame");
|
2009-07-21 17:45:10 -07:00
|
|
|
}
|
2009-08-25 12:00:46 -07:00
|
|
|
} else {
|
|
|
|
NS_WARNING("Subdocument container has no frame");
|
2009-07-21 17:45:10 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-08-27 16:15:08 -07:00
|
|
|
return containerView;
|
2009-07-21 17:44:53 -07:00
|
|
|
}
|
|
|
|
|
2008-08-18 12:22:19 -07:00
|
|
|
nsresult
|
2009-07-21 17:45:10 -07:00
|
|
|
DocumentViewerImpl::CreateDeviceContext(nsIView* aContainerView)
|
2008-08-18 12:22:19 -07:00
|
|
|
{
|
2010-03-22 07:24:18 -07:00
|
|
|
NS_PRECONDITION(!mPresShell && !mWindow,
|
2008-09-28 12:14:28 -07:00
|
|
|
"This will screw up our existing presentation");
|
2008-10-04 13:00:09 -07:00
|
|
|
NS_PRECONDITION(mDocument, "Gotta have a document here");
|
|
|
|
|
|
|
|
nsIDocument* doc = mDocument->GetDisplayDocument();
|
|
|
|
if (doc) {
|
2009-07-21 17:45:10 -07:00
|
|
|
NS_ASSERTION(!aContainerView, "External resource document embedded somewhere?");
|
2008-10-04 13:00:09 -07:00
|
|
|
// We want to use our display document's device context if possible
|
2010-06-25 06:59:57 -07:00
|
|
|
nsIPresShell* shell = doc->GetShell();
|
2008-10-04 13:00:09 -07:00
|
|
|
if (shell) {
|
|
|
|
nsPresContext* ctx = shell->GetPresContext();
|
|
|
|
if (ctx) {
|
|
|
|
mDeviceContext = ctx->DeviceContext();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-09-28 12:14:28 -07:00
|
|
|
// Create a device context even if we already have one, since our widget
|
|
|
|
// might have changed.
|
2009-07-21 17:45:10 -07:00
|
|
|
nsIWidget* widget = nsnull;
|
|
|
|
if (aContainerView) {
|
|
|
|
widget = aContainerView->GetNearestWidget(nsnull);
|
|
|
|
}
|
2009-08-17 20:21:07 -07:00
|
|
|
if (!widget) {
|
|
|
|
widget = mParentWidget;
|
|
|
|
}
|
|
|
|
if (widget) {
|
|
|
|
widget = widget->GetTopLevelWidget();
|
|
|
|
}
|
|
|
|
|
2011-04-16 18:22:42 -07:00
|
|
|
mDeviceContext = new nsDeviceContext();
|
2009-07-21 17:45:10 -07:00
|
|
|
mDeviceContext->Init(widget);
|
2008-08-18 12:22:19 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
// Return the selection for the document. Note that text fields have their
|
2010-03-19 11:32:13 -07:00
|
|
|
// own selection, which cannot be accessed with this method.
|
2007-03-22 10:30:00 -07:00
|
|
|
nsresult DocumentViewerImpl::GetDocumentSelection(nsISelection **aSelection)
|
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aSelection);
|
|
|
|
if (!mPresShell) {
|
|
|
|
return NS_ERROR_NOT_INITIALIZED;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsISelectionController> selcon;
|
|
|
|
selcon = do_QueryInterface(mPresShell);
|
|
|
|
if (selcon)
|
|
|
|
return selcon->GetSelection(nsISelectionController::SELECTION_NORMAL,
|
|
|
|
aSelection);
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ========================================================================================
|
|
|
|
* nsIContentViewerEdit
|
|
|
|
* ======================================================================================== */
|
|
|
|
|
|
|
|
NS_IMETHODIMP DocumentViewerImpl::ClearSelection()
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsISelection> selection;
|
|
|
|
|
2010-03-19 11:32:13 -07:00
|
|
|
// use nsCopySupport::GetSelectionForCopy() ?
|
2007-03-22 10:30:00 -07:00
|
|
|
rv = GetDocumentSelection(getter_AddRefs(selection));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
return selection->CollapseToStart();
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP DocumentViewerImpl::SelectAll()
|
|
|
|
{
|
|
|
|
// XXX this is a temporary implementation copied from nsWebShell
|
|
|
|
// for now. I think nsDocument and friends should have some helper
|
|
|
|
// functions to make this easier.
|
|
|
|
nsCOMPtr<nsISelection> selection;
|
|
|
|
nsresult rv;
|
|
|
|
|
2010-03-19 11:32:13 -07:00
|
|
|
// use nsCopySupport::GetSelectionForCopy() ?
|
2007-03-22 10:30:00 -07:00
|
|
|
rv = GetDocumentSelection(getter_AddRefs(selection));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMHTMLDocument> htmldoc = do_QueryInterface(mDocument);
|
|
|
|
nsCOMPtr<nsIDOMNode> bodyNode;
|
|
|
|
|
|
|
|
if (htmldoc)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMHTMLElement>bodyElement;
|
|
|
|
rv = htmldoc->GetBody(getter_AddRefs(bodyElement));
|
|
|
|
if (NS_FAILED(rv) || !bodyElement) return rv;
|
|
|
|
|
|
|
|
bodyNode = do_QueryInterface(bodyElement);
|
|
|
|
}
|
|
|
|
else if (mDocument)
|
|
|
|
{
|
2010-04-30 06:12:05 -07:00
|
|
|
bodyNode = do_QueryInterface(mDocument->GetRootElement());
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
if (!bodyNode) return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
rv = selection->RemoveAllRanges();
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
rv = selection->SelectAllChildren(bodyNode);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP DocumentViewerImpl::CopySelection()
|
|
|
|
{
|
2010-03-19 11:32:13 -07:00
|
|
|
nsCopySupport::FireClipboardEvent(NS_COPY, mPresShell, nsnull);
|
|
|
|
return NS_OK;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP DocumentViewerImpl::CopyLinkLocation()
|
|
|
|
{
|
|
|
|
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_INITIALIZED);
|
|
|
|
nsCOMPtr<nsIDOMNode> node;
|
|
|
|
GetPopupLinkNode(getter_AddRefs(node));
|
|
|
|
// make noise if we're not in a link
|
|
|
|
NS_ENSURE_TRUE(node, NS_ERROR_FAILURE);
|
|
|
|
|
|
|
|
nsAutoString locationText;
|
|
|
|
nsresult rv = mPresShell->GetLinkLocation(node, locationText);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIClipboardHelper> clipboard(do_GetService("@mozilla.org/widget/clipboardhelper;1", &rv));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
// copy the href onto the clipboard
|
|
|
|
return clipboard->CopyString(locationText);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP DocumentViewerImpl::CopyImage(PRInt32 aCopyFlags)
|
|
|
|
{
|
|
|
|
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_INITIALIZED);
|
|
|
|
nsCOMPtr<nsIImageLoadingContent> node;
|
|
|
|
GetPopupImageNode(getter_AddRefs(node));
|
|
|
|
// make noise if we're not in an image
|
|
|
|
NS_ENSURE_TRUE(node, NS_ERROR_FAILURE);
|
|
|
|
|
|
|
|
return nsCopySupport::ImageCopy(node, aCopyFlags);
|
|
|
|
}
|
|
|
|
|
2007-09-01 01:53:07 -07:00
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
NS_IMETHODIMP DocumentViewerImpl::GetCopyable(bool *aCopyable)
|
2007-09-01 01:53:07 -07:00
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aCopyable);
|
2010-03-19 11:32:13 -07:00
|
|
|
*aCopyable = nsCopySupport::CanCopy(mDocument);
|
2008-02-24 02:55:37 -08:00
|
|
|
return NS_OK;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/* AString getContents (in string mimeType, in boolean selectionOnly); */
|
2011-09-28 23:19:26 -07:00
|
|
|
NS_IMETHODIMP DocumentViewerImpl::GetContents(const char *mimeType, bool selectionOnly, nsAString& aOutValue)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2010-03-19 11:32:13 -07:00
|
|
|
aOutValue.Truncate();
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_INITIALIZED);
|
2010-03-19 11:32:13 -07:00
|
|
|
NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_INITIALIZED);
|
|
|
|
|
|
|
|
// Now we have the selection. Make sure it's nonzero:
|
|
|
|
nsCOMPtr<nsISelection> sel;
|
|
|
|
if (selectionOnly) {
|
|
|
|
nsCopySupport::GetSelectionForCopy(mDocument, getter_AddRefs(sel));
|
|
|
|
NS_ENSURE_TRUE(sel, NS_ERROR_FAILURE);
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
bool isCollapsed;
|
2010-03-19 11:32:13 -07:00
|
|
|
sel->GetIsCollapsed(&isCollapsed);
|
|
|
|
if (isCollapsed)
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// call the copy code
|
|
|
|
return nsCopySupport::GetContents(nsDependentCString(mimeType), 0, sel,
|
|
|
|
mDocument, aOutValue);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/* readonly attribute boolean canGetContents; */
|
2011-09-28 23:19:26 -07:00
|
|
|
NS_IMETHODIMP DocumentViewerImpl::GetCanGetContents(bool *aCanGetContents)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2010-03-19 11:32:13 -07:00
|
|
|
NS_ENSURE_ARG_POINTER(aCanGetContents);
|
|
|
|
*aCanGetContents = PR_FALSE;
|
|
|
|
NS_ENSURE_STATE(mDocument);
|
|
|
|
*aCanGetContents = nsCopySupport::CanCopy(mDocument);
|
|
|
|
return NS_OK;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* ========================================================================================
|
|
|
|
* nsIContentViewerFile
|
|
|
|
* ======================================================================================== */
|
|
|
|
/** ---------------------------------------------------
|
|
|
|
* See documentation above in the nsIContentViewerfile class definition
|
|
|
|
* @update 01/24/00 dwc
|
|
|
|
*/
|
|
|
|
NS_IMETHODIMP
|
2011-09-28 23:19:26 -07:00
|
|
|
DocumentViewerImpl::Print(bool aSilent,
|
2007-03-22 10:30:00 -07:00
|
|
|
FILE * aDebugFile,
|
|
|
|
nsIPrintSettings* aPrintSettings)
|
|
|
|
{
|
|
|
|
#ifdef NS_PRINTING
|
|
|
|
nsCOMPtr<nsIPrintSettings> printSettings;
|
|
|
|
|
|
|
|
#ifdef NS_DEBUG
|
|
|
|
nsresult rv = NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
mDebugFile = aDebugFile;
|
|
|
|
// if they don't pass in a PrintSettings, then make one
|
|
|
|
// it will have all the default values
|
|
|
|
printSettings = aPrintSettings;
|
|
|
|
nsCOMPtr<nsIPrintOptions> printOptions = do_GetService(sPrintOptionsContractID, &rv);
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
// if they don't pass in a PrintSettings, then make one
|
|
|
|
if (printSettings == nsnull) {
|
|
|
|
printOptions->CreatePrintSettings(getter_AddRefs(printSettings));
|
|
|
|
}
|
|
|
|
NS_ASSERTION(printSettings, "You can't PrintPreview without a PrintSettings!");
|
|
|
|
}
|
|
|
|
if (printSettings) printSettings->SetPrintSilent(aSilent);
|
|
|
|
if (printSettings) printSettings->SetShowPrintProgress(PR_FALSE);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
return Print(printSettings, nsnull);
|
|
|
|
#else
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2011-07-15 03:31:34 -07:00
|
|
|
/* [noscript] void printWithParent (in nsIDOMWindow aParentWin, in nsIPrintSettings aThePrintSettings, in nsIWebProgressListener aWPListener); */
|
2007-03-22 10:30:00 -07:00
|
|
|
NS_IMETHODIMP
|
2011-07-15 03:31:34 -07:00
|
|
|
DocumentViewerImpl::PrintWithParent(nsIDOMWindow*, nsIPrintSettings *aThePrintSettings, nsIWebProgressListener *aWPListener)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
#ifdef NS_PRINTING
|
|
|
|
return Print(aThePrintSettings, aWPListener);
|
|
|
|
#else
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
// nsIContentViewerFile interface
|
|
|
|
NS_IMETHODIMP
|
2011-09-28 23:19:26 -07:00
|
|
|
DocumentViewerImpl::GetPrintable(bool *aPrintable)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aPrintable);
|
|
|
|
|
|
|
|
*aPrintable = !GetIsPrinting();
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
//*****************************************************************************
|
|
|
|
// nsIMarkupDocumentViewer
|
|
|
|
//*****************************************************************************
|
|
|
|
|
|
|
|
NS_IMETHODIMP DocumentViewerImpl::ScrollToNode(nsIDOMNode* aNode)
|
|
|
|
{
|
|
|
|
NS_ENSURE_ARG(aNode);
|
|
|
|
NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE);
|
|
|
|
nsCOMPtr<nsIPresShell> presShell;
|
|
|
|
NS_ENSURE_SUCCESS(GetPresShell(getter_AddRefs(presShell)), NS_ERROR_FAILURE);
|
|
|
|
|
|
|
|
// Get the nsIContent interface, because that's what we need to
|
|
|
|
// get the primary frame
|
|
|
|
|
|
|
|
nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
|
|
|
|
NS_ENSURE_TRUE(content, NS_ERROR_FAILURE);
|
|
|
|
|
|
|
|
// Tell the PresShell to scroll to the primary frame of the content.
|
|
|
|
NS_ENSURE_SUCCESS(presShell->ScrollContentIntoView(content,
|
|
|
|
NS_PRESSHELL_SCROLL_TOP,
|
2010-10-28 09:01:37 -07:00
|
|
|
NS_PRESSHELL_SCROLL_ANYWHERE,
|
|
|
|
nsIPresShell::SCROLL_OVERFLOW_HIDDEN),
|
2007-03-22 10:30:00 -07:00
|
|
|
NS_ERROR_FAILURE);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
DocumentViewerImpl::CallChildren(CallChildFunc aFunc, void* aClosure)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDocShellTreeNode> docShellNode(do_QueryReferent(mContainer));
|
|
|
|
if (docShellNode)
|
|
|
|
{
|
|
|
|
PRInt32 i;
|
|
|
|
PRInt32 n;
|
|
|
|
docShellNode->GetChildCount(&n);
|
|
|
|
for (i=0; i < n; i++)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem> child;
|
|
|
|
docShellNode->GetChildAt(i, getter_AddRefs(child));
|
|
|
|
nsCOMPtr<nsIDocShell> childAsShell(do_QueryInterface(child));
|
|
|
|
NS_ASSERTION(childAsShell, "null child in docshell");
|
|
|
|
if (childAsShell)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIContentViewer> childCV;
|
|
|
|
childAsShell->GetContentViewer(getter_AddRefs(childCV));
|
|
|
|
if (childCV)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIMarkupDocumentViewer> markupCV = do_QueryInterface(childCV);
|
|
|
|
if (markupCV) {
|
|
|
|
(*aFunc)(markupCV, aClosure);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-08-07 13:38:35 -07:00
|
|
|
struct ZoomInfo
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2007-08-07 13:38:35 -07:00
|
|
|
float mZoom;
|
2007-03-22 10:30:00 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
|
|
|
SetChildTextZoom(nsIMarkupDocumentViewer* aChild, void* aClosure)
|
|
|
|
{
|
2007-08-07 13:38:35 -07:00
|
|
|
struct ZoomInfo* ZoomInfo = (struct ZoomInfo*) aClosure;
|
|
|
|
aChild->SetTextZoom(ZoomInfo->mZoom);
|
|
|
|
}
|
|
|
|
|
2011-03-10 20:33:43 -08:00
|
|
|
static void
|
|
|
|
SetChildMinFontSize(nsIMarkupDocumentViewer* aChild, void* aClosure)
|
|
|
|
{
|
2011-05-30 09:36:23 -07:00
|
|
|
nsCOMPtr<nsIMarkupDocumentViewer> branch =
|
2011-03-10 20:33:43 -08:00
|
|
|
do_QueryInterface(aChild);
|
2011-04-22 23:48:50 -07:00
|
|
|
branch->SetMinFontSize(NS_PTR_TO_INT32(aClosure));
|
2011-03-10 20:33:43 -08:00
|
|
|
}
|
|
|
|
|
2007-08-07 13:38:35 -07:00
|
|
|
static void
|
|
|
|
SetChildFullZoom(nsIMarkupDocumentViewer* aChild, void* aClosure)
|
|
|
|
{
|
|
|
|
struct ZoomInfo* ZoomInfo = (struct ZoomInfo*) aClosure;
|
|
|
|
aChild->SetFullZoom(ZoomInfo->mZoom);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
static bool
|
2008-10-04 13:00:09 -07:00
|
|
|
SetExtResourceTextZoom(nsIDocument* aDocument, void* aClosure)
|
|
|
|
{
|
|
|
|
// Would it be better to enumerate external resource viewers instead?
|
2010-06-25 06:59:57 -07:00
|
|
|
nsIPresShell* shell = aDocument->GetShell();
|
2008-10-04 13:00:09 -07:00
|
|
|
if (shell) {
|
|
|
|
nsPresContext* ctxt = shell->GetPresContext();
|
|
|
|
if (ctxt) {
|
|
|
|
struct ZoomInfo* ZoomInfo = static_cast<struct ZoomInfo*>(aClosure);
|
|
|
|
ctxt->SetTextZoom(ZoomInfo->mZoom);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
static bool
|
2011-03-10 20:33:43 -08:00
|
|
|
SetExtResourceMinFontSize(nsIDocument* aDocument, void* aClosure)
|
|
|
|
{
|
|
|
|
nsIPresShell* shell = aDocument->GetShell();
|
|
|
|
if (shell) {
|
|
|
|
nsPresContext* ctxt = shell->GetPresContext();
|
|
|
|
if (ctxt) {
|
2011-04-22 23:48:50 -07:00
|
|
|
ctxt->SetMinFontSize(NS_PTR_TO_INT32(aClosure));
|
2011-03-10 20:33:43 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
static bool
|
2008-10-04 13:00:09 -07:00
|
|
|
SetExtResourceFullZoom(nsIDocument* aDocument, void* aClosure)
|
|
|
|
{
|
|
|
|
// Would it be better to enumerate external resource viewers instead?
|
2010-06-25 06:59:57 -07:00
|
|
|
nsIPresShell* shell = aDocument->GetShell();
|
2008-10-04 13:00:09 -07:00
|
|
|
if (shell) {
|
|
|
|
nsPresContext* ctxt = shell->GetPresContext();
|
|
|
|
if (ctxt) {
|
|
|
|
struct ZoomInfo* ZoomInfo = static_cast<struct ZoomInfo*>(aClosure);
|
|
|
|
ctxt->SetFullZoom(ZoomInfo->mZoom);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::SetTextZoom(float aTextZoom)
|
|
|
|
{
|
2009-03-08 12:01:02 -07:00
|
|
|
if (GetIsPrintPreview()) {
|
|
|
|
return NS_OK;
|
2007-11-09 02:19:12 -08:00
|
|
|
}
|
2008-01-26 15:59:50 -08:00
|
|
|
|
2009-03-08 12:01:02 -07:00
|
|
|
mTextZoom = aTextZoom;
|
|
|
|
|
2008-01-26 15:59:50 -08:00
|
|
|
nsIViewManager::UpdateViewBatch batch(GetViewManager());
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
// Set the text zoom on all children of mContainer (even if our zoom didn't
|
|
|
|
// change, our children's zoom may be different, though it would be unusual).
|
|
|
|
// Do this first, in case kids are auto-sizing and post reflow commands on
|
|
|
|
// our presshell (which should be subsumed into our own style change reflow).
|
2007-08-07 13:38:35 -07:00
|
|
|
struct ZoomInfo ZoomInfo = { aTextZoom };
|
|
|
|
CallChildren(SetChildTextZoom, &ZoomInfo);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
// Now change our own zoom
|
2007-11-09 02:19:12 -08:00
|
|
|
nsPresContext* pc = GetPresContext();
|
|
|
|
if (pc && aTextZoom != mPresContext->TextZoom()) {
|
|
|
|
pc->SetTextZoom(aTextZoom);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2008-10-04 13:00:09 -07:00
|
|
|
// And do the external resources
|
|
|
|
mDocument->EnumerateExternalResources(SetExtResourceTextZoom, &ZoomInfo);
|
|
|
|
|
2008-01-26 15:59:50 -08:00
|
|
|
batch.EndUpdateViewBatch(NS_VMREFRESH_NO_SYNC);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::GetTextZoom(float* aTextZoom)
|
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aTextZoom);
|
2007-11-09 02:19:12 -08:00
|
|
|
nsPresContext* pc = GetPresContext();
|
|
|
|
*aTextZoom = pc ? pc->TextZoom() : 1.0f;
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2011-03-10 20:33:43 -08:00
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::SetMinFontSize(PRInt32 aMinFontSize)
|
|
|
|
{
|
|
|
|
if (GetIsPrintPreview()) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
mMinFontSize = aMinFontSize;
|
|
|
|
|
|
|
|
nsIViewManager::UpdateViewBatch batch(GetViewManager());
|
|
|
|
|
|
|
|
// Set the min font on all children of mContainer (even if our min font didn't
|
|
|
|
// change, our children's min font may be different, though it would be unusual).
|
|
|
|
// Do this first, in case kids are auto-sizing and post reflow commands on
|
|
|
|
// our presshell (which should be subsumed into our own style change reflow).
|
2011-04-22 23:48:50 -07:00
|
|
|
CallChildren(SetChildMinFontSize, NS_INT32_TO_PTR(aMinFontSize));
|
2011-03-10 20:33:43 -08:00
|
|
|
|
|
|
|
// Now change our own min font
|
|
|
|
nsPresContext* pc = GetPresContext();
|
|
|
|
if (pc && aMinFontSize != mPresContext->MinFontSize()) {
|
|
|
|
pc->SetMinFontSize(aMinFontSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
// And do the external resources
|
2011-04-22 23:48:50 -07:00
|
|
|
mDocument->EnumerateExternalResources(SetExtResourceMinFontSize,
|
|
|
|
NS_INT32_TO_PTR(aMinFontSize));
|
2011-03-10 20:33:43 -08:00
|
|
|
|
|
|
|
batch.EndUpdateViewBatch(NS_VMREFRESH_NO_SYNC);
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::GetMinFontSize(PRInt32* aMinFontSize)
|
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aMinFontSize);
|
|
|
|
nsPresContext* pc = GetPresContext();
|
|
|
|
*aMinFontSize = pc ? pc->MinFontSize() : 0;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2007-07-25 20:34:16 -07:00
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::SetFullZoom(float aFullZoom)
|
|
|
|
{
|
2009-03-08 12:01:02 -07:00
|
|
|
#ifdef NS_PRINT_PREVIEW
|
|
|
|
if (GetIsPrintPreview()) {
|
|
|
|
nsPresContext* pc = GetPresContext();
|
|
|
|
NS_ENSURE_TRUE(pc, NS_OK);
|
|
|
|
nsCOMPtr<nsIPresShell> shell = pc->GetPresShell();
|
|
|
|
NS_ENSURE_TRUE(shell, NS_OK);
|
|
|
|
|
2009-03-11 08:43:08 -07:00
|
|
|
nsIViewManager::UpdateViewBatch batch(shell->GetViewManager());
|
2009-03-08 12:01:02 -07:00
|
|
|
if (!mPrintPreviewZoomed) {
|
|
|
|
mOriginalPrintPreviewScale = pc->GetPrintPreviewScale();
|
|
|
|
mPrintPreviewZoomed = PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
mPrintPreviewZoom = aFullZoom;
|
|
|
|
pc->SetPrintPreviewScale(aFullZoom * mOriginalPrintPreviewScale);
|
2010-03-20 14:54:19 -07:00
|
|
|
nsIPageSequenceFrame* pf = shell->GetPageSequenceFrame();
|
2009-03-08 12:01:02 -07:00
|
|
|
if (pf) {
|
|
|
|
nsIFrame* f = do_QueryFrame(pf);
|
|
|
|
shell->FrameNeedsReflow(f, nsIPresShell::eResize, NS_FRAME_IS_DIRTY);
|
|
|
|
}
|
|
|
|
|
|
|
|
nsIFrame* rootFrame = shell->GetRootFrame();
|
|
|
|
if (rootFrame) {
|
|
|
|
nsRect rect(nsPoint(0, 0), rootFrame->GetSize());
|
|
|
|
rootFrame->Invalidate(rect);
|
|
|
|
}
|
|
|
|
batch.EndUpdateViewBatch(NS_VMREFRESH_NO_SYNC);
|
|
|
|
return NS_OK;
|
2007-11-09 02:19:12 -08:00
|
|
|
}
|
2009-03-08 12:01:02 -07:00
|
|
|
#endif
|
|
|
|
|
|
|
|
mPageZoom = aFullZoom;
|
2007-11-09 02:19:12 -08:00
|
|
|
|
2008-01-26 15:59:50 -08:00
|
|
|
nsIViewManager::UpdateViewBatch batch(GetViewManager());
|
2007-11-09 02:19:12 -08:00
|
|
|
|
2007-08-07 13:38:35 -07:00
|
|
|
struct ZoomInfo ZoomInfo = { aFullZoom };
|
|
|
|
CallChildren(SetChildFullZoom, &ZoomInfo);
|
2007-11-09 02:19:12 -08:00
|
|
|
|
|
|
|
nsPresContext* pc = GetPresContext();
|
|
|
|
if (pc) {
|
|
|
|
pc->SetFullZoom(aFullZoom);
|
|
|
|
}
|
|
|
|
|
2008-10-04 13:00:09 -07:00
|
|
|
// And do the external resources
|
|
|
|
mDocument->EnumerateExternalResources(SetExtResourceFullZoom, &ZoomInfo);
|
|
|
|
|
2008-01-26 15:59:50 -08:00
|
|
|
batch.EndUpdateViewBatch(NS_VMREFRESH_NO_SYNC);
|
2007-07-25 20:34:16 -07:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::GetFullZoom(float* aFullZoom)
|
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aFullZoom);
|
2009-03-08 12:01:02 -07:00
|
|
|
#ifdef NS_PRINT_PREVIEW
|
|
|
|
if (GetIsPrintPreview()) {
|
|
|
|
*aFullZoom = mPrintPreviewZoom;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
#endif
|
2008-05-26 15:03:11 -07:00
|
|
|
// Check the prescontext first because it might have a temporary
|
|
|
|
// setting for print-preview
|
2007-11-09 02:19:12 -08:00
|
|
|
nsPresContext* pc = GetPresContext();
|
2008-05-26 15:03:11 -07:00
|
|
|
*aFullZoom = pc ? pc->GetFullZoom() : mPageZoom;
|
2007-07-25 20:34:16 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
static void
|
|
|
|
SetChildAuthorStyleDisabled(nsIMarkupDocumentViewer* aChild, void* aClosure)
|
|
|
|
{
|
2011-09-28 23:19:26 -07:00
|
|
|
bool styleDisabled = *static_cast<bool*>(aClosure);
|
2007-03-22 10:30:00 -07:00
|
|
|
aChild->SetAuthorStyleDisabled(styleDisabled);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2011-09-28 23:19:26 -07:00
|
|
|
DocumentViewerImpl::SetAuthorStyleDisabled(bool aStyleDisabled)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
if (mPresShell) {
|
|
|
|
mPresShell->SetAuthorStyleDisabled(aStyleDisabled);
|
|
|
|
}
|
|
|
|
CallChildren(SetChildAuthorStyleDisabled, &aStyleDisabled);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2011-09-28 23:19:26 -07:00
|
|
|
DocumentViewerImpl::GetAuthorStyleDisabled(bool* aStyleDisabled)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
if (mPresShell) {
|
|
|
|
*aStyleDisabled = mPresShell->GetAuthorStyleDisabled();
|
|
|
|
} else {
|
|
|
|
*aStyleDisabled = PR_FALSE;
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::GetDefaultCharacterSet(nsACString& aDefaultCharacterSet)
|
|
|
|
{
|
|
|
|
if (mDefaultCharacterSet.IsEmpty())
|
|
|
|
{
|
2011-05-28 00:03:00 -07:00
|
|
|
const nsAdoptingCString& defCharset =
|
|
|
|
Preferences::GetLocalizedCString("intl.charset.default");
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2011-05-28 00:03:00 -07:00
|
|
|
if (!defCharset.IsEmpty()) {
|
|
|
|
mDefaultCharacterSet = defCharset;
|
|
|
|
} else {
|
2007-03-22 10:30:00 -07:00
|
|
|
mDefaultCharacterSet.AssignLiteral("ISO-8859-1");
|
2011-05-28 00:03:00 -07:00
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
aDefaultCharacterSet = mDefaultCharacterSet;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
SetChildDefaultCharacterSet(nsIMarkupDocumentViewer* aChild, void* aClosure)
|
|
|
|
{
|
2007-07-08 00:08:04 -07:00
|
|
|
const nsACString* charset = static_cast<nsACString*>(aClosure);
|
2007-03-22 10:30:00 -07:00
|
|
|
aChild->SetDefaultCharacterSet(*charset);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::SetDefaultCharacterSet(const nsACString& aDefaultCharacterSet)
|
|
|
|
{
|
|
|
|
mDefaultCharacterSet = aDefaultCharacterSet; // this does a copy of aDefaultCharacterSet
|
|
|
|
// now set the default char set on all children of mContainer
|
|
|
|
CallChildren(SetChildDefaultCharacterSet, (void*) &aDefaultCharacterSet);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// XXX: SEMANTIC CHANGE!
|
|
|
|
// returns a copy of the string. Caller is responsible for freeing result
|
|
|
|
// using Recycle(aForceCharacterSet)
|
|
|
|
NS_IMETHODIMP DocumentViewerImpl::GetForceCharacterSet(nsACString& aForceCharacterSet)
|
|
|
|
{
|
|
|
|
aForceCharacterSet = mForceCharacterSet;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
SetChildForceCharacterSet(nsIMarkupDocumentViewer* aChild, void* aClosure)
|
|
|
|
{
|
2007-07-08 00:08:04 -07:00
|
|
|
const nsACString* charset = static_cast<nsACString*>(aClosure);
|
2007-03-22 10:30:00 -07:00
|
|
|
aChild->SetForceCharacterSet(*charset);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::SetForceCharacterSet(const nsACString& aForceCharacterSet)
|
|
|
|
{
|
|
|
|
mForceCharacterSet = aForceCharacterSet;
|
|
|
|
// now set the force char set on all children of mContainer
|
|
|
|
CallChildren(SetChildForceCharacterSet, (void*) &aForceCharacterSet);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// XXX: SEMANTIC CHANGE!
|
|
|
|
// returns a copy of the string. Caller is responsible for freeing result
|
|
|
|
// using Recycle(aHintCharacterSet)
|
|
|
|
NS_IMETHODIMP DocumentViewerImpl::GetHintCharacterSet(nsACString& aHintCharacterSet)
|
|
|
|
{
|
|
|
|
|
|
|
|
if(kCharsetUninitialized == mHintCharsetSource) {
|
|
|
|
aHintCharacterSet.Truncate();
|
|
|
|
} else {
|
|
|
|
aHintCharacterSet = mHintCharset;
|
|
|
|
// this can't possibly be right. we can't set a value just because somebody got a related value!
|
|
|
|
//mHintCharsetSource = kCharsetUninitialized;
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP DocumentViewerImpl::GetHintCharacterSetSource(PRInt32 *aHintCharacterSetSource)
|
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aHintCharacterSetSource);
|
|
|
|
|
|
|
|
*aHintCharacterSetSource = mHintCharsetSource;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP DocumentViewerImpl::GetPrevDocCharacterSet(nsACString& aPrevDocCharacterSet)
|
|
|
|
{
|
|
|
|
aPrevDocCharacterSet = mPrevDocCharacterSet;
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
SetChildPrevDocCharacterSet(nsIMarkupDocumentViewer* aChild, void* aClosure)
|
|
|
|
{
|
2007-07-08 00:08:04 -07:00
|
|
|
const nsACString* charset = static_cast<nsACString*>(aClosure);
|
2007-03-22 10:30:00 -07:00
|
|
|
aChild->SetPrevDocCharacterSet(*charset);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::SetPrevDocCharacterSet(const nsACString& aPrevDocCharacterSet)
|
|
|
|
{
|
|
|
|
mPrevDocCharacterSet = aPrevDocCharacterSet;
|
|
|
|
CallChildren(SetChildPrevDocCharacterSet, (void*) &aPrevDocCharacterSet);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
SetChildHintCharacterSetSource(nsIMarkupDocumentViewer* aChild, void* aClosure)
|
|
|
|
{
|
|
|
|
aChild->SetHintCharacterSetSource(NS_PTR_TO_INT32(aClosure));
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::SetHintCharacterSetSource(PRInt32 aHintCharacterSetSource)
|
|
|
|
{
|
|
|
|
mHintCharsetSource = aHintCharacterSetSource;
|
|
|
|
// now set the hint char set source on all children of mContainer
|
|
|
|
CallChildren(SetChildHintCharacterSetSource,
|
2011-04-22 23:48:50 -07:00
|
|
|
NS_INT32_TO_PTR(aHintCharacterSetSource));
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
SetChildHintCharacterSet(nsIMarkupDocumentViewer* aChild, void* aClosure)
|
|
|
|
{
|
2007-07-08 00:08:04 -07:00
|
|
|
const nsACString* charset = static_cast<nsACString*>(aClosure);
|
2007-03-22 10:30:00 -07:00
|
|
|
aChild->SetHintCharacterSet(*charset);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::SetHintCharacterSet(const nsACString& aHintCharacterSet)
|
|
|
|
{
|
|
|
|
mHintCharset = aHintCharacterSet;
|
|
|
|
// now set the hint char set on all children of mContainer
|
|
|
|
CallChildren(SetChildHintCharacterSet, (void*) &aHintCharacterSet);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
SetChildBidiOptions(nsIMarkupDocumentViewer* aChild, void* aClosure)
|
|
|
|
{
|
|
|
|
aChild->SetBidiOptions(NS_PTR_TO_INT32(aClosure));
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP DocumentViewerImpl::SetBidiTextDirection(PRUint8 aTextDirection)
|
|
|
|
{
|
|
|
|
PRUint32 bidiOptions;
|
|
|
|
|
|
|
|
GetBidiOptions(&bidiOptions);
|
|
|
|
SET_BIDI_OPTION_DIRECTION(bidiOptions, aTextDirection);
|
|
|
|
SetBidiOptions(bidiOptions);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP DocumentViewerImpl::GetBidiTextDirection(PRUint8* aTextDirection)
|
|
|
|
{
|
|
|
|
PRUint32 bidiOptions;
|
|
|
|
|
|
|
|
if (aTextDirection) {
|
|
|
|
GetBidiOptions(&bidiOptions);
|
|
|
|
*aTextDirection = GET_BIDI_OPTION_DIRECTION(bidiOptions);
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP DocumentViewerImpl::SetBidiTextType(PRUint8 aTextType)
|
|
|
|
{
|
|
|
|
PRUint32 bidiOptions;
|
|
|
|
|
|
|
|
GetBidiOptions(&bidiOptions);
|
|
|
|
SET_BIDI_OPTION_TEXTTYPE(bidiOptions, aTextType);
|
|
|
|
SetBidiOptions(bidiOptions);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP DocumentViewerImpl::GetBidiTextType(PRUint8* aTextType)
|
|
|
|
{
|
|
|
|
PRUint32 bidiOptions;
|
|
|
|
|
|
|
|
if (aTextType) {
|
|
|
|
GetBidiOptions(&bidiOptions);
|
|
|
|
*aTextType = GET_BIDI_OPTION_TEXTTYPE(bidiOptions);
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP DocumentViewerImpl::SetBidiNumeral(PRUint8 aNumeral)
|
|
|
|
{
|
|
|
|
PRUint32 bidiOptions;
|
|
|
|
|
|
|
|
GetBidiOptions(&bidiOptions);
|
|
|
|
SET_BIDI_OPTION_NUMERAL(bidiOptions, aNumeral);
|
|
|
|
SetBidiOptions(bidiOptions);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP DocumentViewerImpl::GetBidiNumeral(PRUint8* aNumeral)
|
|
|
|
{
|
|
|
|
PRUint32 bidiOptions;
|
|
|
|
|
|
|
|
if (aNumeral) {
|
|
|
|
GetBidiOptions(&bidiOptions);
|
|
|
|
*aNumeral = GET_BIDI_OPTION_NUMERAL(bidiOptions);
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP DocumentViewerImpl::SetBidiSupport(PRUint8 aSupport)
|
|
|
|
{
|
|
|
|
PRUint32 bidiOptions;
|
|
|
|
|
|
|
|
GetBidiOptions(&bidiOptions);
|
|
|
|
SET_BIDI_OPTION_SUPPORT(bidiOptions, aSupport);
|
|
|
|
SetBidiOptions(bidiOptions);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP DocumentViewerImpl::GetBidiSupport(PRUint8* aSupport)
|
|
|
|
{
|
|
|
|
PRUint32 bidiOptions;
|
|
|
|
|
|
|
|
if (aSupport) {
|
|
|
|
GetBidiOptions(&bidiOptions);
|
|
|
|
*aSupport = GET_BIDI_OPTION_SUPPORT(bidiOptions);
|
2011-04-24 11:19:05 -07:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
NS_IMETHODIMP DocumentViewerImpl::SetBidiOptions(PRUint32 aBidiOptions)
|
|
|
|
{
|
|
|
|
if (mPresContext) {
|
|
|
|
mPresContext->SetBidi(aBidiOptions, PR_TRUE); // could cause reflow
|
|
|
|
}
|
|
|
|
// now set bidi on all children of mContainer
|
2011-04-22 23:48:50 -07:00
|
|
|
CallChildren(SetChildBidiOptions, NS_INT32_TO_PTR(aBidiOptions));
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP DocumentViewerImpl::GetBidiOptions(PRUint32* aBidiOptions)
|
|
|
|
{
|
|
|
|
if (aBidiOptions) {
|
|
|
|
if (mPresContext) {
|
|
|
|
*aBidiOptions = mPresContext->GetBidi();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
*aBidiOptions = IBMBIDI_DEFAULT_BIDI_OPTIONS;
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP DocumentViewerImpl::SizeToContent()
|
|
|
|
{
|
|
|
|
NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE);
|
|
|
|
|
2008-09-28 12:14:28 -07:00
|
|
|
// Skip doing this on docshell-less documents for now
|
2007-03-22 10:30:00 -07:00
|
|
|
nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryReferent(mContainer));
|
2008-09-28 12:14:28 -07:00
|
|
|
NS_ENSURE_TRUE(docShellAsItem, NS_ERROR_NOT_AVAILABLE);
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
nsCOMPtr<nsIDocShellTreeItem> docShellParent;
|
|
|
|
docShellAsItem->GetSameTypeParent(getter_AddRefs(docShellParent));
|
|
|
|
|
|
|
|
// It's only valid to access this from a top frame. Doesn't work from
|
|
|
|
// sub-frames.
|
|
|
|
NS_ENSURE_TRUE(!docShellParent, NS_ERROR_FAILURE);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIPresShell> presShell;
|
|
|
|
GetPresShell(getter_AddRefs(presShell));
|
|
|
|
NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
|
|
|
|
|
|
|
|
// Flush out all content and style updates. We can't use a resize reflow
|
|
|
|
// because it won't change some sizes that a style change reflow will.
|
|
|
|
mDocument->FlushPendingNotifications(Flush_Layout);
|
|
|
|
|
|
|
|
nsIFrame *root = presShell->GetRootFrame();
|
|
|
|
NS_ENSURE_TRUE(root, NS_ERROR_FAILURE);
|
|
|
|
|
|
|
|
nscoord prefWidth;
|
|
|
|
{
|
2011-04-07 18:04:40 -07:00
|
|
|
nsRefPtr<nsRenderingContext> rcx =
|
2010-08-20 12:29:01 -07:00
|
|
|
presShell->GetReferenceRenderingContext();
|
2007-03-22 10:30:00 -07:00
|
|
|
NS_ENSURE_TRUE(rcx, NS_ERROR_FAILURE);
|
|
|
|
prefWidth = root->GetPrefWidth(rcx);
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult rv = presShell->ResizeReflow(prefWidth, NS_UNCONSTRAINEDSIZE);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
2010-03-25 06:17:11 -07:00
|
|
|
nsRefPtr<nsPresContext> presContext;
|
2007-03-22 10:30:00 -07:00
|
|
|
GetPresContext(getter_AddRefs(presContext));
|
|
|
|
NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE);
|
|
|
|
|
|
|
|
PRInt32 width, height;
|
|
|
|
|
|
|
|
// so how big is it?
|
|
|
|
nsRect shellArea = presContext->GetVisibleArea();
|
2008-03-12 15:04:45 -07:00
|
|
|
// Protect against bogus returns here
|
|
|
|
NS_ENSURE_TRUE(shellArea.width != NS_UNCONSTRAINEDSIZE &&
|
|
|
|
shellArea.height != NS_UNCONSTRAINEDSIZE,
|
|
|
|
NS_ERROR_FAILURE);
|
2007-03-22 10:30:00 -07:00
|
|
|
width = presContext->AppUnitsToDevPixels(shellArea.width);
|
|
|
|
height = presContext->AppUnitsToDevPixels(shellArea.height);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
|
|
|
|
docShellAsItem->GetTreeOwner(getter_AddRefs(treeOwner));
|
|
|
|
NS_ENSURE_TRUE(treeOwner, NS_ERROR_FAILURE);
|
|
|
|
|
2007-11-20 21:09:58 -08:00
|
|
|
/* presContext's size was calculated in app units and has already been
|
2007-03-22 10:30:00 -07:00
|
|
|
rounded to the equivalent pixels (so the width/height calculation
|
|
|
|
we just performed was probably exact, though it was based on
|
|
|
|
values already rounded during ResizeReflow). In a surprising
|
|
|
|
number of instances, this rounding makes a window which for want
|
|
|
|
of one extra pixel's width ends up wrapping the longest line of
|
|
|
|
text during actual window layout. This makes the window too short,
|
|
|
|
generally clipping the OK/Cancel buttons. Here we add one pixel
|
|
|
|
to the calculated width, to circumvent this problem. */
|
|
|
|
NS_ENSURE_SUCCESS(treeOwner->SizeShellTo(docShellAsItem, width+1, height),
|
|
|
|
NS_ERROR_FAILURE);
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMPL_ISUPPORTS1(nsDocViewerSelectionListener, nsISelectionListener)
|
|
|
|
|
|
|
|
nsresult nsDocViewerSelectionListener::Init(DocumentViewerImpl *aDocViewer)
|
|
|
|
{
|
|
|
|
mDocViewer = aDocViewer;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* GetPopupNode, GetPopupLinkNode and GetPopupImageNode are helpers
|
|
|
|
* for the cmd_copyLink / cmd_copyImageLocation / cmd_copyImageContents family
|
|
|
|
* of commands. The focus controller stores the popup node, these retrieve
|
|
|
|
* them and munge appropriately. Note that we have to store the popup node
|
|
|
|
* rather than retrieving it from EventStateManager::GetFocusedContent because
|
|
|
|
* not all content (images included) can receive focus.
|
|
|
|
*/
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
DocumentViewerImpl::GetPopupNode(nsIDOMNode** aNode)
|
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aNode);
|
|
|
|
|
2010-08-10 13:55:31 -07:00
|
|
|
*aNode = nsnull;
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
// get the document
|
2010-01-23 03:41:41 -08:00
|
|
|
nsIDocument* document = GetDocument();
|
2007-03-22 10:30:00 -07:00
|
|
|
NS_ENSURE_TRUE(document, NS_ERROR_FAILURE);
|
|
|
|
|
|
|
|
// get the private dom window
|
2010-02-20 08:07:03 -08:00
|
|
|
nsCOMPtr<nsPIDOMWindow> window(document->GetWindow());
|
|
|
|
NS_ENSURE_TRUE(window, NS_ERROR_NOT_AVAILABLE);
|
|
|
|
if (window) {
|
|
|
|
nsCOMPtr<nsPIWindowRoot> root = window->GetTopWindowRoot();
|
|
|
|
NS_ENSURE_TRUE(root, NS_ERROR_FAILURE);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2010-02-20 08:07:03 -08:00
|
|
|
// get the popup node
|
2010-08-10 13:55:31 -07:00
|
|
|
nsCOMPtr<nsIDOMNode> node = root->GetPopupNode();
|
|
|
|
#ifdef MOZ_XUL
|
|
|
|
if (!node) {
|
|
|
|
nsPIDOMWindow* rootWindow = root->GetWindow();
|
|
|
|
if (rootWindow) {
|
|
|
|
nsCOMPtr<nsIDocument> rootDoc = do_QueryInterface(rootWindow->GetExtantDocument());
|
|
|
|
if (rootDoc) {
|
|
|
|
nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
|
|
|
|
if (pm) {
|
|
|
|
node = pm->GetLastTriggerPopupNode(rootDoc);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
node.swap(*aNode);
|
2010-02-20 08:07:03 -08:00
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2010-01-23 03:41:41 -08:00
|
|
|
return NS_OK;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// GetPopupLinkNode: return popup link node or fail
|
|
|
|
nsresult
|
|
|
|
DocumentViewerImpl::GetPopupLinkNode(nsIDOMNode** aNode)
|
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aNode);
|
|
|
|
|
|
|
|
// you get null unless i say so
|
|
|
|
*aNode = nsnull;
|
|
|
|
|
|
|
|
// find popup node
|
|
|
|
nsCOMPtr<nsIDOMNode> node;
|
|
|
|
nsresult rv = GetPopupNode(getter_AddRefs(node));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
// find out if we have a link in our ancestry
|
|
|
|
while (node) {
|
|
|
|
|
2011-06-24 05:54:28 -07:00
|
|
|
nsCOMPtr<nsIContent> content(do_QueryInterface(node));
|
|
|
|
if (content) {
|
|
|
|
nsCOMPtr<nsIURI> hrefURI = content->GetHrefURI();
|
|
|
|
if (hrefURI) {
|
|
|
|
*aNode = node;
|
|
|
|
NS_IF_ADDREF(*aNode); // addref
|
|
|
|
return NS_OK;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
}
|
2011-06-24 05:54:28 -07:00
|
|
|
|
|
|
|
// get our parent and keep trying...
|
|
|
|
nsCOMPtr<nsIDOMNode> parentNode;
|
|
|
|
node->GetParentNode(getter_AddRefs(parentNode));
|
|
|
|
node = parentNode;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// if we have no node, fail
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetPopupLinkNode: return popup image node or fail
|
|
|
|
nsresult
|
|
|
|
DocumentViewerImpl::GetPopupImageNode(nsIImageLoadingContent** aNode)
|
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aNode);
|
|
|
|
|
|
|
|
// you get null unless i say so
|
|
|
|
*aNode = nsnull;
|
|
|
|
|
|
|
|
// find popup node
|
|
|
|
nsCOMPtr<nsIDOMNode> node;
|
|
|
|
nsresult rv = GetPopupNode(getter_AddRefs(node));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
if (node)
|
|
|
|
CallQueryInterface(node, aNode);
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XXX dr
|
|
|
|
* ------
|
|
|
|
* These two functions -- GetInLink and GetInImage -- are kind of annoying
|
|
|
|
* in that they only get called from the controller (in
|
|
|
|
* nsDOMWindowController::IsCommandEnabled). The actual construction of the
|
|
|
|
* context menus in communicator (nsContextMenu.js) has its own, redundant
|
|
|
|
* tests. No big deal, but good to keep in mind if we ever clean context
|
|
|
|
* menus.
|
|
|
|
*/
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
NS_IMETHODIMP DocumentViewerImpl::GetInLink(bool* aInLink)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
#ifdef DEBUG_dr
|
|
|
|
printf("dr :: DocumentViewerImpl::GetInLink\n");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
NS_ENSURE_ARG_POINTER(aInLink);
|
|
|
|
|
|
|
|
// we're not in a link unless i say so
|
|
|
|
*aInLink = PR_FALSE;
|
|
|
|
|
|
|
|
// get the popup link
|
|
|
|
nsCOMPtr<nsIDOMNode> node;
|
|
|
|
nsresult rv = GetPopupLinkNode(getter_AddRefs(node));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
NS_ENSURE_TRUE(node, NS_ERROR_FAILURE);
|
|
|
|
|
|
|
|
// if we made it here, we're in a link
|
|
|
|
*aInLink = PR_TRUE;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
NS_IMETHODIMP DocumentViewerImpl::GetInImage(bool* aInImage)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
#ifdef DEBUG_dr
|
|
|
|
printf("dr :: DocumentViewerImpl::GetInImage\n");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
NS_ENSURE_ARG_POINTER(aInImage);
|
|
|
|
|
|
|
|
// we're not in an image unless i say so
|
|
|
|
*aInImage = PR_FALSE;
|
|
|
|
|
|
|
|
// get the popup image
|
|
|
|
nsCOMPtr<nsIImageLoadingContent> node;
|
|
|
|
nsresult rv = GetPopupImageNode(getter_AddRefs(node));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
NS_ENSURE_TRUE(node, NS_ERROR_FAILURE);
|
|
|
|
|
|
|
|
// if we made it here, we're in an image
|
|
|
|
*aInImage = PR_TRUE;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsDocViewerSelectionListener::NotifySelectionChanged(nsIDOMDocument *, nsISelection *, PRInt16)
|
|
|
|
{
|
|
|
|
NS_ASSERTION(mDocViewer, "Should have doc viewer!");
|
|
|
|
|
|
|
|
// get the selection state
|
|
|
|
nsCOMPtr<nsISelection> selection;
|
|
|
|
nsresult rv = mDocViewer->GetDocumentSelection(getter_AddRefs(selection));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
bool selectionCollapsed;
|
2007-03-22 10:30:00 -07:00
|
|
|
selection->GetIsCollapsed(&selectionCollapsed);
|
|
|
|
// we only call UpdateCommands when the selection changes from collapsed
|
|
|
|
// to non-collapsed or vice versa. We might need another update string
|
|
|
|
// for simple selection changes, but that would be expenseive.
|
|
|
|
if (!mGotSelectionState || mSelectionWasCollapsed != selectionCollapsed)
|
|
|
|
{
|
2010-01-23 03:41:41 -08:00
|
|
|
nsIDocument* theDoc = mDocViewer->GetDocument();
|
2007-03-22 10:30:00 -07:00
|
|
|
if (!theDoc) return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
nsPIDOMWindow *domWindow = theDoc->GetWindow();
|
|
|
|
if (!domWindow) return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
domWindow->UpdateCommands(NS_LITERAL_STRING("select"));
|
|
|
|
mGotSelectionState = PR_TRUE;
|
|
|
|
mSelectionWasCollapsed = selectionCollapsed;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
//nsDocViewerFocusListener
|
2011-06-28 10:59:14 -07:00
|
|
|
NS_IMPL_ISUPPORTS1(nsDocViewerFocusListener,
|
2007-03-22 10:30:00 -07:00
|
|
|
nsIDOMEventListener)
|
|
|
|
|
|
|
|
nsDocViewerFocusListener::nsDocViewerFocusListener()
|
|
|
|
:mDocViewer(nsnull)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
nsDocViewerFocusListener::~nsDocViewerFocusListener(){}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsDocViewerFocusListener::HandleEvent(nsIDOMEvent* aEvent)
|
|
|
|
{
|
2011-06-28 10:59:14 -07:00
|
|
|
NS_ENSURE_STATE(mDocViewer);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
nsCOMPtr<nsIPresShell> shell;
|
2011-09-25 21:53:30 -07:00
|
|
|
mDocViewer->GetPresShell(getter_AddRefs(shell));
|
2011-06-28 10:59:14 -07:00
|
|
|
NS_ENSURE_TRUE(shell, NS_ERROR_FAILURE);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2011-06-28 10:59:14 -07:00
|
|
|
nsCOMPtr<nsISelectionController> selCon = do_QueryInterface(shell);
|
2007-03-22 10:30:00 -07:00
|
|
|
PRInt16 selectionStatus;
|
|
|
|
selCon->GetDisplaySelection(&selectionStatus);
|
|
|
|
|
2011-06-28 10:59:14 -07:00
|
|
|
nsAutoString eventType;
|
|
|
|
aEvent->GetType(eventType);
|
|
|
|
if (eventType.EqualsLiteral("focus")) {
|
|
|
|
// If selection was disabled, re-enable it.
|
|
|
|
if(selectionStatus == nsISelectionController::SELECTION_DISABLED ||
|
|
|
|
selectionStatus == nsISelectionController::SELECTION_HIDDEN) {
|
|
|
|
selCon->SetDisplaySelection(nsISelectionController::SELECTION_ON);
|
|
|
|
selCon->RepaintSelection(nsISelectionController::SELECTION_NORMAL);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
NS_ABORT_IF_FALSE(eventType.EqualsLiteral("blur"),
|
|
|
|
"Unexpected event type");
|
|
|
|
// If selection was on, disable it.
|
|
|
|
if(selectionStatus == nsISelectionController::SELECTION_ON ||
|
|
|
|
selectionStatus == nsISelectionController::SELECTION_ATTENTION) {
|
|
|
|
selCon->SetDisplaySelection(nsISelectionController::SELECTION_DISABLED);
|
|
|
|
selCon->RepaintSelection(nsISelectionController::SELECTION_NORMAL);
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2011-06-28 10:59:14 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsDocViewerFocusListener::Init(DocumentViewerImpl *aDocViewer)
|
|
|
|
{
|
|
|
|
mDocViewer = aDocViewer;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** ---------------------------------------------------
|
|
|
|
* From nsIWebBrowserPrint
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef NS_PRINTING
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::Print(nsIPrintSettings* aPrintSettings,
|
|
|
|
nsIWebProgressListener* aWebProgressListener)
|
|
|
|
{
|
|
|
|
|
|
|
|
#ifdef MOZ_XUL
|
|
|
|
// Temporary code for Bug 136185 / Bug 240490
|
|
|
|
nsCOMPtr<nsIXULDocument> xulDoc(do_QueryInterface(mDocument));
|
|
|
|
if (xulDoc) {
|
|
|
|
nsPrintEngine::ShowPrintErrorDialog(NS_ERROR_GFX_PRINTER_NO_XUL);
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2008-01-20 23:54:47 -08:00
|
|
|
if (!mContainer) {
|
|
|
|
PR_PL(("Container was destroyed yet we are still trying to use it!"));
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
nsCOMPtr<nsIDocShell> docShell(do_QueryReferent(mContainer));
|
2011-05-10 05:55:26 -07:00
|
|
|
NS_ENSURE_STATE(docShell);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
// Check to see if this document is still busy
|
|
|
|
// If it is busy and we aren't already "queued" up to print then
|
|
|
|
// Indicate there is a print pending and cache the args for later
|
|
|
|
PRUint32 busyFlags = nsIDocShell::BUSY_FLAGS_NONE;
|
|
|
|
if ((NS_FAILED(docShell->GetBusyFlags(&busyFlags)) ||
|
|
|
|
(busyFlags != nsIDocShell::BUSY_FLAGS_NONE && busyFlags & nsIDocShell::BUSY_FLAGS_PAGE_LOADING)) &&
|
|
|
|
!mPrintDocIsFullyLoaded) {
|
|
|
|
if (!mPrintIsPending) {
|
|
|
|
mCachedPrintSettings = aPrintSettings;
|
|
|
|
mCachedPrintWebProgressListner = aWebProgressListener;
|
|
|
|
mPrintIsPending = PR_TRUE;
|
|
|
|
}
|
|
|
|
PR_PL(("Printing Stopped - document is still busy!"));
|
|
|
|
return NS_ERROR_GFX_PRINTER_DOC_IS_BUSY;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIPresShell> presShell;
|
|
|
|
docShell->GetPresShell(getter_AddRefs(presShell));
|
2009-09-09 06:53:06 -07:00
|
|
|
if (!presShell || !mDocument || !mDeviceContext) {
|
2007-03-22 10:30:00 -07:00
|
|
|
PR_PL(("Can't Print without pres shell, document etc"));
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
// if we are printing another URL, then exit
|
|
|
|
// the reason we check here is because this method can be called while
|
|
|
|
// another is still in here (the printing dialog is a good example).
|
|
|
|
// the only time we can print more than one job at a time is the regression tests
|
|
|
|
if (GetIsPrinting()) {
|
|
|
|
// Let the user know we are not ready to print.
|
|
|
|
rv = NS_ERROR_NOT_AVAILABLE;
|
|
|
|
nsPrintEngine::ShowPrintErrorDialog(rv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2011-05-14 05:03:58 -07:00
|
|
|
nsPrintEventDispatcher beforeAndAfterPrint(mDocument);
|
2011-07-06 04:12:26 -07:00
|
|
|
NS_ENSURE_STATE(!GetIsPrinting());
|
2007-03-22 10:30:00 -07:00
|
|
|
// If we are hosting a full-page plugin, tell it to print
|
|
|
|
// first. It shows its own native print UI.
|
|
|
|
nsCOMPtr<nsIPluginDocument> pDoc(do_QueryInterface(mDocument));
|
|
|
|
if (pDoc)
|
|
|
|
return pDoc->Print();
|
|
|
|
|
|
|
|
if (!mPrintEngine) {
|
2011-07-01 06:59:11 -07:00
|
|
|
NS_ENSURE_STATE(mDeviceContext);
|
2007-03-22 10:30:00 -07:00
|
|
|
mPrintEngine = new nsPrintEngine();
|
|
|
|
|
2011-05-10 05:55:26 -07:00
|
|
|
rv = mPrintEngine->Initialize(this, mContainer, mDocument,
|
2010-08-13 02:58:04 -07:00
|
|
|
float(mDeviceContext->AppUnitsPerCSSInch()) /
|
2009-08-24 02:55:28 -07:00
|
|
|
float(mDeviceContext->AppUnitsPerDevPixel()) /
|
|
|
|
mPageZoom,
|
2007-03-22 10:30:00 -07:00
|
|
|
#ifdef NS_DEBUG
|
|
|
|
mDebugFile
|
|
|
|
#else
|
|
|
|
nsnull
|
|
|
|
#endif
|
|
|
|
);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
mPrintEngine->Destroy();
|
|
|
|
mPrintEngine = nsnull;
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = mPrintEngine->Print(aPrintSettings, aWebProgressListener);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
OnDonePrinting();
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings,
|
|
|
|
nsIDOMWindow *aChildDOMWin,
|
|
|
|
nsIWebProgressListener* aWebProgressListener)
|
|
|
|
{
|
|
|
|
#if defined(NS_PRINTING) && defined(NS_PRINT_PREVIEW)
|
2009-12-10 20:02:13 -08:00
|
|
|
NS_WARN_IF_FALSE(IsInitializedForPrintPreview(),
|
|
|
|
"Using docshell.printPreview is the preferred way for print previewing!");
|
|
|
|
|
|
|
|
NS_ENSURE_ARG_POINTER(aChildDOMWin);
|
2007-03-22 10:30:00 -07:00
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
|
|
|
if (GetIsPrinting()) {
|
|
|
|
nsPrintEngine::CloseProgressDialog(aWebProgressListener);
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef MOZ_XUL
|
|
|
|
// Temporary code for Bug 136185 / Bug 240490
|
|
|
|
nsCOMPtr<nsIXULDocument> xulDoc(do_QueryInterface(mDocument));
|
|
|
|
if (xulDoc) {
|
|
|
|
nsPrintEngine::CloseProgressDialog(aWebProgressListener);
|
|
|
|
nsPrintEngine::ShowPrintErrorDialog(NS_ERROR_GFX_PRINTER_NO_XUL, PR_FALSE);
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDocShell> docShell(do_QueryReferent(mContainer));
|
2010-08-27 16:15:08 -07:00
|
|
|
if (!docShell || !mDeviceContext) {
|
|
|
|
PR_PL(("Can't Print Preview without device context and docshell"));
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
2011-05-14 05:03:58 -07:00
|
|
|
nsCOMPtr<nsIDOMDocument> domDoc;
|
|
|
|
aChildDOMWin->GetDocument(getter_AddRefs(domDoc));
|
|
|
|
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
|
|
|
|
NS_ENSURE_STATE(doc);
|
2009-12-10 20:02:13 -08:00
|
|
|
|
2011-05-14 05:03:58 -07:00
|
|
|
nsPrintEventDispatcher beforeAndAfterPrint(doc);
|
2011-07-06 04:12:26 -07:00
|
|
|
NS_ENSURE_STATE(!GetIsPrinting());
|
2011-05-14 05:03:58 -07:00
|
|
|
if (!mPrintEngine) {
|
2007-03-22 10:30:00 -07:00
|
|
|
mPrintEngine = new nsPrintEngine();
|
|
|
|
|
2011-05-10 05:55:26 -07:00
|
|
|
rv = mPrintEngine->Initialize(this, mContainer, doc,
|
2010-08-13 02:58:04 -07:00
|
|
|
float(mDeviceContext->AppUnitsPerCSSInch()) /
|
2009-08-24 02:55:28 -07:00
|
|
|
float(mDeviceContext->AppUnitsPerDevPixel()) /
|
|
|
|
mPageZoom,
|
2007-03-22 10:30:00 -07:00
|
|
|
#ifdef NS_DEBUG
|
|
|
|
mDebugFile
|
|
|
|
#else
|
|
|
|
nsnull
|
|
|
|
#endif
|
|
|
|
);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
mPrintEngine->Destroy();
|
|
|
|
mPrintEngine = nsnull;
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = mPrintEngine->PrintPreview(aPrintSettings, aChildDOMWin, aWebProgressListener);
|
2009-03-08 12:01:02 -07:00
|
|
|
mPrintPreviewZoomed = PR_FALSE;
|
2007-03-22 10:30:00 -07:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
OnDonePrinting();
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
#else
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::PrintPreviewNavigate(PRInt16 aType, PRInt32 aPageNum)
|
|
|
|
{
|
|
|
|
if (!GetIsPrintPreview() ||
|
|
|
|
mPrintEngine->GetIsCreatingPrintPreview())
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
2009-09-02 21:26:00 -07:00
|
|
|
nsIScrollableFrame* sf =
|
|
|
|
mPrintEngine->GetPrintPreviewPresShell()->GetRootScrollFrameAsScrollable();
|
|
|
|
if (!sf)
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
// Check to see if we can short circut scrolling to the top
|
|
|
|
if (aType == nsIWebBrowserPrint::PRINTPREVIEW_HOME ||
|
|
|
|
(aType == nsIWebBrowserPrint::PRINTPREVIEW_GOTO_PAGENUM && aPageNum == 1)) {
|
2009-09-02 21:26:00 -07:00
|
|
|
sf->ScrollTo(nsPoint(0, 0), nsIScrollableFrame::INSTANT);
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Finds the SimplePageSequencer frame
|
|
|
|
// in PP mPrtPreview->mPrintObject->mSeqFrame is null
|
|
|
|
nsIFrame* seqFrame = nsnull;
|
|
|
|
PRInt32 pageCount = 0;
|
|
|
|
if (NS_FAILED(mPrintEngine->GetSeqFrameAndCountPages(seqFrame, pageCount))) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Figure where we are currently scrolled to
|
2009-09-02 21:26:00 -07:00
|
|
|
nsPoint pt = sf->GetScrollPosition();
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
PRInt32 pageNum = 1;
|
|
|
|
nsIFrame * fndPageFrame = nsnull;
|
|
|
|
nsIFrame * currentPage = nsnull;
|
|
|
|
|
|
|
|
// If it is "End" then just do a "goto" to the last page
|
|
|
|
if (aType == nsIWebBrowserPrint::PRINTPREVIEW_END) {
|
|
|
|
aType = nsIWebBrowserPrint::PRINTPREVIEW_GOTO_PAGENUM;
|
|
|
|
aPageNum = pageCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now, locate the current page we are on and
|
|
|
|
// and the page of the page number
|
|
|
|
nscoord gap = 0;
|
2011-08-24 13:54:30 -07:00
|
|
|
nsIFrame* pageFrame = seqFrame->GetFirstPrincipalChild();
|
2007-03-22 10:30:00 -07:00
|
|
|
while (pageFrame != nsnull) {
|
|
|
|
nsRect pageRect = pageFrame->GetRect();
|
|
|
|
if (pageNum == 1) {
|
|
|
|
gap = pageRect.y;
|
|
|
|
}
|
2009-09-02 21:26:00 -07:00
|
|
|
if (pageRect.Contains(pageRect.x, pt.y)) {
|
2007-03-22 10:30:00 -07:00
|
|
|
currentPage = pageFrame;
|
|
|
|
}
|
|
|
|
if (pageNum == aPageNum) {
|
|
|
|
fndPageFrame = pageFrame;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
pageNum++;
|
|
|
|
pageFrame = pageFrame->GetNextSibling();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aType == nsIWebBrowserPrint::PRINTPREVIEW_PREV_PAGE) {
|
|
|
|
if (currentPage) {
|
|
|
|
fndPageFrame = currentPage->GetPrevInFlow();
|
|
|
|
if (!fndPageFrame) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
} else if (aType == nsIWebBrowserPrint::PRINTPREVIEW_NEXT_PAGE) {
|
|
|
|
if (currentPage) {
|
|
|
|
fndPageFrame = currentPage->GetNextInFlow();
|
|
|
|
if (!fndPageFrame) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
} else { // If we get here we are doing "GoTo"
|
|
|
|
if (aPageNum < 0 || aPageNum > pageCount) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-09-02 21:26:00 -07:00
|
|
|
if (fndPageFrame) {
|
2010-08-13 02:58:04 -07:00
|
|
|
nscoord newYPosn =
|
2011-06-10 03:07:26 -07:00
|
|
|
nscoord(mPrintEngine->GetPrintPreviewScale() * fndPageFrame->GetPosition().y);
|
2009-09-02 21:26:00 -07:00
|
|
|
sf->ScrollTo(nsPoint(pt.x, newYPosn), nsIScrollableFrame::INSTANT);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/* readonly attribute nsIPrintSettings globalPrintSettings; */
|
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::GetGlobalPrintSettings(nsIPrintSettings * *aGlobalPrintSettings)
|
|
|
|
{
|
|
|
|
return nsPrintEngine::GetGlobalPrintSettings(aGlobalPrintSettings);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* readonly attribute boolean doingPrint; */
|
|
|
|
// XXX This always returns PR_FALSE for subdocuments
|
|
|
|
NS_IMETHODIMP
|
2011-09-28 23:19:26 -07:00
|
|
|
DocumentViewerImpl::GetDoingPrint(bool *aDoingPrint)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aDoingPrint);
|
|
|
|
|
|
|
|
*aDoingPrint = PR_FALSE;
|
|
|
|
if (mPrintEngine) {
|
|
|
|
// XXX shouldn't this be GetDoingPrint() ?
|
|
|
|
return mPrintEngine->GetDoingPrintPreview(aDoingPrint);
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* readonly attribute boolean doingPrintPreview; */
|
|
|
|
// XXX This always returns PR_FALSE for subdocuments
|
|
|
|
NS_IMETHODIMP
|
2011-09-28 23:19:26 -07:00
|
|
|
DocumentViewerImpl::GetDoingPrintPreview(bool *aDoingPrintPreview)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aDoingPrintPreview);
|
|
|
|
|
|
|
|
*aDoingPrintPreview = PR_FALSE;
|
|
|
|
if (mPrintEngine) {
|
|
|
|
return mPrintEngine->GetDoingPrintPreview(aDoingPrintPreview);
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* readonly attribute nsIPrintSettings currentPrintSettings; */
|
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::GetCurrentPrintSettings(nsIPrintSettings * *aCurrentPrintSettings)
|
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aCurrentPrintSettings);
|
|
|
|
|
|
|
|
*aCurrentPrintSettings = nsnull;
|
|
|
|
NS_ENSURE_TRUE(mPrintEngine, NS_ERROR_FAILURE);
|
|
|
|
|
|
|
|
return mPrintEngine->GetCurrentPrintSettings(aCurrentPrintSettings);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* readonly attribute nsIDOMWindow currentChildDOMWindow; */
|
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::GetCurrentChildDOMWindow(nsIDOMWindow * *aCurrentChildDOMWindow)
|
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aCurrentChildDOMWindow);
|
|
|
|
*aCurrentChildDOMWindow = nsnull;
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* void cancel (); */
|
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::Cancel()
|
|
|
|
{
|
|
|
|
NS_ENSURE_TRUE(mPrintEngine, NS_ERROR_FAILURE);
|
|
|
|
return mPrintEngine->Cancelled();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* void exitPrintPreview (); */
|
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::ExitPrintPreview()
|
|
|
|
{
|
2009-10-15 16:10:27 -07:00
|
|
|
if (GetIsPrinting())
|
|
|
|
return NS_ERROR_FAILURE;
|
2007-03-22 10:30:00 -07:00
|
|
|
NS_ENSURE_TRUE(mPrintEngine, NS_ERROR_FAILURE);
|
|
|
|
|
|
|
|
if (GetIsPrintPreview()) {
|
|
|
|
ReturnToGalleyPresentation();
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------------
|
|
|
|
// Enumerate all the documents for their titles
|
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::EnumerateDocumentNames(PRUint32* aCount,
|
|
|
|
PRUnichar*** aResult)
|
|
|
|
{
|
|
|
|
#ifdef NS_PRINTING
|
|
|
|
NS_ENSURE_ARG(aCount);
|
|
|
|
NS_ENSURE_ARG_POINTER(aResult);
|
|
|
|
NS_ENSURE_TRUE(mPrintEngine, NS_ERROR_FAILURE);
|
|
|
|
|
|
|
|
return mPrintEngine->EnumerateDocumentNames(aCount, aResult);
|
|
|
|
#else
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/* readonly attribute boolean isFramesetFrameSelected; */
|
|
|
|
NS_IMETHODIMP
|
2011-09-28 23:19:26 -07:00
|
|
|
DocumentViewerImpl::GetIsFramesetFrameSelected(bool *aIsFramesetFrameSelected)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
#ifdef NS_PRINTING
|
|
|
|
*aIsFramesetFrameSelected = PR_FALSE;
|
|
|
|
NS_ENSURE_TRUE(mPrintEngine, NS_ERROR_FAILURE);
|
|
|
|
|
|
|
|
return mPrintEngine->GetIsFramesetFrameSelected(aIsFramesetFrameSelected);
|
|
|
|
#else
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/* readonly attribute long printPreviewNumPages; */
|
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::GetPrintPreviewNumPages(PRInt32 *aPrintPreviewNumPages)
|
|
|
|
{
|
|
|
|
#ifdef NS_PRINTING
|
|
|
|
NS_ENSURE_ARG_POINTER(aPrintPreviewNumPages);
|
|
|
|
NS_ENSURE_TRUE(mPrintEngine, NS_ERROR_FAILURE);
|
|
|
|
|
|
|
|
return mPrintEngine->GetPrintPreviewNumPages(aPrintPreviewNumPages);
|
|
|
|
#else
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/* readonly attribute boolean isFramesetDocument; */
|
|
|
|
NS_IMETHODIMP
|
2011-09-28 23:19:26 -07:00
|
|
|
DocumentViewerImpl::GetIsFramesetDocument(bool *aIsFramesetDocument)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
#ifdef NS_PRINTING
|
|
|
|
*aIsFramesetDocument = PR_FALSE;
|
|
|
|
NS_ENSURE_TRUE(mPrintEngine, NS_ERROR_FAILURE);
|
|
|
|
|
|
|
|
return mPrintEngine->GetIsFramesetDocument(aIsFramesetDocument);
|
|
|
|
#else
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/* readonly attribute boolean isIFrameSelected; */
|
|
|
|
NS_IMETHODIMP
|
2011-09-28 23:19:26 -07:00
|
|
|
DocumentViewerImpl::GetIsIFrameSelected(bool *aIsIFrameSelected)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
#ifdef NS_PRINTING
|
|
|
|
*aIsIFrameSelected = PR_FALSE;
|
|
|
|
NS_ENSURE_TRUE(mPrintEngine, NS_ERROR_FAILURE);
|
|
|
|
|
|
|
|
return mPrintEngine->GetIsIFrameSelected(aIsIFrameSelected);
|
|
|
|
#else
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/* readonly attribute boolean isRangeSelection; */
|
|
|
|
NS_IMETHODIMP
|
2011-09-28 23:19:26 -07:00
|
|
|
DocumentViewerImpl::GetIsRangeSelection(bool *aIsRangeSelection)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
#ifdef NS_PRINTING
|
|
|
|
*aIsRangeSelection = PR_FALSE;
|
|
|
|
NS_ENSURE_TRUE(mPrintEngine, NS_ERROR_FAILURE);
|
|
|
|
|
|
|
|
return mPrintEngine->GetIsRangeSelection(aIsRangeSelection);
|
|
|
|
#else
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------------
|
|
|
|
// Printing/Print Preview Helpers
|
|
|
|
//----------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------------
|
|
|
|
// Walks the document tree and tells each DocShell whether Printing/PP is happening
|
|
|
|
void
|
|
|
|
DocumentViewerImpl::SetIsPrintingInDocShellTree(nsIDocShellTreeNode* aParentNode,
|
2011-09-28 23:19:26 -07:00
|
|
|
bool aIsPrintingOrPP,
|
|
|
|
bool aStartAtTop)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem> parentItem(do_QueryInterface(aParentNode));
|
|
|
|
|
|
|
|
// find top of "same parent" tree
|
|
|
|
if (aStartAtTop) {
|
2011-03-24 04:42:54 -07:00
|
|
|
if (aIsPrintingOrPP) {
|
|
|
|
while (parentItem) {
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem> parent;
|
|
|
|
parentItem->GetSameTypeParent(getter_AddRefs(parent));
|
|
|
|
if (!parent) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
parentItem = do_QueryInterface(parent);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
2011-03-24 04:42:54 -07:00
|
|
|
mTopContainerWhilePrinting = do_GetWeakReference(parentItem);
|
|
|
|
} else {
|
|
|
|
parentItem = do_QueryReferent(mTopContainerWhilePrinting);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check to see if the DocShell's ContentViewer is printing/PP
|
|
|
|
nsCOMPtr<nsIContentViewerContainer> viewerContainer(do_QueryInterface(parentItem));
|
|
|
|
if (viewerContainer) {
|
|
|
|
viewerContainer->SetIsPrinting(aIsPrintingOrPP);
|
|
|
|
}
|
|
|
|
|
2011-03-24 04:42:54 -07:00
|
|
|
if (!aParentNode) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
// Traverse children to see if any of them are printing.
|
|
|
|
PRInt32 n;
|
|
|
|
aParentNode->GetChildCount(&n);
|
|
|
|
for (PRInt32 i=0; i < n; i++) {
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem> child;
|
|
|
|
aParentNode->GetChildAt(i, getter_AddRefs(child));
|
|
|
|
nsCOMPtr<nsIDocShellTreeNode> childAsNode(do_QueryInterface(child));
|
|
|
|
NS_ASSERTION(childAsNode, "child isn't nsIDocShellTreeNode");
|
|
|
|
if (childAsNode) {
|
|
|
|
SetIsPrintingInDocShellTree(childAsNode, aIsPrintingOrPP, PR_FALSE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
#endif // NS_PRINTING
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
bool
|
2011-02-09 12:13:18 -08:00
|
|
|
DocumentViewerImpl::ShouldAttachToTopLevel()
|
|
|
|
{
|
|
|
|
if (!mParentWidget)
|
|
|
|
return PR_FALSE;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem> containerItem = do_QueryReferent(mContainer);
|
|
|
|
if (!containerItem)
|
|
|
|
return PR_FALSE;
|
|
|
|
|
|
|
|
// We always attach when using puppet widgets
|
|
|
|
if (nsIWidget::UsePuppetWidgets())
|
|
|
|
return PR_TRUE;
|
|
|
|
|
|
|
|
#ifdef XP_WIN
|
|
|
|
// On windows, in the parent process we also attach, but just to
|
|
|
|
// chrome items
|
|
|
|
PRInt32 docType;
|
|
|
|
nsWindowType winType;
|
|
|
|
containerItem->GetItemType(&docType);
|
|
|
|
mParentWidget->GetWindowType(winType);
|
|
|
|
if ((winType == eWindowType_toplevel ||
|
|
|
|
winType == eWindowType_dialog ||
|
|
|
|
winType == eWindowType_invisible) &&
|
|
|
|
docType == nsIDocShellTreeItem::typeChrome)
|
|
|
|
return PR_TRUE;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
bool CollectDocuments(nsIDocument* aDocument, void* aData)
|
2011-05-14 05:03:58 -07:00
|
|
|
{
|
|
|
|
if (aDocument) {
|
|
|
|
static_cast<nsCOMArray<nsIDocument>*>(aData)->AppendObject(aDocument);
|
|
|
|
aDocument->EnumerateSubDocuments(CollectDocuments, aData);
|
|
|
|
}
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
DocumentViewerImpl::DispatchEventToWindowTree(nsIDocument* aDoc,
|
|
|
|
const nsAString& aEvent)
|
|
|
|
{
|
|
|
|
nsCOMArray<nsIDocument> targets;
|
|
|
|
CollectDocuments(aDoc, &targets);
|
|
|
|
for (PRInt32 i = 0; i < targets.Count(); ++i) {
|
|
|
|
nsIDocument* d = targets[i];
|
|
|
|
nsContentUtils::DispatchTrustedEvent(d, d->GetWindow(),
|
|
|
|
aEvent, PR_FALSE, PR_FALSE, nsnull);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
//------------------------------------------------------------
|
|
|
|
// XXX this always returns PR_FALSE for subdocuments
|
2011-09-28 23:19:26 -07:00
|
|
|
bool
|
2007-03-22 10:30:00 -07:00
|
|
|
DocumentViewerImpl::GetIsPrinting()
|
|
|
|
{
|
|
|
|
#ifdef NS_PRINTING
|
|
|
|
if (mPrintEngine) {
|
|
|
|
return mPrintEngine->GetIsPrinting();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------
|
|
|
|
// Notification from the PrintEngine of the current Printing status
|
|
|
|
void
|
2011-09-28 23:19:26 -07:00
|
|
|
DocumentViewerImpl::SetIsPrinting(bool aIsPrinting)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
#ifdef NS_PRINTING
|
|
|
|
// Set all the docShells in the docshell tree to be printing.
|
|
|
|
// that way if anyone of them tries to "navigate" it can't
|
2011-03-24 04:42:54 -07:00
|
|
|
nsCOMPtr<nsIDocShellTreeNode> docShellTreeNode(do_QueryReferent(mContainer));
|
|
|
|
if (docShellTreeNode || !aIsPrinting) {
|
|
|
|
SetIsPrintingInDocShellTree(docShellTreeNode, aIsPrinting, PR_TRUE);
|
|
|
|
} else {
|
|
|
|
NS_WARNING("Did you close a window before printing?");
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------
|
|
|
|
// The PrintEngine holds the current value
|
|
|
|
// this called from inside the DocViewer.
|
|
|
|
// XXX it always returns PR_FALSE for subdocuments
|
2011-09-28 23:19:26 -07:00
|
|
|
bool
|
2007-03-22 10:30:00 -07:00
|
|
|
DocumentViewerImpl::GetIsPrintPreview()
|
|
|
|
{
|
|
|
|
#ifdef NS_PRINTING
|
|
|
|
if (mPrintEngine) {
|
|
|
|
return mPrintEngine->GetIsPrintPreview();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------
|
|
|
|
// Notification from the PrintEngine of the current PP status
|
|
|
|
void
|
2011-09-28 23:19:26 -07:00
|
|
|
DocumentViewerImpl::SetIsPrintPreview(bool aIsPrintPreview)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
#ifdef NS_PRINTING
|
|
|
|
// Set all the docShells in the docshell tree to be printing.
|
|
|
|
// that way if anyone of them tries to "navigate" it can't
|
2011-03-24 04:42:54 -07:00
|
|
|
nsCOMPtr<nsIDocShellTreeNode> docShellTreeNode(do_QueryReferent(mContainer));
|
|
|
|
if (docShellTreeNode || !aIsPrintPreview) {
|
2007-03-22 10:30:00 -07:00
|
|
|
SetIsPrintingInDocShellTree(docShellTreeNode, aIsPrintPreview, PR_TRUE);
|
|
|
|
}
|
|
|
|
#endif
|
2009-12-10 20:02:13 -08:00
|
|
|
if (!aIsPrintPreview) {
|
2010-02-11 03:02:38 -08:00
|
|
|
if (mPresShell) {
|
|
|
|
DestroyPresShell();
|
|
|
|
}
|
2009-12-10 20:02:13 -08:00
|
|
|
mWindow = nsnull;
|
|
|
|
mViewManager = nsnull;
|
|
|
|
mPresContext = nsnull;
|
|
|
|
mPresShell = nsnull;
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------------
|
|
|
|
// nsIDocumentViewerPrint IFace
|
|
|
|
//----------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
//------------------------------------------------------------
|
|
|
|
void
|
|
|
|
DocumentViewerImpl::IncrementDestroyRefCount()
|
|
|
|
{
|
|
|
|
++mDestroyRefCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------
|
|
|
|
|
|
|
|
static void ResetFocusState(nsIDocShell* aDocShell);
|
|
|
|
|
|
|
|
void
|
|
|
|
DocumentViewerImpl::ReturnToGalleyPresentation()
|
|
|
|
{
|
|
|
|
#if defined(NS_PRINTING) && defined(NS_PRINT_PREVIEW)
|
|
|
|
if (!GetIsPrintPreview()) {
|
|
|
|
NS_ERROR("Wow, we should never get here!");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
SetIsPrintPreview(PR_FALSE);
|
|
|
|
|
|
|
|
mPrintEngine->TurnScriptingOn(PR_TRUE);
|
|
|
|
mPrintEngine->Destroy();
|
|
|
|
mPrintEngine = nsnull;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDocShell> docShell(do_QueryReferent(mContainer));
|
|
|
|
ResetFocusState(docShell);
|
|
|
|
|
2007-11-09 02:19:12 -08:00
|
|
|
SetTextZoom(mTextZoom);
|
|
|
|
SetFullZoom(mPageZoom);
|
2011-03-10 20:33:43 -08:00
|
|
|
SetMinFontSize(mMinFontSize);
|
2007-03-22 10:30:00 -07:00
|
|
|
Show();
|
|
|
|
|
|
|
|
#endif // NS_PRINTING && NS_PRINT_PREVIEW
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------
|
|
|
|
// Reset ESM focus for all descendent doc shells.
|
|
|
|
static void
|
|
|
|
ResetFocusState(nsIDocShell* aDocShell)
|
|
|
|
{
|
Bug 178324, refactor focus by moving all focus handling into one place and simplifying it, add many tests, fixes many other bugs too numerous to mention in this small checkin comment, r=josh,smichaud,ere,dbaron,marco,neil,gavin,smaug,sr=smaug (CLOSED TREE)
2009-06-10 11:00:39 -07:00
|
|
|
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
|
|
|
|
if (!fm)
|
|
|
|
return;
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
nsCOMPtr<nsISimpleEnumerator> docShellEnumerator;
|
|
|
|
aDocShell->GetDocShellEnumerator(nsIDocShellTreeItem::typeContent,
|
|
|
|
nsIDocShell::ENUMERATE_FORWARDS,
|
|
|
|
getter_AddRefs(docShellEnumerator));
|
|
|
|
|
|
|
|
nsCOMPtr<nsISupports> currentContainer;
|
2011-09-28 23:19:26 -07:00
|
|
|
bool hasMoreDocShells;
|
2007-03-22 10:30:00 -07:00
|
|
|
while (NS_SUCCEEDED(docShellEnumerator->HasMoreElements(&hasMoreDocShells))
|
|
|
|
&& hasMoreDocShells) {
|
|
|
|
docShellEnumerator->GetNext(getter_AddRefs(currentContainer));
|
Bug 178324, refactor focus by moving all focus handling into one place and simplifying it, add many tests, fixes many other bugs too numerous to mention in this small checkin comment, r=josh,smichaud,ere,dbaron,marco,neil,gavin,smaug,sr=smaug (CLOSED TREE)
2009-06-10 11:00:39 -07:00
|
|
|
nsCOMPtr<nsIDOMWindow> win = do_GetInterface(currentContainer);
|
|
|
|
if (win)
|
|
|
|
fm->ClearFocus(win);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------
|
|
|
|
// This called ONLY when printing has completed and the DV
|
|
|
|
// is being notified that it should get rid of the PrintEngine.
|
|
|
|
//
|
|
|
|
// BUT, if we are in Print Preview then we want to ignore the
|
|
|
|
// notification (we do not get rid of the PrintEngine)
|
|
|
|
//
|
|
|
|
// One small caveat:
|
|
|
|
// This IS called from two places in this module for cleaning
|
|
|
|
// up when an error occurred during the start up printing
|
|
|
|
// and print preview
|
|
|
|
//
|
|
|
|
void
|
|
|
|
DocumentViewerImpl::OnDonePrinting()
|
|
|
|
{
|
|
|
|
#if defined(NS_PRINTING) && defined(NS_PRINT_PREVIEW)
|
|
|
|
if (mPrintEngine) {
|
|
|
|
if (GetIsPrintPreview()) {
|
|
|
|
mPrintEngine->DestroyPrintingData();
|
|
|
|
} else {
|
|
|
|
mPrintEngine->Destroy();
|
|
|
|
mPrintEngine = nsnull;
|
|
|
|
}
|
|
|
|
|
|
|
|
// We are done printing, now cleanup
|
|
|
|
if (mDeferredWindowClose) {
|
|
|
|
mDeferredWindowClose = PR_FALSE;
|
|
|
|
nsCOMPtr<nsISupports> container = do_QueryReferent(mContainer);
|
2011-07-15 03:31:34 -07:00
|
|
|
nsCOMPtr<nsIDOMWindow> win = do_GetInterface(container);
|
2007-03-22 10:30:00 -07:00
|
|
|
if (win)
|
|
|
|
win->Close();
|
|
|
|
} else if (mClosingWhilePrinting) {
|
|
|
|
if (mDocument) {
|
|
|
|
mDocument->SetScriptGlobalObject(nsnull);
|
|
|
|
mDocument->Destroy();
|
|
|
|
mDocument = nsnull;
|
|
|
|
}
|
|
|
|
mClosingWhilePrinting = PR_FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif // NS_PRINTING && NS_PRINT_PREVIEW
|
|
|
|
}
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
NS_IMETHODIMP DocumentViewerImpl::SetPageMode(bool aPageMode, nsIPrintSettings* aPrintSettings)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
// XXX Page mode is only partially working; it's currently used for
|
|
|
|
// reftests that require a paginated context
|
|
|
|
mIsPageMode = aPageMode;
|
|
|
|
|
|
|
|
if (mPresShell) {
|
2009-01-14 04:24:10 -08:00
|
|
|
DestroyPresShell();
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (mPresContext) {
|
2011-01-21 11:09:11 -08:00
|
|
|
DestroyPresContext();
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
mViewManager = nsnull;
|
|
|
|
mWindow = nsnull;
|
|
|
|
|
|
|
|
NS_ENSURE_STATE(mDocument);
|
|
|
|
if (aPageMode)
|
|
|
|
{
|
2009-07-21 17:44:54 -07:00
|
|
|
mPresContext = CreatePresContext(mDocument,
|
|
|
|
nsPresContext::eContext_PageLayout, FindContainerView());
|
2007-03-22 10:30:00 -07:00
|
|
|
NS_ENSURE_TRUE(mPresContext, NS_ERROR_OUT_OF_MEMORY);
|
|
|
|
mPresContext->SetPaginatedScrolling(PR_TRUE);
|
|
|
|
mPresContext->SetPrintSettings(aPrintSettings);
|
|
|
|
nsresult rv = mPresContext->Init(mDeviceContext);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
}
|
2010-08-27 16:15:08 -07:00
|
|
|
InitInternal(mParentWidget, nsnull, mBounds, PR_TRUE, PR_FALSE);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
Show();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2007-10-05 17:35:00 -07:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
DocumentViewerImpl::GetHistoryEntry(nsISHEntry **aHistoryEntry)
|
|
|
|
{
|
|
|
|
NS_IF_ADDREF(*aHistoryEntry = mSHEntry);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2009-01-14 04:24:10 -08:00
|
|
|
|
2011-02-15 16:35:28 -08:00
|
|
|
NS_IMETHODIMP
|
2011-09-28 23:19:26 -07:00
|
|
|
DocumentViewerImpl::GetIsTabModalPromptAllowed(bool *aAllowed)
|
2011-02-15 16:35:28 -08:00
|
|
|
{
|
|
|
|
*aAllowed = !(mInPermitUnload || mHidden);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2009-01-14 04:24:10 -08:00
|
|
|
void
|
|
|
|
DocumentViewerImpl::DestroyPresShell()
|
|
|
|
{
|
|
|
|
// Break circular reference (or something)
|
|
|
|
mPresShell->EndObservingDocument();
|
|
|
|
|
|
|
|
nsCOMPtr<nsISelection> selection;
|
|
|
|
GetDocumentSelection(getter_AddRefs(selection));
|
|
|
|
nsCOMPtr<nsISelectionPrivate> selPrivate = do_QueryInterface(selection);
|
|
|
|
if (selPrivate && mSelectionListener)
|
|
|
|
selPrivate->RemoveSelectionListener(mSelectionListener);
|
|
|
|
|
2009-05-14 20:08:41 -07:00
|
|
|
nsAutoScriptBlocker scriptBlocker;
|
2009-01-14 04:24:10 -08:00
|
|
|
mPresShell->Destroy();
|
|
|
|
mPresShell = nsnull;
|
|
|
|
}
|
2009-12-10 20:02:13 -08:00
|
|
|
|
2011-01-21 11:09:11 -08:00
|
|
|
void
|
|
|
|
DocumentViewerImpl::DestroyPresContext()
|
|
|
|
{
|
|
|
|
mPresContext->SetContainer(nsnull);
|
|
|
|
mPresContext->SetLinkHandler(nsnull);
|
|
|
|
mPresContext = nsnull;
|
|
|
|
}
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
bool
|
2009-12-10 20:02:13 -08:00
|
|
|
DocumentViewerImpl::IsInitializedForPrintPreview()
|
|
|
|
{
|
|
|
|
return mInitializedForPrintPreview;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
DocumentViewerImpl::InitializeForPrintPreview()
|
|
|
|
{
|
|
|
|
mInitializedForPrintPreview = PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2010-08-27 16:15:08 -07:00
|
|
|
DocumentViewerImpl::SetPrintPreviewPresentation(nsIViewManager* aViewManager,
|
2009-12-10 20:02:13 -08:00
|
|
|
nsPresContext* aPresContext,
|
|
|
|
nsIPresShell* aPresShell)
|
|
|
|
{
|
|
|
|
if (mPresShell) {
|
|
|
|
DestroyPresShell();
|
|
|
|
}
|
|
|
|
|
2010-08-27 16:15:08 -07:00
|
|
|
mWindow = nsnull;
|
2009-12-10 20:02:13 -08:00
|
|
|
mViewManager = aViewManager;
|
|
|
|
mPresContext = aPresContext;
|
|
|
|
mPresShell = aPresShell;
|
|
|
|
}
|