1998-04-14 00:24:54 +04:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
|
|
*
|
|
|
|
* The contents of this file are subject to the Netscape Public License
|
|
|
|
* Version 1.0 (the "NPL"); you may not use this file except in
|
|
|
|
* compliance with the NPL. You may obtain a copy of the NPL at
|
|
|
|
* http://www.mozilla.org/NPL/
|
|
|
|
*
|
|
|
|
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
|
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
|
|
|
* for the specific language governing rights and limitations under the
|
|
|
|
* NPL.
|
|
|
|
*
|
|
|
|
* The Initial Developer of this code under the NPL is Netscape
|
|
|
|
* Communications Corporation. Portions created by Netscape are
|
|
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
|
|
|
* Reserved.
|
|
|
|
*/
|
|
|
|
#include "nsIPresShell.h"
|
|
|
|
#include "nsIPresContext.h"
|
|
|
|
#include "nsIContent.h"
|
|
|
|
#include "nsIDocument.h"
|
1998-06-03 19:46:54 +04:00
|
|
|
#include "nsIDocumentObserver.h"
|
1998-04-14 00:24:54 +04:00
|
|
|
#include "nsIStyleSet.h"
|
1998-11-26 04:34:53 +03:00
|
|
|
#include "nsICSSStyleSheet.h" // XXX for UA sheet loading hack, can this go away please?
|
1998-04-14 00:24:54 +04:00
|
|
|
#include "nsIStyleContext.h"
|
1998-05-20 20:24:54 +04:00
|
|
|
#include "nsFrame.h"
|
1998-06-09 08:51:44 +04:00
|
|
|
#include "nsIReflowCommand.h"
|
1998-04-14 00:24:54 +04:00
|
|
|
#include "nsIViewManager.h"
|
|
|
|
#include "nsCRT.h"
|
|
|
|
#include "plhash.h"
|
1998-06-03 19:46:54 +04:00
|
|
|
#include "prlog.h"
|
1998-12-12 22:21:05 +03:00
|
|
|
#include "prthread.h"
|
|
|
|
#include "prinrval.h"
|
1998-06-09 08:51:44 +04:00
|
|
|
#include "nsVoidArray.h"
|
1998-07-31 09:54:59 +04:00
|
|
|
#include "nsIPref.h"
|
1998-08-28 06:54:06 +04:00
|
|
|
#include "nsIViewObserver.h"
|
1998-09-19 07:24:26 +04:00
|
|
|
#include "nsContainerFrame.h"
|
1998-10-01 08:46:11 +04:00
|
|
|
#include "nsHTMLIIDs.h"
|
1998-10-02 05:12:39 +04:00
|
|
|
#include "nsIDeviceContext.h"
|
1998-11-18 08:25:26 +03:00
|
|
|
#include "nsIEventStateManager.h"
|
|
|
|
#include "nsDOMEvent.h"
|
1998-11-17 05:14:38 +03:00
|
|
|
#include "nsHTMLParts.h"
|
1999-02-12 02:12:28 +03:00
|
|
|
#include "nsIFrameSelection.h"
|
|
|
|
#include "nsIDOMSelection.h"
|
1998-12-08 21:26:06 +03:00
|
|
|
#include "nsLayoutCID.h"
|
1998-12-14 21:34:14 +03:00
|
|
|
#include "nsIDOMRange.h"
|
|
|
|
#include "nsIDOMDocument.h"
|
|
|
|
#include "nsIDOMNode.h"
|
|
|
|
#include "nsIDOMElement.h"
|
1999-01-07 07:47:43 +03:00
|
|
|
#include "nsHTMLAtoms.h"
|
1999-01-22 21:58:14 +03:00
|
|
|
#include "nsCOMPtr.h"
|
1999-02-05 21:25:29 +03:00
|
|
|
#include "nsIEventQueueService.h"
|
|
|
|
#include "nsXPComCIID.h"
|
|
|
|
#include "nsIServiceManager.h"
|
1999-02-12 03:02:56 +03:00
|
|
|
#include "nsICaret.h"
|
|
|
|
#include "nsCaretProperties.h"
|
1999-02-12 08:39:33 +03:00
|
|
|
#include "nsIDOMHTMLDocument.h"
|
|
|
|
#include "nsIScrollableView.h"
|
1998-04-14 00:24:54 +04:00
|
|
|
|
1998-09-15 00:46:42 +04:00
|
|
|
static PRBool gsNoisyRefs = PR_FALSE;
|
1998-04-14 00:24:54 +04:00
|
|
|
#undef NOISY
|
|
|
|
|
1999-02-12 03:02:56 +03:00
|
|
|
|
|
|
|
// comment out to hide caret
|
|
|
|
//#define SHOW_CARET
|
|
|
|
|
1998-05-09 07:22:41 +04:00
|
|
|
static PLHashNumber
|
|
|
|
HashKey(nsIFrame* key)
|
1998-04-14 00:24:54 +04:00
|
|
|
{
|
|
|
|
return (PLHashNumber) key;
|
|
|
|
}
|
|
|
|
|
1998-05-09 07:22:41 +04:00
|
|
|
static PRIntn
|
|
|
|
CompareKeys(nsIFrame* key1, nsIFrame* key2)
|
1998-04-14 00:24:54 +04:00
|
|
|
{
|
|
|
|
return key1 == key2;
|
|
|
|
}
|
|
|
|
|
|
|
|
class FrameHashTable {
|
|
|
|
public:
|
|
|
|
FrameHashTable();
|
|
|
|
~FrameHashTable();
|
|
|
|
|
|
|
|
void* Get(nsIFrame* aKey);
|
|
|
|
void* Put(nsIFrame* aKey, void* aValue);
|
|
|
|
void* Remove(nsIFrame* aKey);
|
|
|
|
|
|
|
|
protected:
|
|
|
|
PLHashTable* mTable;
|
|
|
|
};
|
|
|
|
|
|
|
|
FrameHashTable::FrameHashTable()
|
|
|
|
{
|
|
|
|
mTable = PL_NewHashTable(8, (PLHashFunction) HashKey,
|
|
|
|
(PLHashComparator) CompareKeys,
|
|
|
|
(PLHashComparator) nsnull,
|
|
|
|
nsnull, nsnull);
|
|
|
|
}
|
|
|
|
|
|
|
|
FrameHashTable::~FrameHashTable()
|
|
|
|
{
|
|
|
|
PL_HashTableDestroy(mTable);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the data associated with a frame.
|
|
|
|
*/
|
1998-05-09 07:22:41 +04:00
|
|
|
void*
|
|
|
|
FrameHashTable::Get(nsIFrame* aKey)
|
1998-04-14 00:24:54 +04:00
|
|
|
{
|
|
|
|
PRInt32 hashCode = (PRInt32) aKey;
|
|
|
|
PLHashEntry** hep = PL_HashTableRawLookup(mTable, hashCode, aKey);
|
|
|
|
PLHashEntry* he = *hep;
|
|
|
|
if (nsnull != he) {
|
|
|
|
return he->value;
|
|
|
|
}
|
|
|
|
return nsnull;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create an association between a frame and some data. This call
|
|
|
|
* returns an old association if there was one (or nsnull if there
|
|
|
|
* wasn't).
|
|
|
|
*/
|
1998-05-09 07:22:41 +04:00
|
|
|
void*
|
|
|
|
FrameHashTable::Put(nsIFrame* aKey, void* aData)
|
1998-04-14 00:24:54 +04:00
|
|
|
{
|
|
|
|
PRInt32 hashCode = (PRInt32) aKey;
|
|
|
|
PLHashEntry** hep = PL_HashTableRawLookup(mTable, hashCode, aKey);
|
|
|
|
PLHashEntry* he = *hep;
|
|
|
|
if (nsnull != he) {
|
|
|
|
void* oldValue = he->value;
|
|
|
|
he->value = aData;
|
|
|
|
return oldValue;
|
|
|
|
}
|
|
|
|
PL_HashTableRawAdd(mTable, hep, hashCode, aKey, aData);
|
|
|
|
return nsnull;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Remove an association between a frame and it's data. This returns
|
|
|
|
* the old associated data.
|
|
|
|
*/
|
1998-05-09 07:22:41 +04:00
|
|
|
void*
|
|
|
|
FrameHashTable::Remove(nsIFrame* aKey)
|
1998-04-14 00:24:54 +04:00
|
|
|
{
|
|
|
|
PRInt32 hashCode = (PRInt32) aKey;
|
|
|
|
PLHashEntry** hep = PL_HashTableRawLookup(mTable, hashCode, aKey);
|
|
|
|
PLHashEntry* he = *hep;
|
|
|
|
void* oldValue = nsnull;
|
|
|
|
if (nsnull != he) {
|
|
|
|
oldValue = he->value;
|
|
|
|
PL_HashTableRawRemove(mTable, hep, he);
|
|
|
|
}
|
|
|
|
return oldValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
1999-02-05 21:25:29 +03:00
|
|
|
// Class IID's
|
|
|
|
static NS_DEFINE_IID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
|
|
|
|
static NS_DEFINE_IID(kRangeListCID, NS_RANGELIST_CID);
|
|
|
|
static NS_DEFINE_IID(kCRangeCID, NS_RANGE_CID);
|
|
|
|
|
|
|
|
// IID's
|
1998-04-14 00:24:54 +04:00
|
|
|
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
|
|
|
static NS_DEFINE_IID(kIPresShellIID, NS_IPRESSHELL_IID);
|
1998-06-03 19:46:54 +04:00
|
|
|
static NS_DEFINE_IID(kIDocumentObserverIID, NS_IDOCUMENT_OBSERVER_IID);
|
1998-08-28 06:54:06 +04:00
|
|
|
static NS_DEFINE_IID(kIViewObserverIID, NS_IVIEWOBSERVER_IID);
|
1999-02-12 02:12:28 +03:00
|
|
|
static NS_DEFINE_IID(kIFrameSelectionIID, NS_IFRAMESELECTION_IID);
|
|
|
|
static NS_DEFINE_IID(kIDOMSelectionIID, NS_IDOMSELECTION_IID);
|
1998-12-14 21:34:14 +03:00
|
|
|
static NS_DEFINE_IID(kIDOMNodeIID, NS_IDOMNODE_IID);
|
|
|
|
static NS_DEFINE_IID(kIDOMRangeIID, NS_IDOMRANGE_IID);
|
|
|
|
static NS_DEFINE_IID(kIDOMDocumentIID, NS_IDOMDOCUMENT_IID);
|
|
|
|
static NS_DEFINE_IID(kIFocusTrackerIID, NS_IFOCUSTRACKER_IID);
|
1999-02-05 21:25:29 +03:00
|
|
|
static NS_DEFINE_IID(kIEventQueueServiceIID, NS_IEVENTQUEUESERVICE_IID);
|
1999-02-12 03:02:56 +03:00
|
|
|
static NS_DEFINE_IID(kICaretID, NS_ICARET_IID);
|
1999-02-12 08:39:33 +03:00
|
|
|
static NS_DEFINE_IID(kIDOMHTMLDocumentIID, NS_IDOMHTMLDOCUMENT_IID);
|
|
|
|
static NS_DEFINE_IID(kIContentIID, NS_ICONTENT_IID);
|
|
|
|
static NS_DEFINE_IID(kIScrollableViewIID, NS_ISCROLLABLEVIEW_IID);
|
1998-04-14 00:24:54 +04:00
|
|
|
|
1998-08-28 06:54:06 +04:00
|
|
|
class PresShell : public nsIPresShell, public nsIViewObserver,
|
1998-12-14 21:34:14 +03:00
|
|
|
private nsIDocumentObserver, public nsIFocusTracker
|
1998-08-28 06:54:06 +04:00
|
|
|
|
|
|
|
{
|
1998-04-14 00:24:54 +04:00
|
|
|
public:
|
|
|
|
PresShell();
|
|
|
|
|
|
|
|
void* operator new(size_t sz) {
|
|
|
|
void* rv = new char[sz];
|
|
|
|
nsCRT::zero(rv, sz);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// nsISupports
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
|
|
|
|
// nsIDocumentObserver
|
1998-07-23 03:32:19 +04:00
|
|
|
NS_IMETHOD BeginUpdate(nsIDocument *aDocument);
|
|
|
|
NS_IMETHOD EndUpdate(nsIDocument *aDocument);
|
|
|
|
NS_IMETHOD BeginLoad(nsIDocument *aDocument);
|
|
|
|
NS_IMETHOD EndLoad(nsIDocument *aDocument);
|
|
|
|
NS_IMETHOD BeginReflow(nsIDocument *aDocument, nsIPresShell* aShell);
|
|
|
|
NS_IMETHOD EndReflow(nsIDocument *aDocument, nsIPresShell* aShell);
|
|
|
|
NS_IMETHOD ContentChanged(nsIDocument *aDocument,
|
|
|
|
nsIContent* aContent,
|
1998-06-03 19:46:54 +04:00
|
|
|
nsISupports* aSubContent);
|
1998-09-18 23:53:27 +04:00
|
|
|
NS_IMETHOD AttributeChanged(nsIDocument *aDocument,
|
|
|
|
nsIContent* aContent,
|
1998-09-30 03:46:05 +04:00
|
|
|
nsIAtom* aAttribute,
|
|
|
|
PRInt32 aHint);
|
1998-07-23 03:32:19 +04:00
|
|
|
NS_IMETHOD ContentAppended(nsIDocument *aDocument,
|
1998-09-10 23:32:14 +04:00
|
|
|
nsIContent* aContainer,
|
|
|
|
PRInt32 aNewIndexInContainer);
|
1998-07-23 03:32:19 +04:00
|
|
|
NS_IMETHOD ContentInserted(nsIDocument *aDocument,
|
|
|
|
nsIContent* aContainer,
|
1998-06-03 19:46:54 +04:00
|
|
|
nsIContent* aChild,
|
|
|
|
PRInt32 aIndexInContainer);
|
1998-07-23 03:32:19 +04:00
|
|
|
NS_IMETHOD ContentReplaced(nsIDocument *aDocument,
|
|
|
|
nsIContent* aContainer,
|
1998-06-03 19:46:54 +04:00
|
|
|
nsIContent* aOldChild,
|
|
|
|
nsIContent* aNewChild,
|
|
|
|
PRInt32 aIndexInContainer);
|
1998-09-25 01:39:47 +04:00
|
|
|
NS_IMETHOD ContentRemoved(nsIDocument *aDocument,
|
|
|
|
nsIContent* aContainer,
|
|
|
|
nsIContent* aChild,
|
|
|
|
PRInt32 aIndexInContainer);
|
1998-07-23 03:32:19 +04:00
|
|
|
NS_IMETHOD StyleSheetAdded(nsIDocument *aDocument,
|
|
|
|
nsIStyleSheet* aStyleSheet);
|
1999-02-03 22:38:16 +03:00
|
|
|
NS_IMETHOD StyleSheetRemoved(nsIDocument *aDocument,
|
|
|
|
nsIStyleSheet* aStyleSheet);
|
1998-11-17 05:14:38 +03:00
|
|
|
NS_IMETHOD StyleSheetDisabledStateChanged(nsIDocument *aDocument,
|
|
|
|
nsIStyleSheet* aStyleSheet,
|
|
|
|
PRBool aDisabled);
|
1998-11-26 04:34:53 +03:00
|
|
|
NS_IMETHOD StyleRuleChanged(nsIDocument *aDocument,
|
|
|
|
nsIStyleSheet* aStyleSheet,
|
|
|
|
nsIStyleRule* aStyleRule,
|
|
|
|
PRInt32 aHint);
|
|
|
|
NS_IMETHOD StyleRuleAdded(nsIDocument *aDocument,
|
|
|
|
nsIStyleSheet* aStyleSheet,
|
|
|
|
nsIStyleRule* aStyleRule);
|
|
|
|
NS_IMETHOD StyleRuleRemoved(nsIDocument *aDocument,
|
|
|
|
nsIStyleSheet* aStyleSheet,
|
|
|
|
nsIStyleRule* aStyleRule);
|
1998-07-23 03:32:19 +04:00
|
|
|
NS_IMETHOD DocumentWillBeDestroyed(nsIDocument *aDocument);
|
1998-04-14 00:24:54 +04:00
|
|
|
|
|
|
|
// nsIPresShell
|
1998-06-03 19:46:54 +04:00
|
|
|
NS_IMETHOD Init(nsIDocument* aDocument,
|
|
|
|
nsIPresContext* aPresContext,
|
|
|
|
nsIViewManager* aViewManager,
|
|
|
|
nsIStyleSet* aStyleSet);
|
1999-02-12 20:45:58 +03:00
|
|
|
NS_IMETHOD GetDocument(nsIDocument** aResult);
|
|
|
|
NS_IMETHOD GetPresContext(nsIPresContext** aResult);
|
|
|
|
NS_IMETHOD GetViewManager(nsIViewManager** aResult);
|
|
|
|
NS_IMETHOD GetStyleSet(nsIStyleSet** aResult);
|
1999-01-23 10:03:46 +03:00
|
|
|
NS_IMETHOD GetActiveAlternateStyleSheet(nsString& aSheetTitle);
|
|
|
|
NS_IMETHOD SelectAlternateStyleSheet(const nsString& aSheetTitle);
|
|
|
|
NS_IMETHOD ListAlternateStyleSheets(nsStringArray& aTitleList);
|
1999-02-12 20:45:58 +03:00
|
|
|
NS_IMETHOD GetSelection(nsIDOMSelection** aSelection);
|
1998-05-09 07:22:41 +04:00
|
|
|
NS_IMETHOD EnterReflowLock();
|
|
|
|
NS_IMETHOD ExitReflowLock();
|
1998-12-29 07:56:31 +03:00
|
|
|
NS_IMETHOD BeginObservingDocument();
|
|
|
|
NS_IMETHOD EndObservingDocument();
|
1998-09-10 23:32:14 +04:00
|
|
|
NS_IMETHOD InitialReflow(nscoord aWidth, nscoord aHeight);
|
1998-08-28 06:54:06 +04:00
|
|
|
NS_IMETHOD ResizeReflow(nscoord aWidth, nscoord aHeight);
|
1998-11-06 19:16:01 +03:00
|
|
|
NS_IMETHOD StyleChangeReflow();
|
1999-02-12 20:45:58 +03:00
|
|
|
NS_IMETHOD GetRootFrame(nsIFrame** aFrame) const;
|
|
|
|
NS_IMETHOD GetPageSequenceFrame(nsIPageSequenceFrame** aResult) const;
|
|
|
|
NS_IMETHOD GetPrimaryFrameFor(nsIContent* aContent,
|
|
|
|
nsIFrame** aPrimaryFrame) const;
|
1999-02-11 02:21:22 +03:00
|
|
|
NS_IMETHOD GetLayoutObjectFor(nsIContent* aContent,
|
|
|
|
nsISupports** aResult) const;
|
1998-12-29 06:38:16 +03:00
|
|
|
NS_IMETHOD GetPlaceholderFrameFor(nsIFrame* aFrame,
|
1999-02-12 20:45:58 +03:00
|
|
|
nsIFrame** aPlaceholderFrame) const;
|
1998-12-29 06:38:16 +03:00
|
|
|
NS_IMETHOD SetPlaceholderFrameFor(nsIFrame* aFrame,
|
|
|
|
nsIFrame* aPlaceholderFrame);
|
1998-12-29 07:56:31 +03:00
|
|
|
NS_IMETHOD AppendReflowCommand(nsIReflowCommand* aReflowCommand);
|
|
|
|
NS_IMETHOD ProcessReflowCommands();
|
1999-02-12 20:45:58 +03:00
|
|
|
NS_IMETHOD ClearFrameRefs(nsIFrame* aFrame);
|
|
|
|
NS_IMETHOD CreateRenderingContext(nsIFrame *aFrame,
|
|
|
|
nsIRenderingContext** aContext);
|
1999-02-05 21:25:29 +03:00
|
|
|
NS_IMETHOD CantRenderReplacedElement(nsIPresContext* aPresContext,
|
|
|
|
nsIFrame* aFrame);
|
1999-02-12 08:39:33 +03:00
|
|
|
NS_IMETHOD GoToAnchor(const nsString& aAnchorName) const;
|
1998-08-28 06:54:06 +04:00
|
|
|
|
|
|
|
//nsIViewObserver interface
|
|
|
|
|
|
|
|
NS_IMETHOD Paint(nsIView *aView,
|
|
|
|
nsIRenderingContext& aRenderingContext,
|
|
|
|
const nsRect& aDirtyRect);
|
|
|
|
NS_IMETHOD HandleEvent(nsIView* aView,
|
|
|
|
nsGUIEvent* aEvent,
|
|
|
|
nsEventStatus& aEventStatus);
|
|
|
|
NS_IMETHOD Scrolled(nsIView *aView);
|
|
|
|
NS_IMETHOD ResizeReflow(nsIView *aView, nscoord aWidth, nscoord aHeight);
|
|
|
|
|
1998-12-14 21:34:14 +03:00
|
|
|
//nsIFocusTracker interface
|
1999-01-25 04:48:01 +03:00
|
|
|
NS_IMETHOD SetFocus(nsIFrame *aFrame, nsIFrame *aAnchorFrame);
|
1998-12-14 21:34:14 +03:00
|
|
|
|
1999-01-25 04:48:01 +03:00
|
|
|
NS_IMETHOD GetFocus(nsIFrame **aFrame, nsIFrame **aAnchorFrame);
|
1999-02-05 21:25:29 +03:00
|
|
|
|
|
|
|
// implementation
|
|
|
|
void HandleCantRenderReplacedElementEvent(nsIFrame* aFrame);
|
|
|
|
|
1998-04-14 00:24:54 +04:00
|
|
|
protected:
|
1999-02-12 20:45:58 +03:00
|
|
|
virtual ~PresShell();
|
1998-04-14 00:24:54 +04:00
|
|
|
|
1998-11-26 04:34:53 +03:00
|
|
|
nsresult ReconstructFrames(void);
|
|
|
|
|
1998-07-13 23:49:42 +04:00
|
|
|
#ifdef NS_DEBUG
|
|
|
|
void VerifyIncrementalReflow();
|
1998-11-26 21:11:02 +03:00
|
|
|
PRBool mInVerifyReflow;
|
1998-07-13 23:49:42 +04:00
|
|
|
#endif
|
1998-05-20 20:24:54 +04:00
|
|
|
|
1998-04-14 00:24:54 +04:00
|
|
|
nsIDocument* mDocument;
|
|
|
|
nsIPresContext* mPresContext;
|
|
|
|
nsIStyleSet* mStyleSet;
|
|
|
|
nsIFrame* mRootFrame;
|
|
|
|
nsIViewManager* mViewManager;
|
|
|
|
PRUint32 mUpdateCount;
|
|
|
|
nsVoidArray mReflowCommands;
|
1998-05-09 07:22:41 +04:00
|
|
|
PRUint32 mReflowLockCount;
|
1998-11-18 08:25:26 +03:00
|
|
|
PRBool mIsDestroying;
|
1998-11-21 03:19:36 +03:00
|
|
|
nsIFrame* mCurrentEventFrame;
|
1998-12-08 21:26:06 +03:00
|
|
|
nsIFrame* mFocusEventFrame; //keeps track of which frame has focus.
|
1998-12-14 21:34:14 +03:00
|
|
|
nsIFrame* mAnchorEventFrame; //keeps track of which frame has focus.
|
1999-02-12 03:02:56 +03:00
|
|
|
|
|
|
|
nsCOMPtr<nsIFrameSelection> mSelection;
|
|
|
|
nsCOMPtr<nsICaret> mCaret;
|
|
|
|
|
|
|
|
FrameHashTable* mPlaceholderMap;
|
1998-04-14 00:24:54 +04:00
|
|
|
};
|
|
|
|
|
1998-07-13 23:49:42 +04:00
|
|
|
#ifdef NS_DEBUG
|
|
|
|
/**
|
|
|
|
* Note: the log module is created during library initialization which
|
|
|
|
* means that you cannot perform logging before then.
|
|
|
|
*/
|
|
|
|
static PRLogModuleInfo* gLogModule = PR_NewLogModule("verifyreflow");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static PRBool gVerifyReflow = PRBool(0x55);
|
1998-11-25 21:41:02 +03:00
|
|
|
static PRBool gVerifyReflowAll;
|
1998-07-13 23:49:42 +04:00
|
|
|
|
|
|
|
NS_LAYOUT PRBool
|
|
|
|
nsIPresShell::GetVerifyReflowEnable()
|
|
|
|
{
|
|
|
|
#ifdef NS_DEBUG
|
|
|
|
if (gVerifyReflow == PRBool(0x55)) {
|
|
|
|
gVerifyReflow = 0 != gLogModule->level;
|
1998-11-25 21:41:02 +03:00
|
|
|
if (gLogModule->level > 1) {
|
|
|
|
gVerifyReflowAll = PR_TRUE;
|
|
|
|
}
|
|
|
|
printf("Note: verifyreflow is %sabled",
|
1998-07-13 23:49:42 +04:00
|
|
|
gVerifyReflow ? "en" : "dis");
|
1998-11-25 21:41:02 +03:00
|
|
|
if (gVerifyReflowAll) {
|
|
|
|
printf(" (diff all enabled)\n");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
printf("\n");
|
|
|
|
}
|
1998-07-13 23:49:42 +04:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
return gVerifyReflow;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_LAYOUT void
|
|
|
|
nsIPresShell::SetVerifyReflowEnable(PRBool aEnabled)
|
|
|
|
{
|
|
|
|
gVerifyReflow = aEnabled;
|
|
|
|
}
|
|
|
|
|
1998-04-14 00:24:54 +04:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
1998-07-13 23:49:42 +04:00
|
|
|
NS_LAYOUT nsresult
|
|
|
|
NS_NewPresShell(nsIPresShell** aInstancePtrResult)
|
|
|
|
{
|
|
|
|
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
|
|
|
|
if (nsnull == aInstancePtrResult) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
|
|
|
PresShell* it = new PresShell();
|
|
|
|
if (nsnull == it) {
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
|
|
|
return it->QueryInterface(kIPresShellIID, (void **) aInstancePtrResult);
|
|
|
|
}
|
|
|
|
|
1998-04-14 00:24:54 +04:00
|
|
|
PresShell::PresShell()
|
|
|
|
{
|
1998-11-18 08:25:26 +03:00
|
|
|
//XXX joki 11/17 - temporary event hack.
|
|
|
|
mIsDestroying = PR_FALSE;
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
|
1998-09-15 00:46:42 +04:00
|
|
|
#ifdef NS_DEBUG
|
|
|
|
// for debugging only
|
|
|
|
nsrefcnt PresShell::AddRef(void)
|
|
|
|
{
|
1999-02-12 20:45:58 +03:00
|
|
|
if (gsNoisyRefs) {
|
|
|
|
printf("PresShell: AddRef: %p, cnt = %d \n",this, mRefCnt+1);
|
|
|
|
}
|
1998-09-15 00:46:42 +04:00
|
|
|
return ++mRefCnt;
|
|
|
|
}
|
|
|
|
|
|
|
|
// for debugging only
|
|
|
|
nsrefcnt PresShell::Release(void)
|
|
|
|
{
|
1999-02-12 20:45:58 +03:00
|
|
|
if (gsNoisyRefs) {
|
|
|
|
printf("PresShell Release: %p, cnt = %d \n",this, mRefCnt-1);
|
|
|
|
}
|
1998-09-15 00:46:42 +04:00
|
|
|
if (--mRefCnt == 0) {
|
1999-02-12 20:45:58 +03:00
|
|
|
if (gsNoisyRefs) {
|
|
|
|
printf("PresShell Delete: %p, \n",this);
|
|
|
|
}
|
1998-09-15 00:46:42 +04:00
|
|
|
delete this;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return mRefCnt;
|
|
|
|
}
|
|
|
|
#else
|
1998-09-12 23:33:48 +04:00
|
|
|
NS_IMPL_ADDREF(PresShell)
|
|
|
|
NS_IMPL_RELEASE(PresShell)
|
1998-09-15 00:46:42 +04:00
|
|
|
#endif
|
1998-04-14 00:24:54 +04:00
|
|
|
|
1998-05-09 07:22:41 +04:00
|
|
|
nsresult
|
|
|
|
PresShell::QueryInterface(const nsIID& aIID, void** aInstancePtr)
|
1998-04-14 00:24:54 +04:00
|
|
|
{
|
|
|
|
if (aIID.Equals(kIPresShellIID)) {
|
1998-09-12 23:33:48 +04:00
|
|
|
nsIPresShell* tmp = this;
|
|
|
|
*aInstancePtr = (void*) tmp;
|
|
|
|
NS_ADDREF_THIS();
|
1998-04-14 00:24:54 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
if (aIID.Equals(kIDocumentObserverIID)) {
|
1998-09-12 23:33:48 +04:00
|
|
|
nsIDocumentObserver* tmp = this;
|
|
|
|
*aInstancePtr = (void*) tmp;
|
|
|
|
NS_ADDREF_THIS();
|
1998-04-14 00:24:54 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
1998-08-28 06:54:06 +04:00
|
|
|
if (aIID.Equals(kIViewObserverIID)) {
|
1998-09-12 23:33:48 +04:00
|
|
|
nsIViewObserver* tmp = this;
|
|
|
|
*aInstancePtr = (void*) tmp;
|
|
|
|
NS_ADDREF_THIS();
|
1998-08-28 06:54:06 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
1998-12-14 21:34:14 +03:00
|
|
|
if (aIID.Equals(kIFocusTrackerIID)) {
|
|
|
|
nsIFocusTracker* tmp = this;
|
|
|
|
*aInstancePtr = (void*) tmp;
|
|
|
|
NS_ADDREF_THIS();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
1998-04-14 00:24:54 +04:00
|
|
|
if (aIID.Equals(kISupportsIID)) {
|
1998-09-12 23:33:48 +04:00
|
|
|
nsIPresShell* tmp = this;
|
|
|
|
nsISupports* tmp2 = tmp;
|
|
|
|
*aInstancePtr = (void*) tmp2;
|
|
|
|
NS_ADDREF_THIS();
|
1998-04-14 00:24:54 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
return NS_NOINTERFACE;
|
|
|
|
}
|
|
|
|
|
|
|
|
PresShell::~PresShell()
|
|
|
|
{
|
1998-08-06 23:52:48 +04:00
|
|
|
mRefCnt = 99;/* XXX hack! get around re-entrancy bugs */
|
1998-11-18 08:25:26 +03:00
|
|
|
mIsDestroying = PR_TRUE;
|
1998-04-14 00:24:54 +04:00
|
|
|
if (nsnull != mRootFrame) {
|
1998-08-28 06:54:06 +04:00
|
|
|
mRootFrame->DeleteFrame(*mPresContext);
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
NS_IF_RELEASE(mViewManager);
|
1998-08-09 11:43:22 +04:00
|
|
|
//Release mPresContext after mViewManager
|
|
|
|
NS_IF_RELEASE(mPresContext);
|
1998-04-14 00:24:54 +04:00
|
|
|
NS_IF_RELEASE(mStyleSet);
|
1998-09-23 21:16:51 +04:00
|
|
|
if (nsnull != mDocument) {
|
|
|
|
mDocument->DeleteShell(this);
|
|
|
|
NS_RELEASE(mDocument);
|
|
|
|
}
|
1998-08-06 23:52:48 +04:00
|
|
|
mRefCnt = 0;
|
1998-12-29 06:38:16 +03:00
|
|
|
delete mPlaceholderMap;
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Initialize the presentation shell. Create view manager and style
|
|
|
|
* manager.
|
|
|
|
*/
|
1998-05-09 07:22:41 +04:00
|
|
|
nsresult
|
|
|
|
PresShell::Init(nsIDocument* aDocument,
|
|
|
|
nsIPresContext* aPresContext,
|
|
|
|
nsIViewManager* aViewManager,
|
|
|
|
nsIStyleSet* aStyleSet)
|
1998-04-14 00:24:54 +04:00
|
|
|
{
|
|
|
|
NS_PRECONDITION(nsnull != aDocument, "null ptr");
|
|
|
|
NS_PRECONDITION(nsnull != aPresContext, "null ptr");
|
|
|
|
NS_PRECONDITION(nsnull != aViewManager, "null ptr");
|
|
|
|
if ((nsnull == aDocument) || (nsnull == aPresContext) ||
|
|
|
|
(nsnull == aViewManager)) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
|
|
|
if (nsnull != mDocument) {
|
|
|
|
return NS_ERROR_ALREADY_INITIALIZED;
|
|
|
|
}
|
|
|
|
|
|
|
|
mDocument = aDocument;
|
|
|
|
NS_ADDREF(aDocument);
|
|
|
|
mViewManager = aViewManager;
|
|
|
|
NS_ADDREF(mViewManager);
|
|
|
|
|
1998-08-28 06:54:06 +04:00
|
|
|
//doesn't add a ref since we own it... MMP
|
|
|
|
mViewManager->SetViewObserver((nsIViewObserver *)this);
|
|
|
|
|
1998-04-14 00:24:54 +04:00
|
|
|
// Bind the context to the presentation shell.
|
|
|
|
mPresContext = aPresContext;
|
|
|
|
NS_ADDREF(aPresContext);
|
|
|
|
aPresContext->SetShell(this);
|
|
|
|
|
|
|
|
mStyleSet = aStyleSet;
|
|
|
|
NS_ADDREF(aStyleSet);
|
|
|
|
|
1999-02-12 02:12:28 +03:00
|
|
|
nsCOMPtr<nsIDOMSelection>domselection;
|
|
|
|
nsresult result = nsRepository::CreateInstance(kRangeListCID, nsnull,
|
|
|
|
kIDOMSelectionIID,
|
|
|
|
getter_AddRefs(domselection));
|
1998-12-14 21:34:14 +03:00
|
|
|
if (!NS_SUCCEEDED(result))
|
|
|
|
return result;
|
1999-02-12 02:12:28 +03:00
|
|
|
result = domselection->QueryInterface(kIDOMSelectionIID,
|
|
|
|
getter_AddRefs(mSelection));
|
|
|
|
if (!NS_SUCCEEDED(result))
|
|
|
|
return result;
|
|
|
|
|
1999-01-23 05:38:16 +03:00
|
|
|
// XXX This code causes the document object (and the entire content model) to be leaked...
|
1999-01-23 03:00:46 +03:00
|
|
|
#if 0
|
1999-01-22 21:58:14 +03:00
|
|
|
nsCOMPtr<nsIDOMRange>range;
|
|
|
|
if (NS_SUCCEEDED(nsRepository::CreateInstance(kCRangeCID, nsnull, kIDOMRangeIID, getter_AddRefs(range)))){ //create an irange
|
|
|
|
nsCOMPtr<nsIDocument>doc(GetDocument());
|
|
|
|
nsCOMPtr<nsIDOMDocument>domDoc(doc);
|
|
|
|
if (domDoc){
|
|
|
|
nsCOMPtr<nsIDOMElement> domElement;
|
|
|
|
if (NS_SUCCEEDED(domDoc->GetDocumentElement(getter_AddRefs(domElement)))) {//get the first element from the dom
|
|
|
|
nsCOMPtr<nsIDOMNode>domNode(domElement);
|
|
|
|
if (domNode) {//get the node interface for the range object
|
1998-12-14 21:34:14 +03:00
|
|
|
range->SetStart(domNode,0);
|
|
|
|
range->SetEnd(domNode,0);
|
1999-01-22 21:58:14 +03:00
|
|
|
nsCOMPtr<nsISupports>rangeISupports(range);
|
|
|
|
if (rangeISupports) {
|
1998-12-14 21:34:14 +03:00
|
|
|
selection->AddItem(rangeISupports);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1999-02-12 03:02:56 +03:00
|
|
|
|
1999-01-23 03:00:46 +03:00
|
|
|
#endif
|
1999-02-12 03:02:56 +03:00
|
|
|
|
|
|
|
// Important: this has to happen after the selection has been set up
|
|
|
|
#ifdef SHOW_CARET
|
|
|
|
nsCaretProperties *caretProperties = NewCaretProperties();
|
|
|
|
|
|
|
|
// make the caret
|
|
|
|
nsresult err = NS_NewCaret(getter_AddRefs(mCaret));
|
|
|
|
if (NS_SUCCEEDED(err))
|
|
|
|
mCaret->Init(this, caretProperties);
|
|
|
|
|
|
|
|
delete caretProperties;
|
|
|
|
caretProperties = nsnull;
|
|
|
|
#endif
|
|
|
|
|
1998-04-14 00:24:54 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-02-12 20:45:58 +03:00
|
|
|
NS_IMETHODIMP
|
1998-05-09 07:22:41 +04:00
|
|
|
PresShell::EnterReflowLock()
|
|
|
|
{
|
|
|
|
++mReflowLockCount;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-02-12 20:45:58 +03:00
|
|
|
NS_IMETHODIMP
|
1998-05-09 07:22:41 +04:00
|
|
|
PresShell::ExitReflowLock()
|
|
|
|
{
|
1998-05-12 05:30:40 +04:00
|
|
|
PRUint32 newReflowLockCount = mReflowLockCount - 1;
|
|
|
|
if (newReflowLockCount == 0) {
|
|
|
|
ProcessReflowCommands();
|
1998-05-09 07:22:41 +04:00
|
|
|
}
|
1998-05-12 05:30:40 +04:00
|
|
|
mReflowLockCount = newReflowLockCount;
|
1998-05-09 07:22:41 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-02-12 20:45:58 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::GetDocument(nsIDocument** aResult)
|
1998-04-14 00:24:54 +04:00
|
|
|
{
|
1999-02-12 20:45:58 +03:00
|
|
|
NS_PRECONDITION(nsnull != aResult, "null ptr");
|
|
|
|
if (nsnull == aResult) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
|
|
|
*aResult = mDocument;
|
1998-04-14 00:24:54 +04:00
|
|
|
NS_IF_ADDREF(mDocument);
|
1999-02-12 20:45:58 +03:00
|
|
|
return NS_OK;
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
|
1999-02-12 20:45:58 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::GetPresContext(nsIPresContext** aResult)
|
1998-04-14 00:24:54 +04:00
|
|
|
{
|
1999-02-12 20:45:58 +03:00
|
|
|
NS_PRECONDITION(nsnull != aResult, "null ptr");
|
|
|
|
if (nsnull == aResult) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
|
|
|
*aResult = mPresContext;
|
1998-04-14 00:24:54 +04:00
|
|
|
NS_IF_ADDREF(mPresContext);
|
1999-02-12 20:45:58 +03:00
|
|
|
return NS_OK;
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
|
1999-02-12 20:45:58 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::GetViewManager(nsIViewManager** aResult)
|
1998-04-14 00:24:54 +04:00
|
|
|
{
|
1999-02-12 20:45:58 +03:00
|
|
|
NS_PRECONDITION(nsnull != aResult, "null ptr");
|
|
|
|
if (nsnull == aResult) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
|
|
|
*aResult = mViewManager;
|
1998-04-14 00:24:54 +04:00
|
|
|
NS_IF_ADDREF(mViewManager);
|
1999-02-12 20:45:58 +03:00
|
|
|
return NS_OK;
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
|
1999-02-12 20:45:58 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::GetStyleSet(nsIStyleSet** aResult)
|
1998-04-14 00:24:54 +04:00
|
|
|
{
|
1999-02-12 20:45:58 +03:00
|
|
|
NS_PRECONDITION(nsnull != aResult, "null ptr");
|
|
|
|
if (nsnull == aResult) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
|
|
|
*aResult = mStyleSet;
|
1998-04-14 00:24:54 +04:00
|
|
|
NS_IF_ADDREF(mStyleSet);
|
1999-02-12 20:45:58 +03:00
|
|
|
return NS_OK;
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
|
1999-01-23 10:03:46 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::GetActiveAlternateStyleSheet(nsString& aSheetTitle)
|
|
|
|
{ // first non-html sheet in style set that has title
|
|
|
|
if (nsnull != mStyleSet) {
|
|
|
|
PRInt32 count = mStyleSet->GetNumberOfDocStyleSheets();
|
|
|
|
PRInt32 index;
|
|
|
|
nsAutoString textHtml("text/html");
|
|
|
|
for (index = 0; index < count; index++) {
|
|
|
|
nsIStyleSheet* sheet = mStyleSet->GetDocStyleSheetAt(index);
|
|
|
|
if (nsnull != sheet) {
|
|
|
|
nsAutoString type;
|
|
|
|
sheet->GetType(type);
|
|
|
|
if (PR_FALSE == type.Equals(textHtml)) {
|
|
|
|
nsAutoString title;
|
|
|
|
sheet->GetTitle(title);
|
|
|
|
if (0 < title.Length()) {
|
|
|
|
aSheetTitle = title;
|
|
|
|
index = count; // stop looking
|
|
|
|
}
|
|
|
|
}
|
|
|
|
NS_RELEASE(sheet);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::SelectAlternateStyleSheet(const nsString& aSheetTitle)
|
|
|
|
{
|
|
|
|
if ((nsnull != mDocument) && (nsnull != mStyleSet)) {
|
|
|
|
PRInt32 count = mDocument->GetNumberOfStyleSheets();
|
|
|
|
PRInt32 index;
|
|
|
|
nsAutoString textHtml("text/html");
|
|
|
|
for (index = 0; index < count; index++) {
|
|
|
|
nsIStyleSheet* sheet = mDocument->GetStyleSheetAt(index);
|
|
|
|
if (nsnull != sheet) {
|
|
|
|
nsAutoString type;
|
|
|
|
sheet->GetType(type);
|
|
|
|
if (PR_FALSE == type.Equals(textHtml)) {
|
|
|
|
nsAutoString title;
|
|
|
|
sheet->GetTitle(title);
|
|
|
|
if (0 < title.Length()) {
|
|
|
|
if (title.EqualsIgnoreCase(aSheetTitle)) {
|
|
|
|
mStyleSet->AddDocStyleSheet(sheet, mDocument);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
mStyleSet->RemoveDocStyleSheet(sheet);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
NS_RELEASE(sheet);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ReconstructFrames();
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::ListAlternateStyleSheets(nsStringArray& aTitleList)
|
|
|
|
{
|
|
|
|
if (nsnull != mDocument) {
|
|
|
|
PRInt32 count = mDocument->GetNumberOfStyleSheets();
|
|
|
|
PRInt32 index;
|
|
|
|
nsAutoString textHtml("text/html");
|
|
|
|
for (index = 0; index < count; index++) {
|
|
|
|
nsIStyleSheet* sheet = mDocument->GetStyleSheetAt(index);
|
|
|
|
if (nsnull != sheet) {
|
|
|
|
nsAutoString type;
|
|
|
|
sheet->GetType(type);
|
|
|
|
if (PR_FALSE == type.Equals(textHtml)) {
|
|
|
|
nsAutoString title;
|
|
|
|
sheet->GetTitle(title);
|
|
|
|
if (0 < title.Length()) {
|
|
|
|
if (-1 == aTitleList.IndexOfIgnoreCase(title)) {
|
|
|
|
aTitleList.AppendString(title);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
NS_RELEASE(sheet);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
1998-12-08 21:26:06 +03:00
|
|
|
|
1999-02-12 20:45:58 +03:00
|
|
|
NS_IMETHODIMP
|
1999-02-12 02:12:28 +03:00
|
|
|
PresShell::GetSelection(nsIDOMSelection **aSelection)
|
1998-12-08 21:26:06 +03:00
|
|
|
{
|
|
|
|
if (!aSelection || !mSelection)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
1999-02-12 02:12:28 +03:00
|
|
|
return mSelection->QueryInterface(kIDOMSelectionIID,(void **)aSelection);
|
1998-12-08 21:26:06 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
1998-04-14 00:24:54 +04:00
|
|
|
// Make shell be a document observer
|
1998-12-29 07:56:31 +03:00
|
|
|
NS_IMETHODIMP
|
1998-05-09 07:22:41 +04:00
|
|
|
PresShell::BeginObservingDocument()
|
1998-04-14 00:24:54 +04:00
|
|
|
{
|
|
|
|
if (nsnull != mDocument) {
|
|
|
|
mDocument->AddObserver(this);
|
|
|
|
}
|
1998-12-29 07:56:31 +03:00
|
|
|
return NS_OK;
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Make shell stop being a document observer
|
1998-12-29 07:56:31 +03:00
|
|
|
NS_IMETHODIMP
|
1998-05-09 07:22:41 +04:00
|
|
|
PresShell::EndObservingDocument()
|
1998-04-14 00:24:54 +04:00
|
|
|
{
|
|
|
|
if (nsnull != mDocument) {
|
|
|
|
mDocument->RemoveObserver(this);
|
|
|
|
}
|
1998-12-29 07:56:31 +03:00
|
|
|
return NS_OK;
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
|
1998-08-28 06:54:06 +04:00
|
|
|
NS_IMETHODIMP
|
1998-09-10 23:32:14 +04:00
|
|
|
PresShell::InitialReflow(nscoord aWidth, nscoord aHeight)
|
1998-04-14 00:24:54 +04:00
|
|
|
{
|
1999-02-03 22:38:16 +03:00
|
|
|
nsIContent* root = nsnull;
|
1998-09-10 23:32:14 +04:00
|
|
|
|
1998-06-03 19:46:54 +04:00
|
|
|
EnterReflowLock();
|
|
|
|
|
1998-04-14 00:24:54 +04:00
|
|
|
if (nsnull != mPresContext) {
|
|
|
|
nsRect r(0, 0, aWidth, aHeight);
|
|
|
|
mPresContext->SetVisibleArea(r);
|
|
|
|
}
|
|
|
|
|
1999-02-03 22:38:16 +03:00
|
|
|
if (nsnull != mDocument) {
|
|
|
|
root = mDocument->GetRootContent();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nsnull != root) {
|
|
|
|
if (nsnull == mRootFrame) {
|
|
|
|
// Have style sheet processor construct a frame for the
|
|
|
|
// precursors to the root content object's frame
|
|
|
|
mStyleSet->ConstructRootFrame(mPresContext, root, mRootFrame);
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
1999-02-03 22:38:16 +03:00
|
|
|
|
|
|
|
// Have the style sheet processor construct frame for the root
|
|
|
|
// content object down
|
|
|
|
mStyleSet->ContentInserted(mPresContext, nsnull, root, 0);
|
|
|
|
NS_RELEASE(root);
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
|
1998-09-10 23:32:14 +04:00
|
|
|
if (nsnull != mRootFrame) {
|
|
|
|
// Kick off a top-down reflow
|
|
|
|
NS_FRAME_LOG(NS_FRAME_TRACE_CALLS,
|
|
|
|
("enter nsPresShell::InitialReflow: %d,%d", aWidth, aHeight));
|
|
|
|
#ifdef NS_DEBUG
|
|
|
|
if (nsIFrame::GetVerifyTreeEnable()) {
|
|
|
|
mRootFrame->VerifyTree();
|
|
|
|
}
|
|
|
|
#endif
|
1998-10-02 05:12:39 +04:00
|
|
|
nsRect bounds;
|
1998-09-10 23:32:14 +04:00
|
|
|
mPresContext->GetVisibleArea(bounds);
|
1998-10-02 05:12:39 +04:00
|
|
|
nsSize maxSize(bounds.width, bounds.height);
|
|
|
|
nsHTMLReflowMetrics desiredSize(nsnull);
|
|
|
|
nsReflowStatus status;
|
|
|
|
nsIHTMLReflow* htmlReflow;
|
|
|
|
nsIRenderingContext* rcx = nsnull;
|
|
|
|
|
1999-02-12 20:45:58 +03:00
|
|
|
CreateRenderingContext(mRootFrame, &rcx);
|
1998-10-02 05:12:39 +04:00
|
|
|
|
1998-10-12 18:48:02 +04:00
|
|
|
nsHTMLReflowState reflowState(*mPresContext, mRootFrame,
|
|
|
|
eReflowReason_Initial, maxSize, rcx);
|
1998-10-01 08:46:11 +04:00
|
|
|
|
|
|
|
if (NS_OK == mRootFrame->QueryInterface(kIHTMLReflowIID, (void**)&htmlReflow)) {
|
|
|
|
htmlReflow->Reflow(*mPresContext, desiredSize, reflowState, status);
|
|
|
|
mRootFrame->SizeTo(desiredSize.width, desiredSize.height);
|
1998-09-10 23:32:14 +04:00
|
|
|
#ifdef NS_DEBUG
|
1998-10-01 08:46:11 +04:00
|
|
|
if (nsIFrame::GetVerifyTreeEnable()) {
|
|
|
|
mRootFrame->VerifyTree();
|
|
|
|
}
|
1998-09-10 23:32:14 +04:00
|
|
|
#endif
|
1998-10-01 08:46:11 +04:00
|
|
|
}
|
1998-10-02 05:12:39 +04:00
|
|
|
NS_IF_RELEASE(rcx);
|
1998-09-10 23:32:14 +04:00
|
|
|
NS_FRAME_LOG(NS_FRAME_TRACE_CALLS, ("exit nsPresShell::InitialReflow"));
|
|
|
|
}
|
|
|
|
|
|
|
|
ExitReflowLock();
|
|
|
|
|
|
|
|
return NS_OK; //XXX this needs to be real. MMP
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::ResizeReflow(nscoord aWidth, nscoord aHeight)
|
|
|
|
{
|
|
|
|
EnterReflowLock();
|
|
|
|
|
|
|
|
if (nsnull != mPresContext) {
|
|
|
|
nsRect r(0, 0, aWidth, aHeight);
|
|
|
|
mPresContext->SetVisibleArea(r);
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we don't have a root frame yet, that means we haven't had our initial
|
|
|
|
// reflow...
|
1998-04-14 00:24:54 +04:00
|
|
|
if (nsnull != mRootFrame) {
|
|
|
|
// Kick off a top-down reflow
|
1998-05-20 20:24:54 +04:00
|
|
|
NS_FRAME_LOG(NS_FRAME_TRACE_CALLS,
|
|
|
|
("enter nsPresShell::ResizeReflow: %d,%d", aWidth, aHeight));
|
1998-04-14 00:24:54 +04:00
|
|
|
#ifdef NS_DEBUG
|
1998-05-20 20:24:54 +04:00
|
|
|
if (nsIFrame::GetVerifyTreeEnable()) {
|
|
|
|
mRootFrame->VerifyTree();
|
|
|
|
}
|
1998-04-14 00:24:54 +04:00
|
|
|
#endif
|
1998-10-02 05:12:39 +04:00
|
|
|
nsRect bounds;
|
1998-05-22 22:36:40 +04:00
|
|
|
mPresContext->GetVisibleArea(bounds);
|
1998-10-02 05:12:39 +04:00
|
|
|
nsSize maxSize(bounds.width, bounds.height);
|
|
|
|
nsHTMLReflowMetrics desiredSize(nsnull);
|
|
|
|
nsReflowStatus status;
|
|
|
|
nsIHTMLReflow* htmlReflow;
|
|
|
|
nsIRenderingContext* rcx = nsnull;
|
|
|
|
|
1999-02-12 20:45:58 +03:00
|
|
|
CreateRenderingContext(mRootFrame, &rcx);
|
1998-10-02 05:12:39 +04:00
|
|
|
|
1998-10-12 18:48:02 +04:00
|
|
|
nsHTMLReflowState reflowState(*mPresContext, mRootFrame,
|
|
|
|
eReflowReason_Resize, maxSize, rcx);
|
1998-10-01 08:46:11 +04:00
|
|
|
|
|
|
|
if (NS_OK == mRootFrame->QueryInterface(kIHTMLReflowIID, (void**)&htmlReflow)) {
|
|
|
|
htmlReflow->Reflow(*mPresContext, desiredSize, reflowState, status);
|
|
|
|
mRootFrame->SizeTo(desiredSize.width, desiredSize.height);
|
1998-04-14 00:24:54 +04:00
|
|
|
#ifdef NS_DEBUG
|
1998-10-01 08:46:11 +04:00
|
|
|
if (nsIFrame::GetVerifyTreeEnable()) {
|
|
|
|
mRootFrame->VerifyTree();
|
|
|
|
}
|
1998-04-14 00:24:54 +04:00
|
|
|
#endif
|
1998-10-01 08:46:11 +04:00
|
|
|
}
|
1998-10-02 05:12:39 +04:00
|
|
|
NS_IF_RELEASE(rcx);
|
1998-05-20 20:24:54 +04:00
|
|
|
NS_FRAME_LOG(NS_FRAME_TRACE_CALLS, ("exit nsPresShell::ResizeReflow"));
|
|
|
|
|
1999-01-22 21:58:14 +03:00
|
|
|
if (mSelection)
|
1999-01-25 04:48:01 +03:00
|
|
|
mSelection->ResetSelection(this, mRootFrame);
|
1999-01-22 21:58:14 +03:00
|
|
|
|
1998-04-14 00:24:54 +04:00
|
|
|
// XXX if debugging then we should assert that the cache is empty
|
|
|
|
} else {
|
|
|
|
#ifdef NOISY
|
|
|
|
printf("PresShell::ResizeReflow: null root frame\n");
|
|
|
|
#endif
|
|
|
|
}
|
1998-06-03 19:46:54 +04:00
|
|
|
ExitReflowLock();
|
1998-08-28 06:54:06 +04:00
|
|
|
|
|
|
|
return NS_OK; //XXX this needs to be real. MMP
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
|
1999-01-25 04:48:01 +03:00
|
|
|
//it is ok to pass null, it will simply ignore that parameter.
|
|
|
|
//if necessary we can add a clear focus, but I dont think it is a big
|
|
|
|
//deal.
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::SetFocus(nsIFrame *aFrame, nsIFrame *aAnchorFrame){
|
|
|
|
if (aFrame)
|
|
|
|
mFocusEventFrame = aFrame;
|
|
|
|
if (aAnchorFrame)
|
|
|
|
mAnchorEventFrame = aAnchorFrame;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::GetFocus(nsIFrame **aFrame, nsIFrame **aAnchorFrame){
|
|
|
|
if (!aFrame || !aAnchorFrame)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
*aFrame = mFocusEventFrame;
|
|
|
|
*aAnchorFrame = mAnchorEventFrame;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1998-11-06 19:16:01 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::StyleChangeReflow()
|
|
|
|
{
|
|
|
|
EnterReflowLock();
|
|
|
|
|
|
|
|
if (nsnull != mRootFrame) {
|
|
|
|
// Kick off a top-down reflow
|
|
|
|
NS_FRAME_LOG(NS_FRAME_TRACE_CALLS,
|
|
|
|
("enter nsPresShell::StyleChangeReflow"));
|
|
|
|
#ifdef NS_DEBUG
|
|
|
|
if (nsIFrame::GetVerifyTreeEnable()) {
|
|
|
|
mRootFrame->VerifyTree();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
nsRect bounds;
|
|
|
|
mPresContext->GetVisibleArea(bounds);
|
|
|
|
nsSize maxSize(bounds.width, bounds.height);
|
|
|
|
nsHTMLReflowMetrics desiredSize(nsnull);
|
|
|
|
nsReflowStatus status;
|
|
|
|
nsIHTMLReflow* htmlReflow;
|
|
|
|
nsIRenderingContext* rcx = nsnull;
|
|
|
|
|
1999-02-12 20:45:58 +03:00
|
|
|
CreateRenderingContext(mRootFrame, &rcx);
|
1998-11-06 19:16:01 +03:00
|
|
|
|
|
|
|
// XXX We should be using eReflowReason_StyleChange
|
|
|
|
nsHTMLReflowState reflowState(*mPresContext, mRootFrame,
|
|
|
|
eReflowReason_Resize, maxSize, rcx);
|
|
|
|
|
|
|
|
if (NS_OK == mRootFrame->QueryInterface(kIHTMLReflowIID, (void**)&htmlReflow)) {
|
|
|
|
htmlReflow->Reflow(*mPresContext, desiredSize, reflowState, status);
|
|
|
|
mRootFrame->SizeTo(desiredSize.width, desiredSize.height);
|
|
|
|
#ifdef NS_DEBUG
|
|
|
|
if (nsIFrame::GetVerifyTreeEnable()) {
|
|
|
|
mRootFrame->VerifyTree();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
NS_IF_RELEASE(rcx);
|
|
|
|
NS_FRAME_LOG(NS_FRAME_TRACE_CALLS, ("exit nsPresShell::StyleChangeReflow"));
|
|
|
|
}
|
|
|
|
|
|
|
|
ExitReflowLock();
|
|
|
|
|
|
|
|
return NS_OK; //XXX this needs to be real. MMP
|
|
|
|
}
|
|
|
|
|
1998-12-29 07:45:18 +03:00
|
|
|
NS_IMETHODIMP
|
1999-02-12 20:45:58 +03:00
|
|
|
PresShell::GetRootFrame(nsIFrame** aResult) const
|
1998-04-14 00:24:54 +04:00
|
|
|
{
|
1999-02-12 20:45:58 +03:00
|
|
|
NS_PRECONDITION(nsnull != aResult, "null ptr");
|
|
|
|
if (nsnull == aResult) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
|
|
|
*aResult = mRootFrame;
|
1998-12-29 07:45:18 +03:00
|
|
|
return NS_OK;
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
|
1998-12-07 06:43:02 +03:00
|
|
|
NS_IMETHODIMP
|
1999-02-12 20:45:58 +03:00
|
|
|
PresShell::GetPageSequenceFrame(nsIPageSequenceFrame** aResult) const
|
1998-12-07 06:43:02 +03:00
|
|
|
{
|
1999-02-12 20:45:58 +03:00
|
|
|
NS_PRECONDITION(nsnull != aResult, "null ptr");
|
|
|
|
if (nsnull == aResult) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
|
|
|
|
1998-12-07 06:43:02 +03:00
|
|
|
nsIFrame* child;
|
|
|
|
nsIPageSequenceFrame* pageSequence;
|
|
|
|
|
|
|
|
// The page sequence frame should be either the immediate child or
|
|
|
|
// its child
|
1999-02-10 05:25:01 +03:00
|
|
|
mRootFrame->FirstChild(nsnull, &child);
|
1998-12-07 06:43:02 +03:00
|
|
|
if (nsnull != child) {
|
|
|
|
if (NS_SUCCEEDED(child->QueryInterface(kIPageSequenceFrameIID, (void**)&pageSequence))) {
|
1999-02-12 20:45:58 +03:00
|
|
|
*aResult = pageSequence;
|
1998-12-07 06:43:02 +03:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-02-10 05:25:01 +03:00
|
|
|
child->FirstChild(nsnull, &child);
|
1998-12-07 06:43:02 +03:00
|
|
|
if (nsnull != child) {
|
|
|
|
if (NS_SUCCEEDED(child->QueryInterface(kIPageSequenceFrameIID, (void**)&pageSequence))) {
|
1999-02-12 20:45:58 +03:00
|
|
|
*aResult = pageSequence;
|
1998-12-07 06:43:02 +03:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1999-02-12 20:45:58 +03:00
|
|
|
*aResult = nsnull;
|
1998-12-07 06:43:02 +03:00
|
|
|
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
1998-06-03 19:46:54 +04:00
|
|
|
NS_IMETHODIMP
|
1998-07-23 03:32:19 +04:00
|
|
|
PresShell::BeginUpdate(nsIDocument *aDocument)
|
1998-04-14 00:24:54 +04:00
|
|
|
{
|
|
|
|
mUpdateCount++;
|
1998-06-03 19:46:54 +04:00
|
|
|
return NS_OK;
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
|
1998-06-03 19:46:54 +04:00
|
|
|
NS_IMETHODIMP
|
1998-07-23 03:32:19 +04:00
|
|
|
PresShell::EndUpdate(nsIDocument *aDocument)
|
1998-04-14 00:24:54 +04:00
|
|
|
{
|
|
|
|
NS_PRECONDITION(0 != mUpdateCount, "too many EndUpdate's");
|
|
|
|
if (--mUpdateCount == 0) {
|
|
|
|
// XXX do something here
|
|
|
|
}
|
1998-06-03 19:46:54 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1998-07-23 03:32:19 +04:00
|
|
|
PresShell::BeginLoad(nsIDocument *aDocument)
|
1998-06-03 19:46:54 +04:00
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1998-07-23 03:32:19 +04:00
|
|
|
PresShell::EndLoad(nsIDocument *aDocument)
|
1998-06-03 19:46:54 +04:00
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1998-07-23 03:32:19 +04:00
|
|
|
PresShell::BeginReflow(nsIDocument *aDocument, nsIPresShell* aShell)
|
1998-06-03 19:46:54 +04:00
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1998-07-23 03:32:19 +04:00
|
|
|
PresShell::EndReflow(nsIDocument *aDocument, nsIPresShell* aShell)
|
1998-06-03 19:46:54 +04:00
|
|
|
{
|
|
|
|
return NS_OK;
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
|
1998-12-29 07:56:31 +03:00
|
|
|
NS_IMETHODIMP
|
1998-06-09 08:51:44 +04:00
|
|
|
PresShell::AppendReflowCommand(nsIReflowCommand* aReflowCommand)
|
1998-04-14 00:24:54 +04:00
|
|
|
{
|
1998-11-26 21:11:02 +03:00
|
|
|
#ifdef NS_DEBUG
|
|
|
|
if (mInVerifyReflow) {
|
1998-12-29 07:56:31 +03:00
|
|
|
return NS_OK;
|
1998-11-26 21:11:02 +03:00
|
|
|
}
|
|
|
|
#endif
|
1998-06-09 08:51:44 +04:00
|
|
|
NS_ADDREF(aReflowCommand);
|
1998-12-29 07:56:31 +03:00
|
|
|
return mReflowCommands.AppendElement(aReflowCommand);
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
|
1998-12-29 07:56:31 +03:00
|
|
|
NS_IMETHODIMP
|
1998-05-09 07:22:41 +04:00
|
|
|
PresShell::ProcessReflowCommands()
|
1998-04-14 00:24:54 +04:00
|
|
|
{
|
|
|
|
if (0 != mReflowCommands.Count()) {
|
1998-10-02 05:12:39 +04:00
|
|
|
nsHTMLReflowMetrics desiredSize(nsnull);
|
|
|
|
nsIRenderingContext* rcx;
|
|
|
|
|
1999-02-12 20:45:58 +03:00
|
|
|
CreateRenderingContext(mRootFrame, &rcx);
|
1998-04-14 00:24:54 +04:00
|
|
|
|
|
|
|
while (0 != mReflowCommands.Count()) {
|
1998-06-09 08:51:44 +04:00
|
|
|
nsIReflowCommand* rc = (nsIReflowCommand*) mReflowCommands.ElementAt(0);
|
1998-04-14 00:24:54 +04:00
|
|
|
mReflowCommands.RemoveElementAt(0);
|
|
|
|
|
|
|
|
// Dispatch the reflow command
|
1998-04-17 05:41:24 +04:00
|
|
|
nsSize maxSize;
|
|
|
|
mRootFrame->GetSize(maxSize);
|
1998-06-09 08:51:44 +04:00
|
|
|
#ifdef NS_DEBUG
|
1998-07-03 01:26:00 +04:00
|
|
|
nsIReflowCommand::ReflowType type;
|
1998-06-09 08:51:44 +04:00
|
|
|
rc->GetType(type);
|
1998-07-03 01:26:00 +04:00
|
|
|
NS_FRAME_LOG(NS_FRAME_TRACE_CALLS,
|
|
|
|
("PresShell::ProcessReflowCommands: begin reflow command type=%d",
|
|
|
|
type));
|
1998-06-09 08:51:44 +04:00
|
|
|
#endif
|
1998-10-02 05:12:39 +04:00
|
|
|
rc->Dispatch(*mPresContext, desiredSize, maxSize, *rcx);
|
1998-06-09 08:51:44 +04:00
|
|
|
NS_RELEASE(rc);
|
1998-07-03 01:26:00 +04:00
|
|
|
NS_FRAME_LOG(NS_FRAME_TRACE_CALLS,
|
|
|
|
("PresShell::ProcessReflowCommands: end reflow command"));
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
1998-11-26 21:11:02 +03:00
|
|
|
NS_IF_RELEASE(rcx);
|
1998-04-14 00:24:54 +04:00
|
|
|
|
|
|
|
// Place and size the root frame
|
|
|
|
mRootFrame->SizeTo(desiredSize.width, desiredSize.height);
|
1998-11-26 21:11:02 +03:00
|
|
|
|
1998-04-14 00:24:54 +04:00
|
|
|
#ifdef NS_DEBUG
|
1998-05-20 20:24:54 +04:00
|
|
|
if (nsIFrame::GetVerifyTreeEnable()) {
|
|
|
|
mRootFrame->VerifyTree();
|
|
|
|
}
|
1998-07-13 23:49:42 +04:00
|
|
|
if (GetVerifyReflowEnable()) {
|
1998-12-12 22:21:05 +03:00
|
|
|
// First synchronously render what we have so far so that we can
|
|
|
|
// see it.
|
|
|
|
if (gVerifyReflowAll) {
|
|
|
|
printf("Before verify-reflow\n");
|
|
|
|
nsIView* rootView;
|
|
|
|
mViewManager->GetRootView(rootView);
|
|
|
|
mViewManager->UpdateView(rootView, nsnull, NS_VMREFRESH_IMMEDIATE);
|
|
|
|
PR_Sleep(PR_SecondsToInterval(3));
|
|
|
|
}
|
|
|
|
|
1998-11-26 21:11:02 +03:00
|
|
|
mInVerifyReflow = PR_TRUE;
|
1998-07-13 23:49:42 +04:00
|
|
|
VerifyIncrementalReflow();
|
1998-11-26 21:11:02 +03:00
|
|
|
mInVerifyReflow = PR_FALSE;
|
1998-12-12 22:21:05 +03:00
|
|
|
if (gVerifyReflowAll) {
|
|
|
|
printf("After verify-reflow\n");
|
|
|
|
}
|
1998-11-26 21:11:02 +03:00
|
|
|
|
|
|
|
if (0 != mReflowCommands.Count()) {
|
|
|
|
printf("XXX yikes!\n");
|
|
|
|
}
|
1998-07-13 23:49:42 +04:00
|
|
|
}
|
1998-04-14 00:24:54 +04:00
|
|
|
#endif
|
1998-10-02 05:12:39 +04:00
|
|
|
}
|
1998-12-29 07:56:31 +03:00
|
|
|
|
|
|
|
return NS_OK;
|
1998-10-02 05:12:39 +04:00
|
|
|
}
|
|
|
|
|
1999-02-12 20:45:58 +03:00
|
|
|
NS_IMETHODIMP
|
1998-11-19 03:43:36 +03:00
|
|
|
PresShell::ClearFrameRefs(nsIFrame* aFrame)
|
|
|
|
{
|
|
|
|
nsIEventStateManager *manager;
|
|
|
|
if (NS_OK == mPresContext->GetEventStateManager(&manager)) {
|
|
|
|
manager->ClearFrameRefs(aFrame);
|
|
|
|
NS_RELEASE(manager);
|
|
|
|
}
|
1998-11-21 03:19:36 +03:00
|
|
|
if (aFrame == mCurrentEventFrame) {
|
|
|
|
mCurrentEventFrame = nsnull;
|
|
|
|
}
|
1998-12-08 21:26:06 +03:00
|
|
|
if (aFrame == mFocusEventFrame) {
|
|
|
|
mFocusEventFrame = nsnull;
|
|
|
|
}
|
1999-02-12 20:45:58 +03:00
|
|
|
return NS_OK;
|
1998-11-19 03:43:36 +03:00
|
|
|
}
|
|
|
|
|
1999-02-05 21:25:29 +03:00
|
|
|
NS_IMETHODIMP
|
1999-02-12 20:45:58 +03:00
|
|
|
PresShell::CreateRenderingContext(nsIFrame *aFrame,
|
|
|
|
nsIRenderingContext** aResult)
|
1998-10-02 05:12:39 +04:00
|
|
|
{
|
1999-02-12 20:45:58 +03:00
|
|
|
NS_PRECONDITION(nsnull != aResult, "null ptr");
|
|
|
|
if (nsnull == aResult) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
|
|
|
|
1998-10-02 05:12:39 +04:00
|
|
|
nsIWidget *widget = nsnull;
|
|
|
|
nsIView *view = nsnull;
|
|
|
|
nsPoint pt;
|
|
|
|
nsresult rv;
|
|
|
|
|
1999-02-10 08:38:18 +03:00
|
|
|
aFrame->GetView(&view);
|
1998-10-02 05:12:39 +04:00
|
|
|
|
|
|
|
if (nsnull == view)
|
1999-02-10 08:38:18 +03:00
|
|
|
aFrame->GetOffsetFromView(pt, &view);
|
1998-10-02 05:12:39 +04:00
|
|
|
|
|
|
|
while (nsnull != view)
|
|
|
|
{
|
|
|
|
view->GetWidget(widget);
|
|
|
|
|
|
|
|
if (nsnull != widget)
|
|
|
|
{
|
|
|
|
NS_RELEASE(widget);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
view->GetParent(view);
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
1998-10-02 05:12:39 +04:00
|
|
|
|
1999-02-12 20:45:58 +03:00
|
|
|
nsCOMPtr<nsIDeviceContext> dx;
|
1998-11-14 04:52:27 +03:00
|
|
|
|
1999-02-12 20:45:58 +03:00
|
|
|
nsIRenderingContext* result = nsnull;
|
|
|
|
rv = mPresContext->GetDeviceContext(getter_AddRefs(dx));
|
1999-02-12 21:41:26 +03:00
|
|
|
if (NS_SUCCEEDED(rv) && dx) {
|
1999-02-12 20:45:58 +03:00
|
|
|
if (nsnull != view) {
|
|
|
|
rv = dx->CreateRenderingContext(view, result);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
rv = dx->CreateRenderingContext(result);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*aResult = result;
|
1998-10-02 05:12:39 +04:00
|
|
|
|
|
|
|
return rv;
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
|
1999-02-05 21:25:29 +03:00
|
|
|
void
|
|
|
|
PresShell::HandleCantRenderReplacedElementEvent(nsIFrame* aFrame)
|
|
|
|
{
|
|
|
|
// Double-check that we haven't deleted the frame hierarchy
|
|
|
|
// XXX If we stay with this model we approach, then we need to observe
|
|
|
|
// aFrame and if it's deleted null out the pointer in the PL event struct
|
|
|
|
if (nsnull != mRootFrame) {
|
|
|
|
mStyleSet->CantRenderReplacedElement(mPresContext, aFrame);
|
|
|
|
ProcessReflowCommands();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct CantRenderReplacedElementEvent : public PLEvent {
|
|
|
|
CantRenderReplacedElementEvent(PresShell* aShell, nsIFrame* aFrame);
|
|
|
|
~CantRenderReplacedElementEvent();
|
|
|
|
|
|
|
|
PresShell* mShell;
|
|
|
|
nsIFrame* mFrame;
|
|
|
|
};
|
|
|
|
|
|
|
|
static void PR_CALLBACK
|
|
|
|
HandlePLEvent(CantRenderReplacedElementEvent* aEvent)
|
|
|
|
{
|
|
|
|
aEvent->mShell->HandleCantRenderReplacedElementEvent(aEvent->mFrame);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void PR_CALLBACK
|
|
|
|
DestroyPLEvent(CantRenderReplacedElementEvent* aEvent)
|
|
|
|
{
|
|
|
|
delete aEvent;
|
|
|
|
}
|
|
|
|
|
|
|
|
CantRenderReplacedElementEvent::CantRenderReplacedElementEvent(PresShell* aShell,
|
|
|
|
nsIFrame* aFrame)
|
|
|
|
{
|
|
|
|
mShell = aShell;
|
|
|
|
NS_ADDREF(mShell);
|
|
|
|
mFrame = aFrame;
|
|
|
|
PL_InitEvent(this, nsnull, (PLHandleEventProc)::HandlePLEvent,
|
|
|
|
(PLDestroyEventProc)::DestroyPLEvent);
|
|
|
|
}
|
|
|
|
|
|
|
|
CantRenderReplacedElementEvent::~CantRenderReplacedElementEvent()
|
|
|
|
{
|
|
|
|
NS_RELEASE(mShell);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::CantRenderReplacedElement(nsIPresContext* aPresContext,
|
|
|
|
nsIFrame* aFrame)
|
|
|
|
{
|
1999-02-06 06:41:14 +03:00
|
|
|
#ifdef _WIN32
|
1999-02-05 21:25:29 +03:00
|
|
|
nsIEventQueueService* eventService;
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
// Notify the style set, but post the notification so it doesn't happen
|
|
|
|
// now
|
|
|
|
rv = nsServiceManager::GetService(kEventQueueServiceCID,
|
|
|
|
kIEventQueueServiceIID,
|
|
|
|
(nsISupports **)&eventService);
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
PLEventQueue* eventQueue;
|
|
|
|
rv = eventService->GetThreadEventQueue(PR_GetCurrentThread(),
|
|
|
|
&eventQueue);
|
|
|
|
nsServiceManager::ReleaseService(kEventQueueServiceCID, eventService);
|
|
|
|
|
|
|
|
if (nsnull != eventQueue) {
|
|
|
|
CantRenderReplacedElementEvent* ev;
|
|
|
|
|
|
|
|
ev = new CantRenderReplacedElementEvent(this, aFrame);
|
|
|
|
PL_PostEvent(eventQueue, ev);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return rv;
|
1999-02-06 07:26:30 +03:00
|
|
|
#else
|
|
|
|
return NS_OK;
|
|
|
|
#endif
|
1999-02-05 21:25:29 +03:00
|
|
|
}
|
|
|
|
|
1999-02-12 08:39:33 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::GoToAnchor(const nsString& aAnchorName) const
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMHTMLDocument> htmlDoc;
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
if (NS_SUCCEEDED(mDocument->QueryInterface(kIDOMHTMLDocumentIID,
|
|
|
|
getter_AddRefs(htmlDoc)))) {
|
|
|
|
// Find the element with the specified id
|
|
|
|
nsCOMPtr<nsIDOMElement> element;
|
|
|
|
rv = htmlDoc->GetElementById(aAnchorName, getter_AddRefs(element));
|
|
|
|
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
// Get the nsIContent interface, because that's what we need to
|
|
|
|
// get the primary frame
|
|
|
|
nsCOMPtr<nsIContent> content;
|
|
|
|
|
|
|
|
if (NS_SUCCEEDED(element->QueryInterface(kIContentIID, getter_AddRefs(content)))) {
|
|
|
|
nsIFrame* frame;
|
|
|
|
|
|
|
|
// Get the primary frame
|
1999-02-12 20:45:58 +03:00
|
|
|
if (NS_SUCCEEDED(GetPrimaryFrameFor(content, &frame))) {
|
1999-02-12 08:39:33 +03:00
|
|
|
if (nsnull != mViewManager) {
|
|
|
|
nsIView* viewportView = nsnull;
|
|
|
|
mViewManager->GetRootView(viewportView);
|
|
|
|
if (nsnull != viewportView) {
|
|
|
|
nsIView* viewportScrollView;
|
|
|
|
viewportView->GetChild(0, viewportScrollView);
|
|
|
|
|
|
|
|
// Try and get the nsIScrollableView interface
|
|
|
|
nsIScrollableView* scrollingView;
|
|
|
|
if (NS_SUCCEEDED(viewportScrollView->QueryInterface(kIScrollableViewIID,
|
|
|
|
(void**)&scrollingView))) {
|
|
|
|
// Determine the offset for the given frame relative to the
|
|
|
|
// scrolled view
|
|
|
|
nsIView* scrolledView;
|
|
|
|
nsPoint offset;
|
|
|
|
nsIView* view;
|
|
|
|
|
|
|
|
scrollingView->GetScrolledView(scrolledView);
|
|
|
|
frame->GetOffsetFromView(offset, &view);
|
|
|
|
|
|
|
|
// XXX If view != scrolledView, then there is a scrolled frame,
|
|
|
|
// e.g., a DIV with 'overflow' of 'scroll', somewhere in the middle,
|
|
|
|
// or maybe an absolutely positioned element that has a view. We
|
|
|
|
// need to handle these cases...
|
|
|
|
scrollingView->ScrollTo(0, offset.y, NS_VMREFRESH_IMMEDIATE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
rv = NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
rv = NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1998-06-03 19:46:54 +04:00
|
|
|
NS_IMETHODIMP
|
1998-07-23 03:32:19 +04:00
|
|
|
PresShell::ContentChanged(nsIDocument *aDocument,
|
|
|
|
nsIContent* aContent,
|
1998-05-09 07:22:41 +04:00
|
|
|
nsISupports* aSubContent)
|
1998-04-14 00:24:54 +04:00
|
|
|
{
|
1998-05-06 20:28:55 +04:00
|
|
|
NS_PRECONDITION(nsnull != mRootFrame, "null root frame");
|
1998-05-30 05:31:04 +04:00
|
|
|
|
|
|
|
EnterReflowLock();
|
1998-09-30 03:46:05 +04:00
|
|
|
nsresult rv = mStyleSet->ContentChanged(mPresContext, aContent, aSubContent);
|
1998-05-30 05:31:04 +04:00
|
|
|
ExitReflowLock();
|
1999-01-29 21:57:56 +03:00
|
|
|
if (mSelection)
|
|
|
|
mSelection->ResetSelection(this, mRootFrame);
|
|
|
|
|
1998-09-30 03:46:05 +04:00
|
|
|
return rv;
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
|
1998-09-18 23:53:27 +04:00
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::AttributeChanged(nsIDocument *aDocument,
|
|
|
|
nsIContent* aContent,
|
1998-09-30 03:46:05 +04:00
|
|
|
nsIAtom* aAttribute,
|
|
|
|
PRInt32 aHint)
|
1998-09-18 23:53:27 +04:00
|
|
|
{
|
|
|
|
NS_PRECONDITION(nsnull != mRootFrame, "null root frame");
|
|
|
|
|
|
|
|
EnterReflowLock();
|
1998-09-30 03:46:05 +04:00
|
|
|
nsresult rv = mStyleSet->AttributeChanged(mPresContext, aContent, aAttribute, aHint);
|
1998-09-18 23:53:27 +04:00
|
|
|
ExitReflowLock();
|
1998-09-30 03:46:05 +04:00
|
|
|
return rv;
|
1998-09-18 23:53:27 +04:00
|
|
|
}
|
|
|
|
|
1998-06-03 19:46:54 +04:00
|
|
|
NS_IMETHODIMP
|
1998-07-23 03:32:19 +04:00
|
|
|
PresShell::ContentAppended(nsIDocument *aDocument,
|
1998-09-10 23:32:14 +04:00
|
|
|
nsIContent* aContainer,
|
|
|
|
PRInt32 aNewIndexInContainer)
|
1998-04-14 00:24:54 +04:00
|
|
|
{
|
1998-06-03 19:46:54 +04:00
|
|
|
EnterReflowLock();
|
1998-09-30 03:46:05 +04:00
|
|
|
nsresult rv = mStyleSet->ContentAppended(mPresContext, aContainer, aNewIndexInContainer);
|
1998-06-03 19:46:54 +04:00
|
|
|
ExitReflowLock();
|
1998-09-10 23:32:14 +04:00
|
|
|
return rv;
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
|
1998-06-03 19:46:54 +04:00
|
|
|
NS_IMETHODIMP
|
1998-09-10 23:32:14 +04:00
|
|
|
PresShell::ContentInserted(nsIDocument* aDocument,
|
|
|
|
nsIContent* aContainer,
|
|
|
|
nsIContent* aChild,
|
|
|
|
PRInt32 aIndexInContainer)
|
1998-04-14 00:24:54 +04:00
|
|
|
{
|
1998-09-10 23:32:14 +04:00
|
|
|
EnterReflowLock();
|
1998-09-30 03:46:05 +04:00
|
|
|
nsresult rv = mStyleSet->ContentInserted(mPresContext, aContainer, aChild, aIndexInContainer);
|
1998-09-10 23:32:14 +04:00
|
|
|
ExitReflowLock();
|
|
|
|
return rv;
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
|
1998-06-03 19:46:54 +04:00
|
|
|
NS_IMETHODIMP
|
1998-09-10 23:32:14 +04:00
|
|
|
PresShell::ContentReplaced(nsIDocument* aDocument,
|
|
|
|
nsIContent* aContainer,
|
|
|
|
nsIContent* aOldChild,
|
|
|
|
nsIContent* aNewChild,
|
|
|
|
PRInt32 aIndexInContainer)
|
1998-04-14 00:24:54 +04:00
|
|
|
{
|
1998-09-10 23:32:14 +04:00
|
|
|
EnterReflowLock();
|
1998-09-30 03:46:05 +04:00
|
|
|
nsresult rv = mStyleSet->ContentReplaced(mPresContext, aContainer, aOldChild,
|
|
|
|
aNewChild, aIndexInContainer);
|
1998-09-10 23:32:14 +04:00
|
|
|
ExitReflowLock();
|
|
|
|
return rv;
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
|
1998-06-03 19:46:54 +04:00
|
|
|
NS_IMETHODIMP
|
1998-09-25 01:39:47 +04:00
|
|
|
PresShell::ContentRemoved(nsIDocument *aDocument,
|
|
|
|
nsIContent* aContainer,
|
|
|
|
nsIContent* aChild,
|
|
|
|
PRInt32 aIndexInContainer)
|
1998-04-14 00:24:54 +04:00
|
|
|
{
|
1998-09-25 09:13:06 +04:00
|
|
|
EnterReflowLock();
|
1998-09-30 03:46:05 +04:00
|
|
|
nsresult rv = mStyleSet->ContentRemoved(mPresContext, aContainer,
|
|
|
|
aChild, aIndexInContainer);
|
1998-09-25 09:13:06 +04:00
|
|
|
ExitReflowLock();
|
1998-09-10 23:32:14 +04:00
|
|
|
return rv;
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
|
1998-11-26 04:34:53 +03:00
|
|
|
nsresult
|
|
|
|
PresShell::ReconstructFrames(void)
|
1998-11-17 05:14:38 +03:00
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
if (nsnull != mRootFrame) {
|
|
|
|
if (nsnull != mDocument) {
|
1999-01-26 03:05:21 +03:00
|
|
|
nsIContent* rootContent = mDocument->GetRootContent();
|
|
|
|
if (nsnull != rootContent) {
|
|
|
|
nsIFrame* docElementFrame;
|
|
|
|
nsIFrame* parentFrame;
|
1998-11-17 05:14:38 +03:00
|
|
|
|
1999-01-26 03:05:21 +03:00
|
|
|
// Get the frame that corresponds to the document element
|
1999-02-12 20:45:58 +03:00
|
|
|
GetPrimaryFrameFor(rootContent, &docElementFrame);
|
1999-01-26 03:05:21 +03:00
|
|
|
if (nsnull != docElementFrame) {
|
1999-02-10 04:36:30 +03:00
|
|
|
docElementFrame->GetParent(&parentFrame);
|
1999-01-26 03:05:21 +03:00
|
|
|
|
|
|
|
EnterReflowLock();
|
|
|
|
rv = mStyleSet->ReconstructFrames(mPresContext, rootContent,
|
|
|
|
parentFrame, docElementFrame);
|
|
|
|
ExitReflowLock();
|
|
|
|
NS_RELEASE(rootContent);
|
|
|
|
}
|
1998-11-17 05:14:38 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1998-11-26 04:34:53 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::StyleSheetAdded(nsIDocument *aDocument,
|
|
|
|
nsIStyleSheet* aStyleSheet)
|
|
|
|
{
|
|
|
|
return ReconstructFrames();
|
|
|
|
}
|
|
|
|
|
1999-02-03 22:38:16 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::StyleSheetRemoved(nsIDocument *aDocument,
|
|
|
|
nsIStyleSheet* aStyleSheet)
|
|
|
|
{
|
|
|
|
return ReconstructFrames();
|
|
|
|
}
|
|
|
|
|
1998-11-26 04:34:53 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::StyleSheetDisabledStateChanged(nsIDocument *aDocument,
|
|
|
|
nsIStyleSheet* aStyleSheet,
|
|
|
|
PRBool aDisabled)
|
|
|
|
{
|
|
|
|
return ReconstructFrames();
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::StyleRuleChanged(nsIDocument *aDocument,
|
|
|
|
nsIStyleSheet* aStyleSheet,
|
|
|
|
nsIStyleRule* aStyleRule,
|
|
|
|
PRInt32 aHint)
|
|
|
|
{
|
|
|
|
EnterReflowLock();
|
|
|
|
nsresult rv = mStyleSet->StyleRuleChanged(mPresContext, aStyleSheet,
|
|
|
|
aStyleRule, aHint);
|
|
|
|
ExitReflowLock();
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::StyleRuleAdded(nsIDocument *aDocument,
|
|
|
|
nsIStyleSheet* aStyleSheet,
|
|
|
|
nsIStyleRule* aStyleRule)
|
|
|
|
{
|
|
|
|
EnterReflowLock();
|
|
|
|
nsresult rv = mStyleSet->StyleRuleAdded(mPresContext, aStyleSheet, aStyleRule);
|
|
|
|
ExitReflowLock();
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::StyleRuleRemoved(nsIDocument *aDocument,
|
|
|
|
nsIStyleSheet* aStyleSheet,
|
|
|
|
nsIStyleRule* aStyleRule)
|
|
|
|
{
|
|
|
|
EnterReflowLock();
|
|
|
|
nsresult rv = mStyleSet->StyleRuleRemoved(mPresContext, aStyleSheet, aStyleRule);
|
|
|
|
ExitReflowLock();
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1998-07-23 03:32:19 +04:00
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::DocumentWillBeDestroyed(nsIDocument *aDocument)
|
1998-04-14 00:24:54 +04:00
|
|
|
{
|
1998-06-03 19:46:54 +04:00
|
|
|
return NS_OK;
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
|
1998-05-09 07:22:41 +04:00
|
|
|
static nsIFrame*
|
|
|
|
FindFrameWithContent(nsIFrame* aFrame, nsIContent* aContent)
|
1998-04-14 00:24:54 +04:00
|
|
|
{
|
1998-04-17 05:41:24 +04:00
|
|
|
nsIContent* frameContent;
|
|
|
|
|
1999-02-10 03:42:56 +03:00
|
|
|
aFrame->GetContent(&frameContent);
|
1998-04-14 00:24:54 +04:00
|
|
|
if (frameContent == aContent) {
|
1999-01-07 07:47:43 +03:00
|
|
|
nsIStyleContext* styleContext;
|
|
|
|
nsIAtom* pseudoTag;
|
|
|
|
PRBool isPlaceholder = PR_FALSE;
|
|
|
|
|
|
|
|
// If it's a placeholder frame, then ignore it and keep looking for the
|
|
|
|
// primary frame
|
1999-02-10 03:42:56 +03:00
|
|
|
aFrame->GetStyleContext(&styleContext);
|
1999-01-07 07:47:43 +03:00
|
|
|
styleContext->GetPseudoType(pseudoTag);
|
|
|
|
if (pseudoTag == nsHTMLAtoms::placeholderPseudo) {
|
|
|
|
isPlaceholder = PR_TRUE;
|
|
|
|
}
|
|
|
|
NS_RELEASE(styleContext);
|
|
|
|
NS_IF_RELEASE(pseudoTag);
|
|
|
|
|
|
|
|
if (!isPlaceholder) {
|
1999-01-13 03:38:29 +03:00
|
|
|
NS_IF_RELEASE(frameContent);
|
1998-10-16 00:26:54 +04:00
|
|
|
return aFrame;
|
|
|
|
}
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
1998-11-13 02:03:35 +03:00
|
|
|
NS_IF_RELEASE(frameContent);
|
1998-04-14 00:24:54 +04:00
|
|
|
|
1998-11-17 04:03:28 +03:00
|
|
|
// Search for the frame in each child list that aFrame supports
|
|
|
|
nsIAtom* listName = nsnull;
|
|
|
|
PRInt32 listIndex = 0;
|
|
|
|
do {
|
|
|
|
nsIFrame* kid;
|
1999-02-10 05:25:01 +03:00
|
|
|
aFrame->FirstChild(listName, &kid);
|
1998-11-17 04:03:28 +03:00
|
|
|
while (nsnull != kid) {
|
|
|
|
nsIFrame* result = FindFrameWithContent(kid, aContent);
|
|
|
|
if (nsnull != result) {
|
|
|
|
NS_IF_RELEASE(listName);
|
|
|
|
return result;
|
|
|
|
}
|
1999-02-10 09:13:38 +03:00
|
|
|
kid->GetNextSibling(&kid);
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
1998-11-17 04:03:28 +03:00
|
|
|
NS_IF_RELEASE(listName);
|
1999-02-10 05:25:01 +03:00
|
|
|
aFrame->GetAdditionalChildListName(listIndex++, &listName);
|
1998-11-17 04:03:28 +03:00
|
|
|
} while(nsnull != listName);
|
1998-04-14 00:24:54 +04:00
|
|
|
|
|
|
|
return nsnull;
|
|
|
|
}
|
|
|
|
|
1998-12-29 07:45:18 +03:00
|
|
|
NS_IMETHODIMP
|
1999-02-12 20:45:58 +03:00
|
|
|
PresShell::GetPrimaryFrameFor(nsIContent* aContent,
|
|
|
|
nsIFrame** aResult) const
|
1998-04-14 00:24:54 +04:00
|
|
|
{
|
1999-02-12 20:45:58 +03:00
|
|
|
NS_PRECONDITION(nsnull != aResult, "null ptr");
|
|
|
|
if (nsnull == aResult) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
|
|
|
|
1998-04-14 00:24:54 +04:00
|
|
|
// For the time being do a brute force depth-first search of
|
|
|
|
// the frame tree
|
1999-02-12 20:45:58 +03:00
|
|
|
*aResult = ::FindFrameWithContent(mRootFrame, aContent);
|
1998-12-29 07:45:18 +03:00
|
|
|
return NS_OK;
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
|
1999-02-11 02:21:22 +03:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::GetLayoutObjectFor(nsIContent* aContent,
|
|
|
|
nsISupports** aResult) const
|
|
|
|
{
|
|
|
|
nsresult result = NS_ERROR_NULL_POINTER;
|
|
|
|
if ((nsnull!=aResult) && (nsnull!=aContent))
|
|
|
|
{
|
|
|
|
*aResult = nsnull;
|
|
|
|
nsIFrame *primaryFrame=nsnull;
|
1999-02-12 20:45:58 +03:00
|
|
|
result = GetPrimaryFrameFor(aContent, &primaryFrame);
|
1999-02-11 02:21:22 +03:00
|
|
|
if ((NS_SUCCEEDED(result)) && (nsnull!=primaryFrame))
|
|
|
|
{
|
|
|
|
result = primaryFrame->QueryInterface(kISupportsIID, (void**)aResult);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1998-12-29 06:38:16 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::GetPlaceholderFrameFor(nsIFrame* aFrame,
|
1999-02-12 20:45:58 +03:00
|
|
|
nsIFrame** aResult) const
|
1998-12-29 06:38:16 +03:00
|
|
|
{
|
1999-02-12 20:45:58 +03:00
|
|
|
NS_PRECONDITION(nsnull != aResult, "null ptr");
|
1998-12-29 06:38:16 +03:00
|
|
|
NS_PRECONDITION(nsnull != aFrame, "no frame");
|
1999-02-12 20:45:58 +03:00
|
|
|
if ((nsnull == aResult) || (nsnull == aFrame)) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
1998-12-29 06:38:16 +03:00
|
|
|
|
|
|
|
if (nsnull == mPlaceholderMap) {
|
1999-02-12 20:45:58 +03:00
|
|
|
*aResult = nsnull;
|
1998-12-29 06:38:16 +03:00
|
|
|
} else {
|
1999-02-12 20:45:58 +03:00
|
|
|
*aResult = (nsIFrame*) mPlaceholderMap->Get(aFrame);
|
1998-12-29 06:38:16 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::SetPlaceholderFrameFor(nsIFrame* aFrame,
|
|
|
|
nsIFrame* aPlaceholderFrame)
|
|
|
|
{
|
|
|
|
NS_PRECONDITION(nsnull != aFrame, "no frame");
|
|
|
|
|
|
|
|
if (nsnull == mPlaceholderMap) {
|
|
|
|
mPlaceholderMap = new FrameHashTable;
|
|
|
|
if (nsnull == mPlaceholderMap) {
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-02-06 20:10:42 +03:00
|
|
|
if (nsnull == aPlaceholderFrame) {
|
|
|
|
mPlaceholderMap->Remove(aFrame);
|
|
|
|
} else {
|
|
|
|
mPlaceholderMap->Put(aFrame, (void*)aPlaceholderFrame);
|
|
|
|
}
|
1998-12-29 06:38:16 +03:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1998-08-28 06:54:06 +04:00
|
|
|
//nsIViewObserver
|
|
|
|
|
1998-12-18 18:54:23 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::Paint(nsIView *aView,
|
|
|
|
nsIRenderingContext& aRenderingContext,
|
|
|
|
const nsRect& aDirtyRect)
|
1998-08-28 06:54:06 +04:00
|
|
|
{
|
1998-08-30 23:16:11 +04:00
|
|
|
void* clientData;
|
|
|
|
nsIFrame* frame;
|
1998-10-31 01:06:14 +03:00
|
|
|
nsresult rv = NS_OK;
|
1998-08-28 06:54:06 +04:00
|
|
|
|
|
|
|
NS_ASSERTION(!(nsnull == aView), "null view");
|
|
|
|
|
1998-08-30 23:16:11 +04:00
|
|
|
aView->GetClientData(clientData);
|
|
|
|
frame = (nsIFrame *)clientData;
|
1998-08-28 06:54:06 +04:00
|
|
|
|
1998-10-31 01:06:14 +03:00
|
|
|
if (nsnull != frame) {
|
1998-12-18 18:54:23 +03:00
|
|
|
rv = frame->Paint(*mPresContext, aRenderingContext, aDirtyRect,
|
|
|
|
eFramePaintLayer_Underlay);
|
|
|
|
rv = frame->Paint(*mPresContext, aRenderingContext, aDirtyRect,
|
|
|
|
eFramePaintLayer_Content);
|
|
|
|
rv = frame->Paint(*mPresContext, aRenderingContext, aDirtyRect,
|
|
|
|
eFramePaintLayer_Overlay);
|
1998-10-31 01:06:14 +03:00
|
|
|
#ifdef NS_DEBUG
|
|
|
|
// Draw a border around the frame
|
|
|
|
if (nsIFrame::GetShowFrameBorders()) {
|
|
|
|
nsRect r;
|
|
|
|
frame->GetRect(r);
|
|
|
|
aRenderingContext.SetColor(NS_RGB(0,0,255));
|
|
|
|
aRenderingContext.DrawRect(0, 0, r.width, r.height);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
1998-08-28 06:54:06 +04:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1998-12-18 18:54:23 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::HandleEvent(nsIView *aView,
|
|
|
|
nsGUIEvent* aEvent,
|
|
|
|
nsEventStatus& aEventStatus)
|
1998-08-28 06:54:06 +04:00
|
|
|
{
|
1998-08-30 23:16:11 +04:00
|
|
|
void* clientData;
|
|
|
|
nsIFrame* frame;
|
1998-11-21 03:19:36 +03:00
|
|
|
nsresult rv = NS_OK;
|
1998-08-28 06:54:06 +04:00
|
|
|
|
|
|
|
NS_ASSERTION(!(nsnull == aView), "null view");
|
|
|
|
|
1998-11-19 03:43:36 +03:00
|
|
|
if (mIsDestroying || mReflowLockCount > 0) {
|
1998-11-18 08:25:26 +03:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1998-08-30 23:16:11 +04:00
|
|
|
aView->GetClientData(clientData);
|
|
|
|
frame = (nsIFrame *)clientData;
|
1998-08-28 06:54:06 +04:00
|
|
|
|
1998-11-18 08:25:26 +03:00
|
|
|
if (nsnull != frame) {
|
1998-12-08 21:26:06 +03:00
|
|
|
if (mSelection && mFocusEventFrame && aEvent->eventStructType == NS_KEY_EVENT)
|
|
|
|
{
|
1999-02-02 03:23:40 +03:00
|
|
|
mSelection->HandleKeyEvent((nsIFocusTracker *)this, aEvent, mFocusEventFrame);
|
1998-12-08 21:26:06 +03:00
|
|
|
}
|
1998-11-21 03:19:36 +03:00
|
|
|
frame->GetFrameForPoint(aEvent->point, &mCurrentEventFrame);
|
|
|
|
if (nsnull != mCurrentEventFrame) {
|
1998-11-18 08:25:26 +03:00
|
|
|
//Once we have the targetFrame, handle the event in this order
|
|
|
|
nsIEventStateManager *manager;
|
|
|
|
if (NS_OK == mPresContext->GetEventStateManager(&manager)) {
|
1998-11-24 10:46:58 +03:00
|
|
|
//1. Give event to event manager for pre event state changes and generation of synthetic events.
|
|
|
|
rv = manager->PreHandleEvent(*mPresContext, aEvent, mCurrentEventFrame, aEventStatus);
|
1998-11-18 08:25:26 +03:00
|
|
|
|
|
|
|
//2. Give event to the DOM for third party and JS use.
|
1998-11-21 03:19:36 +03:00
|
|
|
if (nsnull != mCurrentEventFrame && NS_OK == rv) {
|
|
|
|
nsIContent* targetContent;
|
1999-02-10 03:42:56 +03:00
|
|
|
if (NS_OK == mCurrentEventFrame->GetContent(&targetContent) && nsnull != targetContent) {
|
1998-11-21 03:19:36 +03:00
|
|
|
rv = targetContent->HandleDOMEvent(*mPresContext, (nsEvent*)aEvent, nsnull,
|
|
|
|
DOM_EVENT_INIT, aEventStatus);
|
|
|
|
NS_RELEASE(targetContent);
|
|
|
|
}
|
|
|
|
|
1998-11-24 10:46:58 +03:00
|
|
|
//3. Give event to the Frames for browser default processing.
|
|
|
|
// XXX The event isn't translated into the local coordinate space
|
|
|
|
// of the frame...
|
|
|
|
if (nsnull != mCurrentEventFrame && NS_OK == rv) {
|
|
|
|
rv = mCurrentEventFrame->HandleEvent(*mPresContext, aEvent, aEventStatus);
|
|
|
|
|
|
|
|
//4. Give event to event manager for post event state changes and generation of synthetic events.
|
|
|
|
if (nsnull != mCurrentEventFrame && NS_OK == rv) {
|
|
|
|
rv = manager->PostHandleEvent(*mPresContext, aEvent, mCurrentEventFrame, aEventStatus);
|
|
|
|
}
|
|
|
|
}
|
1998-11-18 08:25:26 +03:00
|
|
|
}
|
|
|
|
NS_RELEASE(manager);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1998-11-21 03:19:36 +03:00
|
|
|
else {
|
1998-08-28 06:54:06 +04:00
|
|
|
rv = NS_OK;
|
1998-11-21 03:19:36 +03:00
|
|
|
}
|
1998-08-28 06:54:06 +04:00
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1998-12-18 18:54:23 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::Scrolled(nsIView *aView)
|
1998-08-28 06:54:06 +04:00
|
|
|
{
|
1998-08-30 23:16:11 +04:00
|
|
|
void* clientData;
|
|
|
|
nsIFrame* frame;
|
1998-08-28 06:54:06 +04:00
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
NS_ASSERTION(!(nsnull == aView), "null view");
|
|
|
|
|
1998-08-30 23:16:11 +04:00
|
|
|
aView->GetClientData(clientData);
|
|
|
|
frame = (nsIFrame *)clientData;
|
1998-08-28 06:54:06 +04:00
|
|
|
|
|
|
|
if (nsnull != frame)
|
1998-09-06 00:57:57 +04:00
|
|
|
rv = frame->Scrolled(aView);
|
1998-08-28 06:54:06 +04:00
|
|
|
else
|
|
|
|
rv = NS_OK;
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1998-12-18 18:54:23 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::ResizeReflow(nsIView *aView, nscoord aWidth, nscoord aHeight)
|
1998-08-28 06:54:06 +04:00
|
|
|
{
|
|
|
|
return ResizeReflow(aWidth, aHeight);
|
|
|
|
}
|
|
|
|
|
1998-07-13 23:49:42 +04:00
|
|
|
#ifdef NS_DEBUG
|
|
|
|
#include "nsViewsCID.h"
|
|
|
|
#include "nsWidgetsCID.h"
|
|
|
|
#include "nsIScrollableView.h"
|
|
|
|
#include "nsIDeviceContext.h"
|
|
|
|
#include "nsIURL.h"
|
|
|
|
|
|
|
|
static NS_DEFINE_IID(kViewManagerCID, NS_VIEW_MANAGER_CID);
|
|
|
|
static NS_DEFINE_IID(kIViewManagerIID, NS_IVIEWMANAGER_IID);
|
|
|
|
static NS_DEFINE_IID(kScrollingViewCID, NS_SCROLLING_VIEW_CID);
|
|
|
|
static NS_DEFINE_IID(kIViewIID, NS_IVIEW_IID);
|
|
|
|
static NS_DEFINE_IID(kScrollViewIID, NS_ISCROLLABLEVIEW_IID);
|
|
|
|
static NS_DEFINE_IID(kWidgetCID, NS_CHILD_CID);
|
|
|
|
|
|
|
|
static void
|
1998-11-25 21:41:02 +03:00
|
|
|
LogVerifyMessage(nsIFrame* k1, nsIFrame* k2, const char* aMsg)
|
|
|
|
{
|
|
|
|
printf("verifyreflow: ");
|
|
|
|
nsAutoString name;
|
|
|
|
if (nsnull != k1) {
|
|
|
|
k1->GetFrameName(name);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
name = "(null)";
|
|
|
|
}
|
|
|
|
fputs(name, stdout);
|
|
|
|
|
|
|
|
printf(" != ");
|
|
|
|
|
|
|
|
if (nsnull != k2) {
|
|
|
|
k2->GetFrameName(name);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
name = "(null)";
|
|
|
|
}
|
|
|
|
fputs(name, stdout);
|
|
|
|
|
|
|
|
printf(" %s", aMsg);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
LogVerifyMessage(nsIFrame* k1, nsIFrame* k2, const char* aMsg,
|
|
|
|
const nsRect& r1, const nsRect& r2)
|
1998-07-13 23:49:42 +04:00
|
|
|
{
|
|
|
|
printf("verifyreflow: ");
|
1998-11-19 20:22:29 +03:00
|
|
|
nsAutoString name;
|
|
|
|
k1->GetFrameName(name);
|
|
|
|
fputs(name, stdout);
|
1998-07-13 23:49:42 +04:00
|
|
|
stdout << r1;
|
1998-11-25 21:41:02 +03:00
|
|
|
|
1998-07-13 23:49:42 +04:00
|
|
|
printf(" != ");
|
1998-11-25 21:41:02 +03:00
|
|
|
|
1998-11-19 20:22:29 +03:00
|
|
|
k2->GetFrameName(name);
|
|
|
|
fputs(name, stdout);
|
1998-07-13 23:49:42 +04:00
|
|
|
stdout << r2;
|
1998-11-25 21:41:02 +03:00
|
|
|
|
|
|
|
printf(" %s\n", aMsg);
|
1998-12-12 22:21:05 +03:00
|
|
|
if (gVerifyReflowAll) {
|
1999-01-16 03:00:50 +03:00
|
|
|
k1->List(stdout, 1);
|
|
|
|
k2->List(stdout, 1);
|
1998-12-12 22:21:05 +03:00
|
|
|
}
|
1998-07-13 23:49:42 +04:00
|
|
|
}
|
1998-04-14 00:24:54 +04:00
|
|
|
|
1998-07-13 23:49:42 +04:00
|
|
|
static void
|
|
|
|
CompareTrees(nsIFrame* aA, nsIFrame* aB)
|
1998-04-14 00:24:54 +04:00
|
|
|
{
|
1998-11-25 21:41:02 +03:00
|
|
|
PRBool whoops = PR_FALSE;
|
|
|
|
nsIAtom* listName = nsnull;
|
|
|
|
PRInt32 listIndex = 0;
|
|
|
|
do {
|
|
|
|
nsIFrame* k1, *k2;
|
1999-02-10 05:25:01 +03:00
|
|
|
aA->FirstChild(listName, &k1);
|
|
|
|
aB->FirstChild(listName, &k2);
|
1998-11-25 21:41:02 +03:00
|
|
|
PRInt32 l1 = nsContainerFrame::LengthOf(k1);
|
|
|
|
PRInt32 l2 = nsContainerFrame::LengthOf(k2);
|
|
|
|
if (l1 != l2) {
|
|
|
|
LogVerifyMessage(k1, k2, "child counts don't match: ");
|
|
|
|
printf("%d != %d\n", l1, l2);
|
|
|
|
if (!gVerifyReflowAll) {
|
|
|
|
break;
|
1998-07-13 23:49:42 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-11-25 21:41:02 +03:00
|
|
|
nsRect r1, r2;
|
|
|
|
nsIView* v1, *v2;
|
|
|
|
nsIWidget* w1, *w2;
|
|
|
|
for (;;) {
|
|
|
|
if (((nsnull == k1) && (nsnull != k2)) ||
|
|
|
|
((nsnull != k1) && (nsnull == k2))) {
|
|
|
|
LogVerifyMessage(k1, k2, "child lists are different\n");
|
|
|
|
whoops = PR_TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else if (nsnull != k1) {
|
|
|
|
// Verify that the frames are the same size
|
|
|
|
k1->GetRect(r1);
|
|
|
|
k2->GetRect(r2);
|
|
|
|
if (r1 != r2) {
|
|
|
|
LogVerifyMessage(k1, k2, "(frame rects)", r1, r2);
|
|
|
|
whoops = PR_TRUE;
|
|
|
|
}
|
1998-07-13 23:49:42 +04:00
|
|
|
|
1998-11-25 21:41:02 +03:00
|
|
|
// Make sure either both have views or neither have views; if they
|
|
|
|
// do have views, make sure the views are the same size. If the
|
|
|
|
// views have widgets, make sure they both do or neither does. If
|
|
|
|
// they do, make sure the widgets are the same size.
|
1999-02-10 08:38:18 +03:00
|
|
|
k1->GetView(&v1);
|
|
|
|
k2->GetView(&v2);
|
1998-11-25 21:41:02 +03:00
|
|
|
if (((nsnull == v1) && (nsnull != v2)) ||
|
|
|
|
((nsnull != v1) && (nsnull == v2))) {
|
|
|
|
LogVerifyMessage(k1, k2, "child views are not matched\n");
|
|
|
|
whoops = PR_TRUE;
|
|
|
|
}
|
|
|
|
else if (nsnull != v1) {
|
|
|
|
v1->GetBounds(r1);
|
|
|
|
v2->GetBounds(r2);
|
|
|
|
if (r1 != r2) {
|
|
|
|
LogVerifyMessage(k1, k2, "(view rects)", r1, r2);
|
|
|
|
whoops = PR_TRUE;
|
|
|
|
}
|
1998-07-13 23:49:42 +04:00
|
|
|
|
1998-11-25 21:41:02 +03:00
|
|
|
v1->GetWidget(w1);
|
|
|
|
v2->GetWidget(w2);
|
|
|
|
if (((nsnull == w1) && (nsnull != w2)) ||
|
|
|
|
((nsnull != w1) && (nsnull == w2))) {
|
|
|
|
LogVerifyMessage(k1, k2, "child widgets are not matched\n");
|
|
|
|
whoops = PR_TRUE;
|
|
|
|
}
|
|
|
|
else if (nsnull != w1) {
|
|
|
|
w1->GetBounds(r1);
|
|
|
|
w2->GetBounds(r2);
|
|
|
|
if (r1 != r2) {
|
|
|
|
LogVerifyMessage(k1, k2, "(widget rects)", r1, r2);
|
|
|
|
whoops = PR_TRUE;
|
|
|
|
}
|
1998-07-13 23:49:42 +04:00
|
|
|
}
|
|
|
|
}
|
1998-11-25 21:41:02 +03:00
|
|
|
if (whoops && !gVerifyReflowAll) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Compare the sub-trees too
|
|
|
|
CompareTrees(k1, k2);
|
|
|
|
|
|
|
|
// Advance to next sibling
|
1999-02-10 09:13:38 +03:00
|
|
|
k1->GetNextSibling(&k1);
|
|
|
|
k2->GetNextSibling(&k2);
|
1998-07-13 23:49:42 +04:00
|
|
|
}
|
|
|
|
else {
|
1998-11-25 21:41:02 +03:00
|
|
|
break;
|
1998-07-13 23:49:42 +04:00
|
|
|
}
|
|
|
|
}
|
1998-11-25 21:41:02 +03:00
|
|
|
if (whoops && !gVerifyReflowAll) {
|
|
|
|
break;
|
1998-07-13 23:49:42 +04:00
|
|
|
}
|
1998-11-25 21:41:02 +03:00
|
|
|
NS_IF_RELEASE(listName);
|
|
|
|
|
|
|
|
nsIAtom* listName1;
|
|
|
|
nsIAtom* listName2;
|
1999-02-10 05:25:01 +03:00
|
|
|
aA->GetAdditionalChildListName(listIndex, &listName1);
|
|
|
|
aB->GetAdditionalChildListName(listIndex, &listName2);
|
1998-11-25 21:41:02 +03:00
|
|
|
listIndex++;
|
|
|
|
if (listName1 != listName2) {
|
|
|
|
LogVerifyMessage(k1, k2, "child list names are not matched: ");
|
|
|
|
nsAutoString tmp;
|
|
|
|
if (nsnull != listName1) {
|
|
|
|
listName1->ToString(tmp);
|
|
|
|
fputs(tmp, stdout);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
fputs("(null)", stdout);
|
|
|
|
printf(" != ");
|
|
|
|
if (nsnull != listName2) {
|
|
|
|
listName2->ToString(tmp);
|
|
|
|
fputs(tmp, stdout);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
fputs("(null)", stdout);
|
|
|
|
printf("\n");
|
|
|
|
NS_IF_RELEASE(listName1);
|
|
|
|
NS_IF_RELEASE(listName2);
|
|
|
|
break;
|
1998-07-13 23:49:42 +04:00
|
|
|
}
|
1998-11-25 21:41:02 +03:00
|
|
|
NS_IF_RELEASE(listName2);
|
|
|
|
listName = listName1;
|
|
|
|
} while (listName != nsnull);
|
1998-07-13 23:49:42 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// After an incremental reflow, we verify the correctness by doing a
|
|
|
|
// full reflow into a fresh frame tree.
|
|
|
|
void
|
|
|
|
PresShell::VerifyIncrementalReflow()
|
|
|
|
{
|
|
|
|
// All the stuff we are creating that needs releasing
|
|
|
|
nsIPresContext* cx;
|
|
|
|
nsIViewManager* vm;
|
|
|
|
nsIView* view;
|
|
|
|
nsIPresShell* sh;
|
|
|
|
|
|
|
|
// Create a presentation context to view the new frame tree
|
|
|
|
nsresult rv;
|
1999-02-12 20:45:58 +03:00
|
|
|
PRBool isPaginated = PR_FALSE;
|
|
|
|
mPresContext->IsPaginated(&isPaginated);
|
|
|
|
if (isPaginated) {
|
1998-07-13 23:49:42 +04:00
|
|
|
rv = NS_NewPrintPreviewContext(&cx);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
rv = NS_NewGalleyContext(&cx);
|
|
|
|
}
|
|
|
|
NS_ASSERTION(NS_OK == rv, "failed to create presentation context");
|
1999-02-12 20:45:58 +03:00
|
|
|
nsCOMPtr<nsIDeviceContext> dc;
|
|
|
|
mPresContext->GetDeviceContext(getter_AddRefs(dc));
|
|
|
|
nsCOMPtr<nsIPref> prefs;
|
|
|
|
mPresContext->GetPrefs(getter_AddRefs(prefs));
|
1998-07-31 09:54:59 +04:00
|
|
|
cx->Init(dc, prefs);
|
1998-07-13 23:49:42 +04:00
|
|
|
|
|
|
|
// Get our scrolling preference
|
|
|
|
nsScrollPreference scrolling;
|
1998-08-28 08:56:56 +04:00
|
|
|
nsIView* rootView;
|
|
|
|
mViewManager->GetRootView(rootView);
|
1998-07-13 23:49:42 +04:00
|
|
|
nsIScrollableView* scrollView;
|
|
|
|
rv = rootView->QueryInterface(kScrollViewIID, (void**)&scrollView);
|
|
|
|
if (NS_OK == rv) {
|
1998-08-30 23:16:11 +04:00
|
|
|
scrollView->GetScrollPreference(scrolling);
|
1998-07-13 23:49:42 +04:00
|
|
|
}
|
1998-08-30 23:16:11 +04:00
|
|
|
nsIWidget* rootWidget;
|
|
|
|
rootView->GetWidget(rootWidget);
|
1998-07-13 23:49:42 +04:00
|
|
|
void* nativeParentWidget = rootWidget->GetNativeData(NS_NATIVE_WIDGET);
|
|
|
|
|
|
|
|
// Create a new view manager.
|
1998-09-01 04:26:28 +04:00
|
|
|
rv = nsRepository::CreateInstance(kViewManagerCID, nsnull, kIViewManagerIID,
|
1998-07-13 23:49:42 +04:00
|
|
|
(void**) &vm);
|
1998-08-28 06:54:06 +04:00
|
|
|
if ((NS_OK != rv) || (NS_OK != vm->Init(dc))) {
|
1998-07-13 23:49:42 +04:00
|
|
|
NS_ASSERTION(NS_OK == rv, "failed to create view manager");
|
|
|
|
}
|
|
|
|
|
1998-08-28 06:54:06 +04:00
|
|
|
vm->SetViewObserver((nsIViewObserver *)this);
|
|
|
|
|
1998-07-13 23:49:42 +04:00
|
|
|
// Create a child window of the parent that is our "root view/window"
|
|
|
|
// Create a view
|
|
|
|
nsRect tbounds;
|
|
|
|
mPresContext->GetVisibleArea(tbounds);
|
1998-09-01 04:26:28 +04:00
|
|
|
rv = nsRepository::CreateInstance(kScrollingViewCID, nsnull, kIViewIID,
|
1998-07-13 23:49:42 +04:00
|
|
|
(void **) &view);
|
1998-11-04 07:14:10 +03:00
|
|
|
if ((NS_OK != rv) || (NS_OK != view->Init(vm, tbounds, nsnull))) {
|
1998-07-13 23:49:42 +04:00
|
|
|
NS_ASSERTION(NS_OK == rv, "failed to create scroll view");
|
|
|
|
}
|
1998-11-04 07:14:10 +03:00
|
|
|
|
|
|
|
//now create the widget for the view
|
|
|
|
rv = view->CreateWidget(kWidgetCID, nsnull, nativeParentWidget);
|
|
|
|
if (NS_OK != rv) {
|
|
|
|
NS_ASSERTION(NS_OK == rv, "failed to create scroll view widget");
|
|
|
|
}
|
|
|
|
|
1998-07-13 23:49:42 +04:00
|
|
|
rv = view->QueryInterface(kScrollViewIID, (void**)&scrollView);
|
|
|
|
if (NS_OK == rv) {
|
1998-11-04 07:14:10 +03:00
|
|
|
scrollView->CreateScrollControls(nativeParentWidget);
|
1998-07-13 23:49:42 +04:00
|
|
|
scrollView->SetScrollPreference(scrolling);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
NS_ASSERTION(0, "invalid scrolling view");
|
|
|
|
}
|
|
|
|
|
|
|
|
// Setup hierarchical relationship in view manager
|
|
|
|
vm->SetRootView(view);
|
|
|
|
|
|
|
|
// Make the new presentation context the same size as our
|
|
|
|
// presentation context.
|
|
|
|
nsRect r;
|
|
|
|
mPresContext->GetVisibleArea(r);
|
|
|
|
cx->SetVisibleArea(r);
|
1998-11-25 21:41:02 +03:00
|
|
|
// Create a new presentation shell to view the document. Use the
|
|
|
|
// exact same style information that this document has.
|
|
|
|
rv = mDocument->CreateShell(cx, vm, mStyleSet, &sh);
|
1998-07-13 23:49:42 +04:00
|
|
|
NS_ASSERTION(NS_OK == rv, "failed to create presentation shell");
|
1998-11-25 21:41:02 +03:00
|
|
|
sh->InitialReflow(r.width, r.height);
|
1998-07-13 23:49:42 +04:00
|
|
|
|
|
|
|
// Now that the document has been reflowed, use its frame tree to
|
|
|
|
// compare against our frame tree.
|
1998-12-29 07:45:18 +03:00
|
|
|
nsIFrame* root1;
|
|
|
|
nsIFrame* root2;
|
1999-02-12 20:45:58 +03:00
|
|
|
GetRootFrame(&root1);
|
|
|
|
sh->GetRootFrame(&root2);
|
1998-12-29 07:45:18 +03:00
|
|
|
CompareTrees(root1, root2);
|
1998-07-13 23:49:42 +04:00
|
|
|
|
|
|
|
NS_RELEASE(vm);
|
|
|
|
NS_RELEASE(cx);
|
|
|
|
NS_RELEASE(sh);
|
|
|
|
}
|
|
|
|
#endif
|