1998-04-14 00:24:54 +04:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
|
|
*
|
1999-11-06 06:40:37 +03:00
|
|
|
* The contents of this file are subject to the Netscape 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/NPL/
|
1998-04-14 00:24:54 +04:00
|
|
|
*
|
1999-11-06 06:40:37 +03:00
|
|
|
* 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.
|
1998-04-14 00:24:54 +04:00
|
|
|
*
|
1999-11-06 06:40:37 +03:00
|
|
|
* The Original Code is mozilla.org code.
|
|
|
|
*
|
|
|
|
* The Initial Developer of the Original Code is Netscape
|
1998-04-14 00:24:54 +04:00
|
|
|
* Communications Corporation. Portions created by Netscape are
|
1999-11-06 06:40:37 +03:00
|
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All
|
|
|
|
* Rights Reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s):
|
1999-09-10 22:29:37 +04:00
|
|
|
*/
|
1999-12-05 02:49:50 +03:00
|
|
|
|
1999-12-07 07:36:08 +03:00
|
|
|
#define PL_ARENA_CONST_ALIGN_MASK 3
|
1998-04-14 00:24:54 +04:00
|
|
|
#include "nsIPresShell.h"
|
1999-12-05 02:49:50 +03:00
|
|
|
#include "nsIPresContext.h"
|
1998-04-14 00:24:54 +04:00
|
|
|
#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"
|
1999-08-06 00:17:44 +04:00
|
|
|
#include "nsIServiceManager.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"
|
1998-06-03 19:46:54 +04:00
|
|
|
#include "prlog.h"
|
1998-12-12 22:21:05 +03:00
|
|
|
#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 "nsIDOMSelection.h"
|
1999-12-03 00:45:21 +03:00
|
|
|
#include "nsISelectionController.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-08-25 14:51:55 +04:00
|
|
|
#include "nsWeakReference.h"
|
2000-01-04 23:24:09 +03:00
|
|
|
#include "nsIPageSequenceFrame.h"
|
1999-02-12 03:02:56 +03:00
|
|
|
#include "nsICaret.h"
|
1999-02-12 08:39:33 +03:00
|
|
|
#include "nsIDOMHTMLDocument.h"
|
1999-03-20 04:51:00 +03:00
|
|
|
#include "nsIXMLDocument.h"
|
1999-02-12 08:39:33 +03:00
|
|
|
#include "nsIScrollableView.h"
|
1999-03-01 22:21:01 +03:00
|
|
|
#include "nsIParser.h"
|
|
|
|
#include "nsParserCIID.h"
|
|
|
|
#include "nsHTMLContentSinkStream.h"
|
1999-03-15 08:11:43 +03:00
|
|
|
#include "nsHTMLToTXTSinkStream.h"
|
1999-03-01 22:21:01 +03:00
|
|
|
#include "nsXIFDTD.h"
|
1999-03-12 03:17:14 +03:00
|
|
|
#include "nsIFrameSelection.h"
|
1999-04-03 22:58:04 +04:00
|
|
|
#include "nsViewsCID.h"
|
1999-08-04 08:02:40 +04:00
|
|
|
#include "nsIFrameManager.h"
|
1999-08-25 12:35:06 +04:00
|
|
|
#include "nsISupportsPrimitives.h"
|
1999-08-31 02:38:58 +04:00
|
|
|
#include "nsILayoutHistoryState.h"
|
1999-10-15 08:29:30 +04:00
|
|
|
#include "nsIScrollPositionListener.h"
|
|
|
|
#include "nsICompositeListener.h"
|
1999-11-10 06:41:09 +03:00
|
|
|
#include "nsTimer.h"
|
1999-11-09 06:23:26 +03:00
|
|
|
#include "nsWeakPtr.h"
|
1999-12-07 07:36:08 +03:00
|
|
|
#include "plarena.h"
|
1999-10-20 02:27:20 +04:00
|
|
|
#ifdef MOZ_PERF_METRICS
|
1999-09-20 12:23:33 +04:00
|
|
|
#include "nsITimeRecorder.h"
|
|
|
|
#endif
|
1999-11-02 01:12:45 +03:00
|
|
|
#ifdef NS_DEBUG
|
|
|
|
#include "nsIFrameDebug.h"
|
|
|
|
#endif
|
1999-02-20 02:47:36 +03:00
|
|
|
|
1999-03-24 00:32:48 +03:00
|
|
|
// Drag & Drop, Clipboard
|
|
|
|
#include "nsWidgetsCID.h"
|
|
|
|
#include "nsIClipboard.h"
|
|
|
|
#include "nsITransferable.h"
|
1999-04-01 18:22:00 +04:00
|
|
|
#include "nsIFormatConverter.h"
|
1999-12-18 05:09:29 +03:00
|
|
|
#include "nsIDocShellTreeItem.h"
|
1999-07-04 08:09:54 +04:00
|
|
|
#include "nsIBrowserWindow.h"
|
1999-11-09 06:23:26 +03:00
|
|
|
#include "nsIURI.h"
|
|
|
|
#include "nsIEventQueue.h"
|
|
|
|
#include "nsIEventQueueService.h"
|
1999-12-07 08:28:32 +03:00
|
|
|
#include "nsIScrollableFrame.h"
|
1999-12-23 05:02:33 +03:00
|
|
|
#include "prtime.h"
|
|
|
|
#include "prlong.h"
|
|
|
|
|
1999-11-09 06:23:26 +03:00
|
|
|
|
2000-01-04 23:24:09 +03:00
|
|
|
// Class ID's
|
|
|
|
static NS_DEFINE_CID(kFrameSelectionCID, NS_FRAMESELECTION_CID);
|
|
|
|
static NS_DEFINE_CID(kCRangeCID, NS_RANGE_CID);
|
|
|
|
static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
|
|
|
|
static NS_DEFINE_CID(kViewCID, NS_VIEW_CID);
|
|
|
|
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
|
1999-03-24 00:32:48 +03:00
|
|
|
|
|
|
|
// Drag & Drop, Clipboard Support
|
1999-05-04 18:55:24 +04:00
|
|
|
static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
|
1999-05-14 01:53:57 +04:00
|
|
|
static NS_DEFINE_CID(kCTransferableCID, NS_TRANSFERABLE_CID);
|
2000-01-04 23:24:09 +03:00
|
|
|
static NS_DEFINE_CID(kCXIFConverterCID, NS_XIFFORMATCONVERTER_CID);
|
1998-04-14 00:24:54 +04:00
|
|
|
|
|
|
|
#undef NOISY
|
|
|
|
|
1999-02-12 03:02:56 +03:00
|
|
|
// comment out to hide caret
|
1999-03-02 07:26:49 +03:00
|
|
|
#define SHOW_CARET
|
1999-02-12 03:02:56 +03:00
|
|
|
|
1999-12-23 05:02:33 +03:00
|
|
|
// The upper bound on the amount of time to spend reflowing. When this bound is exceeded
|
|
|
|
// and reflow commands are still queued up, a reflow event is posted. The idea is for reflow
|
|
|
|
// to not hog the processor beyond the time specifed in gMaxRCProcessingTime.
|
|
|
|
// This data member is initialized from the layout.reflow.timeslice pref.
|
|
|
|
// It is used only when asynchronous reflow is enabled by setting gDoAsyncReflow to PR_TRUE.
|
|
|
|
#define NS_MAX_REFLOW_TIME 1000000
|
1999-12-23 06:47:02 +03:00
|
|
|
static PRInt32 gMaxRCProcessingTime = -1;
|
1999-12-23 05:02:33 +03:00
|
|
|
|
1999-12-07 07:36:08 +03:00
|
|
|
// Largest chunk size we recycle
|
2000-01-04 06:09:32 +03:00
|
|
|
static const size_t gMaxRecycledSize = 200;
|
1999-12-07 07:36:08 +03:00
|
|
|
|
1999-12-23 05:02:33 +03:00
|
|
|
// Flag for enabling/disabling asynchronous reflow
|
|
|
|
// Set via the "layout.reflow.async" pref
|
|
|
|
static PRBool gDoAsyncReflow = PR_FALSE;
|
|
|
|
|
2000-01-25 19:00:44 +03:00
|
|
|
// Flag for enabling/disabling asynchronous reflow after the document has loaded.
|
|
|
|
// Set via the "layout.reflow.async.afterDocLoad" pref
|
|
|
|
static PRBool gDoAsyncReflowAfterDocLoad = PR_FALSE;
|
|
|
|
|
1999-12-07 07:36:08 +03:00
|
|
|
// Memory is allocated 4-byte aligned. We have recyclers for chunks up to
|
|
|
|
// 200 bytes
|
|
|
|
class FrameArena {
|
|
|
|
public:
|
|
|
|
FrameArena(PRUint32 aArenaSize = 2048);
|
|
|
|
~FrameArena();
|
|
|
|
|
|
|
|
// Memory management functions
|
|
|
|
nsresult AllocateFrame(size_t aSize, void** aResult);
|
|
|
|
nsresult FreeFrame(size_t aSize, void* aPtr);
|
|
|
|
|
|
|
|
private:
|
|
|
|
// Underlying arena pool
|
|
|
|
PLArenaPool mPool;
|
|
|
|
|
|
|
|
// The recycler array is sparse with the indices being multiples of 4,
|
|
|
|
// i.e., 0, 4, 8, 12, 16, 20, ...
|
|
|
|
void* mRecyclers[gMaxRecycledSize >> 2];
|
|
|
|
};
|
|
|
|
|
|
|
|
FrameArena::FrameArena(PRUint32 aArenaSize)
|
|
|
|
{
|
|
|
|
// Initialize the arena pool
|
|
|
|
PL_INIT_ARENA_POOL(&mPool, "FrameArena", aArenaSize);
|
|
|
|
|
|
|
|
// Zero out the recyclers array
|
|
|
|
nsCRT::memset(mRecyclers, 0, sizeof(mRecyclers));
|
|
|
|
}
|
|
|
|
|
|
|
|
FrameArena::~FrameArena()
|
|
|
|
{
|
|
|
|
// Free the arena in the pool and finish using it
|
|
|
|
PL_FinishArenaPool(&mPool);
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
FrameArena::AllocateFrame(size_t aSize, void** aResult)
|
|
|
|
{
|
|
|
|
void* result = nsnull;
|
|
|
|
|
|
|
|
// Round size to multiple of 4
|
2000-01-04 06:04:56 +03:00
|
|
|
aSize = PR_ROUNDUP(aSize, 4);
|
1999-12-07 07:36:08 +03:00
|
|
|
|
|
|
|
// Check recyclers first
|
|
|
|
if (aSize < gMaxRecycledSize) {
|
|
|
|
const int index = aSize >> 2;
|
|
|
|
|
|
|
|
result = mRecyclers[index];
|
|
|
|
if (result) {
|
|
|
|
// Need to move to the next object
|
|
|
|
void* next = *((void**)result);
|
|
|
|
mRecyclers[index] = next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!result) {
|
|
|
|
// Allocate a new chunk from the arena
|
|
|
|
PL_ARENA_ALLOCATE(result, &mPool, aSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
*aResult = result;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
FrameArena::FreeFrame(size_t aSize, void* aPtr)
|
|
|
|
{
|
|
|
|
// Round size to multiple of 4
|
2000-01-04 06:09:32 +03:00
|
|
|
aSize = PR_ROUNDUP(aSize, 4);
|
1999-12-07 07:36:08 +03:00
|
|
|
|
|
|
|
// See if it's a size that we recycle
|
|
|
|
if (aSize < gMaxRecycledSize) {
|
|
|
|
const int index = aSize >> 2;
|
|
|
|
void* currentTop = mRecyclers[index];
|
|
|
|
mRecyclers[index] = aPtr;
|
|
|
|
*((void**)aPtr) = currentTop;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-10-15 08:29:30 +04:00
|
|
|
class PresShellViewEventListener : public nsIScrollPositionListener,
|
|
|
|
public nsICompositeListener
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
PresShellViewEventListener();
|
|
|
|
virtual ~PresShellViewEventListener();
|
|
|
|
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
|
|
|
|
// nsIScrollPositionListener methods
|
|
|
|
NS_IMETHOD ScrollPositionWillChange(nsIScrollableView *aView, nscoord aX, nscoord aY);
|
|
|
|
NS_IMETHOD ScrollPositionDidChange(nsIScrollableView *aView, nscoord aX, nscoord aY);
|
|
|
|
|
|
|
|
// nsICompositeListener methods
|
|
|
|
NS_IMETHOD WillRefreshRegion(nsIViewManager *aViewManager,
|
|
|
|
nsIView *aView,
|
|
|
|
nsIRenderingContext *aContext,
|
|
|
|
nsIRegion *aRegion,
|
|
|
|
PRUint32 aUpdateFlags);
|
|
|
|
|
|
|
|
NS_IMETHOD DidRefreshRegion(nsIViewManager *aViewManager,
|
|
|
|
nsIView *aView,
|
|
|
|
nsIRenderingContext *aContext,
|
|
|
|
nsIRegion *aRegion,
|
|
|
|
PRUint32 aUpdateFlags);
|
|
|
|
|
|
|
|
NS_IMETHOD WillRefreshRect(nsIViewManager *aViewManager,
|
|
|
|
nsIView *aView,
|
|
|
|
nsIRenderingContext *aContext,
|
|
|
|
const nsRect *aRect,
|
|
|
|
PRUint32 aUpdateFlags);
|
|
|
|
|
|
|
|
NS_IMETHOD DidRefreshRect(nsIViewManager *aViewManager,
|
|
|
|
nsIView *aView,
|
|
|
|
nsIRenderingContext *aContext,
|
|
|
|
const nsRect *aRect,
|
|
|
|
PRUint32 aUpdateFlags);
|
|
|
|
|
|
|
|
nsresult SetPresShell(nsIPresShell *aPresShell);
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
nsresult HideCaret();
|
|
|
|
nsresult RestoreCaretVisibility();
|
|
|
|
|
|
|
|
nsIPresShell *mPresShell;
|
|
|
|
PRBool mWasVisible;
|
|
|
|
PRInt32 mCallCount;
|
|
|
|
};
|
|
|
|
|
1998-08-28 06:54:06 +04:00
|
|
|
class PresShell : public nsIPresShell, public nsIViewObserver,
|
1999-02-20 02:47:36 +03:00
|
|
|
private nsIDocumentObserver, public nsIFocusTracker,
|
1999-12-03 00:45:21 +03:00
|
|
|
public nsISelectionController,
|
1999-10-22 04:19:18 +04:00
|
|
|
public nsSupportsWeakReference
|
1998-08-28 06:54:06 +04:00
|
|
|
{
|
1998-04-14 00:24:54 +04:00
|
|
|
public:
|
|
|
|
PresShell();
|
|
|
|
|
1999-02-26 23:02:06 +03:00
|
|
|
NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
|
1999-02-26 20:08:48 +03:00
|
|
|
|
1998-04-14 00:24:54 +04:00
|
|
|
// nsISupports
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
|
|
|
|
// nsIPresShell
|
1998-06-03 19:46:54 +04:00
|
|
|
NS_IMETHOD Init(nsIDocument* aDocument,
|
|
|
|
nsIPresContext* aPresContext,
|
|
|
|
nsIViewManager* aViewManager,
|
|
|
|
nsIStyleSet* aStyleSet);
|
1999-12-05 02:49:50 +03:00
|
|
|
|
|
|
|
NS_IMETHOD AllocateFrame(size_t aSize, void** aResult);
|
|
|
|
NS_IMETHOD FreeFrame(size_t aSize, void* aFreeChunk);
|
|
|
|
|
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-07-18 06:27:19 +04:00
|
|
|
NS_IMETHOD GetSelection(SelectionType aType, nsIDOMSelection** aSelection);
|
1999-08-31 01:54:40 +04:00
|
|
|
NS_IMETHOD ScrollSelectionIntoView(SelectionType aType, SelectionRegion aRegion);
|
|
|
|
NS_IMETHOD RepaintSelection(SelectionType aType);
|
1999-07-18 06:27:19 +04:00
|
|
|
NS_IMETHOD GetFrameSelection(nsIFrameSelection** aSelection);
|
|
|
|
|
1998-05-09 07:22:41 +04:00
|
|
|
NS_IMETHOD EnterReflowLock();
|
2000-01-25 19:00:44 +03:00
|
|
|
NS_IMETHOD ExitReflowLock(PRBool aTryToReflow);
|
1999-11-09 06:23:26 +03:00
|
|
|
|
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-25 22:55:06 +03:00
|
|
|
NS_IMETHOD GetStyleContextFor(nsIFrame* aFrame,
|
|
|
|
nsIStyleContext** aStyleContext) 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 07:56:31 +03:00
|
|
|
NS_IMETHOD AppendReflowCommand(nsIReflowCommand* aReflowCommand);
|
2000-01-12 11:28:24 +03:00
|
|
|
NS_IMETHOD CancelReflowCommand(nsIFrame* aTargetFrame, nsIReflowCommand::ReflowType* aCmdType);
|
2000-01-24 09:43:15 +03:00
|
|
|
NS_IMETHOD ProcessReflowCommands(PRBool aInterruptible);
|
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
|
|
|
|
1999-02-19 01:52:21 +03:00
|
|
|
NS_IMETHOD ScrollFrameIntoView(nsIFrame *aFrame,
|
1999-07-19 22:38:33 +04:00
|
|
|
PRIntn aVPercent,
|
|
|
|
PRIntn aHPercent) const;
|
1999-04-07 07:56:07 +04:00
|
|
|
|
1999-07-17 03:27:46 +04:00
|
|
|
NS_IMETHOD NotifyDestroyingFrame(nsIFrame* aFrame);
|
1999-08-04 08:02:40 +04:00
|
|
|
|
|
|
|
NS_IMETHOD GetFrameManager(nsIFrameManager** aFrameManager) const;
|
1999-07-17 03:27:46 +04:00
|
|
|
|
1999-04-07 07:56:07 +04:00
|
|
|
NS_IMETHOD DoCopy();
|
1999-08-31 18:35:50 +04:00
|
|
|
|
1999-12-06 10:44:18 +03:00
|
|
|
// XXX This function needs to be renamed to something better.
|
|
|
|
// It is not simply a getter for the layout history state. It
|
|
|
|
// creates a new state object and captures frame state onto it
|
1999-08-31 02:38:58 +04:00
|
|
|
NS_IMETHOD GetHistoryState(nsILayoutHistoryState** aLayoutHistoryState);
|
1999-12-06 10:44:18 +03:00
|
|
|
|
1999-09-15 04:43:53 +04:00
|
|
|
NS_IMETHOD SetHistoryState(nsILayoutHistoryState* aLayoutHistoryState);
|
1999-08-31 02:38:58 +04:00
|
|
|
|
1999-11-09 06:23:26 +03:00
|
|
|
NS_IMETHOD GetReflowEventStatus(PRBool* aPending);
|
|
|
|
NS_IMETHOD SetReflowEventStatus(PRBool aPending);
|
2000-01-28 03:48:02 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Reflow batching
|
|
|
|
*/
|
|
|
|
NS_IMETHOD BeginBatchingReflows();
|
|
|
|
NS_IMETHOD EndBatchingReflows(PRBool aFlushPendingReflows);
|
|
|
|
NS_IMETHOD GetReflowBatchingStatus(PRBool* aBatch);
|
|
|
|
|
2000-01-24 09:43:15 +03:00
|
|
|
NS_IMETHOD FlushPendingNotifications();
|
1999-11-09 06:23:26 +03:00
|
|
|
|
2000-02-09 18:48:01 +03:00
|
|
|
NS_IMETHOD IsReflowLocked(PRBool* aIsLocked);
|
2000-01-28 03:48:02 +03:00
|
|
|
|
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,
|
1999-11-24 09:03:41 +03:00
|
|
|
nsEventStatus* aEventStatus);
|
1998-08-28 06:54:06 +04:00
|
|
|
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-02-21 06:49:32 +03:00
|
|
|
NS_IMETHOD ScrollFrameIntoView(nsIFrame *aFrame);
|
1999-02-13 07:45:44 +03:00
|
|
|
// caret handling
|
1999-08-05 00:46:16 +04:00
|
|
|
NS_IMETHOD GetCaret(nsICaret **aOutCaret);
|
|
|
|
NS_IMETHOD SetCaretEnabled(PRBool aaInEnable);
|
|
|
|
NS_IMETHOD GetCaretEnabled(PRBool *aOutEnabled);
|
1999-02-13 07:45:44 +03:00
|
|
|
|
1999-08-05 00:46:16 +04:00
|
|
|
NS_IMETHOD SetDisplayNonTextSelection(PRBool aaInEnable);
|
|
|
|
NS_IMETHOD GetDisplayNonTextSelection(PRBool *aOutEnable);
|
1999-05-17 04:21:18 +04:00
|
|
|
|
1999-12-03 00:45:21 +03:00
|
|
|
// nsISelectionController
|
1999-10-22 04:19:18 +04:00
|
|
|
|
|
|
|
NS_IMETHOD CharacterMove(PRBool aForward, PRBool aExtend);
|
|
|
|
NS_IMETHOD WordMove(PRBool aForward, PRBool aExtend);
|
|
|
|
NS_IMETHOD LineMove(PRBool aForward, PRBool aExtend);
|
|
|
|
NS_IMETHOD IntraLineMove(PRBool aForward, PRBool aExtend);
|
|
|
|
NS_IMETHOD PageMove(PRBool aForward, PRBool aExtend);
|
|
|
|
NS_IMETHOD ScrollPage(PRBool aForward);
|
1999-12-15 06:54:52 +03:00
|
|
|
NS_IMETHOD ScrollLine(PRBool aForward);
|
|
|
|
NS_IMETHOD ScrollHorizontal(PRBool aLeft);
|
1999-12-11 03:02:08 +03:00
|
|
|
NS_IMETHOD CompleteScroll(PRBool aForward);
|
|
|
|
NS_IMETHOD CompleteMove(PRBool aForward, PRBool aExtend);
|
1999-10-22 04:19:18 +04:00
|
|
|
NS_IMETHOD SelectAll();
|
1999-02-13 07:45:44 +03:00
|
|
|
|
1999-07-14 21:30:07 +04:00
|
|
|
// nsIDocumentObserver
|
|
|
|
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,
|
|
|
|
nsISupports* aSubContent);
|
|
|
|
NS_IMETHOD ContentStatesChanged(nsIDocument* aDocument,
|
|
|
|
nsIContent* aContent1,
|
|
|
|
nsIContent* aContent2);
|
|
|
|
NS_IMETHOD AttributeChanged(nsIDocument *aDocument,
|
|
|
|
nsIContent* aContent,
|
1999-10-16 03:16:45 +04:00
|
|
|
PRInt32 aNameSpaceID,
|
1999-07-14 21:30:07 +04:00
|
|
|
nsIAtom* aAttribute,
|
|
|
|
PRInt32 aHint);
|
|
|
|
NS_IMETHOD ContentAppended(nsIDocument *aDocument,
|
|
|
|
nsIContent* aContainer,
|
|
|
|
PRInt32 aNewIndexInContainer);
|
|
|
|
NS_IMETHOD ContentInserted(nsIDocument *aDocument,
|
|
|
|
nsIContent* aContainer,
|
|
|
|
nsIContent* aChild,
|
|
|
|
PRInt32 aIndexInContainer);
|
|
|
|
NS_IMETHOD ContentReplaced(nsIDocument *aDocument,
|
|
|
|
nsIContent* aContainer,
|
|
|
|
nsIContent* aOldChild,
|
|
|
|
nsIContent* aNewChild,
|
|
|
|
PRInt32 aIndexInContainer);
|
|
|
|
NS_IMETHOD ContentRemoved(nsIDocument *aDocument,
|
|
|
|
nsIContent* aContainer,
|
|
|
|
nsIContent* aChild,
|
|
|
|
PRInt32 aIndexInContainer);
|
|
|
|
NS_IMETHOD StyleSheetAdded(nsIDocument *aDocument,
|
|
|
|
nsIStyleSheet* aStyleSheet);
|
|
|
|
NS_IMETHOD StyleSheetRemoved(nsIDocument *aDocument,
|
|
|
|
nsIStyleSheet* aStyleSheet);
|
|
|
|
NS_IMETHOD StyleSheetDisabledStateChanged(nsIDocument *aDocument,
|
|
|
|
nsIStyleSheet* aStyleSheet,
|
|
|
|
PRBool aDisabled);
|
|
|
|
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);
|
|
|
|
NS_IMETHOD DocumentWillBeDestroyed(nsIDocument *aDocument);
|
1999-12-23 05:02:33 +03:00
|
|
|
|
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);
|
|
|
|
|
1999-04-02 03:58:11 +04:00
|
|
|
PRBool mCaretEnabled;
|
|
|
|
|
1999-04-03 22:58:04 +04:00
|
|
|
nsresult CloneStyleSet(nsIStyleSet* aSet, nsIStyleSet** aResult);
|
1999-11-02 01:12:45 +03:00
|
|
|
|
|
|
|
#ifdef NS_DEBUG
|
1999-09-10 22:49:23 +04:00
|
|
|
PRBool 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
|
|
|
|
1999-04-30 13:04:36 +04: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).
|
1999-05-05 03:27:42 +04:00
|
|
|
|
|
|
|
// these are the same Document and PresContext owned by the DocViewer.
|
|
|
|
// we must share ownership.
|
|
|
|
nsCOMPtr<nsIDocument> mDocument;
|
|
|
|
nsCOMPtr<nsIPresContext> mPresContext;
|
1999-04-30 13:04:36 +04:00
|
|
|
nsCOMPtr<nsIStyleSet> mStyleSet;
|
|
|
|
nsIViewManager* mViewManager; // [WEAK] docViewer owns it so I don't have to
|
1999-08-31 18:35:50 +04:00
|
|
|
nsILayoutHistoryState* mHistoryState; // [WEAK] session history owns this
|
1998-04-14 00:24:54 +04:00
|
|
|
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;
|
1999-06-15 07:14:28 +04:00
|
|
|
nsIContent* mCurrentEventContent;
|
1999-09-02 22:14:01 +04:00
|
|
|
nsVoidArray mCurrentEventFrameStack;
|
2000-02-03 05:49:58 +03:00
|
|
|
#ifdef NS_DEBUG
|
|
|
|
nsRect mCurrentTargetRect;
|
|
|
|
nsIView* mCurrentTargetView;
|
|
|
|
#endif
|
1999-02-12 03:02:56 +03:00
|
|
|
|
|
|
|
nsCOMPtr<nsIFrameSelection> mSelection;
|
|
|
|
nsCOMPtr<nsICaret> mCaret;
|
1999-05-17 04:21:18 +04:00
|
|
|
PRBool mDisplayNonTextSelection;
|
1999-02-21 22:43:40 +03:00
|
|
|
PRBool mScrollingEnabled; //used to disable programmable scrolling from outside
|
1999-08-05 07:23:39 +04:00
|
|
|
nsIFrameManager* mFrameManager; // we hold a reference
|
1999-10-15 08:29:30 +04:00
|
|
|
PresShellViewEventListener *mViewEventListener;
|
1999-11-09 06:23:26 +03:00
|
|
|
PRBool mPendingReflowEvent;
|
|
|
|
nsCOMPtr<nsIEventQueue> mEventQueue;
|
1999-12-07 07:36:08 +03:00
|
|
|
FrameArena mFrameArena;
|
1999-12-23 06:47:02 +03:00
|
|
|
PRInt32 mAccumulatedReflowTime; // Time spent in reflow command processing so far
|
2000-01-24 09:43:15 +03:00
|
|
|
PRPackedBool mDocumentIsLoading; // A flag that is true while the document is loading.
|
2000-01-28 03:48:02 +03:00
|
|
|
PRPackedBool mBatchReflows; // When set to true, the pres shell batches reflow commands.
|
1999-11-09 06:23:26 +03:00
|
|
|
|
1999-11-12 00:35:34 +03:00
|
|
|
MOZ_TIMER_DECLARE(mReflowWatch) // Used for measuring time spent in reflow
|
2000-01-24 09:43:15 +03:00
|
|
|
MOZ_TIMER_DECLARE(mFrameCreationWatch) // Used for measuring time spent in frame creation
|
1999-12-23 05:02:33 +03:00
|
|
|
|
1999-11-09 06:23:26 +03:00
|
|
|
|
|
|
|
#ifdef DEBUG_nisheeth
|
|
|
|
PRInt32 mReflows;
|
|
|
|
PRInt32 mDiscardedReflowCommands;
|
|
|
|
#endif
|
1999-07-17 03:27:46 +04:00
|
|
|
|
1999-12-23 05:02:33 +03:00
|
|
|
|
1999-02-21 22:43:40 +03:00
|
|
|
private:
|
|
|
|
//helper funcs for disabing autoscrolling
|
|
|
|
void DisableScrolling(){mScrollingEnabled = PR_FALSE;}
|
|
|
|
void EnableScrolling(){mScrollingEnabled = PR_TRUE;}
|
|
|
|
PRBool IsScrollingEnabled(){return mScrollingEnabled;}
|
1999-09-02 22:14:01 +04:00
|
|
|
|
|
|
|
//helper funcs for event handling
|
1999-06-15 07:14:28 +04:00
|
|
|
nsIFrame* GetCurrentEventFrame();
|
1999-09-02 22:14:01 +04:00
|
|
|
void PushCurrentEventFrame();
|
|
|
|
void PopCurrentEventFrame();
|
1999-09-15 04:43:53 +04:00
|
|
|
|
1999-11-09 06:23:26 +03:00
|
|
|
// helper function for posting reflow events
|
|
|
|
void PostReflowEvent();
|
|
|
|
PRBool AlreadyInQueue(nsIReflowCommand* aReflowCommand);
|
1998-04-14 00:24:54 +04:00
|
|
|
};
|
|
|
|
|
1999-09-21 11:53:49 +04:00
|
|
|
#ifdef NS_DEBUG
|
|
|
|
static void
|
2000-01-22 04:16:50 +03:00
|
|
|
VerifyStyleTree(nsIPresContext* aPresContext, nsIFrameManager* aFrameManager)
|
1999-09-21 11:53:49 +04:00
|
|
|
{
|
1999-11-02 01:12:45 +03:00
|
|
|
if (aFrameManager && nsIFrameDebug::GetVerifyStyleTreeEnable()) {
|
1999-10-19 02:20:37 +04:00
|
|
|
nsIFrame* rootFrame;
|
|
|
|
|
|
|
|
aFrameManager->GetRootFrame(&rootFrame);
|
2000-01-22 04:16:50 +03:00
|
|
|
aFrameManager->DebugVerifyStyleTree(aPresContext, rootFrame);
|
1999-09-21 11:53:49 +04:00
|
|
|
}
|
|
|
|
}
|
2000-01-22 04:16:50 +03:00
|
|
|
#define VERIFY_STYLE_TREE VerifyStyleTree(mPresContext, mFrameManager)
|
1999-09-21 11:53:49 +04:00
|
|
|
#else
|
|
|
|
#define VERIFY_STYLE_TREE
|
|
|
|
#endif
|
|
|
|
|
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.
|
|
|
|
*/
|
1999-02-26 20:08:48 +03:00
|
|
|
static PRLogModuleInfo* gLogModule;
|
1998-07-13 23:49:42 +04:00
|
|
|
|
1999-09-10 22:49:23 +04:00
|
|
|
static PRUint32 gVerifyReflowFlags;
|
|
|
|
|
1999-10-05 18:51:12 +04:00
|
|
|
#define VERIFY_REFLOW_ON 0x01
|
|
|
|
#define VERIFY_REFLOW_NOISY 0x02
|
|
|
|
#define VERIFY_REFLOW_ALL 0x04
|
|
|
|
#define VERIFY_REFLOW_DUMP_COMMANDS 0x08
|
|
|
|
#define VERIFY_REFLOW_NOISY_RC 0x10
|
|
|
|
#define VERIFY_REFLOW_REALLY_NOISY_RC 0x20
|
1999-04-28 02:14:17 +04:00
|
|
|
#endif
|
1998-07-13 23:49:42 +04:00
|
|
|
|
1999-09-10 22:49:23 +04:00
|
|
|
static PRBool gVerifyReflowEnabled;
|
|
|
|
|
1998-07-13 23:49:42 +04:00
|
|
|
NS_LAYOUT PRBool
|
|
|
|
nsIPresShell::GetVerifyReflowEnable()
|
|
|
|
{
|
|
|
|
#ifdef NS_DEBUG
|
1999-09-10 22:49:23 +04:00
|
|
|
static PRBool firstTime = PR_TRUE;
|
|
|
|
if (firstTime) {
|
|
|
|
firstTime = PR_FALSE;
|
1999-02-26 20:08:48 +03:00
|
|
|
gLogModule = PR_NewLogModule("verifyreflow");
|
1999-09-10 22:49:23 +04:00
|
|
|
gVerifyReflowFlags = gLogModule->level;
|
|
|
|
if (VERIFY_REFLOW_ON & gVerifyReflowFlags) {
|
|
|
|
gVerifyReflowEnabled = PR_TRUE;
|
1998-11-25 21:41:02 +03:00
|
|
|
}
|
|
|
|
printf("Note: verifyreflow is %sabled",
|
1999-09-10 22:49:23 +04:00
|
|
|
gVerifyReflowEnabled ? "en" : "dis");
|
|
|
|
if (VERIFY_REFLOW_NOISY & gVerifyReflowFlags) {
|
|
|
|
printf(" (noisy)");
|
1998-11-25 21:41:02 +03:00
|
|
|
}
|
1999-09-10 22:49:23 +04:00
|
|
|
if (VERIFY_REFLOW_ALL & gVerifyReflowFlags) {
|
|
|
|
printf(" (all)");
|
1998-11-25 21:41:02 +03:00
|
|
|
}
|
1999-09-15 04:27:05 +04:00
|
|
|
if (VERIFY_REFLOW_DUMP_COMMANDS & gVerifyReflowFlags) {
|
|
|
|
printf(" (show reflow commands)");
|
|
|
|
}
|
|
|
|
if (VERIFY_REFLOW_NOISY_RC & gVerifyReflowFlags) {
|
|
|
|
printf(" (noisy reflow commands)");
|
1999-10-05 18:51:12 +04:00
|
|
|
if (VERIFY_REFLOW_REALLY_NOISY_RC & gVerifyReflowFlags) {
|
|
|
|
printf(" (REALLY noisy reflow commands)");
|
|
|
|
}
|
1999-09-15 04:27:05 +04:00
|
|
|
}
|
1999-09-10 22:49:23 +04:00
|
|
|
printf("\n");
|
1998-07-13 23:49:42 +04:00
|
|
|
}
|
|
|
|
#endif
|
1999-09-10 22:49:23 +04:00
|
|
|
return gVerifyReflowEnabled;
|
1998-07-13 23:49:42 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_LAYOUT void
|
|
|
|
nsIPresShell::SetVerifyReflowEnable(PRBool aEnabled)
|
|
|
|
{
|
1999-09-10 22:49:23 +04:00
|
|
|
gVerifyReflowEnabled = aEnabled;
|
1998-07-13 23:49:42 +04:00
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
}
|
2000-01-04 23:24:09 +03:00
|
|
|
return it->QueryInterface(NS_GET_IID(nsIPresShell),
|
|
|
|
(void **) aInstancePtrResult);
|
1998-07-13 23:49:42 +04:00
|
|
|
}
|
|
|
|
|
1998-04-14 00:24:54 +04:00
|
|
|
PresShell::PresShell()
|
|
|
|
{
|
1998-11-18 08:25:26 +03:00
|
|
|
mIsDestroying = PR_FALSE;
|
1999-04-02 03:58:11 +04:00
|
|
|
mCaretEnabled = PR_FALSE;
|
1999-05-17 04:21:18 +04:00
|
|
|
mDisplayNonTextSelection = PR_FALSE;
|
1999-06-15 07:14:28 +04:00
|
|
|
mCurrentEventContent = nsnull;
|
1999-09-02 22:14:01 +04:00
|
|
|
mCurrentEventFrame = nsnull;
|
1999-02-21 22:43:40 +03:00
|
|
|
EnableScrolling();
|
2000-02-03 05:49:58 +03:00
|
|
|
#ifdef NS_DEBUG
|
|
|
|
mCurrentTargetView = nsnull;
|
|
|
|
#endif
|
2000-01-25 19:00:44 +03:00
|
|
|
mPendingReflowEvent = PR_FALSE;
|
2000-01-24 22:11:02 +03:00
|
|
|
mDocumentIsLoading = PR_TRUE;
|
2000-01-28 03:48:02 +03:00
|
|
|
mBatchReflows = PR_FALSE;
|
1999-11-09 06:23:26 +03:00
|
|
|
|
|
|
|
#ifdef DEBUG_nisheeth
|
|
|
|
mReflows = 0;
|
|
|
|
mDiscardedReflowCommands = 0;
|
|
|
|
#endif
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
|
1998-09-12 23:33:48 +04:00
|
|
|
NS_IMPL_ADDREF(PresShell)
|
|
|
|
NS_IMPL_RELEASE(PresShell)
|
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
|
|
|
{
|
2000-01-04 23:24:09 +03:00
|
|
|
if (!aInstancePtr) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aIID.Equals(NS_GET_IID(nsIPresShell))) {
|
1998-09-12 23:33:48 +04:00
|
|
|
nsIPresShell* tmp = this;
|
|
|
|
*aInstancePtr = (void*) tmp;
|
2000-01-04 23:24:09 +03:00
|
|
|
} else if (aIID.Equals(NS_GET_IID(nsIDocumentObserver))) {
|
1998-09-12 23:33:48 +04:00
|
|
|
nsIDocumentObserver* tmp = this;
|
|
|
|
*aInstancePtr = (void*) tmp;
|
2000-01-04 23:24:09 +03:00
|
|
|
} else if (aIID.Equals(NS_GET_IID(nsIViewObserver))) {
|
1998-09-12 23:33:48 +04:00
|
|
|
nsIViewObserver* tmp = this;
|
|
|
|
*aInstancePtr = (void*) tmp;
|
2000-01-04 23:24:09 +03:00
|
|
|
} else if (aIID.Equals(NS_GET_IID(nsIFocusTracker))) {
|
1998-12-14 21:34:14 +03:00
|
|
|
nsIFocusTracker* tmp = this;
|
|
|
|
*aInstancePtr = (void*) tmp;
|
2000-01-04 23:24:09 +03:00
|
|
|
} else if (aIID.Equals(NS_GET_IID(nsISelectionController))) {
|
1999-12-03 00:45:21 +03:00
|
|
|
nsISelectionController* tmp = this;
|
1999-02-20 02:47:36 +03:00
|
|
|
*aInstancePtr = (void*) tmp;
|
2000-01-04 23:24:09 +03:00
|
|
|
} else if (aIID.Equals(NS_GET_IID(nsISupportsWeakReference))) {
|
1999-08-25 14:51:55 +04:00
|
|
|
nsISupportsWeakReference* tmp = this;
|
|
|
|
*aInstancePtr = (void*) tmp;
|
2000-01-04 23:24:09 +03:00
|
|
|
} else if (aIID.Equals(NS_GET_IID(nsISupports))) {
|
1998-09-12 23:33:48 +04:00
|
|
|
nsIPresShell* tmp = this;
|
|
|
|
nsISupports* tmp2 = tmp;
|
|
|
|
*aInstancePtr = (void*) tmp2;
|
2000-01-04 23:24:09 +03:00
|
|
|
} else {
|
|
|
|
*aInstancePtr = nsnull;
|
|
|
|
|
|
|
|
return NS_NOINTERFACE;
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
2000-01-04 23:24:09 +03:00
|
|
|
|
|
|
|
NS_ADDREF_THIS();
|
|
|
|
|
|
|
|
return NS_OK;
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
PresShell::~PresShell()
|
|
|
|
{
|
1998-08-06 23:52:48 +04:00
|
|
|
mRefCnt = 99;/* XXX hack! get around re-entrancy bugs */
|
1999-04-30 04:08:17 +04:00
|
|
|
|
1998-11-18 08:25:26 +03:00
|
|
|
mIsDestroying = PR_TRUE;
|
1999-06-15 07:14:28 +04:00
|
|
|
|
1999-10-07 04:31:21 +04:00
|
|
|
// Clobber weak leaks in case of re-entrancy during tear down
|
|
|
|
mHistoryState = nsnull;
|
|
|
|
|
1999-06-15 07:14:28 +04:00
|
|
|
NS_IF_RELEASE(mCurrentEventContent);
|
1999-10-07 04:31:21 +04:00
|
|
|
|
1999-04-30 04:08:17 +04:00
|
|
|
if (mViewManager) {
|
|
|
|
// Disable paints during tear down of the frame tree
|
|
|
|
mViewManager->DisableRefresh();
|
1999-10-07 04:31:21 +04:00
|
|
|
mViewManager = nsnull;
|
1999-04-30 04:08:17 +04:00
|
|
|
}
|
1999-10-07 04:31:21 +04:00
|
|
|
|
1999-10-19 02:20:37 +04:00
|
|
|
// Destroy the frame manager. This will destroy the frame hierarchy
|
1999-08-05 07:23:39 +04:00
|
|
|
NS_IF_RELEASE(mFrameManager);
|
1999-10-07 04:31:21 +04:00
|
|
|
|
|
|
|
if (mDocument) {
|
1998-09-23 21:16:51 +04:00
|
|
|
mDocument->DeleteShell(this);
|
1999-10-07 04:31:21 +04:00
|
|
|
}
|
1999-10-18 23:00:49 +04:00
|
|
|
|
|
|
|
// We hold a reference to the pres context, and it holds a weak link back
|
|
|
|
// to us. To avoid the pres context having a dangling reference, set its
|
|
|
|
// pres shell to NULL
|
|
|
|
if (mPresContext) {
|
|
|
|
mPresContext->SetShell(nsnull);
|
|
|
|
}
|
1998-08-06 23:52:48 +04:00
|
|
|
mRefCnt = 0;
|
1999-10-15 08:29:30 +04:00
|
|
|
|
|
|
|
if (mViewEventListener) {
|
|
|
|
mViewEventListener->SetPresShell((nsIPresShell*)nsnull);
|
|
|
|
NS_RELEASE(mViewEventListener);
|
|
|
|
}
|
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");
|
1999-12-05 02:49:50 +03:00
|
|
|
|
1998-04-14 00:24:54 +04:00
|
|
|
if ((nsnull == aDocument) || (nsnull == aPresContext) ||
|
|
|
|
(nsnull == aViewManager)) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
1999-05-05 03:27:42 +04:00
|
|
|
if (mDocument) {
|
1998-04-14 00:24:54 +04:00
|
|
|
return NS_ERROR_ALREADY_INITIALIZED;
|
|
|
|
}
|
|
|
|
|
1999-05-05 03:27:42 +04:00
|
|
|
mDocument = dont_QueryInterface(aDocument);
|
1998-04-14 00:24:54 +04:00
|
|
|
mViewManager = aViewManager;
|
|
|
|
|
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.
|
1999-05-05 03:27:42 +04:00
|
|
|
mPresContext = dont_QueryInterface(aPresContext);
|
1998-04-14 00:24:54 +04:00
|
|
|
aPresContext->SetShell(this);
|
|
|
|
|
1999-04-30 13:04:36 +04:00
|
|
|
mStyleSet = dont_QueryInterface(aStyleSet);
|
1998-04-14 00:24:54 +04:00
|
|
|
|
1999-08-31 18:35:50 +04:00
|
|
|
mHistoryState = nsnull;
|
|
|
|
|
1999-07-18 06:27:19 +04:00
|
|
|
nsresult result = nsComponentManager::CreateInstance(kFrameSelectionCID, nsnull,
|
2000-01-04 23:24:09 +03:00
|
|
|
NS_GET_IID(nsIFrameSelection),
|
1999-07-18 06:27:19 +04:00
|
|
|
getter_AddRefs(mSelection));
|
1998-12-14 21:34:14 +03:00
|
|
|
if (!NS_SUCCEEDED(result))
|
|
|
|
return result;
|
1999-04-26 08:02:04 +04:00
|
|
|
|
1999-08-04 08:02:40 +04:00
|
|
|
// Create and initialize the frame manager
|
|
|
|
result = NS_NewFrameManager(&mFrameManager);
|
|
|
|
if (NS_FAILED(result)) {
|
|
|
|
return result;
|
|
|
|
}
|
1999-10-19 02:20:37 +04:00
|
|
|
result = mFrameManager->Init(this, mStyleSet);
|
|
|
|
if (NS_FAILED(result)) {
|
|
|
|
return result;
|
|
|
|
}
|
1999-08-04 08:02:40 +04:00
|
|
|
|
1999-04-26 08:02:04 +04:00
|
|
|
result = mSelection->Init((nsIFocusTracker *) this);
|
|
|
|
if (!NS_SUCCEEDED(result))
|
|
|
|
return result;
|
1999-02-12 03:02:56 +03:00
|
|
|
// Important: this has to happen after the selection has been set up
|
|
|
|
#ifdef SHOW_CARET
|
|
|
|
// make the caret
|
|
|
|
nsresult err = NS_NewCaret(getter_AddRefs(mCaret));
|
|
|
|
if (NS_SUCCEEDED(err))
|
1999-04-02 03:58:11 +04:00
|
|
|
{
|
1999-07-15 02:18:29 +04:00
|
|
|
mCaret->Init(this);
|
1999-04-02 03:58:11 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
//SetCaretEnabled(PR_TRUE); // make it show in browser windows
|
1999-02-12 03:02:56 +03:00
|
|
|
#endif
|
1999-04-30 00:24:21 +04:00
|
|
|
//set up selection to be displayed in document
|
|
|
|
nsCOMPtr<nsISupports> container;
|
|
|
|
result = aPresContext->GetContainer(getter_AddRefs(container));
|
|
|
|
if (NS_SUCCEEDED(result) && container) {
|
1999-12-18 05:09:29 +03:00
|
|
|
nsCOMPtr<nsIDocShellTreeItem> docShell(do_QueryInterface(container, &result));
|
|
|
|
if (NS_SUCCEEDED(result) && docShell){
|
|
|
|
PRInt32 docShellType;
|
|
|
|
result = docShell->GetItemType(&docShellType);
|
1999-04-30 00:24:21 +04:00
|
|
|
if (NS_SUCCEEDED(result)){
|
1999-12-18 05:09:29 +03:00
|
|
|
if (nsIDocShellTreeItem::typeContent == docShellType){
|
1999-04-30 00:24:21 +04:00
|
|
|
mDocument->SetDisplaySelection(PR_TRUE);
|
|
|
|
}
|
1999-11-09 06:23:26 +03:00
|
|
|
}
|
1999-04-30 00:24:21 +04:00
|
|
|
}
|
|
|
|
}
|
1999-11-30 03:32:43 +03:00
|
|
|
|
1999-11-09 06:23:26 +03:00
|
|
|
// Cache the event queue of the current UI thread
|
|
|
|
NS_WITH_SERVICE(nsIEventQueueService, eventService, kEventQueueServiceCID, &result);
|
1999-11-30 03:32:43 +03:00
|
|
|
if (NS_SUCCEEDED(result)) // XXX this implies that the UI is the current thread.
|
|
|
|
result = eventService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(mEventQueue));
|
1999-11-09 06:23:26 +03:00
|
|
|
|
1999-12-23 05:02:33 +03:00
|
|
|
|
1999-12-23 06:47:02 +03:00
|
|
|
if (gMaxRCProcessingTime == -1) {
|
1999-12-23 05:02:33 +03:00
|
|
|
// First, set the defaults
|
1999-12-23 06:47:02 +03:00
|
|
|
gMaxRCProcessingTime = NS_MAX_REFLOW_TIME;
|
1999-12-23 05:02:33 +03:00
|
|
|
gDoAsyncReflow = PR_FALSE;
|
2000-02-02 03:19:52 +03:00
|
|
|
gDoAsyncReflowAfterDocLoad = PR_TRUE;
|
1999-12-23 05:02:33 +03:00
|
|
|
|
|
|
|
// Get the prefs service
|
|
|
|
NS_WITH_SERVICE(nsIPref, prefs, kPrefServiceCID, &result);
|
2000-02-02 03:19:52 +03:00
|
|
|
if (NS_SUCCEEDED(result)) {
|
2000-01-13 07:27:05 +03:00
|
|
|
prefs->GetIntPref("layout.reflow.timeslice", &gMaxRCProcessingTime);
|
1999-12-23 05:02:33 +03:00
|
|
|
prefs->GetBoolPref("layout.reflow.async", &gDoAsyncReflow);
|
2000-01-25 19:00:44 +03:00
|
|
|
prefs->GetBoolPref("layout.reflow.async.afterDocLoad", &gDoAsyncReflowAfterDocLoad);
|
1999-12-23 05:02:33 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-04-14 00:24:54 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-12-05 02:49:50 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::FreeFrame(size_t aSize, void* aPtr)
|
|
|
|
{
|
1999-12-07 07:36:08 +03:00
|
|
|
mFrameArena.FreeFrame(aSize, aPtr);
|
1999-12-05 02:49:50 +03:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::AllocateFrame(size_t aSize, void** aResult)
|
|
|
|
{
|
1999-12-07 07:36:08 +03:00
|
|
|
return mFrameArena.AllocateFrame(aSize, aResult);
|
1999-12-05 02:49:50 +03:00
|
|
|
}
|
|
|
|
|
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
|
2000-01-25 19:00:44 +03:00
|
|
|
PresShell::ExitReflowLock(PRBool aTryToReflow)
|
1998-05-09 07:22:41 +04:00
|
|
|
{
|
1998-05-12 05:30:40 +04:00
|
|
|
PRUint32 newReflowLockCount = mReflowLockCount - 1;
|
2000-01-28 03:48:02 +03:00
|
|
|
if (newReflowLockCount == 0 && aTryToReflow && !mBatchReflows) {
|
2000-01-25 19:00:44 +03:00
|
|
|
/* If a) layout.reflow.async is true, OR
|
|
|
|
* b) layout.reflow.async.afterDocLoad is true AND the doc has finished loading
|
|
|
|
* Then
|
|
|
|
* Process the reflow commands asynchronously
|
|
|
|
* Else
|
|
|
|
* Process the reflow commands synchronously.
|
|
|
|
*/
|
|
|
|
if (gDoAsyncReflow ||
|
|
|
|
(gDoAsyncReflowAfterDocLoad && !mDocumentIsLoading)) {
|
1999-11-09 06:23:26 +03:00
|
|
|
PostReflowEvent();
|
2000-01-25 19:00:44 +03:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
ProcessReflowCommands(PR_FALSE);
|
|
|
|
}
|
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;
|
1999-05-05 03:27:42 +04:00
|
|
|
NS_IF_ADDREF(*aResult);
|
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;
|
1999-05-05 03:27:42 +04:00
|
|
|
NS_IF_ADDREF(*aResult);
|
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;
|
1999-04-30 13:04:36 +04:00
|
|
|
NS_IF_ADDREF(*aResult);
|
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
|
1999-04-30 13:04:36 +04:00
|
|
|
if (mStyleSet) {
|
1999-01-23 10:03:46 +03:00
|
|
|
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)
|
|
|
|
{
|
1999-05-05 03:27:42 +04:00
|
|
|
if (mDocument && mStyleSet) {
|
1999-01-23 10:03:46 +03:00
|
|
|
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)
|
|
|
|
{
|
1999-05-05 03:27:42 +04:00
|
|
|
if (mDocument) {
|
1999-01-23 10:03:46 +03:00
|
|
|
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-07-18 06:27:19 +04:00
|
|
|
PresShell::GetSelection(SelectionType aType, nsIDOMSelection **aSelection)
|
1998-12-08 21:26:06 +03:00
|
|
|
{
|
|
|
|
if (!aSelection || !mSelection)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
1999-07-18 06:27:19 +04:00
|
|
|
return mSelection->GetSelection(aType, aSelection);
|
1998-12-08 21:26:06 +03:00
|
|
|
}
|
|
|
|
|
1999-08-31 01:54:40 +04:00
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::ScrollSelectionIntoView(SelectionType aType, SelectionRegion aRegion)
|
|
|
|
{
|
|
|
|
if (!mSelection)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
return mSelection->ScrollSelectionIntoView(aType, aRegion);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::RepaintSelection(SelectionType aType)
|
|
|
|
{
|
|
|
|
if (!mSelection)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
1999-10-26 08:44:41 +04:00
|
|
|
return mSelection->RepaintSelection(mPresContext, aType);
|
1999-08-31 01:54:40 +04:00
|
|
|
}
|
|
|
|
|
1999-07-18 06:27:19 +04:00
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::GetFrameSelection(nsIFrameSelection** aSelection)
|
|
|
|
{
|
|
|
|
if (!aSelection || !mSelection)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
*aSelection = mSelection;
|
|
|
|
(*aSelection)->AddRef();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
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
|
|
|
{
|
1999-05-05 03:27:42 +04:00
|
|
|
if (mDocument) {
|
1998-04-14 00:24:54 +04:00
|
|
|
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
|
|
|
{
|
1999-05-05 03:27:42 +04:00
|
|
|
if (mDocument) {
|
1998-04-14 00:24:54 +04:00
|
|
|
mDocument->RemoveObserver(this);
|
|
|
|
}
|
1999-02-20 02:47:36 +03:00
|
|
|
if (mSelection){
|
|
|
|
nsCOMPtr<nsIDOMSelection> domselection;
|
|
|
|
nsresult result;
|
1999-07-19 22:04:35 +04:00
|
|
|
result = mSelection->GetSelection(SELECTION_NORMAL, getter_AddRefs(domselection));
|
1999-02-20 02:47:36 +03:00
|
|
|
if (NS_FAILED(result))
|
|
|
|
return result;
|
|
|
|
if (!domselection)
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
1999-04-26 08:02:04 +04:00
|
|
|
mSelection->ShutDown();
|
1999-02-20 02:47:36 +03:00
|
|
|
}
|
1998-12-29 07:56:31 +03:00
|
|
|
return NS_OK;
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
|
1999-08-28 01:50:37 +04:00
|
|
|
#ifdef DEBUG_kipp
|
|
|
|
char* nsPresShell_ReflowStackPointerTop;
|
|
|
|
#endif
|
|
|
|
|
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
|
|
|
|
1999-12-23 05:02:33 +03:00
|
|
|
#ifdef NS_DEBUG
|
|
|
|
if (VERIFY_REFLOW_NOISY_RC & gVerifyReflowFlags) {
|
|
|
|
nsCOMPtr<nsIURI> uri;
|
|
|
|
if (mDocument) {
|
|
|
|
uri = dont_AddRef(mDocument->GetDocumentURL());
|
|
|
|
if (uri) {
|
|
|
|
char* url = nsnull;
|
|
|
|
uri->GetSpec(&url);
|
|
|
|
printf("*** PresShell::InitialReflow (this=%p, url='%s')\n", this, url);
|
|
|
|
Recycle(url);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
1999-09-15 03:43:35 +04:00
|
|
|
StCaretHider caretHider(this); // stack-based class hides caret until dtor.
|
|
|
|
|
1998-06-03 19:46:54 +04:00
|
|
|
EnterReflowLock();
|
|
|
|
|
1999-05-05 03:27:42 +04:00
|
|
|
if (mPresContext) {
|
1998-04-14 00:24:54 +04:00
|
|
|
nsRect r(0, 0, aWidth, aHeight);
|
|
|
|
mPresContext->SetVisibleArea(r);
|
|
|
|
}
|
|
|
|
|
1999-05-05 03:27:42 +04:00
|
|
|
if (mDocument) {
|
1999-02-03 22:38:16 +03:00
|
|
|
root = mDocument->GetRootContent();
|
|
|
|
}
|
|
|
|
|
1999-10-19 02:20:37 +04:00
|
|
|
// Get the root frame from the frame manager
|
|
|
|
nsIFrame* rootFrame;
|
|
|
|
mFrameManager->GetRootFrame(&rootFrame);
|
|
|
|
|
1999-02-03 22:38:16 +03:00
|
|
|
if (nsnull != root) {
|
1999-11-10 06:41:09 +03:00
|
|
|
MOZ_TIMER_DEBUGLOG(("Reset and start: Frame Creation: PresShell::InitialReflow(), this=%p\n", this));
|
|
|
|
MOZ_TIMER_RESET(mFrameCreationWatch);
|
|
|
|
MOZ_TIMER_START(mFrameCreationWatch);
|
1999-10-19 02:20:37 +04:00
|
|
|
|
|
|
|
if (!rootFrame) {
|
1999-02-03 22:38:16 +03:00
|
|
|
// Have style sheet processor construct a frame for the
|
|
|
|
// precursors to the root content object's frame
|
1999-10-19 02:20:37 +04:00
|
|
|
mStyleSet->ConstructRootFrame(mPresContext, root, rootFrame);
|
|
|
|
mFrameManager->SetRootFrame(rootFrame);
|
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);
|
1999-09-21 11:53:49 +04:00
|
|
|
VERIFY_STYLE_TREE;
|
1999-11-10 06:41:09 +03:00
|
|
|
MOZ_TIMER_DEBUGLOG(("Stop: Frame Creation: PresShell::InitialReflow(), this=%p\n", this));
|
|
|
|
MOZ_TIMER_STOP(mFrameCreationWatch);
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
|
1999-10-19 02:20:37 +04:00
|
|
|
if (rootFrame) {
|
1999-11-10 06:41:09 +03:00
|
|
|
MOZ_TIMER_DEBUGLOG(("Reset and start: Reflow: PresShell::InitialReflow(), this=%p\n", this));
|
|
|
|
MOZ_TIMER_RESET(mReflowWatch);
|
|
|
|
MOZ_TIMER_START(mReflowWatch);
|
1998-09-10 23:32:14 +04:00
|
|
|
// Kick off a top-down reflow
|
|
|
|
NS_FRAME_LOG(NS_FRAME_TRACE_CALLS,
|
|
|
|
("enter nsPresShell::InitialReflow: %d,%d", aWidth, aHeight));
|
|
|
|
#ifdef NS_DEBUG
|
1999-11-02 01:12:45 +03:00
|
|
|
if (nsIFrameDebug::GetVerifyTreeEnable()) {
|
|
|
|
nsIFrameDebug* frameDebug;
|
|
|
|
|
2000-01-04 23:24:09 +03:00
|
|
|
if (NS_SUCCEEDED(rootFrame->QueryInterface(NS_GET_IID(nsIFrameDebug),
|
|
|
|
(void**)&frameDebug))) {
|
1999-11-02 01:12:45 +03:00
|
|
|
frameDebug->VerifyTree();
|
|
|
|
}
|
1998-09-10 23:32:14 +04:00
|
|
|
}
|
1999-08-28 01:50:37 +04:00
|
|
|
#endif
|
|
|
|
#ifdef DEBUG_kipp
|
|
|
|
nsPresShell_ReflowStackPointerTop = (char*) &aWidth;
|
1998-09-10 23:32:14 +04:00
|
|
|
#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;
|
|
|
|
nsIRenderingContext* rcx = nsnull;
|
|
|
|
|
2000-01-12 01:15:20 +03:00
|
|
|
nsresult rv=CreateRenderingContext(rootFrame, &rcx);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1998-10-02 05:12:39 +04:00
|
|
|
|
1999-11-24 09:03:41 +03:00
|
|
|
nsHTMLReflowState reflowState(mPresContext, rootFrame,
|
1999-03-05 07:29:11 +03:00
|
|
|
eReflowReason_Initial, rcx, maxSize);
|
1999-11-19 18:33:29 +03:00
|
|
|
nsIView* view;
|
1998-10-01 08:46:11 +04:00
|
|
|
|
1999-11-24 09:03:41 +03:00
|
|
|
rootFrame->WillReflow(mPresContext);
|
1999-11-19 18:33:29 +03:00
|
|
|
rootFrame->GetView(mPresContext, &view);
|
|
|
|
if (view) {
|
|
|
|
nsContainerFrame::PositionFrameView(mPresContext, rootFrame, view);
|
|
|
|
}
|
1999-11-24 09:03:41 +03:00
|
|
|
rootFrame->Reflow(mPresContext, desiredSize, reflowState, status);
|
1999-10-30 06:52:11 +04:00
|
|
|
rootFrame->SizeTo(mPresContext, desiredSize.width, desiredSize.height);
|
|
|
|
mPresContext->SetVisibleArea(nsRect(0,0,desiredSize.width,desiredSize.height));
|
1999-11-19 18:33:29 +03:00
|
|
|
if (view) {
|
|
|
|
nsContainerFrame::SyncFrameViewAfterReflow(mPresContext, rootFrame, view,
|
|
|
|
nsnull);
|
|
|
|
}
|
1999-11-24 09:03:41 +03:00
|
|
|
rootFrame->DidReflow(mPresContext, NS_FRAME_REFLOW_FINISHED);
|
1999-07-08 02:34:31 +04:00
|
|
|
|
1998-09-10 23:32:14 +04:00
|
|
|
#ifdef NS_DEBUG
|
1999-11-02 01:12:45 +03:00
|
|
|
if (nsIFrameDebug::GetVerifyTreeEnable()) {
|
|
|
|
nsIFrameDebug* frameDebug;
|
|
|
|
|
2000-01-04 23:24:09 +03:00
|
|
|
if (NS_SUCCEEDED(rootFrame->QueryInterface(NS_GET_IID(nsIFrameDebug),
|
|
|
|
(void**)&frameDebug))) {
|
1999-11-02 01:12:45 +03:00
|
|
|
frameDebug->VerifyTree();
|
|
|
|
}
|
1998-10-01 08:46:11 +04:00
|
|
|
}
|
1999-10-30 06:52:11 +04:00
|
|
|
#endif
|
|
|
|
VERIFY_STYLE_TREE;
|
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"));
|
1999-11-10 06:41:09 +03:00
|
|
|
MOZ_TIMER_DEBUGLOG(("Stop: Reflow: PresShell::InitialReflow(), this=%p\n", this));
|
|
|
|
MOZ_TIMER_STOP(mReflowWatch);
|
1998-09-10 23:32:14 +04:00
|
|
|
}
|
|
|
|
|
2000-01-25 19:00:44 +03:00
|
|
|
ExitReflowLock(PR_TRUE);
|
1998-09-10 23:32:14 +04:00
|
|
|
|
1999-10-15 08:29:30 +04:00
|
|
|
if (mViewManager && mCaret && !mViewEventListener) {
|
|
|
|
nsIScrollableView* scrollingView = nsnull;
|
|
|
|
mViewManager->GetRootScrollableView(&scrollingView);
|
|
|
|
|
|
|
|
if (scrollingView) {
|
|
|
|
mViewEventListener = new PresShellViewEventListener;
|
|
|
|
|
|
|
|
if (!mViewEventListener)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
NS_ADDREF(mViewEventListener);
|
|
|
|
mViewEventListener->SetPresShell(this);
|
|
|
|
scrollingView->AddScrollPositionListener((nsIScrollPositionListener *)mViewEventListener);
|
|
|
|
mViewManager->AddCompositeListener((nsICompositeListener *)mViewEventListener);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-09-10 23:32:14 +04:00
|
|
|
return NS_OK; //XXX this needs to be real. MMP
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::ResizeReflow(nscoord aWidth, nscoord aHeight)
|
|
|
|
{
|
1999-09-15 03:43:35 +04:00
|
|
|
StCaretHider caretHider(this); // stack-based class hides caret until dtor.
|
1998-09-10 23:32:14 +04:00
|
|
|
EnterReflowLock();
|
|
|
|
|
1999-05-05 03:27:42 +04:00
|
|
|
if (mPresContext) {
|
1998-09-10 23:32:14 +04:00
|
|
|
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...
|
1999-10-19 02:20:37 +04:00
|
|
|
nsIFrame* rootFrame;
|
|
|
|
mFrameManager->GetRootFrame(&rootFrame);
|
|
|
|
if (rootFrame) {
|
1998-04-14 00:24:54 +04:00
|
|
|
// 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
|
1999-11-02 01:12:45 +03:00
|
|
|
if (nsIFrameDebug::GetVerifyTreeEnable()) {
|
|
|
|
nsIFrameDebug* frameDebug;
|
|
|
|
|
2000-01-04 23:24:09 +03:00
|
|
|
if (NS_SUCCEEDED(rootFrame->QueryInterface(NS_GET_IID(nsIFrameDebug),
|
|
|
|
(void**)&frameDebug))) {
|
1999-11-02 01:12:45 +03:00
|
|
|
frameDebug->VerifyTree();
|
|
|
|
}
|
1998-05-20 20:24:54 +04:00
|
|
|
}
|
1999-08-28 01:50:37 +04:00
|
|
|
#endif
|
|
|
|
#ifdef DEBUG_kipp
|
|
|
|
nsPresShell_ReflowStackPointerTop = (char*) &aWidth;
|
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;
|
|
|
|
nsIRenderingContext* rcx = nsnull;
|
|
|
|
|
2000-01-12 01:15:20 +03:00
|
|
|
nsresult rv=CreateRenderingContext(rootFrame, &rcx);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1998-10-02 05:12:39 +04:00
|
|
|
|
1999-11-24 09:03:41 +03:00
|
|
|
nsHTMLReflowState reflowState(mPresContext, rootFrame,
|
1999-03-05 07:29:11 +03:00
|
|
|
eReflowReason_Resize, rcx, maxSize);
|
1999-11-19 18:33:29 +03:00
|
|
|
nsIView* view;
|
1998-10-01 08:46:11 +04:00
|
|
|
|
1999-11-24 09:03:41 +03:00
|
|
|
rootFrame->WillReflow(mPresContext);
|
1999-11-19 18:33:29 +03:00
|
|
|
rootFrame->GetView(mPresContext, &view);
|
|
|
|
if (view) {
|
|
|
|
nsContainerFrame::PositionFrameView(mPresContext, rootFrame, view);
|
|
|
|
}
|
1999-11-24 09:03:41 +03:00
|
|
|
rootFrame->Reflow(mPresContext, desiredSize, reflowState, status);
|
1999-10-30 06:52:11 +04:00
|
|
|
rootFrame->SizeTo(mPresContext, desiredSize.width, desiredSize.height);
|
1999-11-19 18:33:29 +03:00
|
|
|
if (view) {
|
|
|
|
nsContainerFrame::SyncFrameViewAfterReflow(mPresContext, rootFrame, view,
|
|
|
|
nsnull);
|
|
|
|
}
|
1999-11-24 09:03:41 +03:00
|
|
|
rootFrame->DidReflow(mPresContext, NS_FRAME_REFLOW_FINISHED);
|
1998-04-14 00:24:54 +04:00
|
|
|
#ifdef NS_DEBUG
|
1999-11-02 01:12:45 +03:00
|
|
|
if (nsIFrameDebug::GetVerifyTreeEnable()) {
|
|
|
|
nsIFrameDebug* frameDebug;
|
|
|
|
|
2000-01-04 23:24:09 +03:00
|
|
|
if (NS_SUCCEEDED(rootFrame->QueryInterface(NS_GET_IID(nsIFrameDebug),
|
|
|
|
(void**)&frameDebug))) {
|
1999-11-02 01:12:45 +03:00
|
|
|
frameDebug->VerifyTree();
|
|
|
|
}
|
1998-10-01 08:46:11 +04:00
|
|
|
}
|
1999-10-30 06:52:11 +04:00
|
|
|
#endif
|
|
|
|
VERIFY_STYLE_TREE;
|
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"));
|
|
|
|
|
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
|
|
|
|
}
|
2000-01-25 19:00:44 +03:00
|
|
|
ExitReflowLock(PR_TRUE);
|
1999-02-13 07:45:44 +03:00
|
|
|
|
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-07-17 03:27:46 +04:00
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::ScrollFrameIntoView(nsIFrame *aFrame){
|
1999-02-21 06:49:32 +03:00
|
|
|
if (!aFrame)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
1999-02-21 22:43:40 +03:00
|
|
|
if (IsScrollingEnabled())
|
1999-07-19 22:38:33 +04:00
|
|
|
return ScrollFrameIntoView(aFrame, NS_PRESSHELL_SCROLL_ANYWHERE,
|
|
|
|
NS_PRESSHELL_SCROLL_ANYWHERE);
|
1999-02-21 22:43:40 +03:00
|
|
|
return NS_OK;
|
1999-02-21 06:49:32 +03:00
|
|
|
}
|
|
|
|
|
1999-07-17 03:27:46 +04:00
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::NotifyDestroyingFrame(nsIFrame* aFrame)
|
|
|
|
{
|
|
|
|
// Cancel any pending reflow commands targeted at this frame
|
2000-01-12 11:28:24 +03:00
|
|
|
CancelReflowCommand(aFrame, nsnull);
|
1999-07-17 03:27:46 +04:00
|
|
|
|
1999-08-06 00:17:44 +04:00
|
|
|
// Notify the frame manager
|
|
|
|
if (mFrameManager) {
|
|
|
|
mFrameManager->NotifyDestroyingFrame(aFrame);
|
|
|
|
}
|
|
|
|
|
1999-07-17 03:27:46 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-02-13 07:45:44 +03:00
|
|
|
|
1999-08-04 08:02:40 +04:00
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::GetFrameManager(nsIFrameManager** aFrameManager) const
|
|
|
|
{
|
|
|
|
*aFrameManager = mFrameManager;
|
|
|
|
NS_IF_ADDREF(mFrameManager);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-02-13 07:45:44 +03:00
|
|
|
NS_IMETHODIMP PresShell::GetCaret(nsICaret **outCaret)
|
|
|
|
{
|
|
|
|
if (!outCaret || !mCaret)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
2000-01-04 23:24:09 +03:00
|
|
|
return mCaret->QueryInterface(NS_GET_IID(nsICaret), (void **)outCaret);
|
1999-02-13 07:45:44 +03:00
|
|
|
}
|
|
|
|
|
1999-08-05 00:46:16 +04:00
|
|
|
NS_IMETHODIMP PresShell::SetCaretEnabled(PRBool aInEnable)
|
1999-04-02 03:58:11 +04:00
|
|
|
{
|
|
|
|
nsresult result = NS_OK;
|
|
|
|
PRBool oldEnabled = mCaretEnabled;
|
|
|
|
|
1999-08-05 00:46:16 +04:00
|
|
|
mCaretEnabled = aInEnable;
|
1999-04-02 03:58:11 +04:00
|
|
|
|
|
|
|
if (mCaret && (mCaretEnabled != oldEnabled))
|
|
|
|
{
|
2000-01-25 19:00:44 +03:00
|
|
|
// Update the document's content and frame models.
|
|
|
|
if (mDocument) mDocument->FlushPendingNotifications();
|
|
|
|
|
1999-04-02 03:58:11 +04:00
|
|
|
if (mCaretEnabled)
|
|
|
|
result = mCaret->SetCaretVisible(PR_TRUE);
|
|
|
|
else
|
|
|
|
result = mCaret->SetCaretVisible(PR_FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
1999-08-05 00:46:16 +04:00
|
|
|
NS_IMETHODIMP PresShell::GetCaretEnabled(PRBool *aOutEnabled)
|
|
|
|
{
|
|
|
|
if (!aOutEnabled) { return NS_ERROR_INVALID_ARG; }
|
|
|
|
*aOutEnabled = mCaretEnabled;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP PresShell::SetDisplayNonTextSelection(PRBool aInEnable)
|
1999-05-17 04:21:18 +04:00
|
|
|
{
|
|
|
|
mDisplayNonTextSelection = PR_TRUE;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-08-05 00:46:16 +04:00
|
|
|
NS_IMETHODIMP PresShell::GetDisplayNonTextSelection(PRBool *aOutEnable)
|
1999-05-17 04:21:18 +04:00
|
|
|
{
|
1999-08-05 00:46:16 +04:00
|
|
|
if (!aOutEnable)
|
|
|
|
return NS_ERROR_INVALID_ARG;
|
|
|
|
*aOutEnable = mDisplayNonTextSelection;
|
1999-05-17 04:21:18 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-12-03 00:45:21 +03:00
|
|
|
//implementation of nsISelectionController
|
1999-04-02 03:58:11 +04:00
|
|
|
|
1999-10-22 04:19:18 +04:00
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::CharacterMove(PRBool aForward, PRBool aExtend)
|
1999-02-20 02:47:36 +03:00
|
|
|
{
|
1999-12-11 03:02:08 +03:00
|
|
|
return mSelection->CharacterMove(aForward, aExtend);
|
1999-10-22 04:19:18 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::WordMove(PRBool aForward, PRBool aExtend)
|
|
|
|
{
|
1999-12-11 03:02:08 +03:00
|
|
|
return mSelection->WordMove(aForward, aExtend);
|
1999-10-22 04:19:18 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::LineMove(PRBool aForward, PRBool aExtend)
|
|
|
|
{
|
1999-12-11 03:02:08 +03:00
|
|
|
return mSelection->LineMove(aForward, aExtend);
|
1999-10-22 04:19:18 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::IntraLineMove(PRBool aForward, PRBool aExtend)
|
|
|
|
{
|
1999-12-11 03:02:08 +03:00
|
|
|
return mSelection->IntraLineMove(aForward, aExtend);
|
1999-10-22 04:19:18 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::PageMove(PRBool aForward, PRBool aExtend)
|
|
|
|
{
|
1999-12-17 01:48:02 +03:00
|
|
|
return ScrollPage(aForward);
|
|
|
|
#if 0
|
|
|
|
|
1999-12-11 03:02:08 +03:00
|
|
|
nsCOMPtr<nsIViewManager> viewManager;
|
|
|
|
nsresult result = GetViewManager(getter_AddRefs(viewManager));
|
|
|
|
if (NS_SUCCEEDED(result) && viewManager)
|
|
|
|
{
|
1999-12-15 06:54:52 +03:00
|
|
|
nsIScrollableView *scrollView;
|
|
|
|
result = viewManager->GetRootScrollableView(&scrollView);
|
1999-12-11 03:02:08 +03:00
|
|
|
if (NS_SUCCEEDED(result) && scrollView)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
1999-12-17 01:48:02 +03:00
|
|
|
#endif //0
|
1999-10-22 04:19:18 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::ScrollPage(PRBool aForward)
|
1999-12-11 03:02:08 +03:00
|
|
|
{
|
|
|
|
nsCOMPtr<nsIViewManager> viewManager;
|
|
|
|
nsresult result = GetViewManager(getter_AddRefs(viewManager));
|
|
|
|
if (NS_SUCCEEDED(result) && viewManager)
|
|
|
|
{
|
1999-12-15 06:54:52 +03:00
|
|
|
nsIScrollableView *scrollView;
|
|
|
|
result = viewManager->GetRootScrollableView(&scrollView);
|
1999-12-11 03:02:08 +03:00
|
|
|
if (NS_SUCCEEDED(result) && scrollView)
|
|
|
|
{
|
|
|
|
scrollView->ScrollByPages(aForward ? 1 : -1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
1999-12-15 06:54:52 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::ScrollLine(PRBool aForward)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIViewManager> viewManager;
|
|
|
|
nsresult result = GetViewManager(getter_AddRefs(viewManager));
|
|
|
|
if (NS_SUCCEEDED(result) && viewManager)
|
|
|
|
{
|
|
|
|
nsIScrollableView *scrollView;
|
|
|
|
result = viewManager->GetRootScrollableView(&scrollView);
|
|
|
|
if (NS_SUCCEEDED(result) && scrollView)
|
|
|
|
{
|
|
|
|
scrollView->ScrollByLines(aForward ? 1 : -1);
|
|
|
|
//NEW FOR LINES
|
|
|
|
// force the update to happen now, otherwise multiple scrolls can
|
|
|
|
// occur before the update is processed. (bug #7354)
|
|
|
|
|
|
|
|
// I'd use Composite here, but it doesn't always work.
|
|
|
|
// vm->Composite();
|
2000-01-27 02:04:40 +03:00
|
|
|
viewManager->ForceUpdate();
|
1999-12-15 06:54:52 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::ScrollHorizontal(PRBool aLeft)
|
|
|
|
{
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
1999-12-11 03:02:08 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::CompleteScroll(PRBool aForward)
|
|
|
|
{
|
1999-12-17 01:48:02 +03:00
|
|
|
nsCOMPtr<nsIViewManager> viewManager;
|
|
|
|
nsresult result = GetViewManager(getter_AddRefs(viewManager));
|
|
|
|
if (NS_SUCCEEDED(result) && viewManager)
|
|
|
|
{
|
|
|
|
nsIScrollableView *scrollView;
|
|
|
|
result = viewManager->GetRootScrollableView(&scrollView);
|
|
|
|
if (NS_SUCCEEDED(result) && scrollView)
|
|
|
|
{
|
|
|
|
scrollView->ScrollByWhole(!aForward);//TRUE = top, aForward TRUE=bottom
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
1999-12-11 03:02:08 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::CompleteMove(PRBool aForward, PRBool aExtend)
|
1999-10-22 04:19:18 +04:00
|
|
|
{
|
1999-12-17 01:48:02 +03:00
|
|
|
return CompleteScroll(aForward);
|
1999-10-22 04:19:18 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::SelectAll()
|
|
|
|
{
|
1999-12-11 03:02:08 +03:00
|
|
|
return mSelection->SelectAll();
|
1999-02-20 02:47:36 +03:00
|
|
|
}
|
|
|
|
|
1999-12-03 00:45:21 +03:00
|
|
|
//end implementations nsISelectionController
|
1999-10-22 04:19:18 +04:00
|
|
|
|
|
|
|
|
|
|
|
|
1998-11-06 19:16:01 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::StyleChangeReflow()
|
|
|
|
{
|
|
|
|
EnterReflowLock();
|
|
|
|
|
1999-10-19 02:20:37 +04:00
|
|
|
nsIFrame* rootFrame;
|
|
|
|
mFrameManager->GetRootFrame(&rootFrame);
|
|
|
|
if (rootFrame) {
|
1998-11-06 19:16:01 +03:00
|
|
|
// Kick off a top-down reflow
|
|
|
|
NS_FRAME_LOG(NS_FRAME_TRACE_CALLS,
|
|
|
|
("enter nsPresShell::StyleChangeReflow"));
|
|
|
|
#ifdef NS_DEBUG
|
1999-11-02 01:12:45 +03:00
|
|
|
if (nsIFrameDebug::GetVerifyTreeEnable()) {
|
|
|
|
nsIFrameDebug* frameDebug;
|
|
|
|
|
2000-01-04 23:24:09 +03:00
|
|
|
if (NS_SUCCEEDED(rootFrame->QueryInterface(NS_GET_IID(nsIFrameDebug),
|
|
|
|
(void**)&frameDebug))) {
|
1999-11-02 01:12:45 +03:00
|
|
|
frameDebug->VerifyTree();
|
|
|
|
}
|
1998-11-06 19:16:01 +03:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
nsRect bounds;
|
|
|
|
mPresContext->GetVisibleArea(bounds);
|
|
|
|
nsSize maxSize(bounds.width, bounds.height);
|
|
|
|
nsHTMLReflowMetrics desiredSize(nsnull);
|
|
|
|
nsReflowStatus status;
|
|
|
|
nsIRenderingContext* rcx = nsnull;
|
|
|
|
|
2000-01-12 01:15:20 +03:00
|
|
|
nsresult rv=CreateRenderingContext(rootFrame, &rcx);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1998-11-06 19:16:01 +03:00
|
|
|
|
|
|
|
// XXX We should be using eReflowReason_StyleChange
|
1999-11-24 09:03:41 +03:00
|
|
|
nsHTMLReflowState reflowState(mPresContext, rootFrame,
|
1999-03-05 07:29:11 +03:00
|
|
|
eReflowReason_Resize, rcx, maxSize);
|
1999-11-19 18:33:29 +03:00
|
|
|
nsIView* view;
|
1998-11-06 19:16:01 +03:00
|
|
|
|
1999-11-24 09:03:41 +03:00
|
|
|
rootFrame->WillReflow(mPresContext);
|
1999-11-19 18:33:29 +03:00
|
|
|
rootFrame->GetView(mPresContext, &view);
|
|
|
|
if (view) {
|
|
|
|
nsContainerFrame::PositionFrameView(mPresContext, rootFrame, view);
|
|
|
|
}
|
1999-11-24 09:03:41 +03:00
|
|
|
rootFrame->Reflow(mPresContext, desiredSize, reflowState, status);
|
1999-10-30 06:52:11 +04:00
|
|
|
rootFrame->SizeTo(mPresContext, desiredSize.width, desiredSize.height);
|
1999-11-19 18:33:29 +03:00
|
|
|
mPresContext->SetVisibleArea(nsRect(0,0,desiredSize.width,desiredSize.height));
|
|
|
|
if (view) {
|
|
|
|
nsContainerFrame::SyncFrameViewAfterReflow(mPresContext, rootFrame, view,
|
|
|
|
nsnull);
|
|
|
|
}
|
1999-11-24 09:03:41 +03:00
|
|
|
rootFrame->DidReflow(mPresContext, NS_FRAME_REFLOW_FINISHED);
|
1998-11-06 19:16:01 +03:00
|
|
|
#ifdef NS_DEBUG
|
1999-11-02 01:12:45 +03:00
|
|
|
if (nsIFrameDebug::GetVerifyTreeEnable()) {
|
|
|
|
nsIFrameDebug* frameDebug;
|
|
|
|
|
2000-01-04 23:24:09 +03:00
|
|
|
if (NS_SUCCEEDED(rootFrame->QueryInterface(NS_GET_IID(nsIFrameDebug),
|
|
|
|
(void**)&frameDebug))) {
|
1999-11-02 01:12:45 +03:00
|
|
|
frameDebug->VerifyTree();
|
|
|
|
}
|
1998-11-06 19:16:01 +03:00
|
|
|
}
|
1999-10-30 06:52:11 +04:00
|
|
|
#endif
|
|
|
|
VERIFY_STYLE_TREE;
|
1998-11-06 19:16:01 +03:00
|
|
|
NS_IF_RELEASE(rcx);
|
|
|
|
NS_FRAME_LOG(NS_FRAME_TRACE_CALLS, ("exit nsPresShell::StyleChangeReflow"));
|
|
|
|
}
|
|
|
|
|
2000-01-25 19:00:44 +03:00
|
|
|
ExitReflowLock(PR_TRUE);
|
1998-11-06 19:16:01 +03:00
|
|
|
|
|
|
|
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-10-19 02:20:37 +04:00
|
|
|
return mFrameManager->GetRootFrame(aResult);
|
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;
|
|
|
|
}
|
|
|
|
|
1999-10-19 02:20:37 +04:00
|
|
|
nsIFrame* rootFrame;
|
1998-12-07 06:43:02 +03:00
|
|
|
nsIFrame* child;
|
1999-12-07 08:28:32 +03:00
|
|
|
nsIPageSequenceFrame* pageSequence = nsnull;
|
1998-12-07 06:43:02 +03:00
|
|
|
|
1999-12-07 08:28:32 +03:00
|
|
|
// The page sequence frame is the child of the rootFrame
|
1999-10-19 02:20:37 +04:00
|
|
|
mFrameManager->GetRootFrame(&rootFrame);
|
2000-01-22 04:16:50 +03:00
|
|
|
rootFrame->FirstChild(mPresContext, nsnull, &child);
|
1999-12-07 08:28:32 +03:00
|
|
|
|
1998-12-07 06:43:02 +03:00
|
|
|
if (nsnull != child) {
|
1999-12-07 08:28:32 +03:00
|
|
|
|
|
|
|
// but the child could be wrapped in a scrollframe so lets check
|
|
|
|
nsIScrollableFrame* scrollable = nsnull;
|
2000-01-04 23:24:09 +03:00
|
|
|
nsresult rv = child->QueryInterface(NS_GET_IID(nsIScrollableFrame),
|
|
|
|
(void **)&scrollable);
|
1999-12-07 08:28:32 +03:00
|
|
|
if (NS_SUCCEEDED(rv) && (nsnull != scrollable)) {
|
|
|
|
// if it is then get the scrolled frame
|
|
|
|
scrollable->GetScrolledFrame(nsnull, child);
|
|
|
|
}
|
|
|
|
|
|
|
|
// make sure the child is a pageSequence
|
2000-01-04 23:24:09 +03:00
|
|
|
rv = child->QueryInterface(NS_GET_IID(nsIPageSequenceFrame),
|
|
|
|
(void**)&pageSequence);
|
1999-12-07 08:28:32 +03:00
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv),"Error: Could not find pageSequence!");
|
|
|
|
|
1999-02-12 20:45:58 +03:00
|
|
|
*aResult = pageSequence;
|
1998-12-07 06:43:02 +03:00
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-12-07 08:28:32 +03:00
|
|
|
|
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)
|
1999-09-20 10:55:24 +04:00
|
|
|
{
|
1999-10-20 02:27:20 +04:00
|
|
|
#ifdef MOZ_PERF_METRICS
|
1999-09-20 10:55:24 +04:00
|
|
|
// Reset style resolution stopwatch maintained by style set
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
nsCOMPtr<nsITimeRecorder> watch = do_QueryInterface(mStyleSet, &rv);
|
|
|
|
if (NS_SUCCEEDED(rv) && watch) {
|
1999-11-10 06:41:09 +03:00
|
|
|
MOZ_TIMER_DEBUGLOG(("Reset: Style Resolution: PresShell::BeginLoad(), this=%p\n", this));
|
1999-09-20 10:55:24 +04:00
|
|
|
watch->ResetTimer(NS_TIMER_STYLE_RESOLUTION);
|
|
|
|
}
|
|
|
|
#endif
|
2000-01-24 09:43:15 +03:00
|
|
|
|
|
|
|
mDocumentIsLoading = PR_TRUE;
|
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
|
|
|
{
|
1999-11-09 06:23:26 +03:00
|
|
|
#ifdef DEBUG_nisheeth
|
|
|
|
if (aDocument) {
|
|
|
|
nsIURI* uri = nsnull;
|
|
|
|
if ((uri = aDocument->GetDocumentURL())) {
|
|
|
|
char* spec = nsnull;
|
|
|
|
if (NS_SUCCEEDED(uri->GetSpec(&spec))) {
|
|
|
|
printf("**** Url: '%s', Reflows: %d, Discarded Reflows: %d\n", spec, mReflows, mDiscardedReflowCommands);
|
|
|
|
Recycle(spec);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
NS_RELEASE(uri);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
1999-10-20 02:27:20 +04:00
|
|
|
#ifdef MOZ_PERF_METRICS
|
1999-09-20 10:55:24 +04:00
|
|
|
// Dump reflow, style resolution and frame construction times here.
|
1999-11-10 06:41:09 +03:00
|
|
|
MOZ_TIMER_DEBUGLOG(("Stop: Reflow: PresShell::EndLoad(), this=%p\n", this));
|
|
|
|
MOZ_TIMER_STOP(mReflowWatch);
|
|
|
|
MOZ_TIMER_LOG(("Reflow time (this=%p): ", this));
|
|
|
|
MOZ_TIMER_PRINT(mReflowWatch);
|
|
|
|
|
|
|
|
MOZ_TIMER_DEBUGLOG(("Stop: Frame Creation: PresShell::EndLoad(), this=%p\n", this));
|
|
|
|
MOZ_TIMER_STOP(mFrameCreationWatch);
|
|
|
|
MOZ_TIMER_LOG(("Frame construction plus style resolution time (this=%p): ", this));
|
|
|
|
MOZ_TIMER_PRINT(mFrameCreationWatch);
|
1999-09-20 10:55:24 +04:00
|
|
|
|
|
|
|
// Print style resolution stopwatch maintained by style set
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
nsCOMPtr<nsITimeRecorder> watch = do_QueryInterface(mStyleSet, &rv);
|
|
|
|
if (NS_SUCCEEDED(rv) && watch) {
|
1999-11-10 06:41:09 +03:00
|
|
|
MOZ_TIMER_DEBUGLOG(("Stop: Style Resolution: PresShell::EndLoad(), this=%p\n", this));
|
1999-09-22 05:49:31 +04:00
|
|
|
watch->StopTimer(NS_TIMER_STYLE_RESOLUTION);
|
1999-11-10 06:41:09 +03:00
|
|
|
MOZ_TIMER_LOG(("Style resolution time (this=%p): ", this));
|
|
|
|
watch->PrintTimer(NS_TIMER_STYLE_RESOLUTION);
|
1999-09-20 10:55:24 +04:00
|
|
|
}
|
1999-09-17 11:16:42 +04:00
|
|
|
#endif
|
2000-01-25 19:00:44 +03:00
|
|
|
|
|
|
|
mDocumentIsLoading = PR_FALSE;
|
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
|
|
|
}
|
|
|
|
|
1999-11-09 06:23:26 +03:00
|
|
|
|
|
|
|
// aReflowCommand is considered to be already in the queue if the
|
|
|
|
// frame it targets is targeted by a pre-existing reflow command in
|
|
|
|
// the queue.
|
|
|
|
PRBool
|
|
|
|
PresShell::AlreadyInQueue(nsIReflowCommand* aReflowCommand)
|
|
|
|
{
|
|
|
|
PRInt32 i, n = mReflowCommands.Count();
|
|
|
|
nsIFrame* targetFrame;
|
1999-12-23 05:02:33 +03:00
|
|
|
PRBool inQueue = PR_FALSE;
|
1999-11-09 06:23:26 +03:00
|
|
|
|
1999-12-23 05:02:33 +03:00
|
|
|
if (!gDoAsyncReflow)
|
|
|
|
return PR_FALSE;
|
1999-11-12 07:41:34 +03:00
|
|
|
|
1999-11-09 06:23:26 +03:00
|
|
|
if (NS_SUCCEEDED(aReflowCommand->GetTarget(targetFrame))) {
|
|
|
|
// Iterate over the reflow commands and compare the targeted frames.
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
nsIReflowCommand* rc = (nsIReflowCommand*) mReflowCommands.ElementAt(i);
|
|
|
|
if (rc) {
|
|
|
|
nsIFrame* targetOfQueuedRC;
|
|
|
|
if (NS_SUCCEEDED(rc->GetTarget(targetOfQueuedRC))) {
|
|
|
|
nsIReflowCommand::ReflowType RCType;
|
|
|
|
nsIReflowCommand::ReflowType queuedRCType;
|
|
|
|
aReflowCommand->GetType(RCType);
|
|
|
|
rc->GetType(queuedRCType);
|
|
|
|
if (targetFrame == targetOfQueuedRC &&
|
1999-12-23 05:02:33 +03:00
|
|
|
RCType == queuedRCType) {
|
1999-11-09 06:23:26 +03:00
|
|
|
#ifdef DEBUG_nisheeth
|
|
|
|
mDiscardedReflowCommands++;
|
1999-12-23 05:02:33 +03:00
|
|
|
#endif
|
|
|
|
#ifdef DEBUG
|
|
|
|
if (VERIFY_REFLOW_NOISY_RC & gVerifyReflowFlags) {
|
|
|
|
printf("*** PresShell::AlreadyInQueue(): Discarding reflow command: this=%p\n", this);
|
|
|
|
aReflowCommand->List(stdout);
|
|
|
|
}
|
1999-11-09 06:23:26 +03:00
|
|
|
#endif
|
|
|
|
inQueue = PR_TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return inQueue;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
{
|
1999-09-15 04:27:05 +04:00
|
|
|
#ifdef DEBUG
|
1998-11-26 21:11:02 +03:00
|
|
|
if (mInVerifyReflow) {
|
1998-12-29 07:56:31 +03:00
|
|
|
return NS_OK;
|
1999-12-23 05:02:33 +03:00
|
|
|
}
|
|
|
|
if (VERIFY_REFLOW_NOISY_RC & gVerifyReflowFlags) {
|
|
|
|
printf("\nPresShell@%p: adding reflow command\n", this);
|
|
|
|
aReflowCommand->List(stdout);
|
|
|
|
if (VERIFY_REFLOW_REALLY_NOISY_RC & gVerifyReflowFlags) {
|
|
|
|
printf("Current content model:\n");
|
|
|
|
nsCOMPtr<nsIContent> rootContent;
|
|
|
|
rootContent = getter_AddRefs(mDocument->GetRootContent());
|
|
|
|
if (rootContent) {
|
|
|
|
rootContent->List(stdout, 0);
|
1999-09-15 04:27:05 +04:00
|
|
|
}
|
|
|
|
}
|
1999-12-23 05:02:33 +03:00
|
|
|
}
|
1998-11-26 21:11:02 +03:00
|
|
|
#endif
|
1999-11-09 06:23:26 +03:00
|
|
|
nsresult rv = NS_OK;
|
|
|
|
if (!AlreadyInQueue(aReflowCommand)) {
|
|
|
|
NS_ADDREF(aReflowCommand);
|
|
|
|
rv = (mReflowCommands.AppendElement(aReflowCommand) ? NS_OK : NS_ERROR_OUT_OF_MEMORY);
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
|
1999-04-24 00:01:20 +04:00
|
|
|
NS_IMETHODIMP
|
2000-01-12 11:28:24 +03:00
|
|
|
PresShell::CancelReflowCommand(nsIFrame* aTargetFrame, nsIReflowCommand::ReflowType* aCmdType)
|
1999-04-24 00:01:20 +04:00
|
|
|
{
|
|
|
|
PRInt32 i, n = mReflowCommands.Count();
|
|
|
|
for (i = 0; i < n; i++) {
|
1999-10-29 05:53:56 +04:00
|
|
|
nsIReflowCommand* rc = (nsIReflowCommand*) mReflowCommands.ElementAt(i);
|
1999-04-24 00:01:20 +04:00
|
|
|
if (rc) {
|
2000-01-12 11:28:24 +03:00
|
|
|
nsIFrame* target;
|
1999-04-24 00:01:20 +04:00
|
|
|
if (NS_SUCCEEDED(rc->GetTarget(target))) {
|
|
|
|
if (target == aTargetFrame) {
|
2000-01-12 11:28:24 +03:00
|
|
|
if (aCmdType != NULL) {
|
|
|
|
// If aCmdType is specified, only remove reflow commands of that type
|
|
|
|
nsIReflowCommand::ReflowType type;
|
|
|
|
if (NS_SUCCEEDED(rc->GetType(type))) {
|
|
|
|
if (type != *aCmdType)
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
1999-12-23 05:02:33 +03:00
|
|
|
#ifdef DEBUG
|
|
|
|
if (VERIFY_REFLOW_NOISY_RC & gVerifyReflowFlags) {
|
|
|
|
printf("PresShell: removing rc=%p for frame ", rc);
|
|
|
|
nsFrame::ListTag(stdout, aTargetFrame);
|
|
|
|
printf("\n");
|
|
|
|
}
|
1999-10-29 05:53:56 +04:00
|
|
|
#endif
|
1999-04-24 00:01:20 +04:00
|
|
|
mReflowCommands.RemoveElementAt(i);
|
1999-10-29 05:53:56 +04:00
|
|
|
NS_RELEASE(rc);
|
1999-04-24 00:01:20 +04:00
|
|
|
n--;
|
|
|
|
i--;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-11-09 06:23:26 +03:00
|
|
|
|
|
|
|
//-------------- Begin Reflow Event Definition ------------------------
|
|
|
|
|
|
|
|
struct ReflowEvent : public PLEvent {
|
|
|
|
ReflowEvent(nsIPresShell* aPresShell, nsIEventQueue* aQueue);
|
|
|
|
~ReflowEvent() { }
|
|
|
|
|
|
|
|
void HandleEvent() {
|
|
|
|
nsCOMPtr<nsIPresShell> presShell = do_QueryReferent(mPresShell);
|
|
|
|
if (presShell) {
|
1999-12-23 05:02:33 +03:00
|
|
|
#ifdef DEBUG
|
|
|
|
if (VERIFY_REFLOW_NOISY_RC & gVerifyReflowFlags) {
|
1999-12-28 23:26:56 +03:00
|
|
|
printf("\n*** Handling reflow event: PresShell=%p, event=%p\n", presShell.get(), this);
|
1999-12-23 05:02:33 +03:00
|
|
|
}
|
|
|
|
#endif
|
2000-01-28 03:48:02 +03:00
|
|
|
PRBool isBatching;
|
1999-12-23 05:02:33 +03:00
|
|
|
presShell->SetReflowEventStatus(PR_FALSE);
|
1999-11-09 06:23:26 +03:00
|
|
|
presShell->EnterReflowLock();
|
2000-01-28 03:48:02 +03:00
|
|
|
presShell->GetReflowBatchingStatus(&isBatching);
|
|
|
|
if (!isBatching) presShell->ProcessReflowCommands(PR_TRUE);
|
|
|
|
presShell->ExitReflowLock(PR_FALSE);
|
1999-11-09 06:23:26 +03:00
|
|
|
}
|
|
|
|
else
|
|
|
|
mPresShell = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsWeakPtr mPresShell;
|
|
|
|
};
|
|
|
|
|
|
|
|
static void PR_CALLBACK HandlePLEvent(ReflowEvent* aEvent)
|
|
|
|
{
|
|
|
|
aEvent->HandleEvent();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void PR_CALLBACK DestroyPLEvent(ReflowEvent* aEvent)
|
|
|
|
{
|
|
|
|
delete aEvent;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ReflowEvent::ReflowEvent(nsIPresShell* aPresShell, nsIEventQueue* aQueue)
|
|
|
|
{
|
|
|
|
NS_ASSERTION(aPresShell && aQueue, "Null parameters!");
|
|
|
|
|
|
|
|
mPresShell = getter_AddRefs(NS_GetWeakReference(aPresShell));
|
|
|
|
|
|
|
|
PL_InitEvent(this, nsnull,
|
|
|
|
(PLHandleEventProc) ::HandlePLEvent,
|
|
|
|
(PLDestroyEventProc) ::DestroyPLEvent);
|
|
|
|
|
|
|
|
aQueue->PostEvent(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------- End Reflow Event Definition ---------------------------
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
PresShell::PostReflowEvent()
|
|
|
|
{
|
1999-12-23 05:02:33 +03:00
|
|
|
if (!mPendingReflowEvent && mReflowCommands.Count() > 0) {
|
1999-11-09 06:23:26 +03:00
|
|
|
ReflowEvent* ev;
|
|
|
|
ev = new ReflowEvent((nsIPresShell*) this, mEventQueue);
|
1999-12-23 05:02:33 +03:00
|
|
|
#ifdef DEBUG
|
|
|
|
if (VERIFY_REFLOW_NOISY_RC & gVerifyReflowFlags) {
|
|
|
|
printf("\n*** PresShell::PostReflowEvent(), this=%p, event=%p\n", this, ev);
|
|
|
|
}
|
|
|
|
#endif
|
1999-11-09 06:23:26 +03:00
|
|
|
mPendingReflowEvent = PR_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-12-29 07:56:31 +03:00
|
|
|
NS_IMETHODIMP
|
2000-01-24 09:43:15 +03:00
|
|
|
PresShell::ProcessReflowCommands(PRBool aInterruptible)
|
1998-04-14 00:24:54 +04:00
|
|
|
{
|
1999-11-10 06:41:09 +03:00
|
|
|
MOZ_TIMER_DEBUGLOG(("Start: Reflow: PresShell::ProcessReflowCommands(), this=%p\n", this));
|
1999-12-23 05:02:33 +03:00
|
|
|
MOZ_TIMER_START(mReflowWatch);
|
|
|
|
PRTime beforeReflow, afterReflow;
|
|
|
|
PRInt64 diff;
|
|
|
|
|
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-12-23 05:02:33 +03:00
|
|
|
nsIFrame* rootFrame;
|
1999-10-19 02:20:37 +04:00
|
|
|
|
1999-11-09 06:23:26 +03:00
|
|
|
#ifdef DEBUG_nisheeth
|
|
|
|
mReflows++;
|
|
|
|
#endif
|
|
|
|
|
1999-10-19 02:20:37 +04:00
|
|
|
mFrameManager->GetRootFrame(&rootFrame);
|
2000-01-12 01:15:20 +03:00
|
|
|
nsresult rv=CreateRenderingContext(rootFrame, &rcx);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1998-04-14 00:24:54 +04:00
|
|
|
|
1999-09-15 04:27:05 +04:00
|
|
|
#ifdef DEBUG
|
|
|
|
if (GetVerifyReflowEnable()) {
|
|
|
|
if (VERIFY_REFLOW_ALL & gVerifyReflowFlags) {
|
|
|
|
printf("ProcessReflowCommands: begin incremental reflow\n");
|
|
|
|
}
|
1999-10-22 00:45:39 +04:00
|
|
|
}
|
1999-12-23 05:02:33 +03:00
|
|
|
if (VERIFY_REFLOW_DUMP_COMMANDS & gVerifyReflowFlags) {
|
1999-10-22 00:45:39 +04:00
|
|
|
PRInt32 i, n = mReflowCommands.Count();
|
1999-12-23 05:02:33 +03:00
|
|
|
printf("\nPresShell::ProcessReflowCommands: this=%p, count=%d\n", this, n);
|
1999-10-22 00:45:39 +04:00
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
nsIReflowCommand* rc = (nsIReflowCommand*)
|
|
|
|
mReflowCommands.ElementAt(i);
|
|
|
|
rc->List(stdout);
|
1999-09-15 04:27:05 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
1999-12-23 05:02:33 +03:00
|
|
|
|
1998-04-14 00:24:54 +04:00
|
|
|
while (0 != mReflowCommands.Count()) {
|
1999-09-15 04:27:05 +04:00
|
|
|
// Use RemoveElementAt in case the reflowcommand dispatches a
|
|
|
|
// new one during its execution.
|
1998-06-09 08:51:44 +04:00
|
|
|
nsIReflowCommand* rc = (nsIReflowCommand*) mReflowCommands.ElementAt(0);
|
1999-12-23 05:02:33 +03:00
|
|
|
mReflowCommands.RemoveElementAt(0);
|
1998-04-14 00:24:54 +04:00
|
|
|
|
|
|
|
// Dispatch the reflow command
|
1998-04-17 05:41:24 +04:00
|
|
|
nsSize maxSize;
|
1999-10-19 02:20:37 +04:00
|
|
|
rootFrame->GetSize(maxSize);
|
2000-01-24 09:43:15 +03:00
|
|
|
if (aInterruptible) beforeReflow = PR_Now();
|
1999-11-24 09:03:41 +03:00
|
|
|
rc->Dispatch(mPresContext, desiredSize, maxSize, *rcx);
|
2000-01-24 09:43:15 +03:00
|
|
|
if (aInterruptible) afterReflow = PR_Now();
|
1998-06-09 08:51:44 +04:00
|
|
|
NS_RELEASE(rc);
|
1999-09-21 11:53:49 +04:00
|
|
|
VERIFY_STYLE_TREE;
|
1999-12-23 05:02:33 +03:00
|
|
|
|
2000-01-24 09:43:15 +03:00
|
|
|
if (aInterruptible) {
|
2000-01-13 07:27:05 +03:00
|
|
|
PRInt64 totalTime;
|
|
|
|
PRInt64 maxTime;
|
|
|
|
LL_SUB(diff, afterReflow, beforeReflow);
|
|
|
|
|
|
|
|
LL_I2L(totalTime, mAccumulatedReflowTime);
|
|
|
|
LL_ADD(totalTime, totalTime, diff);
|
|
|
|
LL_L2I(mAccumulatedReflowTime, totalTime);
|
|
|
|
|
|
|
|
LL_I2L(maxTime, gMaxRCProcessingTime);
|
|
|
|
if (LL_CMP(totalTime, >, maxTime))
|
2000-01-19 06:58:05 +03:00
|
|
|
break;
|
1999-12-23 05:02:33 +03:00
|
|
|
}
|
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
|
|
|
|
2000-01-24 09:43:15 +03:00
|
|
|
if (aInterruptible) {
|
1999-12-23 05:02:33 +03:00
|
|
|
if (mReflowCommands.Count() > 0) {
|
|
|
|
// Reflow Commands are still queued up.
|
|
|
|
// Schedule a reflow event to handle them asynchronously.
|
|
|
|
PostReflowEvent();
|
|
|
|
}
|
1999-09-15 04:27:05 +04:00
|
|
|
#ifdef DEBUG
|
2000-01-13 07:27:05 +03:00
|
|
|
if (VERIFY_REFLOW_DUMP_COMMANDS & gVerifyReflowFlags) {
|
|
|
|
printf("Time spent in PresShell::ProcessReflowCommands(), this=%p, time=%d micro seconds\n",
|
|
|
|
this, mAccumulatedReflowTime);
|
1999-12-23 05:02:33 +03:00
|
|
|
}
|
2000-01-12 11:28:24 +03:00
|
|
|
#endif
|
1999-12-23 06:47:02 +03:00
|
|
|
mAccumulatedReflowTime = 0;
|
1999-12-23 05:02:33 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
if (VERIFY_REFLOW_DUMP_COMMANDS & gVerifyReflowFlags) {
|
|
|
|
printf("\nPresShell::ProcessReflowCommands() finished: this=%p\n", this);
|
|
|
|
}
|
|
|
|
|
1999-11-02 01:12:45 +03:00
|
|
|
if (nsIFrameDebug::GetVerifyTreeEnable()) {
|
|
|
|
nsIFrameDebug* frameDebug;
|
|
|
|
|
2000-01-04 23:24:09 +03:00
|
|
|
if (NS_SUCCEEDED(rootFrame->QueryInterface(NS_GET_IID(nsIFrameDebug),
|
|
|
|
(void**)&frameDebug))) {
|
1999-11-02 01:12:45 +03:00
|
|
|
frameDebug->VerifyTree();
|
|
|
|
}
|
1998-05-20 20:24:54 +04:00
|
|
|
}
|
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.
|
1999-09-10 22:49:23 +04:00
|
|
|
nsIView* rootView;
|
|
|
|
mViewManager->GetRootView(rootView);
|
1999-11-14 05:51:25 +03:00
|
|
|
mViewManager->UpdateView(rootView, NS_VMREFRESH_IMMEDIATE);
|
1998-12-12 22:21:05 +03:00
|
|
|
|
1998-11-26 21:11:02 +03:00
|
|
|
mInVerifyReflow = PR_TRUE;
|
1999-09-10 22:49:23 +04:00
|
|
|
PRBool ok = VerifyIncrementalReflow();
|
1998-11-26 21:11:02 +03:00
|
|
|
mInVerifyReflow = PR_FALSE;
|
1999-09-15 04:27:05 +04:00
|
|
|
if (VERIFY_REFLOW_ALL & gVerifyReflowFlags) {
|
|
|
|
printf("ProcessReflowCommands: finished (%s)\n",
|
|
|
|
ok ? "ok" : "failed");
|
1998-12-12 22:21:05 +03:00
|
|
|
}
|
1998-11-26 21:11:02 +03:00
|
|
|
|
|
|
|
if (0 != mReflowCommands.Count()) {
|
1999-09-10 22:49:23 +04:00
|
|
|
printf("XXX yikes! reflow commands queued during verify-reflow\n");
|
1998-11-26 21:11:02 +03:00
|
|
|
}
|
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
|
|
|
}
|
1999-12-23 05:02:33 +03:00
|
|
|
|
1999-11-10 06:41:09 +03:00
|
|
|
MOZ_TIMER_DEBUGLOG(("Stop: Reflow: PresShell::ProcessReflowCommands(), this=%p\n", this));
|
1999-12-23 05:02:33 +03:00
|
|
|
MOZ_TIMER_STOP(mReflowWatch);
|
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);
|
|
|
|
}
|
1999-04-02 03:58:11 +04:00
|
|
|
|
|
|
|
if (mCaret) {
|
|
|
|
mCaret->ClearFrameRefs(aFrame);
|
|
|
|
}
|
|
|
|
|
1998-11-21 03:19:36 +03:00
|
|
|
if (aFrame == mCurrentEventFrame) {
|
1999-06-15 07:14:28 +04:00
|
|
|
mCurrentEventFrame->GetContent(&mCurrentEventContent);
|
1998-11-21 03:19:36 +03:00
|
|
|
mCurrentEventFrame = nsnull;
|
|
|
|
}
|
1999-09-02 22:14:01 +04:00
|
|
|
|
|
|
|
for (int i=0; i<mCurrentEventFrameStack.Count(); i++) {
|
|
|
|
if (aFrame == (nsIFrame*)mCurrentEventFrameStack.ElementAt(i)) {
|
|
|
|
mCurrentEventFrameStack.ReplaceElementAt(nsnull, i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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
|
|
|
nsIView *view = nsnull;
|
|
|
|
nsPoint pt;
|
|
|
|
nsresult rv;
|
|
|
|
|
1999-10-26 08:44:41 +04:00
|
|
|
aFrame->GetView(mPresContext, &view);
|
1998-10-02 05:12:39 +04:00
|
|
|
|
|
|
|
if (nsnull == view)
|
1999-10-26 08:44:41 +04:00
|
|
|
aFrame->GetOffsetFromView(mPresContext, pt, &view);
|
1998-10-02 05:12:39 +04:00
|
|
|
|
2000-01-27 02:04:40 +03:00
|
|
|
nsCOMPtr<nsIWidget> widget;
|
|
|
|
if (nsnull != view) {
|
|
|
|
nsCOMPtr<nsIViewManager> vm;
|
|
|
|
view->GetViewManager(*getter_AddRefs(vm));
|
|
|
|
vm->GetWidgetForView(view, getter_AddRefs(widget));
|
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) {
|
2000-01-27 02:04:40 +03:00
|
|
|
if (nsnull != widget) {
|
|
|
|
rv = dx->CreateRenderingContext(widget, result);
|
1999-02-12 20:45:58 +03:00
|
|
|
}
|
|
|
|
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
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::CantRenderReplacedElement(nsIPresContext* aPresContext,
|
|
|
|
nsIFrame* aFrame)
|
|
|
|
{
|
1999-08-06 00:17:44 +04:00
|
|
|
if (mFrameManager) {
|
1999-10-30 05:31:49 +04:00
|
|
|
return mFrameManager->CantRenderReplacedElement(aPresContext, aFrame);
|
1999-02-05 21:25:29 +03:00
|
|
|
}
|
1999-08-06 00:17:44 +04:00
|
|
|
|
|
|
|
return NS_OK;
|
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;
|
1999-03-20 04:51:00 +03:00
|
|
|
nsCOMPtr<nsIXMLDocument> xmlDoc;
|
1999-04-14 01:50:47 +04:00
|
|
|
nsresult rv = NS_OK;
|
1999-03-20 04:51:00 +03:00
|
|
|
nsCOMPtr<nsIContent> content;
|
1999-02-12 08:39:33 +03:00
|
|
|
|
2000-01-04 23:24:09 +03:00
|
|
|
if (NS_SUCCEEDED(mDocument->QueryInterface(NS_GET_IID(nsIDOMHTMLDocument),
|
1999-03-20 04:51:00 +03:00
|
|
|
getter_AddRefs(htmlDoc)))) {
|
1999-02-12 08:39:33 +03:00
|
|
|
nsCOMPtr<nsIDOMElement> element;
|
|
|
|
|
1999-03-20 04:51:00 +03:00
|
|
|
// Find the element with the specified id
|
|
|
|
rv = htmlDoc->GetElementById(aAnchorName, getter_AddRefs(element));
|
1999-04-09 08:28:15 +04:00
|
|
|
if (NS_SUCCEEDED(rv) && element) {
|
1999-02-12 08:39:33 +03:00
|
|
|
// Get the nsIContent interface, because that's what we need to
|
|
|
|
// get the primary frame
|
2000-01-04 23:24:09 +03:00
|
|
|
rv = element->QueryInterface(NS_GET_IID(nsIContent),
|
|
|
|
getter_AddRefs(content));
|
1999-03-20 04:51:00 +03:00
|
|
|
}
|
|
|
|
}
|
2000-01-04 23:24:09 +03:00
|
|
|
else if (NS_SUCCEEDED(mDocument->QueryInterface(NS_GET_IID(nsIXMLDocument),
|
1999-03-20 04:51:00 +03:00
|
|
|
getter_AddRefs(xmlDoc)))) {
|
|
|
|
rv = xmlDoc->GetContentById(aAnchorName, getter_AddRefs(content));
|
|
|
|
}
|
1999-02-12 08:39:33 +03:00
|
|
|
|
1999-04-09 08:28:15 +04:00
|
|
|
if (NS_SUCCEEDED(rv) && content) {
|
1999-03-20 04:51:00 +03:00
|
|
|
nsIFrame* frame;
|
|
|
|
|
|
|
|
// Get the primary frame
|
|
|
|
if (NS_SUCCEEDED(GetPrimaryFrameFor(content, &frame))) {
|
1999-07-19 22:38:33 +04:00
|
|
|
rv = ScrollFrameIntoView(frame, NS_PRESSHELL_SCROLL_TOP,
|
|
|
|
NS_PRESSHELL_SCROLL_ANYWHERE);
|
1999-02-12 08:39:33 +03:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
rv = NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1999-02-19 01:52:21 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::ScrollFrameIntoView(nsIFrame *aFrame,
|
1999-07-19 22:38:33 +04:00
|
|
|
PRIntn aVPercent,
|
|
|
|
PRIntn aHPercent) const
|
1999-02-19 01:52:21 +03:00
|
|
|
{
|
1999-07-19 22:38:33 +04:00
|
|
|
nsresult rv = NS_OK;
|
|
|
|
if (!aFrame) {
|
1999-02-19 01:52:21 +03:00
|
|
|
return NS_ERROR_NULL_POINTER;
|
1999-07-19 22:38:33 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (mViewManager) {
|
|
|
|
// Get the viewport scroller
|
1999-02-19 01:52:21 +03:00
|
|
|
nsIScrollableView* scrollingView;
|
|
|
|
mViewManager->GetRootScrollableView(&scrollingView);
|
|
|
|
|
|
|
|
if (scrollingView) {
|
|
|
|
nsIView* scrolledView;
|
|
|
|
nsPoint offset;
|
1999-07-19 22:38:33 +04:00
|
|
|
nsIView* closestView;
|
1999-02-19 01:52:21 +03:00
|
|
|
|
1999-07-19 22:38:33 +04:00
|
|
|
// Determine the offset from aFrame to the scrolled view. We do that by
|
|
|
|
// getting the offset from its closest view and then walking up
|
1999-02-19 01:52:21 +03:00
|
|
|
scrollingView->GetScrolledView(scrolledView);
|
1999-10-26 08:44:41 +04:00
|
|
|
aFrame->GetOffsetFromView(mPresContext, offset, &closestView);
|
1999-07-19 22:38:33 +04:00
|
|
|
|
|
|
|
// XXX Deal with the case where there is a scrolled element, e.g., a
|
|
|
|
// DIV in the middle...
|
1999-08-08 00:43:47 +04:00
|
|
|
while ((closestView != nsnull) && (closestView != scrolledView)) {
|
1999-07-19 22:38:33 +04:00
|
|
|
nscoord x, y;
|
|
|
|
|
|
|
|
// Update the offset
|
|
|
|
closestView->GetPosition(&x, &y);
|
|
|
|
offset.MoveBy(x, y);
|
|
|
|
|
|
|
|
// Get its parent view
|
|
|
|
closestView->GetParent(closestView);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Determine the visible rect in the scrolled view's coordinate space.
|
|
|
|
// The size of the visible area is the clip view size
|
|
|
|
const nsIView* clipView;
|
|
|
|
nsRect visibleRect;
|
|
|
|
|
|
|
|
scrollingView->GetScrollPosition(visibleRect.x, visibleRect.y);
|
|
|
|
scrollingView->GetClipView(&clipView);
|
|
|
|
clipView->GetDimensions(&visibleRect.width, &visibleRect.height);
|
|
|
|
|
|
|
|
// The actual scroll offsets
|
|
|
|
nscoord scrollOffsetX = visibleRect.x;
|
|
|
|
nscoord scrollOffsetY = visibleRect.y;
|
|
|
|
|
|
|
|
// The frame's bounds in the coordinate space of the scrolled frame
|
|
|
|
nsRect frameBounds;
|
|
|
|
aFrame->GetRect(frameBounds);
|
|
|
|
frameBounds.x = offset.x;
|
|
|
|
frameBounds.y = offset.y;
|
|
|
|
|
|
|
|
// See how the frame should be positioned vertically
|
|
|
|
if (NS_PRESSHELL_SCROLL_ANYWHERE == aVPercent) {
|
|
|
|
// The caller doesn't care where the frame is positioned vertically,
|
|
|
|
// so long as it's fully visible
|
|
|
|
if (frameBounds.y < visibleRect.y) {
|
|
|
|
// Scroll up so the frame's top edge is visible
|
|
|
|
scrollOffsetY = frameBounds.y;
|
|
|
|
} else if (frameBounds.YMost() > visibleRect.YMost()) {
|
|
|
|
// Scroll down so the frame's bottom edge is visible. Make sure the
|
|
|
|
// frame's top edge is still visible
|
|
|
|
scrollOffsetY += frameBounds.YMost() - visibleRect.YMost();
|
|
|
|
if (scrollOffsetY > frameBounds.y) {
|
|
|
|
scrollOffsetY = frameBounds.y;
|
1999-02-20 02:43:41 +03:00
|
|
|
}
|
|
|
|
}
|
2000-01-25 23:36:24 +03:00
|
|
|
} else if (NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE == aVPercent) {
|
|
|
|
// Scroll only if no part of the frame is visible in this view
|
|
|
|
if (frameBounds.YMost() < visibleRect.y) {
|
|
|
|
// Scroll up so the frame's top edge is visible
|
|
|
|
scrollOffsetY = frameBounds.y;
|
|
|
|
} else if (frameBounds.y > visibleRect.YMost()) {
|
|
|
|
// Scroll down so the frame's bottom edge is visible. Make sure the
|
|
|
|
// frame's top edge is still visible
|
|
|
|
scrollOffsetY += frameBounds.YMost() - visibleRect.YMost();
|
|
|
|
if (scrollOffsetY > frameBounds.y) {
|
|
|
|
scrollOffsetY = frameBounds.y;
|
|
|
|
}
|
|
|
|
}
|
1999-07-19 22:38:33 +04:00
|
|
|
} else {
|
|
|
|
// Align the frame edge according to the specified percentage
|
|
|
|
nscoord frameAlignY = frameBounds.y + (frameBounds.height * aVPercent) / 100;
|
|
|
|
scrollOffsetY = frameAlignY - (visibleRect.height * aVPercent) / 100;
|
|
|
|
}
|
|
|
|
|
|
|
|
// See how the frame should be positioned horizontally
|
|
|
|
if (NS_PRESSHELL_SCROLL_ANYWHERE == aHPercent) {
|
|
|
|
// The caller doesn't care where the frame is positioned horizontally,
|
|
|
|
// so long as it's fully visible
|
|
|
|
if (frameBounds.x < visibleRect.x) {
|
|
|
|
// Scroll left so the frame's left edge is visible
|
|
|
|
scrollOffsetX = frameBounds.x;
|
|
|
|
} else if (frameBounds.XMost() > visibleRect.XMost()) {
|
|
|
|
// Scroll right so the frame's right edge is visible. Make sure the
|
|
|
|
// frame's left edge is still visible
|
|
|
|
scrollOffsetX += frameBounds.XMost() - visibleRect.XMost();
|
|
|
|
if (scrollOffsetX > frameBounds.x) {
|
|
|
|
scrollOffsetX = frameBounds.x;
|
1999-02-21 00:27:28 +03:00
|
|
|
}
|
1999-02-20 02:43:41 +03:00
|
|
|
}
|
2000-01-25 23:36:24 +03:00
|
|
|
} else if (NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE == aHPercent) {
|
|
|
|
// Scroll only if no part of the frame is visible in this view
|
|
|
|
if (frameBounds.XMost() < visibleRect.x) {
|
|
|
|
// Scroll left so the frame's left edge is visible
|
|
|
|
scrollOffsetX = frameBounds.x;
|
|
|
|
} else if (frameBounds.x > visibleRect.XMost()) {
|
|
|
|
// Scroll right so the frame's right edge is visible. Make sure the
|
|
|
|
// frame's left edge is still visible
|
|
|
|
scrollOffsetX += frameBounds.XMost() - visibleRect.XMost();
|
|
|
|
if (scrollOffsetX > frameBounds.x) {
|
|
|
|
scrollOffsetX = frameBounds.x;
|
|
|
|
}
|
|
|
|
}
|
1999-07-19 22:38:33 +04:00
|
|
|
} else {
|
|
|
|
// Align the frame edge according to the specified percentage
|
|
|
|
nscoord frameAlignX = frameBounds.x + (frameBounds.width * aHPercent) / 100;
|
|
|
|
scrollOffsetX = frameAlignX - (visibleRect.width * aHPercent) / 100;
|
1999-02-20 02:43:41 +03:00
|
|
|
}
|
2000-01-25 23:36:24 +03:00
|
|
|
if (scrollOffsetX != 0 || scrollOffsetY != 0) {
|
|
|
|
scrollingView->ScrollTo(scrollOffsetX, scrollOffsetY, NS_VMREFRESH_IMMEDIATE);
|
|
|
|
}
|
1999-02-19 01:52:21 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1999-04-07 07:56:07 +04:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::DoCopy()
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDocument> doc;
|
|
|
|
GetDocument(getter_AddRefs(doc));
|
|
|
|
if (doc) {
|
|
|
|
nsString buffer;
|
1999-11-05 04:29:49 +03:00
|
|
|
nsresult rv;
|
|
|
|
|
1999-12-03 00:45:21 +03:00
|
|
|
nsIDOMSelection* sel;
|
1999-07-18 06:27:19 +04:00
|
|
|
GetSelection(SELECTION_NORMAL, &sel);
|
1999-04-07 07:56:07 +04:00
|
|
|
|
|
|
|
if (sel != nsnull)
|
|
|
|
doc->CreateXIF(buffer,sel);
|
|
|
|
NS_IF_RELEASE(sel);
|
|
|
|
|
|
|
|
// Get the Clipboard
|
1999-11-05 04:29:49 +03:00
|
|
|
NS_WITH_SERVICE(nsIClipboard, clipboard, kCClipboardCID, &rv);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-04-07 07:56:07 +04:00
|
|
|
|
1999-08-25 12:35:06 +04:00
|
|
|
if ( clipboard ) {
|
1999-05-14 01:53:57 +04:00
|
|
|
// Create a transferable for putting data on the Clipboard
|
|
|
|
nsCOMPtr<nsITransferable> trans;
|
|
|
|
rv = nsComponentManager::CreateInstance(kCTransferableCID, nsnull,
|
2000-01-04 23:24:09 +03:00
|
|
|
NS_GET_IID(nsITransferable),
|
|
|
|
getter_AddRefs(trans));
|
1999-08-25 12:35:06 +04:00
|
|
|
if ( trans ) {
|
1999-05-14 01:53:57 +04:00
|
|
|
// The data on the clipboard will be in "XIF" format
|
|
|
|
// so give the clipboard transferable a "XIFConverter" for
|
|
|
|
// converting from XIF to other formats
|
|
|
|
nsCOMPtr<nsIFormatConverter> xifConverter;
|
|
|
|
rv = nsComponentManager::CreateInstance(kCXIFConverterCID, nsnull,
|
2000-01-04 23:24:09 +03:00
|
|
|
NS_GET_IID(nsIFormatConverter),
|
|
|
|
getter_AddRefs(xifConverter));
|
1999-08-25 12:35:06 +04:00
|
|
|
if ( xifConverter ) {
|
1999-05-14 01:53:57 +04:00
|
|
|
// Add the XIF DataFlavor to the transferable
|
|
|
|
// this tells the transferable that it can handle receiving the XIF format
|
1999-08-25 12:35:06 +04:00
|
|
|
trans->AddDataFlavor(kXIFMime);
|
1999-05-14 01:53:57 +04:00
|
|
|
|
|
|
|
// Add the converter for going from XIF to other formats
|
|
|
|
trans->SetConverter(xifConverter);
|
|
|
|
|
1999-08-25 12:35:06 +04:00
|
|
|
// Now add the XIF data to the transferable, placing it into a nsISupportsWString object.
|
1999-07-23 06:25:17 +04:00
|
|
|
// the transferable wants the number bytes for the data and since it is double byte
|
1999-08-25 12:35:06 +04:00
|
|
|
// we multiply by 2.
|
|
|
|
nsCOMPtr<nsISupportsWString> dataWrapper;
|
2000-01-04 23:24:09 +03:00
|
|
|
rv = nsComponentManager::CreateInstance(NS_SUPPORTS_WSTRING_PROGID,
|
|
|
|
nsnull,
|
|
|
|
NS_GET_IID(nsISupportsWString),
|
|
|
|
getter_AddRefs(dataWrapper));
|
1999-08-25 12:35:06 +04:00
|
|
|
if ( dataWrapper ) {
|
|
|
|
dataWrapper->SetData ( NS_CONST_CAST(PRUnichar*,buffer.GetUnicode()) );
|
|
|
|
// QI the data object an |nsISupports| so that when the transferable holds
|
|
|
|
// onto it, it will addref the correct interface.
|
|
|
|
nsCOMPtr<nsISupports> genericDataObj ( do_QueryInterface(dataWrapper) );
|
|
|
|
trans->SetTransferData(kXIFMime, genericDataObj, buffer.Length()*2);
|
|
|
|
}
|
|
|
|
|
1999-05-14 01:53:57 +04:00
|
|
|
// put the transferable on the clipboard
|
|
|
|
clipboard->SetData(trans, nsnull);
|
1999-04-07 07:56:07 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-12-06 10:44:18 +03:00
|
|
|
|
|
|
|
// XXX This function needs to be renamed to something better.
|
|
|
|
// It is not simply a getter for the layout history state. It
|
|
|
|
// creates a new state object and captures frame state onto it.
|
1999-08-31 02:38:58 +04:00
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::GetHistoryState(nsILayoutHistoryState** aState)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
|
|
|
NS_PRECONDITION(nsnull != aState, "null state pointer");
|
|
|
|
|
2000-01-14 12:28:54 +03:00
|
|
|
if (!mHistoryState) {
|
|
|
|
// Create the document state object
|
|
|
|
rv = NS_NewLayoutHistoryState(aState); // This addrefs
|
1999-08-31 02:38:58 +04:00
|
|
|
|
2000-01-14 12:28:54 +03:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
*aState = nsnull;
|
|
|
|
return rv;
|
|
|
|
}
|
1999-08-31 02:38:58 +04:00
|
|
|
|
2000-01-14 12:28:54 +03:00
|
|
|
// Capture frame state for the entire frame hierarchy
|
|
|
|
nsIFrame* rootFrame = nsnull;
|
|
|
|
rv = GetRootFrame(&rootFrame);
|
|
|
|
if (NS_FAILED(rv) || nsnull == rootFrame) return rv;
|
1999-08-31 02:38:58 +04:00
|
|
|
|
2000-01-14 12:28:54 +03:00
|
|
|
rv = mFrameManager->CaptureFrameState(mPresContext, rootFrame, *aState);
|
1999-08-31 02:38:58 +04:00
|
|
|
|
2000-01-14 12:28:54 +03:00
|
|
|
mHistoryState = *aState;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
*aState = mHistoryState;
|
|
|
|
NS_IF_ADDREF(mHistoryState);
|
|
|
|
|
1999-08-31 02:38:58 +04:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-08-31 18:35:50 +04:00
|
|
|
PresShell::SetHistoryState(nsILayoutHistoryState* aLayoutHistoryState)
|
1999-08-31 02:38:58 +04:00
|
|
|
{
|
1999-08-31 18:35:50 +04:00
|
|
|
mHistoryState = aLayoutHistoryState;
|
|
|
|
return NS_OK;
|
1999-08-31 02:38:58 +04:00
|
|
|
}
|
1999-04-07 07:56:07 +04:00
|
|
|
|
1999-11-09 06:23:26 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::GetReflowEventStatus(PRBool* aPending)
|
|
|
|
{
|
|
|
|
if (aPending)
|
|
|
|
*aPending = mPendingReflowEvent;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::SetReflowEventStatus(PRBool aPending)
|
|
|
|
{
|
|
|
|
mPendingReflowEvent = aPending;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2000-01-29 01:58:17 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::FlushPendingNotifications()
|
|
|
|
{
|
|
|
|
// XXX Only flush if the lock count is 0. Ideally nothing
|
|
|
|
// besides Enter/ExitReflowLock should call ProcessReflowCommands.
|
|
|
|
// Will be changed by Nisheeth.
|
|
|
|
if (!mReflowLockCount) {
|
|
|
|
ProcessReflowCommands(PR_FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2000-02-09 18:48:01 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::IsReflowLocked(PRBool* aIsReflowLocked)
|
|
|
|
{
|
|
|
|
*aIsReflowLocked = (mReflowLockCount > 0);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2000-01-28 03:48:02 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::BeginBatchingReflows()
|
|
|
|
{
|
|
|
|
mBatchReflows = PR_TRUE;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::EndBatchingReflows(PRBool aFlushPendingReflows)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
mBatchReflows = PR_FALSE;
|
|
|
|
if (aFlushPendingReflows) {
|
|
|
|
rv = FlushPendingNotifications();
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::GetReflowBatchingStatus(PRBool* aIsBatching)
|
|
|
|
{
|
|
|
|
*aIsBatching = mBatchReflows;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
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-30 05:31:04 +04:00
|
|
|
EnterReflowLock();
|
1998-09-30 03:46:05 +04:00
|
|
|
nsresult rv = mStyleSet->ContentChanged(mPresContext, aContent, aSubContent);
|
1999-09-21 11:53:49 +04:00
|
|
|
VERIFY_STYLE_TREE;
|
2000-01-25 19:00:44 +03:00
|
|
|
ExitReflowLock(PR_TRUE);
|
1999-01-29 21:57:56 +03:00
|
|
|
|
1998-09-30 03:46:05 +04:00
|
|
|
return rv;
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
|
1999-02-27 10:15:09 +03:00
|
|
|
NS_IMETHODIMP
|
1999-04-20 04:06:58 +04:00
|
|
|
PresShell::ContentStatesChanged(nsIDocument* aDocument,
|
|
|
|
nsIContent* aContent1,
|
|
|
|
nsIContent* aContent2)
|
1999-02-27 10:15:09 +03:00
|
|
|
{
|
|
|
|
EnterReflowLock();
|
1999-04-20 04:06:58 +04:00
|
|
|
nsresult rv = mStyleSet->ContentStatesChanged(mPresContext, aContent1, aContent2);
|
1999-09-21 11:53:49 +04:00
|
|
|
VERIFY_STYLE_TREE;
|
2000-01-25 19:00:44 +03:00
|
|
|
ExitReflowLock(PR_TRUE);
|
1999-02-27 10:15:09 +03:00
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1998-09-18 23:53:27 +04:00
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::AttributeChanged(nsIDocument *aDocument,
|
|
|
|
nsIContent* aContent,
|
1999-10-16 03:16:45 +04:00
|
|
|
PRInt32 aNameSpaceID,
|
1998-09-30 03:46:05 +04:00
|
|
|
nsIAtom* aAttribute,
|
|
|
|
PRInt32 aHint)
|
1998-09-18 23:53:27 +04:00
|
|
|
{
|
|
|
|
EnterReflowLock();
|
1999-10-16 03:16:45 +04:00
|
|
|
nsresult rv = mStyleSet->AttributeChanged(mPresContext, aContent, aNameSpaceID, aAttribute, aHint);
|
1999-09-21 11:53:49 +04:00
|
|
|
VERIFY_STYLE_TREE;
|
2000-01-25 19:00:44 +03:00
|
|
|
ExitReflowLock(PR_TRUE);
|
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();
|
1999-11-10 06:41:09 +03:00
|
|
|
MOZ_TIMER_DEBUGLOG(("Start: Frame Creation: PresShell::ContentAppended(), this=%p\n", this));
|
|
|
|
MOZ_TIMER_START(mFrameCreationWatch);
|
1998-09-30 03:46:05 +04:00
|
|
|
nsresult rv = mStyleSet->ContentAppended(mPresContext, aContainer, aNewIndexInContainer);
|
1999-09-21 11:53:49 +04:00
|
|
|
VERIFY_STYLE_TREE;
|
1999-08-31 18:35:50 +04:00
|
|
|
|
|
|
|
if (NS_SUCCEEDED(rv) && nsnull != mHistoryState) {
|
|
|
|
// If history state has been set by session history, ask the frame manager
|
|
|
|
// to restore frame state for the frame hierarchy created for the chunk of
|
|
|
|
// content that just came in.
|
1999-09-24 05:58:32 +04:00
|
|
|
nsIFrame* frame;
|
1999-08-31 18:35:50 +04:00
|
|
|
rv = GetPrimaryFrameFor(aContainer, &frame);
|
1999-09-24 05:58:32 +04:00
|
|
|
if (NS_SUCCEEDED(rv) && nsnull != frame)
|
1999-10-26 08:44:41 +04:00
|
|
|
mFrameManager->RestoreFrameState(mPresContext, frame, mHistoryState);
|
1999-08-31 18:35:50 +04:00
|
|
|
}
|
|
|
|
|
1999-11-10 06:41:09 +03:00
|
|
|
MOZ_TIMER_DEBUGLOG(("Stop: Frame Creation: PresShell::ContentAppended(), this=%p\n", this));
|
|
|
|
MOZ_TIMER_STOP(mFrameCreationWatch);
|
2000-01-25 19:00:44 +03:00
|
|
|
ExitReflowLock(PR_TRUE);
|
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);
|
1999-09-21 11:53:49 +04:00
|
|
|
VERIFY_STYLE_TREE;
|
2000-01-25 19:00:44 +03:00
|
|
|
ExitReflowLock(PR_TRUE);
|
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::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);
|
1999-09-21 11:53:49 +04:00
|
|
|
VERIFY_STYLE_TREE;
|
2000-01-25 19:00:44 +03:00
|
|
|
ExitReflowLock(PR_TRUE);
|
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-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);
|
1999-09-21 11:53:49 +04:00
|
|
|
VERIFY_STYLE_TREE;
|
2000-01-25 19:00:44 +03:00
|
|
|
ExitReflowLock(PR_TRUE);
|
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;
|
1999-01-26 03:05:21 +03:00
|
|
|
|
1999-03-01 19:57:35 +03:00
|
|
|
EnterReflowLock();
|
|
|
|
rv = mStyleSet->ReconstructDocElementHierarchy(mPresContext);
|
1999-09-21 11:53:49 +04:00
|
|
|
VERIFY_STYLE_TREE;
|
2000-01-25 19:00:44 +03:00
|
|
|
ExitReflowLock(PR_TRUE);
|
1999-03-01 19:57:35 +03:00
|
|
|
|
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);
|
1999-09-21 11:53:49 +04:00
|
|
|
VERIFY_STYLE_TREE;
|
2000-01-25 19:00:44 +03:00
|
|
|
ExitReflowLock(PR_TRUE);
|
1998-11-26 04:34:53 +03:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::StyleRuleAdded(nsIDocument *aDocument,
|
|
|
|
nsIStyleSheet* aStyleSheet,
|
|
|
|
nsIStyleRule* aStyleRule)
|
|
|
|
{
|
|
|
|
EnterReflowLock();
|
1999-04-03 22:58:04 +04:00
|
|
|
nsresult rv = mStyleSet->StyleRuleAdded(mPresContext, aStyleSheet,
|
|
|
|
aStyleRule);
|
1999-09-21 11:53:49 +04:00
|
|
|
VERIFY_STYLE_TREE;
|
2000-01-25 19:00:44 +03:00
|
|
|
ExitReflowLock(PR_TRUE);
|
1999-04-03 22:58:04 +04:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
1999-03-10 04:17:49 +03:00
|
|
|
// XXX For now reconstruct everything
|
|
|
|
return ReconstructFrames();
|
1998-11-26 04:34:53 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::StyleRuleRemoved(nsIDocument *aDocument,
|
|
|
|
nsIStyleSheet* aStyleSheet,
|
|
|
|
nsIStyleRule* aStyleRule)
|
|
|
|
{
|
|
|
|
EnterReflowLock();
|
1999-04-03 22:58:04 +04:00
|
|
|
nsresult rv = mStyleSet->StyleRuleRemoved(mPresContext, aStyleSheet,
|
|
|
|
aStyleRule);
|
1999-09-21 11:53:49 +04:00
|
|
|
VERIFY_STYLE_TREE;
|
2000-01-25 19:00:44 +03:00
|
|
|
ExitReflowLock(PR_TRUE);
|
1999-04-03 22:58:04 +04:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
1999-03-10 04:17:49 +03:00
|
|
|
// XXX For now reconstruct everything
|
|
|
|
return ReconstructFrames();
|
1998-11-26 04:34:53 +03:00
|
|
|
}
|
|
|
|
|
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-12-29 07:45:18 +03:00
|
|
|
NS_IMETHODIMP
|
1999-02-12 20:45:58 +03:00
|
|
|
PresShell::GetPrimaryFrameFor(nsIContent* aContent,
|
1999-07-06 07:52:33 +04:00
|
|
|
nsIFrame** aResult) const
|
1998-04-14 00:24:54 +04:00
|
|
|
{
|
1999-08-05 07:23:39 +04:00
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
if (mFrameManager) {
|
|
|
|
rv = mFrameManager->GetPrimaryFrameFor(aContent, aResult);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
*aResult = nsnull;
|
|
|
|
rv = NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
|
1999-02-25 22:55:06 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::GetStyleContextFor(nsIFrame* aFrame,
|
|
|
|
nsIStyleContext** aStyleContext) const
|
|
|
|
{
|
|
|
|
if (!aFrame || !aStyleContext) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
|
|
|
return (aFrame->GetStyleContext(aStyleContext));
|
|
|
|
}
|
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))
|
|
|
|
{
|
2000-01-04 23:24:09 +03:00
|
|
|
result = primaryFrame->QueryInterface(NS_GET_IID(nsISupports),
|
|
|
|
(void**)aResult);
|
1999-02-11 02:21:22 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
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-08-05 07:23:39 +04:00
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
if (mFrameManager) {
|
|
|
|
rv = mFrameManager->GetPlaceholderFrameFor(aFrame, aResult);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
*aResult = nsnull;
|
|
|
|
rv = NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
1998-12-29 06:38:16 +03:00
|
|
|
}
|
|
|
|
|
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;
|
1999-09-15 03:43:35 +04:00
|
|
|
|
|
|
|
if (nsnull != frame)
|
|
|
|
{
|
|
|
|
StCaretHider caretHider(this); // stack-based class hides caret until dtor.
|
1998-08-28 06:54:06 +04:00
|
|
|
|
1999-11-24 09:03:41 +03:00
|
|
|
rv = frame->Paint(mPresContext, aRenderingContext, aDirtyRect,
|
1999-03-26 03:39:35 +03:00
|
|
|
NS_FRAME_PAINT_LAYER_BACKGROUND);
|
1999-11-24 09:03:41 +03:00
|
|
|
rv = frame->Paint(mPresContext, aRenderingContext, aDirtyRect,
|
1999-03-26 03:39:35 +03:00
|
|
|
NS_FRAME_PAINT_LAYER_FLOATERS);
|
1999-11-24 09:03:41 +03:00
|
|
|
rv = frame->Paint(mPresContext, aRenderingContext, aDirtyRect,
|
1999-03-26 03:39:35 +03:00
|
|
|
NS_FRAME_PAINT_LAYER_FOREGROUND);
|
1999-09-15 03:43:35 +04:00
|
|
|
|
|
|
|
|
1998-10-31 01:06:14 +03:00
|
|
|
#ifdef NS_DEBUG
|
|
|
|
// Draw a border around the frame
|
1999-11-02 01:12:45 +03:00
|
|
|
if (nsIFrameDebug::GetShowFrameBorders()) {
|
1998-10-31 01:06:14 +03:00
|
|
|
nsRect r;
|
|
|
|
frame->GetRect(r);
|
|
|
|
aRenderingContext.SetColor(NS_RGB(0,0,255));
|
|
|
|
aRenderingContext.DrawRect(0, 0, r.width, r.height);
|
|
|
|
}
|
2000-02-03 05:49:58 +03:00
|
|
|
// Draw a border around the current event target
|
|
|
|
if ((nsIFrameDebug::GetShowEventTargetFrameBorder()) && (aView == mCurrentTargetView)) {
|
|
|
|
aRenderingContext.SetColor(NS_RGB(128,0,128));
|
|
|
|
aRenderingContext.DrawRect(mCurrentTargetRect.x, mCurrentTargetRect.y, mCurrentTargetRect.width, mCurrentTargetRect.height);
|
|
|
|
}
|
1998-10-31 01:06:14 +03:00
|
|
|
#endif
|
|
|
|
}
|
1999-09-15 03:43:35 +04:00
|
|
|
|
1998-08-28 06:54:06 +04:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1999-06-15 07:14:28 +04:00
|
|
|
nsIFrame*
|
|
|
|
PresShell::GetCurrentEventFrame()
|
|
|
|
{
|
|
|
|
if (!mCurrentEventFrame && mCurrentEventContent) {
|
1999-11-03 10:11:45 +03:00
|
|
|
// Make sure the content still has a document reference. If not,
|
|
|
|
// then we assume it is no longer in the content tree and the
|
|
|
|
// frame shouldn't get an event, nor should we even assume its
|
|
|
|
// safe to try and find the frame.
|
|
|
|
nsCOMPtr<nsIDocument> doc;
|
|
|
|
nsresult result = mCurrentEventContent->GetDocument(*getter_AddRefs(doc));
|
|
|
|
if (NS_SUCCEEDED(result) && doc) {
|
|
|
|
GetPrimaryFrameFor(mCurrentEventContent, &mCurrentEventFrame);
|
|
|
|
}
|
1999-06-15 07:14:28 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return mCurrentEventFrame;
|
|
|
|
}
|
|
|
|
|
1999-09-02 22:14:01 +04:00
|
|
|
void
|
|
|
|
PresShell::PushCurrentEventFrame()
|
|
|
|
{
|
|
|
|
if (mCurrentEventFrame) {
|
|
|
|
mCurrentEventFrameStack.InsertElementAt((void*)mCurrentEventFrame, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
PresShell::PopCurrentEventFrame()
|
|
|
|
{
|
|
|
|
mCurrentEventFrame = nsnull;
|
|
|
|
|
1999-09-02 23:21:45 +04:00
|
|
|
if (0 != mCurrentEventFrameStack.Count()) {
|
1999-09-02 22:14:01 +04:00
|
|
|
mCurrentEventFrame = (nsIFrame*)mCurrentEventFrameStack.ElementAt(0);
|
|
|
|
mCurrentEventFrameStack.RemoveElementAt(0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-12-18 18:54:23 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShell::HandleEvent(nsIView *aView,
|
|
|
|
nsGUIEvent* aEvent,
|
1999-11-24 09:03:41 +03:00
|
|
|
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
|
|
|
|
1999-12-11 03:02:08 +03:00
|
|
|
/* if (mSelection && aEvent->eventStructType == NS_KEY_EVENT)
|
1999-09-14 02:19:31 +04:00
|
|
|
{//KEY HANDLERS WILL GET RID OF THIS
|
1999-10-26 08:44:41 +04:00
|
|
|
if (mDisplayNonTextSelection && NS_SUCCEEDED(mSelection->HandleKeyEvent(mPresContext, aEvent)))
|
1999-09-14 02:19:31 +04:00
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
1999-12-11 03:02:08 +03:00
|
|
|
*/
|
1998-11-18 08:25:26 +03:00
|
|
|
if (nsnull != frame) {
|
1999-09-02 22:14:01 +04:00
|
|
|
PushCurrentEventFrame();
|
1999-05-21 03:16:53 +04:00
|
|
|
|
1999-07-26 19:02:19 +04:00
|
|
|
nsIEventStateManager *manager;
|
|
|
|
nsIContent* focusContent = nsnull;
|
|
|
|
if (NS_OK == mPresContext->GetEventStateManager(&manager)) {
|
|
|
|
if (NS_IS_KEY_EVENT(aEvent)) {
|
|
|
|
//Key events go to the focused frame, not point based.
|
1999-08-24 04:42:02 +04:00
|
|
|
manager->GetFocusedContent(&focusContent);
|
|
|
|
if (focusContent)
|
|
|
|
GetPrimaryFrameFor(focusContent, &mCurrentEventFrame);
|
1999-10-26 08:44:41 +04:00
|
|
|
else frame->GetFrameForPoint(mPresContext, aEvent->point, &mCurrentEventFrame);
|
1999-07-26 19:02:19 +04:00
|
|
|
}
|
1999-09-02 22:14:01 +04:00
|
|
|
else {
|
1999-10-26 08:44:41 +04:00
|
|
|
frame->GetFrameForPoint(mPresContext, aEvent->point, &mCurrentEventFrame);
|
1999-09-02 22:14:01 +04:00
|
|
|
}
|
1999-07-26 19:02:19 +04:00
|
|
|
NS_IF_RELEASE(mCurrentEventContent);
|
|
|
|
if (GetCurrentEventFrame() || focusContent) {
|
1998-11-18 08:25:26 +03:00
|
|
|
//Once we have the targetFrame, handle the event in this order
|
1998-11-24 10:46:58 +03:00
|
|
|
//1. Give event to event manager for pre event state changes and generation of synthetic events.
|
1999-11-24 09:03:41 +03:00
|
|
|
rv = manager->PreHandleEvent(mPresContext, aEvent, mCurrentEventFrame, aEventStatus, aView);
|
1998-11-18 08:25:26 +03:00
|
|
|
|
|
|
|
//2. Give event to the DOM for third party and JS use.
|
1999-07-26 19:02:19 +04:00
|
|
|
if ((GetCurrentEventFrame() || focusContent) && NS_OK == rv) {
|
|
|
|
if (focusContent) {
|
1999-11-24 09:03:41 +03:00
|
|
|
rv = focusContent->HandleDOMEvent(mPresContext, (nsEvent*)aEvent, nsnull,
|
1999-03-29 02:22:54 +04:00
|
|
|
NS_EVENT_FLAG_INIT, aEventStatus);
|
1999-07-26 19:02:19 +04:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
nsIContent* targetContent;
|
|
|
|
if (NS_OK == mCurrentEventFrame->GetContent(&targetContent) && nsnull != targetContent) {
|
1999-11-24 09:03:41 +03:00
|
|
|
rv = targetContent->HandleDOMEvent(mPresContext, (nsEvent*)aEvent, nsnull,
|
1999-07-26 19:02:19 +04:00
|
|
|
NS_EVENT_FLAG_INIT, aEventStatus);
|
|
|
|
NS_RELEASE(targetContent);
|
|
|
|
}
|
1998-11-21 03:19:36 +03:00
|
|
|
}
|
|
|
|
|
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...
|
1999-07-26 19:02:19 +04:00
|
|
|
if (GetCurrentEventFrame() && NS_OK == rv) {
|
1999-11-24 09:03:41 +03:00
|
|
|
rv = mCurrentEventFrame->HandleEvent(mPresContext, aEvent, aEventStatus);
|
1999-07-26 19:02:19 +04:00
|
|
|
}
|
1998-11-24 10:46:58 +03:00
|
|
|
|
1999-07-26 19:02:19 +04:00
|
|
|
//4. Give event to event manager for post event state changes and generation of synthetic events.
|
|
|
|
if ((GetCurrentEventFrame() || focusContent) && NS_OK == rv) {
|
1999-11-24 09:03:41 +03:00
|
|
|
rv = manager->PostHandleEvent(mPresContext, aEvent, mCurrentEventFrame, aEventStatus, aView);
|
1998-11-24 10:46:58 +03:00
|
|
|
}
|
1998-11-18 08:25:26 +03:00
|
|
|
}
|
|
|
|
}
|
1999-07-26 19:02:19 +04:00
|
|
|
NS_RELEASE(manager);
|
|
|
|
NS_IF_RELEASE(focusContent);
|
1998-11-18 08:25:26 +03:00
|
|
|
}
|
2000-02-03 05:49:58 +03:00
|
|
|
#ifdef NS_DEBUG
|
|
|
|
if ((nsIFrameDebug::GetShowEventTargetFrameBorder()) && (GetCurrentEventFrame())) {
|
|
|
|
nsIView *oldView = mCurrentTargetView;
|
|
|
|
nsPoint offset(0,0);
|
|
|
|
nsRect oldTargetRect(mCurrentTargetRect);
|
|
|
|
mCurrentEventFrame->GetRect(mCurrentTargetRect);
|
|
|
|
mCurrentEventFrame->GetView(mPresContext, &mCurrentTargetView);
|
|
|
|
if ( ! mCurrentTargetView ) {
|
|
|
|
mCurrentEventFrame->GetOffsetFromView(mPresContext, offset, &mCurrentTargetView);
|
|
|
|
}
|
|
|
|
if (mCurrentTargetView) {
|
|
|
|
mCurrentTargetRect.x = offset.x;
|
|
|
|
mCurrentTargetRect.y = offset.y;
|
|
|
|
// use aView or mCurrentTargetView??
|
|
|
|
if ( (mCurrentTargetRect != oldTargetRect) || (mCurrentTargetView != oldView)) {
|
|
|
|
nsIViewManager *vm;
|
|
|
|
if ((NS_OK == GetViewManager(&vm)) && vm) {
|
|
|
|
vm->UpdateView(mCurrentTargetView,mCurrentTargetRect,0);
|
|
|
|
if (oldView)
|
|
|
|
vm->UpdateView(oldView,oldTargetRect,0);
|
|
|
|
NS_IF_RELEASE(vm);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
1999-09-02 22:14:01 +04:00
|
|
|
PopCurrentEventFrame();
|
1998-11-18 08:25:26 +03:00
|
|
|
}
|
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"
|
1999-04-04 01:54:32 +04:00
|
|
|
#include "nsILinkHandler.h"
|
1998-07-13 23:49:42 +04:00
|
|
|
|
2000-01-04 23:24:09 +03:00
|
|
|
static NS_DEFINE_CID(kViewManagerCID, NS_VIEW_MANAGER_CID);
|
|
|
|
static NS_DEFINE_CID(kScrollingViewCID, NS_SCROLLING_VIEW_CID);
|
|
|
|
static NS_DEFINE_CID(kWidgetCID, NS_CHILD_CID);
|
1998-07-13 23:49:42 +04:00
|
|
|
|
|
|
|
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) {
|
1999-11-02 01:12:45 +03:00
|
|
|
nsIFrameDebug* frameDebug;
|
|
|
|
|
2000-01-04 23:24:09 +03:00
|
|
|
if (NS_SUCCEEDED(k1->QueryInterface(NS_GET_IID(nsIFrameDebug),
|
|
|
|
(void**)&frameDebug))) {
|
1999-11-02 01:12:45 +03:00
|
|
|
frameDebug->GetFrameName(name);
|
|
|
|
}
|
1998-11-25 21:41:02 +03:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
name = "(null)";
|
|
|
|
}
|
|
|
|
fputs(name, stdout);
|
|
|
|
|
|
|
|
printf(" != ");
|
|
|
|
|
|
|
|
if (nsnull != k2) {
|
1999-11-02 01:12:45 +03:00
|
|
|
nsIFrameDebug* frameDebug;
|
|
|
|
|
2000-01-04 23:24:09 +03:00
|
|
|
if (NS_SUCCEEDED(k2->QueryInterface(NS_GET_IID(nsIFrameDebug),
|
|
|
|
(void**)&frameDebug))) {
|
1999-11-02 01:12:45 +03:00
|
|
|
frameDebug->GetFrameName(name);
|
|
|
|
}
|
1998-11-25 21:41:02 +03:00
|
|
|
}
|
|
|
|
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;
|
1999-11-02 01:12:45 +03:00
|
|
|
nsIFrameDebug* frameDebug;
|
|
|
|
|
2000-01-04 23:24:09 +03:00
|
|
|
if (NS_SUCCEEDED(k1->QueryInterface(NS_GET_IID(nsIFrameDebug),
|
|
|
|
(void**)&frameDebug))) {
|
1999-11-02 01:12:45 +03:00
|
|
|
frameDebug->GetFrameName(name);
|
|
|
|
fputs(name, stdout);
|
|
|
|
}
|
1999-09-10 22:49:23 +04:00
|
|
|
printf("{%d, %d, %d, %d}", r1.x, r1.y, r1.width, r1.height);
|
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
|
|
|
|
2000-01-04 23:24:09 +03:00
|
|
|
if (NS_SUCCEEDED(k2->QueryInterface(NS_GET_IID(nsIFrameDebug),
|
|
|
|
(void**)&frameDebug))) {
|
1999-11-02 01:12:45 +03:00
|
|
|
frameDebug->GetFrameName(name);
|
|
|
|
fputs(name, stdout);
|
|
|
|
}
|
1999-09-10 22:49:23 +04:00
|
|
|
printf("{%d, %d, %d, %d}", r2.x, r2.y, r2.width, r2.height);
|
1998-11-25 21:41:02 +03:00
|
|
|
|
|
|
|
printf(" %s\n", aMsg);
|
1998-07-13 23:49:42 +04:00
|
|
|
}
|
1998-04-14 00:24:54 +04:00
|
|
|
|
1999-04-03 22:58:04 +04:00
|
|
|
static PRBool
|
1999-10-26 08:44:41 +04:00
|
|
|
CompareTrees(nsIPresContext* aPresContext, nsIFrame* aA, nsIFrame* aB)
|
1998-04-14 00:24:54 +04:00
|
|
|
{
|
1999-04-03 22:58:04 +04:00
|
|
|
PRBool ok = PR_TRUE;
|
1998-11-25 21:41:02 +03:00
|
|
|
nsIAtom* listName = nsnull;
|
|
|
|
PRInt32 listIndex = 0;
|
|
|
|
do {
|
|
|
|
nsIFrame* k1, *k2;
|
2000-01-22 04:16:50 +03:00
|
|
|
aA->FirstChild(aPresContext, listName, &k1);
|
|
|
|
aB->FirstChild(aPresContext, listName, &k2);
|
1998-11-25 21:41:02 +03:00
|
|
|
PRInt32 l1 = nsContainerFrame::LengthOf(k1);
|
|
|
|
PRInt32 l2 = nsContainerFrame::LengthOf(k2);
|
|
|
|
if (l1 != l2) {
|
1999-04-03 22:58:04 +04:00
|
|
|
ok = PR_FALSE;
|
1998-11-25 21:41:02 +03:00
|
|
|
LogVerifyMessage(k1, k2, "child counts don't match: ");
|
|
|
|
printf("%d != %d\n", l1, l2);
|
1999-09-10 22:49:23 +04:00
|
|
|
if (0 == (VERIFY_REFLOW_ALL & gVerifyReflowFlags)) {
|
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
|
|
|
nsRect r1, r2;
|
|
|
|
nsIView* v1, *v2;
|
|
|
|
nsIWidget* w1, *w2;
|
|
|
|
for (;;) {
|
|
|
|
if (((nsnull == k1) && (nsnull != k2)) ||
|
|
|
|
((nsnull != k1) && (nsnull == k2))) {
|
1999-04-03 22:58:04 +04:00
|
|
|
ok = PR_FALSE;
|
1998-11-25 21:41:02 +03:00
|
|
|
LogVerifyMessage(k1, k2, "child lists are different\n");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else if (nsnull != k1) {
|
|
|
|
// Verify that the frames are the same size
|
|
|
|
k1->GetRect(r1);
|
|
|
|
k2->GetRect(r2);
|
|
|
|
if (r1 != r2) {
|
1999-04-03 22:58:04 +04:00
|
|
|
ok = PR_FALSE;
|
1998-11-25 21:41:02 +03:00
|
|
|
LogVerifyMessage(k1, k2, "(frame rects)", r1, r2);
|
|
|
|
}
|
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-10-26 08:44:41 +04:00
|
|
|
k1->GetView(aPresContext, &v1);
|
|
|
|
k2->GetView(aPresContext, &v2);
|
1998-11-25 21:41:02 +03:00
|
|
|
if (((nsnull == v1) && (nsnull != v2)) ||
|
|
|
|
((nsnull != v1) && (nsnull == v2))) {
|
1999-04-03 22:58:04 +04:00
|
|
|
ok = PR_FALSE;
|
1998-11-25 21:41:02 +03:00
|
|
|
LogVerifyMessage(k1, k2, "child views are not matched\n");
|
|
|
|
}
|
|
|
|
else if (nsnull != v1) {
|
|
|
|
v1->GetBounds(r1);
|
|
|
|
v2->GetBounds(r2);
|
|
|
|
if (r1 != r2) {
|
|
|
|
LogVerifyMessage(k1, k2, "(view rects)", r1, r2);
|
|
|
|
}
|
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))) {
|
1999-04-03 22:58:04 +04:00
|
|
|
ok = PR_FALSE;
|
1998-11-25 21:41:02 +03:00
|
|
|
LogVerifyMessage(k1, k2, "child widgets are not matched\n");
|
|
|
|
}
|
|
|
|
else if (nsnull != w1) {
|
|
|
|
w1->GetBounds(r1);
|
|
|
|
w2->GetBounds(r2);
|
|
|
|
if (r1 != r2) {
|
|
|
|
LogVerifyMessage(k1, k2, "(widget rects)", r1, r2);
|
|
|
|
}
|
1998-07-13 23:49:42 +04:00
|
|
|
}
|
|
|
|
}
|
1999-09-10 22:49:23 +04:00
|
|
|
if (!ok && (0 == (VERIFY_REFLOW_ALL & gVerifyReflowFlags))) {
|
1998-11-25 21:41:02 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Compare the sub-trees too
|
1999-10-26 08:44:41 +04:00
|
|
|
if (!CompareTrees(aPresContext, k1, k2)) {
|
1999-09-10 22:49:23 +04:00
|
|
|
ok = PR_FALSE;
|
|
|
|
if (0 == (VERIFY_REFLOW_ALL & gVerifyReflowFlags)) {
|
1999-04-03 22:58:04 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
1998-11-25 21:41:02 +03:00
|
|
|
|
|
|
|
// 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
|
|
|
}
|
|
|
|
}
|
1999-09-10 22:49:23 +04:00
|
|
|
if (!ok && (0 == (VERIFY_REFLOW_ALL & gVerifyReflowFlags))) {
|
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
|
|
|
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) {
|
1999-09-10 22:49:23 +04:00
|
|
|
if (0 == (VERIFY_REFLOW_ALL & gVerifyReflowFlags)) {
|
|
|
|
ok = PR_FALSE;
|
|
|
|
}
|
1998-11-25 21:41:02 +03:00
|
|
|
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;
|
1999-04-03 22:58:04 +04:00
|
|
|
} while (ok && (listName != nsnull));
|
|
|
|
|
|
|
|
return ok;
|
|
|
|
}
|
1999-11-02 01:12:45 +03:00
|
|
|
#endif
|
1999-04-03 22:58:04 +04:00
|
|
|
|
|
|
|
#if 0
|
|
|
|
static nsIFrame*
|
|
|
|
FindTopFrame(nsIFrame* aRoot)
|
|
|
|
{
|
|
|
|
if (nsnull != aRoot) {
|
|
|
|
nsIContent* content;
|
|
|
|
aRoot->GetContent(&content);
|
|
|
|
if (nsnull != content) {
|
|
|
|
nsIAtom* tag;
|
|
|
|
content->GetTag(tag);
|
|
|
|
if (nsnull != tag) {
|
|
|
|
NS_RELEASE(tag);
|
|
|
|
NS_RELEASE(content);
|
|
|
|
return aRoot;
|
|
|
|
}
|
|
|
|
NS_RELEASE(content);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Try one of the children
|
|
|
|
nsIFrame* kid;
|
|
|
|
aRoot->FirstChild(nsnull, &kid);
|
|
|
|
while (nsnull != kid) {
|
|
|
|
nsIFrame* result = FindTopFrame(kid);
|
|
|
|
if (nsnull != result) {
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
kid->GetNextSibling(&kid);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nsnull;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
PresShell::CloneStyleSet(nsIStyleSet* aSet, nsIStyleSet** aResult)
|
|
|
|
{
|
|
|
|
nsIStyleSet* clone;
|
|
|
|
nsresult rv = NS_NewStyleSet(&clone);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
PRInt32 i, n;
|
|
|
|
n = aSet->GetNumberOfOverrideStyleSheets();
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
nsIStyleSheet* ss;
|
|
|
|
ss = aSet->GetOverrideStyleSheetAt(i);
|
|
|
|
if (nsnull != ss) {
|
|
|
|
clone->AppendOverrideStyleSheet(ss);
|
|
|
|
NS_RELEASE(ss);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
n = aSet->GetNumberOfDocStyleSheets();
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
nsIStyleSheet* ss;
|
|
|
|
ss = aSet->GetDocStyleSheetAt(i);
|
|
|
|
if (nsnull != ss) {
|
|
|
|
clone->AddDocStyleSheet(ss, mDocument);
|
|
|
|
NS_RELEASE(ss);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
n = aSet->GetNumberOfBackstopStyleSheets();
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
nsIStyleSheet* ss;
|
|
|
|
ss = aSet->GetBackstopStyleSheetAt(i);
|
|
|
|
if (nsnull != ss) {
|
|
|
|
clone->AppendBackstopStyleSheet(ss);
|
|
|
|
NS_RELEASE(ss);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*aResult = clone;
|
|
|
|
return NS_OK;
|
1998-07-13 23:49:42 +04:00
|
|
|
}
|
|
|
|
|
1999-11-02 01:12:45 +03:00
|
|
|
#ifdef DEBUG
|
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.
|
1999-09-10 22:49:23 +04:00
|
|
|
PRBool
|
1998-07-13 23:49:42 +04:00
|
|
|
PresShell::VerifyIncrementalReflow()
|
|
|
|
{
|
|
|
|
// All the stuff we are creating that needs releasing
|
|
|
|
nsIPresContext* cx;
|
|
|
|
nsIViewManager* vm;
|
|
|
|
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);
|
|
|
|
}
|
1999-04-03 22:58:04 +04:00
|
|
|
#if 1
|
|
|
|
nsISupports* container;
|
|
|
|
if (NS_SUCCEEDED(mPresContext->GetContainer(&container)) &&
|
|
|
|
(nsnull != container)) {
|
|
|
|
cx->SetContainer(container);
|
1999-04-04 01:54:32 +04:00
|
|
|
nsILinkHandler* lh;
|
2000-01-04 23:24:09 +03:00
|
|
|
if (NS_SUCCEEDED(container->QueryInterface(NS_GET_IID(nsILinkHandler),
|
1999-04-04 01:54:32 +04:00
|
|
|
(void**)&lh))) {
|
|
|
|
cx->SetLinkHandler(lh);
|
|
|
|
NS_RELEASE(lh);
|
|
|
|
}
|
1999-04-03 22:58:04 +04:00
|
|
|
NS_RELEASE(container);
|
|
|
|
}
|
|
|
|
#endif
|
1998-07-13 23:49:42 +04:00
|
|
|
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;
|
2000-01-04 23:24:09 +03:00
|
|
|
rv = rootView->QueryInterface(NS_GET_IID(nsIScrollableView),
|
|
|
|
(void**)&scrollView);
|
1998-07-13 23:49:42 +04:00
|
|
|
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.
|
1999-04-03 22:58:04 +04:00
|
|
|
rv = nsComponentManager::CreateInstance(kViewManagerCID, nsnull,
|
2000-01-04 23:24:09 +03:00
|
|
|
NS_GET_IID(nsIViewManager),
|
|
|
|
(void**) &vm);
|
1999-04-03 22:58:04 +04:00
|
|
|
if (NS_FAILED(rv)) {
|
1998-07-13 23:49:42 +04:00
|
|
|
NS_ASSERTION(NS_OK == rv, "failed to create view manager");
|
|
|
|
}
|
1999-04-03 22:58:04 +04:00
|
|
|
rv = vm->Init(dc);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
NS_ASSERTION(NS_OK == rv, "failed to init view manager");
|
|
|
|
}
|
1998-08-28 06:54:06 +04:00
|
|
|
|
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);
|
1999-04-03 22:58:04 +04:00
|
|
|
nsIView* view;
|
|
|
|
rv = nsComponentManager::CreateInstance(kViewCID, nsnull,
|
2000-01-04 23:24:09 +03:00
|
|
|
NS_GET_IID(nsIView),
|
|
|
|
(void **) &view);
|
1999-04-03 22:58:04 +04:00
|
|
|
if (NS_FAILED(rv)) {
|
1998-07-13 23:49:42 +04:00
|
|
|
NS_ASSERTION(NS_OK == rv, "failed to create scroll view");
|
|
|
|
}
|
1999-04-03 22:58:04 +04:00
|
|
|
rv = view->Init(vm, tbounds, nsnull);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
NS_ASSERTION(NS_OK == rv, "failed to init 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
|
|
|
// 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);
|
1999-04-03 22:58:04 +04:00
|
|
|
|
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.
|
1999-04-30 13:04:36 +04:00
|
|
|
nsCOMPtr<nsIStyleSet> newSet;
|
|
|
|
rv = CloneStyleSet(mStyleSet, getter_AddRefs(newSet));
|
1999-04-03 22:58:04 +04:00
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "failed to clone style set");
|
|
|
|
rv = mDocument->CreateShell(cx, vm, newSet, &sh);
|
1998-07-13 23:49:42 +04:00
|
|
|
NS_ASSERTION(NS_OK == rv, "failed to create presentation shell");
|
1999-04-03 22:58:04 +04:00
|
|
|
vm->SetViewObserver((nsIViewObserver *)((PresShell*)sh));
|
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;
|
1999-02-12 20:45:58 +03:00
|
|
|
GetRootFrame(&root1);
|
1999-04-03 22:58:04 +04:00
|
|
|
nsIFrame* root2;
|
1999-02-12 20:45:58 +03:00
|
|
|
sh->GetRootFrame(&root2);
|
1999-04-03 22:58:04 +04:00
|
|
|
#if 0
|
|
|
|
root1 = FindTopFrame(root1);
|
|
|
|
root2 = FindTopFrame(root2);
|
|
|
|
#endif
|
1999-10-26 08:44:41 +04:00
|
|
|
PRBool ok = CompareTrees(mPresContext, root1, root2);
|
1999-09-10 22:49:23 +04:00
|
|
|
if (!ok && (VERIFY_REFLOW_NOISY & gVerifyReflowFlags)) {
|
1999-04-20 04:24:21 +04:00
|
|
|
printf("Verify reflow failed, primary tree:\n");
|
1999-11-02 01:12:45 +03:00
|
|
|
nsIFrameDebug* frameDebug;
|
|
|
|
|
2000-01-04 23:24:09 +03:00
|
|
|
if (NS_SUCCEEDED(root1->QueryInterface(NS_GET_IID(nsIFrameDebug),
|
|
|
|
(void**)&frameDebug))) {
|
1999-11-02 01:12:45 +03:00
|
|
|
frameDebug->List(mPresContext, stdout, 0);
|
|
|
|
}
|
1999-04-20 04:24:21 +04:00
|
|
|
printf("Verification tree:\n");
|
2000-01-04 23:24:09 +03:00
|
|
|
if (NS_SUCCEEDED(root2->QueryInterface(NS_GET_IID(nsIFrameDebug),
|
|
|
|
(void**)&frameDebug))) {
|
1999-11-02 01:12:45 +03:00
|
|
|
frameDebug->List(mPresContext, stdout, 0);
|
|
|
|
}
|
1999-04-03 22:58:04 +04:00
|
|
|
}
|
1998-07-13 23:49:42 +04:00
|
|
|
|
1999-04-03 22:58:04 +04:00
|
|
|
// printf("Incremental reflow doomed view tree:\n");
|
|
|
|
// view->List(stdout, 1);
|
1999-04-20 04:24:21 +04:00
|
|
|
// view->SetVisibility(nsViewVisibility_kHide);
|
|
|
|
cx->Stop();
|
1999-04-03 22:58:04 +04:00
|
|
|
cx->SetContainer(nsnull);
|
1998-07-13 23:49:42 +04:00
|
|
|
NS_RELEASE(cx);
|
1999-04-03 22:58:04 +04:00
|
|
|
sh->EndObservingDocument();
|
1998-07-13 23:49:42 +04:00
|
|
|
NS_RELEASE(sh);
|
1999-04-03 22:58:04 +04:00
|
|
|
NS_RELEASE(vm);
|
1999-09-10 22:49:23 +04:00
|
|
|
|
|
|
|
return ok;
|
1998-07-13 23:49:42 +04:00
|
|
|
}
|
|
|
|
#endif
|
1999-10-15 08:29:30 +04:00
|
|
|
|
|
|
|
// PresShellViewEventListener
|
|
|
|
|
|
|
|
NS_IMPL_ISUPPORTS2(PresShellViewEventListener, nsIScrollPositionListener, nsICompositeListener)
|
|
|
|
|
|
|
|
PresShellViewEventListener::PresShellViewEventListener()
|
|
|
|
{
|
|
|
|
NS_INIT_ISUPPORTS();
|
|
|
|
mPresShell = 0;
|
|
|
|
mWasVisible = PR_FALSE;
|
|
|
|
mCallCount = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
PresShellViewEventListener::~PresShellViewEventListener()
|
|
|
|
{
|
|
|
|
mPresShell = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
PresShellViewEventListener::SetPresShell(nsIPresShell *aPresShell)
|
|
|
|
{
|
|
|
|
mPresShell = aPresShell;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
PresShellViewEventListener::HideCaret()
|
|
|
|
{
|
|
|
|
nsresult result = NS_OK;
|
|
|
|
|
|
|
|
if (mPresShell && 0 == mCallCount)
|
|
|
|
{
|
|
|
|
result = mPresShell->GetCaretEnabled(&mWasVisible);
|
|
|
|
|
|
|
|
if (NS_SUCCEEDED(result) && mWasVisible)
|
|
|
|
result = mPresShell->SetCaretEnabled(PR_FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
++mCallCount;
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
PresShellViewEventListener::RestoreCaretVisibility()
|
|
|
|
{
|
|
|
|
nsresult result = NS_OK;
|
|
|
|
|
|
|
|
--mCallCount;
|
|
|
|
|
|
|
|
if (mPresShell && 0 == mCallCount && mWasVisible)
|
|
|
|
result = mPresShell->SetCaretEnabled(PR_TRUE);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShellViewEventListener::ScrollPositionWillChange(nsIScrollableView *aView, nscoord aX, nscoord aY)
|
|
|
|
{
|
|
|
|
return HideCaret();
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShellViewEventListener::ScrollPositionDidChange(nsIScrollableView *aView, nscoord aX, nscoord aY)
|
|
|
|
{
|
|
|
|
return RestoreCaretVisibility();
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShellViewEventListener::WillRefreshRegion(nsIViewManager *aViewManager,
|
|
|
|
nsIView *aView,
|
|
|
|
nsIRenderingContext *aContext,
|
|
|
|
nsIRegion *aRegion,
|
|
|
|
PRUint32 aUpdateFlags)
|
|
|
|
{
|
|
|
|
return HideCaret();
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShellViewEventListener::DidRefreshRegion(nsIViewManager *aViewManager,
|
|
|
|
nsIView *aView,
|
|
|
|
nsIRenderingContext *aContext,
|
|
|
|
nsIRegion *aRegion,
|
|
|
|
PRUint32 aUpdateFlags)
|
|
|
|
{
|
|
|
|
return RestoreCaretVisibility();
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShellViewEventListener::WillRefreshRect(nsIViewManager *aViewManager,
|
|
|
|
nsIView *aView,
|
|
|
|
nsIRenderingContext *aContext,
|
|
|
|
const nsRect *aRect,
|
|
|
|
PRUint32 aUpdateFlags)
|
|
|
|
{
|
|
|
|
return HideCaret();
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
PresShellViewEventListener::DidRefreshRect(nsIViewManager *aViewManager,
|
|
|
|
nsIView *aView,
|
|
|
|
nsIRenderingContext *aContext,
|
|
|
|
const nsRect *aRect,
|
|
|
|
PRUint32 aUpdateFlags)
|
|
|
|
{
|
|
|
|
return RestoreCaretVisibility();
|
|
|
|
}
|