1998-04-13 20:24:54 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
|
|
*
|
|
|
|
* The contents of this file are subject to the Netscape Public License
|
|
|
|
* Version 1.0 (the "NPL"); you may not use this file except in
|
|
|
|
* compliance with the NPL. You may obtain a copy of the NPL at
|
|
|
|
* http://www.mozilla.org/NPL/
|
|
|
|
*
|
|
|
|
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
|
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
|
|
|
* for the specific language governing rights and limitations under the
|
|
|
|
* NPL.
|
|
|
|
*
|
|
|
|
* The Initial Developer of this code under the NPL is Netscape
|
|
|
|
* Communications Corporation. Portions created by Netscape are
|
|
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
|
|
|
* Reserved.
|
|
|
|
*/
|
|
|
|
#include "nsFrame.h"
|
|
|
|
#include "nsIContent.h"
|
|
|
|
#include "nsIAtom.h"
|
|
|
|
#include "nsString.h"
|
|
|
|
#include "nsIStyleContext.h"
|
|
|
|
#include "nsIView.h"
|
|
|
|
#include "nsIViewManager.h"
|
|
|
|
#include "nsIPresContext.h"
|
|
|
|
#include "nsCRT.h"
|
|
|
|
#include "nsGUIEvent.h"
|
1998-07-23 02:55:33 +00:00
|
|
|
#include "nsDOMEvent.h"
|
1998-04-13 20:24:54 +00:00
|
|
|
#include "nsStyleConsts.h"
|
1998-05-08 16:33:07 +00:00
|
|
|
#include "nsIPresShell.h"
|
1998-05-20 16:24:13 +00:00
|
|
|
#include "prlog.h"
|
|
|
|
#include "prprf.h"
|
|
|
|
#include <stdarg.h>
|
1998-06-02 05:28:11 +00:00
|
|
|
#include "nsIPtr.h"
|
1998-06-05 21:06:24 +00:00
|
|
|
#include "nsISizeOfHandler.h"
|
1998-04-13 20:24:54 +00:00
|
|
|
|
1998-04-27 16:44:52 +00:00
|
|
|
#include "nsIDOMText.h"
|
1998-05-08 18:33:42 +00:00
|
|
|
#include "nsSelectionRange.h"
|
|
|
|
#include "nsDocument.h"
|
|
|
|
#include "nsIDeviceContext.h"
|
|
|
|
#include "nsIPresShell.h"
|
|
|
|
|
1998-07-18 18:18:20 +00:00
|
|
|
// Some Misc #defines
|
1998-07-22 22:01:46 +00:00
|
|
|
#define SELECTION_DEBUG 0
|
1998-07-18 18:18:20 +00:00
|
|
|
#define FORCE_SELECTION_UPDATE 1
|
|
|
|
#define TRACKER_DEBUG 0
|
|
|
|
#define CALC_DEBUG 0
|
|
|
|
|
|
|
|
// Tracker Data
|
|
|
|
#define kInsertInRemoveList 0
|
|
|
|
#define kInsertInAddList 1
|
|
|
|
|
|
|
|
|
1998-06-02 05:28:11 +00:00
|
|
|
NS_DEF_PTR(nsIView);
|
|
|
|
NS_DEF_PTR(nsIViewManager);
|
|
|
|
|
1998-05-08 18:33:42 +00:00
|
|
|
// Kludged Content stuff
|
|
|
|
nsIFrame * fFrameArray[1024];
|
|
|
|
nsIContent * fContentArray[1024];
|
|
|
|
PRInt32 fMax = -1;
|
|
|
|
|
|
|
|
nsIContent * fTrackerContentArrayRemoveList[1024];
|
|
|
|
PRInt32 fTrackerRemoveListMax = 0;
|
|
|
|
nsIContent * fTrackerContentArrayAddList[1024];
|
|
|
|
PRInt32 fTrackerAddListMax = 0;
|
1998-04-27 16:44:52 +00:00
|
|
|
|
1998-07-17 23:00:54 +00:00
|
|
|
nsIDocument *gDoc = nsnull;
|
|
|
|
|
1998-04-27 16:44:52 +00:00
|
|
|
// [HACK] Foward Declarations
|
1998-07-17 23:00:54 +00:00
|
|
|
/*
|
1998-07-18 18:18:20 +00:00
|
|
|
void BuildContentList(nsIContent*aContent);
|
1998-04-27 16:44:52 +00:00
|
|
|
PRBool IsInRange(nsIContent * aStartContent, nsIContent * aEndContent, nsIContent * aContent);
|
|
|
|
PRBool IsBefore(nsIContent * aNewContent, nsIContent * aCurrentContent);
|
|
|
|
nsIContent * GetPrevContent(nsIContent * aContent);
|
|
|
|
nsIContent * GetNextContent(nsIContent * aContent);
|
1998-07-18 18:18:20 +00:00
|
|
|
void PrintIndex(char * aStr, nsIContent * aContent);
|
1998-07-17 23:00:54 +00:00
|
|
|
*/
|
|
|
|
|
1998-05-08 18:33:42 +00:00
|
|
|
void RefreshContentFrames(nsIPresContext& aPresContext, nsIContent * aStartContent, nsIContent * aEndContent);
|
|
|
|
void ForceDrawFrame(nsFrame * aFrame);
|
|
|
|
void resetContentTrackers();
|
|
|
|
void RefreshFromContentTrackers(nsIPresContext& aPresContext);
|
|
|
|
void addRangeToSelectionTrackers(nsIContent * aStartContent, nsIContent * aEndContent, PRUint32 aType);
|
|
|
|
|
1998-04-27 16:44:52 +00:00
|
|
|
|
|
|
|
|
1998-05-08 18:33:42 +00:00
|
|
|
|
|
|
|
// Initialize Global Selection Data
|
|
|
|
nsIFrame * nsFrame::mCurrentFrame = nsnull;
|
|
|
|
PRBool nsFrame::mDoingSelection = PR_FALSE;
|
|
|
|
PRBool nsFrame::mDidDrag = PR_FALSE;
|
|
|
|
PRInt32 nsFrame::mStartPos = 0;
|
|
|
|
|
|
|
|
// Selection data is valid only from the Mouse Press to the Mouse Release
|
|
|
|
nsSelectionRange * nsFrame::mSelectionRange = nsnull;
|
|
|
|
nsISelection * nsFrame::mSelection = nsnull;
|
|
|
|
|
|
|
|
nsSelectionPoint * nsFrame::mStartSelectionPoint = nsnull;
|
|
|
|
nsSelectionPoint * nsFrame::mEndSelectionPoint = nsnull;
|
|
|
|
|
1998-05-20 16:24:13 +00:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
static PRBool gShowFrameBorders = PR_FALSE;
|
1998-05-08 18:33:42 +00:00
|
|
|
|
1998-04-13 20:24:54 +00:00
|
|
|
NS_LAYOUT void nsIFrame::ShowFrameBorders(PRBool aEnable)
|
|
|
|
{
|
|
|
|
gShowFrameBorders = aEnable;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_LAYOUT PRBool nsIFrame::GetShowFrameBorders()
|
|
|
|
{
|
|
|
|
return gShowFrameBorders;
|
|
|
|
}
|
|
|
|
|
1998-05-20 16:24:13 +00:00
|
|
|
/**
|
|
|
|
* Note: the log module is created during library initialization which
|
|
|
|
* means that you cannot perform logging before then.
|
|
|
|
*/
|
|
|
|
PRLogModuleInfo* nsIFrame::gLogModule = PR_NewLogModule("frame");
|
|
|
|
|
|
|
|
static PRLogModuleInfo* gFrameVerifyTreeLogModuleInfo;
|
|
|
|
|
|
|
|
static PRBool gFrameVerifyTreeEnable = PRBool(0x55);
|
|
|
|
|
|
|
|
NS_LAYOUT PRBool
|
|
|
|
nsIFrame::GetVerifyTreeEnable()
|
|
|
|
{
|
|
|
|
#ifdef NS_DEBUG
|
|
|
|
if (gFrameVerifyTreeEnable == PRBool(0x55)) {
|
|
|
|
if (nsnull == gFrameVerifyTreeLogModuleInfo) {
|
|
|
|
gFrameVerifyTreeLogModuleInfo = PR_NewLogModule("frameverifytree");
|
|
|
|
gFrameVerifyTreeEnable = 0 != gFrameVerifyTreeLogModuleInfo->level;
|
|
|
|
printf("Note: frameverifytree is %sabled\n",
|
|
|
|
gFrameVerifyTreeEnable ? "en" : "dis");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
return gFrameVerifyTreeEnable;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_LAYOUT void
|
|
|
|
nsIFrame::SetVerifyTreeEnable(PRBool aEnabled)
|
|
|
|
{
|
|
|
|
gFrameVerifyTreeEnable = aEnabled;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_LAYOUT PRLogModuleInfo*
|
|
|
|
nsIFrame::GetLogModuleInfo()
|
|
|
|
{
|
|
|
|
return gLogModule;
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
1998-04-13 20:24:54 +00:00
|
|
|
static NS_DEFINE_IID(kIFrameIID, NS_IFRAME_IID);
|
|
|
|
|
|
|
|
nsresult
|
1998-05-05 23:56:50 +00:00
|
|
|
nsFrame::NewFrame(nsIFrame** aInstancePtrResult,
|
1998-04-13 20:24:54 +00:00
|
|
|
nsIContent* aContent,
|
|
|
|
nsIFrame* aParent)
|
|
|
|
{
|
|
|
|
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
|
|
|
|
if (nsnull == aInstancePtrResult) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
1998-05-05 23:56:50 +00:00
|
|
|
nsIFrame* it = new nsFrame(aContent, aParent);
|
1998-04-13 20:24:54 +00:00
|
|
|
if (nsnull == it) {
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
|
|
|
*aInstancePtrResult = it;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
void* nsFrame::operator new(size_t size)
|
|
|
|
{
|
|
|
|
void* result = new char[size];
|
|
|
|
|
|
|
|
nsCRT::zero(result, size);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
1998-05-05 23:56:50 +00:00
|
|
|
nsFrame::nsFrame(nsIContent* aContent, nsIFrame* aParent)
|
|
|
|
: mContent(aContent), mContentParent(aParent), mGeometricParent(aParent)
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
|
|
|
NS_ADDREF(mContent);
|
1998-05-29 02:10:12 +00:00
|
|
|
mState = NS_FRAME_FIRST_REFLOW;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsFrame::~nsFrame()
|
|
|
|
{
|
|
|
|
NS_RELEASE(mContent);
|
|
|
|
NS_IF_RELEASE(mStyleContext);
|
|
|
|
if (nsnull != mView) {
|
|
|
|
// Break association between view and frame
|
|
|
|
mView->SetFrame(nsnull);
|
|
|
|
NS_RELEASE(mView);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// nsISupports
|
|
|
|
|
|
|
|
nsresult nsFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
|
|
|
|
{
|
|
|
|
if (NULL == aInstancePtr) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
|
|
|
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
|
|
|
static NS_DEFINE_IID(kClassIID, kIFrameIID);
|
|
|
|
if (aIID.Equals(kClassIID) || (aIID.Equals(kISupportsIID))) {
|
|
|
|
*aInstancePtr = (void*)this;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
return NS_NOINTERFACE;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsrefcnt nsFrame::AddRef(void)
|
|
|
|
{
|
|
|
|
NS_ERROR("not supported");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsrefcnt nsFrame::Release(void)
|
|
|
|
{
|
|
|
|
NS_ERROR("not supported");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// nsIFrame
|
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::DeleteFrame()
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
|
|
|
nsIView* view = mView;
|
|
|
|
if (nsnull == view) {
|
1998-04-17 01:41:24 +00:00
|
|
|
nsIFrame* parent;
|
|
|
|
|
|
|
|
GetParentWithView(parent);
|
1998-04-13 20:24:54 +00:00
|
|
|
if (nsnull != parent) {
|
1998-04-17 01:41:24 +00:00
|
|
|
parent->GetView(view);
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (nsnull != view) {
|
|
|
|
nsIViewManager* vm = view->GetViewManager();
|
|
|
|
nsIPresContext* cx = vm->GetPresContext();
|
1998-04-17 01:41:24 +00:00
|
|
|
// XXX Is this a really good ordering for the releases? MMP
|
1998-04-13 20:24:54 +00:00
|
|
|
NS_RELEASE(vm);
|
1998-05-29 22:36:21 +00:00
|
|
|
if (view != mView) //if this is the view that we own, let's not release it...
|
|
|
|
NS_RELEASE(view);
|
1998-04-13 20:24:54 +00:00
|
|
|
cx->StopLoadImage(this);
|
|
|
|
NS_RELEASE(cx);
|
|
|
|
}
|
|
|
|
|
|
|
|
delete this;
|
1998-04-17 01:41:24 +00:00
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-06-05 21:06:24 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsFrame::SizeOf(nsISizeOfHandler* aHandler) const
|
|
|
|
{
|
|
|
|
aHandler->Add(sizeof(*this));
|
|
|
|
SizeOfWithoutThis(aHandler);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nsFrame::SizeOfWithoutThis(nsISizeOfHandler* aHandler) const
|
|
|
|
{
|
|
|
|
// Note: style context's are accounted for via the style system's
|
|
|
|
// sizeof support
|
|
|
|
|
|
|
|
// Note: content is accounted for via the content system's sizeof
|
|
|
|
// support
|
|
|
|
}
|
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::GetContent(nsIContent*& aContent) const
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
|
|
|
if (nsnull != mContent) {
|
|
|
|
NS_ADDREF(mContent);
|
|
|
|
}
|
1998-04-17 01:41:24 +00:00
|
|
|
aContent = mContent;
|
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-05-05 23:56:50 +00:00
|
|
|
NS_METHOD nsFrame::GetContentIndex(PRInt32& aIndexInParent) const
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
1998-05-05 23:56:50 +00:00
|
|
|
nsIContent* parent = mContent->GetParent();
|
1998-05-07 00:08:20 +00:00
|
|
|
if (nsnull != parent) {
|
|
|
|
aIndexInParent = parent->IndexOf(mContent);
|
|
|
|
NS_RELEASE(parent);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
aIndexInParent = 0;
|
|
|
|
}
|
1998-04-17 01:41:24 +00:00
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::GetStyleContext(nsIPresContext* aPresContext,
|
|
|
|
nsIStyleContext*& aStyleContext)
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
1998-04-22 06:32:55 +00:00
|
|
|
if ((nsnull == mStyleContext) && (nsnull != aPresContext)) {
|
1998-04-13 20:24:54 +00:00
|
|
|
mStyleContext = aPresContext->ResolveStyleContextFor(mContent, mGeometricParent); // XXX should be content parent???
|
1998-04-28 23:25:07 +00:00
|
|
|
if (nsnull != mStyleContext) {
|
1998-05-01 20:43:02 +00:00
|
|
|
DidSetStyleContext(aPresContext);
|
1998-04-28 23:25:07 +00:00
|
|
|
}
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
NS_IF_ADDREF(mStyleContext);
|
1998-04-17 01:41:24 +00:00
|
|
|
aStyleContext = mStyleContext;
|
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-05-01 20:43:02 +00:00
|
|
|
NS_METHOD nsFrame::SetStyleContext(nsIPresContext* aPresContext,nsIStyleContext* aContext)
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
|
|
|
NS_PRECONDITION(nsnull != aContext, "null ptr");
|
|
|
|
if (aContext != mStyleContext) {
|
|
|
|
NS_IF_RELEASE(mStyleContext);
|
|
|
|
if (nsnull != aContext) {
|
|
|
|
mStyleContext = aContext;
|
|
|
|
NS_ADDREF(aContext);
|
1998-05-01 20:43:02 +00:00
|
|
|
DidSetStyleContext(aPresContext);
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
}
|
1998-04-17 01:41:24 +00:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1998-04-28 23:25:07 +00:00
|
|
|
// Subclass hook for style post processing
|
1998-05-01 20:43:02 +00:00
|
|
|
NS_METHOD nsFrame::DidSetStyleContext(nsIPresContext* aPresContext)
|
1998-04-28 23:25:07 +00:00
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1998-06-05 06:09:09 +00:00
|
|
|
NS_METHOD nsFrame::GetStyleData(nsStyleStructID aSID, const nsStyleStruct*& aStyleStruct) const
|
1998-04-17 01:41:24 +00:00
|
|
|
{
|
|
|
|
NS_ASSERTION(mStyleContext!=nsnull,"null style context");
|
|
|
|
if (mStyleContext) {
|
1998-06-05 06:09:09 +00:00
|
|
|
aStyleStruct = mStyleContext->GetStyleData(aSID);
|
1998-04-17 01:41:24 +00:00
|
|
|
} else {
|
|
|
|
aStyleStruct = nsnull;
|
|
|
|
}
|
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Geometric and content parent member functions
|
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::GetContentParent(nsIFrame*& aParent) const
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
1998-04-17 01:41:24 +00:00
|
|
|
aParent = mContentParent;
|
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::SetContentParent(const nsIFrame* aParent)
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
|
|
|
mContentParent = (nsIFrame*)aParent;
|
1998-04-17 01:41:24 +00:00
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::GetGeometricParent(nsIFrame*& aParent) const
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
1998-04-17 01:41:24 +00:00
|
|
|
aParent = mGeometricParent;
|
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::SetGeometricParent(const nsIFrame* aParent)
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
|
|
|
mGeometricParent = (nsIFrame*)aParent;
|
1998-04-17 01:41:24 +00:00
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Bounding rect member functions
|
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::GetRect(nsRect& aRect) const
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
|
|
|
aRect = mRect;
|
1998-04-17 01:41:24 +00:00
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::GetOrigin(nsPoint& aPoint) const
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
|
|
|
aPoint.x = mRect.x;
|
|
|
|
aPoint.y = mRect.y;
|
1998-04-17 01:41:24 +00:00
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::GetSize(nsSize& aSize) const
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
1998-04-17 01:41:24 +00:00
|
|
|
aSize.width = mRect.width;
|
|
|
|
aSize.height = mRect.height;
|
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::SetRect(const nsRect& aRect)
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
|
|
|
MoveTo(aRect.x, aRect.y);
|
|
|
|
SizeTo(aRect.width, aRect.height);
|
1998-04-17 01:41:24 +00:00
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::MoveTo(nscoord aX, nscoord aY)
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
1998-06-26 00:31:44 +00:00
|
|
|
mRect.x = aX;
|
|
|
|
mRect.y = aY;
|
1998-04-13 20:24:54 +00:00
|
|
|
|
1998-05-27 02:13:28 +00:00
|
|
|
// Let the view know
|
1998-05-28 21:55:13 +00:00
|
|
|
if ((nsnull != mView) && (0 == (mState & NS_FRAME_IN_REFLOW))) {
|
|
|
|
// Position view relative to its parent, not relative to our
|
1998-05-27 02:13:28 +00:00
|
|
|
// parent frame (our parent frame may not have a view).
|
|
|
|
nsIView* parentWithView;
|
|
|
|
nsPoint origin;
|
|
|
|
GetOffsetFromView(origin, parentWithView);
|
1998-06-02 22:04:54 +00:00
|
|
|
nsIViewManager *vm = mView->GetViewManager();
|
|
|
|
vm->MoveViewTo(mView, origin.x, origin.y);
|
|
|
|
NS_RELEASE(vm);
|
1998-05-27 02:13:28 +00:00
|
|
|
NS_IF_RELEASE(parentWithView);
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
1998-04-17 01:41:24 +00:00
|
|
|
|
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::SizeTo(nscoord aWidth, nscoord aHeight)
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
1998-05-07 16:13:09 +00:00
|
|
|
mRect.width = aWidth;
|
|
|
|
mRect.height = aHeight;
|
1998-04-17 01:41:24 +00:00
|
|
|
|
1998-05-07 16:13:09 +00:00
|
|
|
// Let the view know
|
1998-05-28 21:55:13 +00:00
|
|
|
if ((nsnull != mView) && (0 == (mState & NS_FRAME_IN_REFLOW))) {
|
1998-06-02 22:04:54 +00:00
|
|
|
nsIViewManager *vm = mView->GetViewManager();
|
|
|
|
vm->ResizeView(mView, aWidth, aHeight);
|
|
|
|
NS_RELEASE(vm);
|
1998-05-07 16:13:09 +00:00
|
|
|
}
|
1998-04-17 01:41:24 +00:00
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Child frame enumeration
|
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::ChildCount(PRInt32& aChildCount) const
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
1998-04-17 01:41:24 +00:00
|
|
|
aChildCount = 0;
|
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::ChildAt(PRInt32 aIndex, nsIFrame*& aFrame) const
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
|
|
|
NS_ERROR("not a container");
|
1998-04-17 01:41:24 +00:00
|
|
|
aFrame = nsnull;
|
1998-05-08 17:02:35 +00:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::IndexOf(const nsIFrame* aChild, PRInt32& aIndex) const
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
|
|
|
NS_ERROR("not a container");
|
1998-04-17 01:41:24 +00:00
|
|
|
aIndex = -1;
|
1998-05-08 17:02:35 +00:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::FirstChild(nsIFrame*& aFirstChild) const
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
1998-04-17 01:41:24 +00:00
|
|
|
aFirstChild = nsnull;
|
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::NextChild(const nsIFrame* aChild, nsIFrame*& aNextChild) const
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
|
|
|
NS_ERROR("not a container");
|
1998-04-17 01:41:24 +00:00
|
|
|
aNextChild = nsnull;
|
1998-05-08 17:02:35 +00:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::PrevChild(const nsIFrame* aChild, nsIFrame*& aPrevChild) const
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
|
|
|
NS_ERROR("not a container");
|
1998-04-17 01:41:24 +00:00
|
|
|
aPrevChild = nsnull;
|
1998-05-08 17:02:35 +00:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::LastChild(nsIFrame*& aLastChild) const
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
1998-04-17 01:41:24 +00:00
|
|
|
aLastChild = nsnull;
|
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-07-27 18:05:35 +00:00
|
|
|
|
|
|
|
PRBool nsFrame::DisplaySelection(nsIPresContext& aPresContext)
|
|
|
|
{
|
|
|
|
nsIPresShell *shell = aPresContext.GetShell();
|
|
|
|
nsIDocument *doc = shell->GetDocument();
|
|
|
|
PRBool result = doc->GetDisplaySelection();
|
|
|
|
NS_RELEASE(shell);
|
|
|
|
NS_RELEASE(doc);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::Paint(nsIPresContext& aPresContext,
|
|
|
|
nsIRenderingContext& aRenderingContext,
|
|
|
|
const nsRect& aDirtyRect)
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
1998-07-27 18:05:35 +00:00
|
|
|
if (DisplaySelection(aPresContext) == PR_FALSE)
|
|
|
|
return NS_OK;
|
1998-05-08 18:33:42 +00:00
|
|
|
|
|
|
|
PRBool clearAfterPaint = PR_FALSE;
|
|
|
|
|
|
|
|
// Get Content
|
|
|
|
nsIContent * content;
|
|
|
|
GetContent(content);
|
|
|
|
if (content->ChildCount() > 0) {
|
1998-05-18 21:03:55 +00:00
|
|
|
NS_RELEASE(content);
|
1998-05-08 18:33:42 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1998-07-17 23:00:54 +00:00
|
|
|
nsIPresShell * shell = aPresContext.GetShell();
|
|
|
|
nsIDocument * doc = shell->GetDocument();
|
1998-05-08 18:33:42 +00:00
|
|
|
if (mSelectionRange == nsnull) { // Get Selection Object
|
|
|
|
nsISelection * selection = doc->GetSelection();
|
|
|
|
|
|
|
|
mSelectionRange = selection->GetRange();
|
|
|
|
|
|
|
|
clearAfterPaint = PR_TRUE;
|
|
|
|
NS_RELEASE(selection);
|
|
|
|
}
|
|
|
|
|
1998-07-17 23:00:54 +00:00
|
|
|
PRBool inRange = doc->IsInRange(mSelectionRange->GetStartContent(), mSelectionRange->GetEndContent(), content);
|
|
|
|
|
1998-07-18 21:44:11 +00:00
|
|
|
#ifdef DONT_DO_THIS_USE_NSPR_LOGGING_INSTEAD
|
1998-07-17 23:00:54 +00:00
|
|
|
if (PR_TRUE == inRange)
|
|
|
|
cout << "IN" << endl;
|
|
|
|
else
|
|
|
|
cout << "OUT" << endl;
|
1998-07-18 21:44:11 +00:00
|
|
|
#endif
|
1998-07-17 23:00:54 +00:00
|
|
|
|
|
|
|
|
|
|
|
if (inRange) {
|
1998-05-08 18:33:42 +00:00
|
|
|
nsRect rect;
|
|
|
|
GetRect(rect);
|
|
|
|
rect.width--;
|
|
|
|
rect.height--;
|
|
|
|
aRenderingContext.SetColor(NS_RGB(0,0,255));
|
|
|
|
aRenderingContext.DrawRect(rect);
|
|
|
|
aRenderingContext.DrawLine(rect.x, rect.y, rect.x+rect.width, rect.y+rect.height);
|
|
|
|
aRenderingContext.DrawLine(rect.x, rect.y+rect.height, rect.x+rect.width, rect.y);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (clearAfterPaint) {
|
|
|
|
mSelectionRange = nsnull;
|
|
|
|
}
|
|
|
|
NS_RELEASE(content);
|
1998-07-17 23:00:54 +00:00
|
|
|
NS_RELEASE(doc);
|
|
|
|
NS_RELEASE(shell);
|
1998-07-27 18:05:35 +00:00
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-04-27 16:44:52 +00:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::HandleEvent(nsIPresContext& aPresContext,
|
|
|
|
nsGUIEvent* aEvent,
|
|
|
|
nsEventStatus& aEventStatus)
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
1998-06-08 00:57:15 +00:00
|
|
|
aEventStatus = nsEventStatus_eIgnore;
|
|
|
|
|
1998-07-11 03:47:56 +00:00
|
|
|
if (nsnull != mContent) {
|
1998-07-23 02:55:33 +00:00
|
|
|
mContent->HandleDOMEvent(aPresContext, (nsEvent*)aEvent, nsnull, DOM_EVENT_INIT, aEventStatus);
|
1998-06-23 21:53:02 +00:00
|
|
|
}
|
1998-04-27 16:44:52 +00:00
|
|
|
|
1998-07-27 18:05:35 +00:00
|
|
|
if (DisplaySelection(aPresContext) == PR_FALSE)
|
|
|
|
return NS_OK;
|
1998-04-27 16:44:52 +00:00
|
|
|
|
1998-06-08 00:57:15 +00:00
|
|
|
if(nsEventStatus_eIgnore == aEventStatus) {
|
|
|
|
if (aEvent->message == NS_MOUSE_MOVE && mDoingSelection ||
|
|
|
|
aEvent->message == NS_MOUSE_LEFT_BUTTON_UP ||
|
|
|
|
aEvent->message == NS_MOUSE_LEFT_BUTTON_DOWN) {
|
|
|
|
} else {
|
|
|
|
aEventStatus = nsEventStatus_eIgnore;
|
|
|
|
return NS_OK;
|
1998-04-27 16:44:52 +00:00
|
|
|
}
|
1998-07-18 18:18:20 +00:00
|
|
|
if (SELECTION_DEBUG) printf("Message: %d-------------------------------------------------------------\n",aEvent->message);
|
1998-04-27 16:44:52 +00:00
|
|
|
|
|
|
|
|
1998-06-08 00:57:15 +00:00
|
|
|
if (aEvent->message == NS_MOUSE_LEFT_BUTTON_UP) {
|
|
|
|
if (mDoingSelection) {
|
|
|
|
//mEndSelect = 0;
|
|
|
|
HandleRelease(aPresContext, aEvent, aEventStatus, this);
|
|
|
|
}
|
|
|
|
} else if (aEvent->message == NS_MOUSE_MOVE) {
|
|
|
|
mDidDrag = PR_TRUE;
|
1998-04-27 16:44:52 +00:00
|
|
|
|
1998-07-18 18:18:20 +00:00
|
|
|
//if (SELECTION_DEBUG) printf("HandleEvent(Drag)::mSelectionRange %s\n", mSelectionRange->ToString());
|
1998-06-08 00:57:15 +00:00
|
|
|
HandleDrag(aPresContext, aEvent, aEventStatus, this);
|
1998-07-18 18:18:20 +00:00
|
|
|
if (SELECTION_DEBUG) printf("HandleEvent(Drag)::mSelectionRange %s\n", mSelectionRange->ToString());
|
1998-06-08 00:57:15 +00:00
|
|
|
|
|
|
|
} else if (aEvent->message == NS_MOUSE_LEFT_BUTTON_DOWN) {
|
1998-07-18 18:18:20 +00:00
|
|
|
/*nsIContent * content;
|
1998-06-08 00:57:15 +00:00
|
|
|
GetContent(content);
|
|
|
|
BuildContentList(content);
|
1998-05-08 18:33:42 +00:00
|
|
|
|
1998-07-18 18:18:20 +00:00
|
|
|
NS_RELEASE(content);*/
|
1998-06-08 00:57:15 +00:00
|
|
|
|
|
|
|
HandlePress(aPresContext, aEvent, aEventStatus, this);
|
|
|
|
}
|
1998-04-27 16:44:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1998-05-08 18:33:42 +00:00
|
|
|
/**
|
|
|
|
* Handles the Mouse Press Event for the frame
|
|
|
|
*/
|
1998-04-27 16:44:52 +00:00
|
|
|
NS_METHOD nsFrame::HandlePress(nsIPresContext& aPresContext,
|
|
|
|
nsGUIEvent* aEvent,
|
|
|
|
nsEventStatus& aEventStatus,
|
|
|
|
nsFrame * aFrame)
|
|
|
|
{
|
1998-07-27 18:05:35 +00:00
|
|
|
if (DisplaySelection(aPresContext) == PR_FALSE)
|
|
|
|
{
|
|
|
|
aEventStatus = nsEventStatus_eIgnore;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1998-05-08 18:33:42 +00:00
|
|
|
nsFrame * currentFrame = aFrame;
|
|
|
|
nsIPresShell * shell = aPresContext.GetShell();
|
1998-07-17 23:00:54 +00:00
|
|
|
|
|
|
|
gDoc = shell->GetDocument();
|
|
|
|
nsISelection * selection = gDoc->GetSelection();
|
1998-05-08 18:33:42 +00:00
|
|
|
nsMouseEvent * mouseEvent = (nsMouseEvent *)aEvent;
|
|
|
|
|
|
|
|
mSelectionRange = selection->GetRange();
|
|
|
|
|
1998-07-17 23:00:54 +00:00
|
|
|
|
1998-05-08 18:33:42 +00:00
|
|
|
|
1998-04-27 16:44:52 +00:00
|
|
|
|
1998-07-22 21:56:48 +00:00
|
|
|
PRUint32 actualOffset = 0;
|
1998-04-27 16:44:52 +00:00
|
|
|
|
|
|
|
mDoingSelection = PR_TRUE;
|
|
|
|
mDidDrag = PR_FALSE;
|
|
|
|
mCurrentFrame = currentFrame;
|
|
|
|
|
1998-07-22 21:56:48 +00:00
|
|
|
mStartPos = GetPosition(aPresContext, aEvent, currentFrame, actualOffset);
|
1998-04-27 16:44:52 +00:00
|
|
|
|
|
|
|
// Click count is 1
|
1998-05-08 18:33:42 +00:00
|
|
|
nsIContent * newContent;
|
|
|
|
currentFrame->GetContent(newContent);
|
1998-04-27 16:44:52 +00:00
|
|
|
|
1998-05-08 18:33:42 +00:00
|
|
|
mCurrentFrame = currentFrame;
|
1998-04-27 16:44:52 +00:00
|
|
|
|
1998-05-08 18:33:42 +00:00
|
|
|
if (mStartSelectionPoint == nsnull) {
|
|
|
|
mStartSelectionPoint = new nsSelectionPoint(nsnull, -1, PR_TRUE);
|
|
|
|
}
|
|
|
|
if (mEndSelectionPoint == nsnull) {
|
|
|
|
mEndSelectionPoint = new nsSelectionPoint(nsnull, -1, PR_TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
mSelectionRange->GetStartPoint(mStartSelectionPoint);
|
|
|
|
mSelectionRange->GetEndPoint(mEndSelectionPoint);
|
|
|
|
|
|
|
|
resetContentTrackers();
|
|
|
|
|
|
|
|
// keep old start and end
|
|
|
|
nsIContent * startContent = mSelectionRange->GetStartContent();
|
|
|
|
nsIContent * endContent = mSelectionRange->GetEndContent();
|
|
|
|
|
1998-07-18 18:18:20 +00:00
|
|
|
if (SELECTION_DEBUG) printf("****** Shift[%s]\n", (mouseEvent->isShift?"Down":"Up"));
|
1998-05-08 18:33:42 +00:00
|
|
|
|
1998-07-18 18:18:20 +00:00
|
|
|
PRBool inRange = gDoc->IsInRange(mSelectionRange->GetStartContent(), mSelectionRange->GetEndContent(), newContent);
|
1998-07-17 23:00:54 +00:00
|
|
|
PRBool isBefore = gDoc->IsBefore(newContent,startContent);
|
|
|
|
|
1998-07-18 21:44:11 +00:00
|
|
|
#ifdef DONT_DO_THIS_USE_NSPR_LOGGING_INSTEAD
|
1998-07-17 23:00:54 +00:00
|
|
|
if (PR_TRUE == inRange)
|
|
|
|
cout << "IN" << endl;
|
|
|
|
else if (PR_TRUE == isBefore)
|
|
|
|
cout << "BEFORE" << endl;
|
|
|
|
else
|
|
|
|
cout << "AFTER" << endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (inRange) {
|
1998-05-08 18:33:42 +00:00
|
|
|
//resetContentTrackers();
|
1998-07-18 18:18:20 +00:00
|
|
|
if (TRACKER_DEBUG) printf("Adding split range to removed selection. Shift[%s]\n", (mouseEvent->isShift?"Down":"Up"));
|
1998-04-27 16:44:52 +00:00
|
|
|
|
1998-05-08 18:33:42 +00:00
|
|
|
if (mouseEvent->isShift) {
|
1998-07-17 23:00:54 +00:00
|
|
|
nsIContent * prevContent = gDoc->GetPrevContent(newContent);
|
|
|
|
nsIContent * nextContent = gDoc->GetNextContent(newContent);
|
1998-04-27 16:44:52 +00:00
|
|
|
|
1998-05-08 18:33:42 +00:00
|
|
|
addRangeToSelectionTrackers(mSelectionRange->GetStartContent(), prevContent, kInsertInRemoveList);
|
|
|
|
addRangeToSelectionTrackers(nextContent, mSelectionRange->GetEndContent(), kInsertInRemoveList);
|
|
|
|
|
|
|
|
mEndSelectionPoint->SetPoint(newContent, mStartPos, PR_FALSE);
|
1998-07-22 21:56:48 +00:00
|
|
|
|
1998-05-08 18:33:42 +00:00
|
|
|
} else {
|
|
|
|
addRangeToSelectionTrackers(mSelectionRange->GetStartContent(), mSelectionRange->GetEndContent(), kInsertInRemoveList); // removed from selection
|
|
|
|
|
|
|
|
mEndSelectionPoint->SetPoint(newContent, mStartPos, PR_TRUE);
|
1998-07-22 21:56:48 +00:00
|
|
|
|
1998-05-08 18:33:42 +00:00
|
|
|
mStartSelectionPoint->SetPoint(newContent, mStartPos, PR_TRUE);
|
|
|
|
|
|
|
|
addRangeToSelectionTrackers(newContent, newContent, kInsertInAddList); // add to selection
|
|
|
|
}
|
|
|
|
|
1998-07-17 23:00:54 +00:00
|
|
|
} else if (isBefore) {
|
1998-05-08 18:33:42 +00:00
|
|
|
if (mouseEvent->isShift) {
|
|
|
|
if (mStartSelectionPoint->IsAnchor()) {
|
1998-07-18 18:18:20 +00:00
|
|
|
if (SELECTION_DEBUG) printf("New Content is before, Start will now be end\n");
|
1998-05-08 18:33:42 +00:00
|
|
|
|
|
|
|
addRangeToSelectionTrackers(mSelectionRange->GetStartContent(), mSelectionRange->GetEndContent(), kInsertInRemoveList); // removed from selection
|
1998-04-27 16:44:52 +00:00
|
|
|
|
1998-07-17 23:00:54 +00:00
|
|
|
nsIContent * prevContent = gDoc->GetPrevContent(newContent);
|
|
|
|
nsIContent * nextContent = gDoc->GetNextContent(newContent);
|
1998-05-08 18:33:42 +00:00
|
|
|
|
1998-07-22 21:56:48 +00:00
|
|
|
mEndSelectionPoint->SetPoint(mStartSelectionPoint->GetContent(),
|
|
|
|
mStartSelectionPoint->GetOffset(),
|
|
|
|
PR_TRUE);
|
|
|
|
|
1998-05-08 18:33:42 +00:00
|
|
|
mStartSelectionPoint->SetPoint(newContent, mStartPos, PR_FALSE);
|
|
|
|
|
|
|
|
addRangeToSelectionTrackers(newContent, mEndSelectionPoint->GetContent(), kInsertInAddList); // add to selection
|
|
|
|
} else {
|
1998-07-18 18:18:20 +00:00
|
|
|
if (SELECTION_DEBUG) printf("New Content is before, Appending to Beginning\n");
|
1998-05-08 18:33:42 +00:00
|
|
|
addRangeToSelectionTrackers(newContent, mEndSelectionPoint->GetContent(), kInsertInAddList); // add to selection
|
|
|
|
mStartSelectionPoint->SetPoint(newContent, mStartPos, PR_FALSE);
|
|
|
|
}
|
1998-04-27 16:44:52 +00:00
|
|
|
} else {
|
1998-07-18 18:18:20 +00:00
|
|
|
if (SELECTION_DEBUG) printf("Adding full range to removed selection. (insert selection)\n");
|
1998-05-08 18:33:42 +00:00
|
|
|
addRangeToSelectionTrackers(mSelectionRange->GetStartContent(), mSelectionRange->GetEndContent(), kInsertInRemoveList); // removed from selection
|
|
|
|
|
|
|
|
mEndSelectionPoint->SetPoint(newContent, mStartPos, PR_TRUE);
|
1998-07-22 21:56:48 +00:00
|
|
|
|
1998-05-08 18:33:42 +00:00
|
|
|
mStartSelectionPoint->SetPoint(newContent, mStartPos, PR_TRUE);
|
|
|
|
|
|
|
|
addRangeToSelectionTrackers(newContent, newContent, kInsertInAddList); // add to selection
|
|
|
|
}
|
|
|
|
} else { // Content is After End
|
|
|
|
|
|
|
|
if (mouseEvent->isShift) {
|
|
|
|
if (mStartSelectionPoint->IsAnchor()) {
|
1998-07-18 18:18:20 +00:00
|
|
|
if (SELECTION_DEBUG) printf("New Content is after, Append new content\n");
|
1998-05-08 18:33:42 +00:00
|
|
|
addRangeToSelectionTrackers(mEndSelectionPoint->GetContent(), newContent, kInsertInAddList); // add to selection
|
|
|
|
mEndSelectionPoint->SetPoint(newContent, mStartPos, PR_FALSE);
|
|
|
|
} else {
|
1998-07-18 18:18:20 +00:00
|
|
|
if (SELECTION_DEBUG) printf("New Content is after, End will now be Start\n");
|
1998-05-08 18:33:42 +00:00
|
|
|
|
|
|
|
addRangeToSelectionTrackers(mSelectionRange->GetStartContent(), mSelectionRange->GetEndContent(), kInsertInRemoveList); // removed from selection
|
|
|
|
|
1998-07-17 23:00:54 +00:00
|
|
|
nsIContent * prevContent = gDoc->GetPrevContent(newContent);
|
|
|
|
nsIContent * nextContent = gDoc->GetNextContent(newContent);
|
1998-05-08 18:33:42 +00:00
|
|
|
|
1998-07-22 21:56:48 +00:00
|
|
|
mStartSelectionPoint->SetPoint(mEndSelectionPoint->GetContent(),
|
|
|
|
mEndSelectionPoint->GetOffset(),
|
|
|
|
PR_TRUE);
|
|
|
|
|
1998-05-08 18:33:42 +00:00
|
|
|
mEndSelectionPoint->SetPoint(newContent, mStartPos, PR_FALSE);
|
|
|
|
|
|
|
|
addRangeToSelectionTrackers(mEndSelectionPoint->GetContent(), newContent, kInsertInAddList); // add to selection
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
1998-07-18 18:18:20 +00:00
|
|
|
if (TRACKER_DEBUG) printf("Adding full range to removed selection.\n");
|
1998-05-08 18:33:42 +00:00
|
|
|
addRangeToSelectionTrackers(mSelectionRange->GetStartContent(), mSelectionRange->GetEndContent(), kInsertInRemoveList); // removed from selection
|
|
|
|
|
|
|
|
mEndSelectionPoint->SetPoint(newContent, mStartPos, PR_TRUE);
|
1998-07-22 21:56:48 +00:00
|
|
|
|
1998-05-08 18:33:42 +00:00
|
|
|
mStartSelectionPoint->SetPoint(newContent, mStartPos, PR_TRUE);
|
|
|
|
|
|
|
|
addRangeToSelectionTrackers(newContent, newContent, kInsertInAddList); // add to selection
|
1998-04-27 16:44:52 +00:00
|
|
|
}
|
|
|
|
}
|
1998-05-08 18:33:42 +00:00
|
|
|
|
|
|
|
/*if (mStartSelectionPoint == nsnull) {
|
|
|
|
mStartSelectionPoint = new nsSelectionPoint(newContent, mStartPos, PR_TRUE);
|
|
|
|
} else {
|
|
|
|
mStartSelectionPoint->SetPoint(newContent, mStartPos, PR_TRUE);
|
1998-04-27 16:44:52 +00:00
|
|
|
}
|
1998-05-08 18:33:42 +00:00
|
|
|
if (mEndSelectionPoint == nsnull) {
|
|
|
|
mEndSelectionPoint = new nsSelectionPoint(newContent, mStartPos, PR_TRUE);
|
|
|
|
} else {
|
|
|
|
mEndSelectionPoint->SetPoint(newContent, mStartPos, PR_TRUE);
|
|
|
|
}*/
|
|
|
|
|
|
|
|
mSelectionRange->SetStartPoint(mStartSelectionPoint);
|
|
|
|
mSelectionRange->SetEndPoint(mEndSelectionPoint);
|
|
|
|
|
1998-04-27 16:44:52 +00:00
|
|
|
|
|
|
|
// [TODO] Recycle sub-selections here?
|
1998-05-08 18:33:42 +00:00
|
|
|
////fSubSelection = new SubSelection(mSelectionRange);
|
1998-04-27 16:44:52 +00:00
|
|
|
////selection.setSelection(fSubSelection);
|
1998-05-08 18:33:42 +00:00
|
|
|
//aPart.setSelection(mSelectionRange);
|
1998-04-27 16:44:52 +00:00
|
|
|
//updateSelection();
|
1998-05-08 18:33:42 +00:00
|
|
|
//resetContentTrackers();
|
1998-04-27 16:44:52 +00:00
|
|
|
|
1998-05-08 18:33:42 +00:00
|
|
|
//addRangeToSelectionTrackers(newContent, newContent, kInsertInAddList);
|
|
|
|
|
|
|
|
//RefreshContentFrames(aPresContext, startContent, endContent);
|
|
|
|
RefreshFromContentTrackers(aPresContext);
|
1998-04-27 16:44:52 +00:00
|
|
|
|
|
|
|
//// [TODO] Set position of caret at start point,
|
|
|
|
//// [TODO] Turn on caret and have it rendered
|
|
|
|
////printf("Selection Start Point set.");
|
|
|
|
|
|
|
|
|
|
|
|
//buildContentTree(currentFrame);
|
|
|
|
|
|
|
|
//fCurrentParentContentList = eventStrategy.getParentList();
|
1998-07-18 18:18:20 +00:00
|
|
|
if (SELECTION_DEBUG) printf("HandleEvent::mSelectionRange %s\n", mSelectionRange->ToString());
|
1998-04-27 16:44:52 +00:00
|
|
|
|
|
|
|
// Force Update
|
1998-05-08 18:33:42 +00:00
|
|
|
ForceDrawFrame(this);
|
|
|
|
|
|
|
|
NS_RELEASE(newContent);
|
1998-07-17 23:00:54 +00:00
|
|
|
NS_RELEASE(shell);
|
|
|
|
NS_RELEASE(selection);
|
1998-04-27 16:44:52 +00:00
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
aEventStatus = nsEventStatus_eIgnore;
|
|
|
|
return NS_OK;
|
1998-04-27 16:44:52 +00:00
|
|
|
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-04-27 16:44:52 +00:00
|
|
|
NS_METHOD nsFrame::HandleDrag(nsIPresContext& aPresContext,
|
|
|
|
nsGUIEvent* aEvent,
|
|
|
|
nsEventStatus& aEventStatus,
|
|
|
|
nsFrame * aFrame)
|
|
|
|
{
|
1998-07-27 18:05:35 +00:00
|
|
|
if (DisplaySelection(aPresContext) == PR_FALSE)
|
|
|
|
{
|
|
|
|
aEventStatus = nsEventStatus_eIgnore;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1998-05-08 18:33:42 +00:00
|
|
|
// keep old start and end
|
|
|
|
nsIContent * startContent = mSelectionRange->GetStartContent();
|
|
|
|
nsIContent * endContent = mSelectionRange->GetEndContent();
|
|
|
|
|
1998-04-27 16:44:52 +00:00
|
|
|
mDidDrag = PR_TRUE;
|
|
|
|
|
|
|
|
if (aFrame != nsnull) {
|
1998-05-08 18:33:42 +00:00
|
|
|
//printf("nsFrame::HandleDrag\n");
|
1998-04-27 16:44:52 +00:00
|
|
|
|
|
|
|
// Check to see if we have changed frame
|
|
|
|
if (aFrame != mCurrentFrame) {
|
|
|
|
// We are in a new Frame!
|
1998-07-18 18:18:20 +00:00
|
|
|
if (SELECTION_DEBUG) printf("HandleDrag::Different Frame in selection!\n");
|
1998-04-27 16:44:52 +00:00
|
|
|
|
|
|
|
// Get Content for current Frame
|
|
|
|
nsIContent * currentContent;
|
|
|
|
mCurrentFrame->GetContent(currentContent);
|
|
|
|
|
|
|
|
// Get Content for New Frame
|
|
|
|
nsIContent * newContent;
|
|
|
|
aFrame->GetContent(newContent);
|
|
|
|
|
|
|
|
// Check to see if we are still in the same Content
|
|
|
|
if (currentContent == newContent) {
|
1998-07-18 18:18:20 +00:00
|
|
|
if (SELECTION_DEBUG) printf("HandleDrag::New Frame, same content.\n");
|
1998-04-27 16:44:52 +00:00
|
|
|
|
1998-05-08 18:33:42 +00:00
|
|
|
AdjustPointsInNewContent(aPresContext, aEvent, aFrame);
|
1998-04-27 16:44:52 +00:00
|
|
|
|
1998-07-17 23:00:54 +00:00
|
|
|
} else if (gDoc->IsBefore(newContent, currentContent)) {
|
1998-07-18 18:18:20 +00:00
|
|
|
if (SELECTION_DEBUG) printf("HandleDrag::New Frame, is Before.\n");
|
1998-04-27 16:44:52 +00:00
|
|
|
|
1998-05-08 18:33:42 +00:00
|
|
|
resetContentTrackers();
|
1998-04-27 16:44:52 +00:00
|
|
|
NewContentIsBefore(aPresContext, aEvent, newContent, currentContent, aFrame);
|
|
|
|
|
|
|
|
} else { // Content is AFTER
|
1998-07-18 18:18:20 +00:00
|
|
|
if (SELECTION_DEBUG) printf("HandleDrag::New Frame, is After.\n");
|
1998-04-27 16:44:52 +00:00
|
|
|
|
1998-05-08 18:33:42 +00:00
|
|
|
resetContentTrackers();
|
1998-04-27 16:44:52 +00:00
|
|
|
NewContentIsAfter(aPresContext, aEvent, newContent, currentContent, aFrame);
|
|
|
|
}
|
|
|
|
mCurrentFrame = aFrame;
|
1998-05-08 18:33:42 +00:00
|
|
|
|
|
|
|
NS_RELEASE(currentContent);
|
|
|
|
NS_RELEASE(newContent);
|
1998-04-27 16:44:52 +00:00
|
|
|
} else {
|
1998-07-18 18:18:20 +00:00
|
|
|
//if (SELECTION_DEBUG) printf("HandleDrag::Same Frame.\n");
|
1998-04-27 16:44:52 +00:00
|
|
|
|
|
|
|
// Same Frame as before
|
1998-07-18 18:18:20 +00:00
|
|
|
//if (SELECTION_DEBUG) printf("\nSame Start: %s\n", mStartSelectionPoint->ToString());
|
|
|
|
//if (SELECTION_DEBUG) printf("Same End: %s\n", mEndSelectionPoint->ToString());
|
1998-04-27 16:44:52 +00:00
|
|
|
// [TODO] Uncomment these soon
|
1998-05-08 18:33:42 +00:00
|
|
|
|
|
|
|
if (mStartSelectionPoint->GetContent() == mEndSelectionPoint->GetContent()) {
|
1998-07-18 18:18:20 +00:00
|
|
|
//if (SELECTION_DEBUG) printf("Start & End Frame are the same: \n");
|
1998-07-22 21:56:48 +00:00
|
|
|
AdjustPointsInSameContent(aPresContext, aEvent);
|
1998-04-27 16:44:52 +00:00
|
|
|
} else {
|
1998-07-18 18:18:20 +00:00
|
|
|
//if (SELECTION_DEBUG) printf("Start & End Frame are different: \n");
|
1998-04-27 16:44:52 +00:00
|
|
|
|
|
|
|
// Get Content for New Frame
|
|
|
|
nsIContent * newContent;
|
1998-05-08 18:33:42 +00:00
|
|
|
aFrame->GetContent(newContent);
|
1998-07-22 21:56:48 +00:00
|
|
|
PRInt32 newPos = -1;
|
|
|
|
PRUint32 actualOffset = 0;
|
1998-04-27 16:44:52 +00:00
|
|
|
|
1998-07-22 21:56:48 +00:00
|
|
|
newPos = GetPosition(aPresContext, aEvent, aFrame, actualOffset);
|
1998-04-27 16:44:52 +00:00
|
|
|
|
1998-05-08 18:33:42 +00:00
|
|
|
if (newContent == mStartSelectionPoint->GetContent()) {
|
1998-07-18 18:18:20 +00:00
|
|
|
//if (SELECTION_DEBUG) printf("New Content equals Start Content\n");
|
1998-05-08 18:33:42 +00:00
|
|
|
mStartSelectionPoint->SetOffset(newPos);
|
|
|
|
mSelectionRange->SetStartPoint(mStartSelectionPoint);
|
|
|
|
} else if (newContent == mEndSelectionPoint->GetContent()) {
|
1998-07-18 18:18:20 +00:00
|
|
|
//if (SELECTION_DEBUG) printf("New Content equals End Content\n");
|
1998-05-08 18:33:42 +00:00
|
|
|
mEndSelectionPoint->SetOffset(newPos);
|
|
|
|
mSelectionRange->SetEndPoint(mEndSelectionPoint);
|
1998-04-27 16:44:52 +00:00
|
|
|
} else {
|
1998-07-18 18:18:20 +00:00
|
|
|
if (SELECTION_DEBUG) printf("=====\n=====\n=====\n=====\n=====\n=====\n Should NOT be here.\n");
|
1998-04-27 16:44:52 +00:00
|
|
|
}
|
|
|
|
|
1998-07-18 18:18:20 +00:00
|
|
|
//if (SELECTION_DEBUG) printf("*Same Start: "+mStartSelectionPoint->GetOffset()+
|
1998-05-08 18:33:42 +00:00
|
|
|
// " "+mStartSelectionPoint->IsAnchor()+
|
|
|
|
// " End: "+mEndSelectionPoint->GetOffset() +
|
|
|
|
// " "+mEndSelectionPoint->IsAnchor());
|
|
|
|
NS_RELEASE(newContent);
|
|
|
|
}
|
1998-04-27 16:44:52 +00:00
|
|
|
//??doDragRepaint(mCurrentFrame);
|
|
|
|
}
|
|
|
|
}
|
1998-05-08 18:33:42 +00:00
|
|
|
// Force Update
|
|
|
|
ForceDrawFrame(this);
|
|
|
|
//RefreshContentFrames(aPresContext, startContent, endContent);
|
|
|
|
RefreshFromContentTrackers(aPresContext);
|
1998-04-27 16:44:52 +00:00
|
|
|
|
|
|
|
aEventStatus = nsEventStatus_eIgnore;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_METHOD nsFrame::HandleRelease(nsIPresContext& aPresContext,
|
|
|
|
nsGUIEvent* aEvent,
|
|
|
|
nsEventStatus& aEventStatus,
|
|
|
|
nsFrame * aFrame)
|
|
|
|
{
|
|
|
|
mDoingSelection = PR_FALSE;
|
|
|
|
aEventStatus = nsEventStatus_eIgnore;
|
1998-07-17 23:00:54 +00:00
|
|
|
NS_IF_RELEASE(gDoc);
|
1998-04-27 16:44:52 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1998-05-08 18:33:42 +00:00
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
//-- GetPosition
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
PRInt32 nsFrame::GetPosition(nsIPresContext& aPresContext,
|
1998-07-22 21:56:48 +00:00
|
|
|
nsGUIEvent * aEvent,
|
|
|
|
nsIFrame * aNewFrame,
|
|
|
|
PRUint32& aAcutalContentOffset) {
|
1998-05-08 18:33:42 +00:00
|
|
|
|
|
|
|
//PRInt32 offset;
|
|
|
|
//PRInt32 width;
|
|
|
|
//CalcCursorPosition(aPresContext, aEvent, aNewFrame, offset, width);
|
|
|
|
//offset += aNewFrame->GetContentOffset();
|
|
|
|
|
|
|
|
//return offset;
|
1998-07-22 21:56:48 +00:00
|
|
|
aAcutalContentOffset = 0;
|
1998-05-08 18:33:42 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************
|
|
|
|
* Adjusts the Starting and Ending TextPoint for a Range
|
|
|
|
*********************************************************/
|
|
|
|
void nsFrame::AdjustPointsInNewContent(nsIPresContext& aPresContext,
|
|
|
|
nsGUIEvent * aEvent,
|
|
|
|
nsIFrame * aNewFrame) {
|
1998-07-22 21:56:48 +00:00
|
|
|
PRUint32 actualOffset = 0;
|
|
|
|
|
1998-05-08 18:33:42 +00:00
|
|
|
// Get new Cursor Poition in the new content
|
1998-07-22 21:56:48 +00:00
|
|
|
PRInt32 newPos = GetPosition(aPresContext, aEvent, aNewFrame, actualOffset);
|
1998-05-08 18:33:42 +00:00
|
|
|
|
|
|
|
if (mStartSelectionPoint->IsAnchor()) {
|
|
|
|
if (newPos == mStartSelectionPoint->GetOffset()) {
|
|
|
|
mEndSelectionPoint->SetOffset(newPos);
|
|
|
|
mEndSelectionPoint->SetAnchor(PR_TRUE);
|
|
|
|
mSelectionRange->SetEndPoint(mEndSelectionPoint);
|
|
|
|
} else if (newPos < mStartSelectionPoint->GetOffset()) {
|
|
|
|
mEndSelectionPoint->SetOffset(mStartSelectionPoint->GetOffset());
|
|
|
|
mEndSelectionPoint->SetAnchor(PR_TRUE);
|
|
|
|
mStartSelectionPoint->SetOffset(newPos);
|
|
|
|
mStartSelectionPoint->SetAnchor(PR_FALSE);
|
|
|
|
mSelectionRange->SetRange(mStartSelectionPoint, mEndSelectionPoint);
|
|
|
|
} else {
|
|
|
|
mEndSelectionPoint->SetOffset(newPos);
|
|
|
|
mSelectionRange->SetEndPoint(mEndSelectionPoint);
|
|
|
|
}
|
|
|
|
} else if (mEndSelectionPoint->IsAnchor()) {
|
|
|
|
int endPos = mEndSelectionPoint->GetOffset();
|
|
|
|
if (newPos == mEndSelectionPoint->GetOffset()) {
|
|
|
|
mStartSelectionPoint->SetOffset(newPos);
|
|
|
|
mStartSelectionPoint->SetAnchor(PR_TRUE);
|
|
|
|
mSelectionRange->SetStartPoint(mStartSelectionPoint);
|
|
|
|
} else if (newPos > mEndSelectionPoint->GetOffset()) {
|
|
|
|
mEndSelectionPoint->SetOffset(newPos);
|
|
|
|
mEndSelectionPoint->SetAnchor(PR_FALSE);
|
|
|
|
mStartSelectionPoint->SetOffset(endPos);
|
|
|
|
mStartSelectionPoint->SetAnchor(PR_TRUE);
|
|
|
|
mSelectionRange->SetRange(mStartSelectionPoint, mEndSelectionPoint);
|
|
|
|
} else {
|
|
|
|
mStartSelectionPoint->SetOffset(newPos);
|
|
|
|
mSelectionRange->SetStartPoint(mStartSelectionPoint);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// [TODO] Should get here
|
|
|
|
// throw exception
|
1998-07-18 18:18:20 +00:00
|
|
|
if (SELECTION_DEBUG) printf("--\n--\n--\n--\n--\n--\n--\n Should be here. #102\n");
|
1998-05-08 18:33:42 +00:00
|
|
|
//return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************
|
|
|
|
* Adjusts the Starting and Ending TextPoint for a Range
|
|
|
|
*********************************************************/
|
|
|
|
void nsFrame::AdjustPointsInSameContent(nsIPresContext& aPresContext,
|
|
|
|
nsGUIEvent * aEvent) {
|
1998-07-22 21:56:48 +00:00
|
|
|
PRUint32 actualOffset = 0;
|
|
|
|
|
1998-05-08 18:33:42 +00:00
|
|
|
// Get new Cursor Poition in the same content
|
1998-07-22 21:56:48 +00:00
|
|
|
PRInt32 newPos = GetPosition(aPresContext, aEvent, mCurrentFrame, actualOffset);
|
1998-07-18 18:18:20 +00:00
|
|
|
if (SELECTION_DEBUG) printf("AdjustTextPointsInSameContent newPos: %d\n", newPos);
|
1998-05-08 18:33:42 +00:00
|
|
|
|
|
|
|
if (mStartSelectionPoint->IsAnchor()) {
|
|
|
|
if (newPos == mStartSelectionPoint->GetOffset()) {
|
|
|
|
mEndSelectionPoint->SetOffset(newPos);
|
|
|
|
mEndSelectionPoint->SetAnchor(PR_TRUE);
|
|
|
|
mSelectionRange->SetEndPoint(mEndSelectionPoint);
|
|
|
|
} else if (newPos < mStartSelectionPoint->GetOffset()) {
|
|
|
|
mStartSelectionPoint->SetOffset(newPos);
|
|
|
|
mStartSelectionPoint->SetAnchor(PR_FALSE);
|
|
|
|
mEndSelectionPoint->SetAnchor(PR_TRUE);
|
|
|
|
mSelectionRange->SetRange(mStartSelectionPoint, mEndSelectionPoint);
|
|
|
|
} else {
|
|
|
|
mEndSelectionPoint->SetAnchor(PR_FALSE);
|
|
|
|
mEndSelectionPoint->SetOffset(newPos);
|
|
|
|
mSelectionRange->SetEndPoint(mEndSelectionPoint);
|
|
|
|
}
|
|
|
|
} else if (mEndSelectionPoint->IsAnchor()) {
|
|
|
|
if (newPos == mEndSelectionPoint->GetOffset()) {
|
|
|
|
mStartSelectionPoint->SetOffset(newPos);
|
|
|
|
mStartSelectionPoint->SetAnchor(PR_TRUE);
|
|
|
|
mSelectionRange->SetStartPoint(mStartSelectionPoint);
|
|
|
|
} else if (newPos > mEndSelectionPoint->GetOffset()) {
|
|
|
|
mEndSelectionPoint->SetOffset(newPos);
|
|
|
|
mEndSelectionPoint->SetAnchor(PR_FALSE);
|
|
|
|
mStartSelectionPoint->SetAnchor(PR_TRUE);
|
|
|
|
mSelectionRange->SetRange(mStartSelectionPoint, mEndSelectionPoint);
|
|
|
|
} else {
|
|
|
|
mStartSelectionPoint->SetAnchor(PR_FALSE);
|
|
|
|
mStartSelectionPoint->SetOffset(newPos);
|
|
|
|
mSelectionRange->SetStartPoint(mStartSelectionPoint);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// [TODO] Should get here
|
|
|
|
// throw exception
|
1998-07-18 18:18:20 +00:00
|
|
|
if (SELECTION_DEBUG) printf("--\n--\n--\n--\n--\n--\n--\n Should be here. #101\n");
|
1998-05-08 18:33:42 +00:00
|
|
|
//return;
|
|
|
|
}
|
|
|
|
|
1998-07-18 18:18:20 +00:00
|
|
|
if (SELECTION_DEBUG) printf("Start %s End %s\n", mStartSelectionPoint->ToString(), mEndSelectionPoint->ToString());
|
1998-05-08 18:33:42 +00:00
|
|
|
//}
|
|
|
|
}
|
1998-04-27 16:44:52 +00:00
|
|
|
|
1998-07-17 04:52:12 +00:00
|
|
|
NS_METHOD nsFrame::GetCursorAndContentAt(nsIPresContext& aPresContext,
|
1998-04-17 01:41:24 +00:00
|
|
|
const nsPoint& aPoint,
|
|
|
|
nsIFrame** aFrame,
|
1998-07-17 04:52:12 +00:00
|
|
|
nsIContent** aContent,
|
1998-04-17 01:41:24 +00:00
|
|
|
PRInt32& aCursor)
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
1998-07-17 04:52:12 +00:00
|
|
|
*aContent = mContent;
|
1998-04-17 01:41:24 +00:00
|
|
|
aCursor = NS_STYLE_CURSOR_INHERIT;
|
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Resize and incremental reflow
|
1998-05-14 00:47:32 +00:00
|
|
|
NS_METHOD
|
|
|
|
nsFrame::GetFrameState(nsFrameState& aResult)
|
|
|
|
{
|
|
|
|
aResult = mState;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_METHOD
|
|
|
|
nsFrame::SetFrameState(nsFrameState aNewState)
|
|
|
|
{
|
|
|
|
mState = aNewState;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Resize reflow methods
|
|
|
|
|
|
|
|
NS_METHOD
|
|
|
|
nsFrame::WillReflow(nsIPresContext& aPresContext)
|
|
|
|
{
|
1998-06-25 16:33:10 +00:00
|
|
|
NS_FRAME_TRACE_MSG(NS_FRAME_TRACE_CALLS,
|
|
|
|
("WillReflow: oldState=%x", mState));
|
1998-05-14 00:47:32 +00:00
|
|
|
mState |= NS_FRAME_IN_REFLOW;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_METHOD
|
|
|
|
nsFrame::DidReflow(nsIPresContext& aPresContext,
|
|
|
|
nsDidReflowStatus aStatus)
|
|
|
|
{
|
1998-06-25 16:33:10 +00:00
|
|
|
NS_FRAME_TRACE_MSG(NS_FRAME_TRACE_CALLS,
|
|
|
|
("nsFrame::DidReflow: aStatus=%d", aStatus));
|
1998-05-14 00:47:32 +00:00
|
|
|
if (NS_FRAME_REFLOW_FINISHED == aStatus) {
|
1998-05-29 02:10:12 +00:00
|
|
|
mState &= ~(NS_FRAME_IN_REFLOW | NS_FRAME_FIRST_REFLOW);
|
1998-05-28 21:55:13 +00:00
|
|
|
|
|
|
|
if (nsnull != mView) {
|
|
|
|
// Position and size view relative to its parent, not relative to our
|
|
|
|
// parent frame (our parent frame may not have a view).
|
|
|
|
nsIView* parentWithView;
|
|
|
|
nsPoint origin;
|
|
|
|
GetOffsetFromView(origin, parentWithView);
|
1998-06-02 22:04:54 +00:00
|
|
|
nsIViewManager *vm = mView->GetViewManager();
|
|
|
|
vm->ResizeView(mView, mRect.width, mRect.height);
|
|
|
|
vm->MoveViewTo(mView, origin.x, origin.y);
|
|
|
|
NS_RELEASE(vm);
|
1998-05-28 21:55:13 +00:00
|
|
|
NS_IF_RELEASE(parentWithView);
|
|
|
|
}
|
1998-05-14 00:47:32 +00:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
1998-04-13 20:24:54 +00:00
|
|
|
|
1998-07-15 02:53:09 +00:00
|
|
|
NS_METHOD nsFrame::Reflow(nsIPresContext& aPresContext,
|
1998-05-22 03:52:51 +00:00
|
|
|
nsReflowMetrics& aDesiredSize,
|
|
|
|
const nsReflowState& aReflowState,
|
|
|
|
nsReflowStatus& aStatus)
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
|
|
|
aDesiredSize.width = 0;
|
|
|
|
aDesiredSize.height = 0;
|
|
|
|
aDesiredSize.ascent = 0;
|
|
|
|
aDesiredSize.descent = 0;
|
1998-05-25 17:31:49 +00:00
|
|
|
if (nsnull != aDesiredSize.maxElementSize) {
|
|
|
|
aDesiredSize.maxElementSize->width = 0;
|
|
|
|
aDesiredSize.maxElementSize->height = 0;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
1998-05-12 04:17:56 +00:00
|
|
|
aStatus = NS_FRAME_COMPLETE;
|
1998-05-25 17:31:49 +00:00
|
|
|
|
|
|
|
if (eReflowReason_Incremental == aReflowState.reason) {
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::ContentAppended(nsIPresShell* aShell,
|
|
|
|
nsIPresContext* aPresContext,
|
|
|
|
nsIContent* aContainer)
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
1998-04-17 01:41:24 +00:00
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::ContentInserted(nsIPresShell* aShell,
|
|
|
|
nsIPresContext* aPresContext,
|
|
|
|
nsIContent* aContainer,
|
|
|
|
nsIContent* aChild,
|
|
|
|
PRInt32 aIndexInParent)
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
1998-04-17 01:41:24 +00:00
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::ContentReplaced(nsIPresShell* aShell,
|
|
|
|
nsIPresContext* aPresContext,
|
|
|
|
nsIContent* aContainer,
|
|
|
|
nsIContent* aOldChild,
|
|
|
|
nsIContent* aNewChild,
|
|
|
|
PRInt32 aIndexInParent)
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
1998-04-17 01:41:24 +00:00
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::ContentDeleted(nsIPresShell* aShell,
|
|
|
|
nsIPresContext* aPresContext,
|
|
|
|
nsIContent* aContainer,
|
|
|
|
nsIContent* aChild,
|
|
|
|
PRInt32 aIndexInParent)
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
1998-04-17 01:41:24 +00:00
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-05-08 04:45:37 +00:00
|
|
|
NS_METHOD nsFrame::ContentChanged(nsIPresShell* aShell,
|
|
|
|
nsIPresContext* aPresContext,
|
|
|
|
nsIContent* aChild,
|
|
|
|
nsISupports* aSubContent)
|
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1998-07-15 02:59:06 +00:00
|
|
|
NS_METHOD nsFrame::GetReflowMetrics(nsIPresContext& aPresContext,
|
1998-04-17 01:41:24 +00:00
|
|
|
nsReflowMetrics& aMetrics)
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
|
|
|
aMetrics.width = mRect.width;
|
|
|
|
aMetrics.height = mRect.height;
|
|
|
|
aMetrics.ascent = mRect.height;
|
|
|
|
aMetrics.descent = 0;
|
1998-04-17 01:41:24 +00:00
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Flow member functions
|
|
|
|
|
1998-05-22 04:54:11 +00:00
|
|
|
NS_METHOD nsFrame::IsSplittable(nsSplittableType& aIsSplittable) const
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
1998-05-22 04:54:11 +00:00
|
|
|
aIsSplittable = NS_FRAME_NOT_SPLITTABLE;
|
1998-04-17 01:41:24 +00:00
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-07-15 03:23:23 +00:00
|
|
|
NS_METHOD nsFrame::CreateContinuingFrame(nsIPresContext& aPresContext,
|
1998-05-07 00:08:20 +00:00
|
|
|
nsIFrame* aParent,
|
|
|
|
nsIStyleContext* aStyleContext,
|
|
|
|
nsIFrame*& aContinuingFrame)
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
|
|
|
NS_ERROR("not splittable");
|
1998-04-17 01:41:24 +00:00
|
|
|
aContinuingFrame = nsnull;
|
1998-05-08 17:02:35 +00:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::GetPrevInFlow(nsIFrame*& aPrevInFlow) const
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
1998-04-17 01:41:24 +00:00
|
|
|
aPrevInFlow = nsnull;
|
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::SetPrevInFlow(nsIFrame*)
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
|
|
|
NS_ERROR("not splittable");
|
1998-05-08 17:02:35 +00:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::GetNextInFlow(nsIFrame*& aNextInFlow) const
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
1998-04-17 01:41:24 +00:00
|
|
|
aNextInFlow = nsnull;
|
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::SetNextInFlow(nsIFrame*)
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
|
|
|
NS_ERROR("not splittable");
|
1998-05-08 17:02:35 +00:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::AppendToFlow(nsIFrame* aAfterFrame)
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
|
|
|
NS_ERROR("not splittable");
|
1998-05-08 17:02:35 +00:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::PrependToFlow(nsIFrame* aBeforeFrame)
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
|
|
|
NS_ERROR("not splittable");
|
1998-05-08 17:02:35 +00:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::RemoveFromFlow()
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
|
|
|
NS_ERROR("not splittable");
|
1998-05-08 17:02:35 +00:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::BreakFromPrevFlow()
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
|
|
|
NS_ERROR("not splittable");
|
1998-05-08 17:02:35 +00:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::BreakFromNextFlow()
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
|
|
|
NS_ERROR("not splittable");
|
1998-05-08 17:02:35 +00:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Associated view object
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::GetView(nsIView*& aView) const
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
1998-04-17 01:41:24 +00:00
|
|
|
aView = mView;
|
|
|
|
NS_IF_ADDREF(aView);
|
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::SetView(nsIView* aView)
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
|
|
|
NS_IF_RELEASE(mView);
|
|
|
|
if (nsnull != aView) {
|
|
|
|
mView = aView;
|
|
|
|
aView->SetFrame(this);
|
|
|
|
NS_ADDREF(aView);
|
|
|
|
}
|
1998-04-17 01:41:24 +00:00
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Find the first geometric parent that has a view
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::GetParentWithView(nsIFrame*& aParent) const
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
1998-04-17 01:41:24 +00:00
|
|
|
aParent = mGeometricParent;
|
1998-04-13 20:24:54 +00:00
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
while (nsnull != aParent) {
|
|
|
|
nsIView* parView;
|
|
|
|
|
|
|
|
aParent->GetView(parView);
|
1998-04-13 20:24:54 +00:00
|
|
|
if (nsnull != parView) {
|
|
|
|
NS_RELEASE(parView);
|
|
|
|
break;
|
|
|
|
}
|
1998-04-17 01:41:24 +00:00
|
|
|
aParent->GetGeometricParent(aParent);
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Returns the offset from this frame to the closest geometric parent that
|
|
|
|
// has a view. Also returns the containing view or null in case of error
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::GetOffsetFromView(nsPoint& aOffset, nsIView*& aView) const
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
1998-04-17 01:41:24 +00:00
|
|
|
nsIFrame* frame = (nsIFrame*)this;
|
1998-04-13 20:24:54 +00:00
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
aView = nsnull;
|
1998-04-13 20:24:54 +00:00
|
|
|
aOffset.MoveTo(0, 0);
|
|
|
|
do {
|
1998-04-17 01:41:24 +00:00
|
|
|
nsPoint origin;
|
|
|
|
|
1998-04-13 20:24:54 +00:00
|
|
|
frame->GetOrigin(origin);
|
|
|
|
aOffset += origin;
|
1998-04-17 01:41:24 +00:00
|
|
|
frame->GetGeometricParent(frame);
|
|
|
|
if (nsnull != frame) {
|
|
|
|
frame->GetView(aView);
|
|
|
|
}
|
|
|
|
} while ((nsnull != frame) && (nsnull == aView));
|
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::GetWindow(nsIWidget*& aWindow) const
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
1998-04-17 01:41:24 +00:00
|
|
|
nsIFrame* frame = (nsIFrame*)this;
|
|
|
|
|
|
|
|
aWindow = nsnull;
|
1998-04-13 20:24:54 +00:00
|
|
|
while (nsnull != frame) {
|
1998-04-17 01:41:24 +00:00
|
|
|
nsIView* view;
|
|
|
|
|
|
|
|
frame->GetView(view);
|
1998-04-13 20:24:54 +00:00
|
|
|
if (nsnull != view) {
|
1998-04-17 01:41:24 +00:00
|
|
|
aWindow = view->GetWidget();
|
1998-04-13 20:24:54 +00:00
|
|
|
NS_RELEASE(view);
|
1998-04-17 01:41:24 +00:00
|
|
|
if (nsnull != aWindow) {
|
|
|
|
break;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
}
|
1998-04-17 01:41:24 +00:00
|
|
|
frame->GetParentWithView(frame);
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_POSTCONDITION(nsnull != aWindow, "no window in frame tree");
|
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-06-02 05:28:11 +00:00
|
|
|
void nsFrame::Invalidate(const nsRect& aDamageRect) const
|
|
|
|
{
|
|
|
|
nsIViewManagerPtr viewManager;
|
|
|
|
|
|
|
|
if (nsnull != mView) {
|
|
|
|
viewManager = mView->GetViewManager();
|
1998-07-24 00:01:53 +00:00
|
|
|
viewManager->UpdateView(mView, aDamageRect, NS_VMREFRESH_NO_SYNC);
|
1998-06-02 05:28:11 +00:00
|
|
|
|
|
|
|
} else {
|
|
|
|
nsRect rect(aDamageRect);
|
|
|
|
nsPoint offset;
|
|
|
|
nsIViewPtr view;
|
|
|
|
|
|
|
|
GetOffsetFromView(offset, view.AssignRef());
|
1998-06-25 17:23:32 +00:00
|
|
|
NS_ASSERTION(view.IsNotNull(), "no view");
|
1998-06-02 05:28:11 +00:00
|
|
|
rect += offset;
|
|
|
|
viewManager = view->GetViewManager();
|
1998-07-24 00:01:53 +00:00
|
|
|
viewManager->UpdateView(view, rect, NS_VMREFRESH_NO_SYNC);
|
1998-06-02 05:28:11 +00:00
|
|
|
}
|
|
|
|
}
|
1998-05-13 22:38:09 +00:00
|
|
|
|
|
|
|
// Style sizing methods
|
|
|
|
NS_METHOD nsFrame::IsPercentageBase(PRBool& aBase) const
|
|
|
|
{
|
1998-06-05 06:09:09 +00:00
|
|
|
const nsStylePosition* position;
|
|
|
|
GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)position);
|
1998-05-13 22:38:09 +00:00
|
|
|
if (position->mPosition != NS_STYLE_POSITION_NORMAL) {
|
|
|
|
aBase = PR_TRUE;
|
|
|
|
}
|
|
|
|
else {
|
1998-06-05 06:09:09 +00:00
|
|
|
const nsStyleDisplay* display;
|
|
|
|
GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)display);
|
1998-05-13 22:38:09 +00:00
|
|
|
if ((display->mDisplay == NS_STYLE_DISPLAY_BLOCK) ||
|
|
|
|
(display->mDisplay == NS_STYLE_DISPLAY_LIST_ITEM)) {
|
|
|
|
aBase = PR_TRUE;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
aBase = PR_FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_METHOD nsFrame::GetAutoMarginSize(PRUint8 aSide, nscoord& aSize) const
|
|
|
|
{
|
|
|
|
aSize = 0; // XXX probably not right, subclass override?
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1998-04-13 20:24:54 +00:00
|
|
|
// Sibling pointer used to link together frames
|
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::GetNextSibling(nsIFrame*& aNextSibling) const
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
1998-04-17 01:41:24 +00:00
|
|
|
aNextSibling = mNextSibling;
|
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::SetNextSibling(nsIFrame* aNextSibling)
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
|
|
|
mNextSibling = aNextSibling;
|
1998-04-17 01:41:24 +00:00
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-06-03 22:49:45 +00:00
|
|
|
// Transparency query
|
|
|
|
NS_METHOD nsFrame::IsTransparent(PRBool& aTransparent) const
|
|
|
|
{
|
|
|
|
//XXX this needs to be overridden in just about every leaf class? MMP
|
|
|
|
aTransparent = PR_TRUE;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1998-04-13 20:24:54 +00:00
|
|
|
// Debugging
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::List(FILE* out, PRInt32 aIndent) const
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
|
|
|
// Indent
|
|
|
|
for (PRInt32 i = aIndent; --i >= 0; ) fputs(" ", out);
|
|
|
|
|
|
|
|
// Output the tag and rect
|
|
|
|
ListTag(out);
|
1998-06-03 15:45:48 +00:00
|
|
|
if (nsnull != mView) {
|
|
|
|
fprintf(out, " [view=%p]", mView);
|
|
|
|
}
|
1998-04-13 20:24:54 +00:00
|
|
|
fputs(" ", out);
|
|
|
|
out << mRect;
|
1998-05-18 16:53:09 +00:00
|
|
|
if (0 != mState) {
|
|
|
|
fprintf(out, " [state=%08x]", mState);
|
|
|
|
}
|
1998-04-13 20:24:54 +00:00
|
|
|
fputs("<>\n", out);
|
1998-04-17 01:41:24 +00:00
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Output the frame's tag
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::ListTag(FILE* out) const
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
|
|
|
nsIAtom* tag = mContent->GetTag();
|
|
|
|
if (tag != nsnull) {
|
|
|
|
nsAutoString buf;
|
|
|
|
tag->ToString(buf);
|
|
|
|
fputs(buf, out);
|
|
|
|
NS_RELEASE(tag);
|
|
|
|
}
|
1998-05-05 23:56:50 +00:00
|
|
|
PRInt32 contentIndex;
|
|
|
|
|
|
|
|
GetContentIndex(contentIndex);
|
|
|
|
fprintf(out, "(%d)@%p", contentIndex, this);
|
1998-04-17 01:41:24 +00:00
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-04-17 01:41:24 +00:00
|
|
|
NS_METHOD nsFrame::VerifyTree() const
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
1998-05-28 19:00:31 +00:00
|
|
|
NS_ASSERTION(0 == (mState & NS_FRAME_IN_REFLOW), "frame is in reflow");
|
1998-04-17 01:41:24 +00:00
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
1998-04-27 16:44:52 +00:00
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
//------------------------------
|
|
|
|
void WalkTree(nsIContent * aParent) {
|
1998-05-08 18:33:42 +00:00
|
|
|
|
|
|
|
/*if (aParent->ChildCount() == 0) {
|
|
|
|
nsIDOMText * textContent;
|
|
|
|
nsresult status = aParent->QueryInterface(kIDOMTextIID, (void**) &textContent);
|
|
|
|
if (NS_OK == status) {
|
|
|
|
nsString text;
|
|
|
|
textContent->GetData(text);
|
|
|
|
if (text.Length() == 1) {
|
|
|
|
char * str = text.ToNewCString();
|
|
|
|
if (str[0] >= 32 && str[0] != '\n') {
|
|
|
|
fContentArray[fMax++] = aParent;
|
|
|
|
}
|
|
|
|
delete str;
|
|
|
|
} else {
|
|
|
|
fContentArray[fMax++] = aParent;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}*/
|
1998-04-27 16:44:52 +00:00
|
|
|
fContentArray[fMax++] = aParent;
|
1998-05-08 18:33:42 +00:00
|
|
|
|
1998-04-27 16:44:52 +00:00
|
|
|
for (PRInt32 i=0;i<aParent->ChildCount();i++) {
|
|
|
|
nsIContent * node = aParent->ChildAt(i);
|
|
|
|
WalkTree(node);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------
|
|
|
|
void PrintContent() {
|
|
|
|
//static NS_DEFINE_IID(kITextContentIID, NS_ITEXTCONTENT_IID);
|
|
|
|
static NS_DEFINE_IID(kIDOMTextIID, NS_IDOMTEXT_IID);
|
|
|
|
|
|
|
|
nsIDOMText * textContent;
|
|
|
|
|
|
|
|
for (int i=0;i<fMax;i++) {
|
|
|
|
nsresult status = fContentArray[i]->QueryInterface(kIDOMTextIID, (void**) &textContent);
|
|
|
|
if (NS_OK == status) {
|
|
|
|
nsString text;
|
|
|
|
//textContent->GetText(text, 0, textContent->GetLength());
|
|
|
|
textContent->GetData(text);
|
|
|
|
char * str = text.ToNewCString();
|
1998-05-08 18:33:42 +00:00
|
|
|
if (text.Length() > 1) {
|
|
|
|
printf("%i [%s]\n", i, str);
|
|
|
|
} else {
|
|
|
|
printf("%i [%s] %d\n", i, str, str[0]);
|
|
|
|
}
|
1998-04-27 16:44:52 +00:00
|
|
|
delete str;
|
|
|
|
}
|
|
|
|
}
|
1998-05-08 18:33:42 +00:00
|
|
|
printf("Total pieces of Content: %d\n", fMax);
|
1998-04-27 16:44:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//------------------------------
|
1998-07-18 18:18:20 +00:00
|
|
|
/*void BuildContentList(nsIContent * Start) {
|
1998-04-27 16:44:52 +00:00
|
|
|
|
|
|
|
if (fMax > -1) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
fMax = 0;
|
|
|
|
nsIContent * node = Start;
|
|
|
|
nsIContent * parent = node->GetParent();
|
|
|
|
// root content
|
|
|
|
while (parent != nsnull) {
|
|
|
|
parent = node->GetParent();
|
|
|
|
if (parent != nsnull) {
|
|
|
|
node = parent;
|
|
|
|
}
|
|
|
|
} // while
|
|
|
|
//fContentArray = new nsIContent[1024];
|
|
|
|
WalkTree(node);
|
1998-07-18 18:18:20 +00:00
|
|
|
if (SELECTION_DEBUG) PrintContent();
|
|
|
|
}*/
|
1998-04-27 16:44:52 +00:00
|
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
// Determines whether a piece of content in question is inbetween the two
|
|
|
|
// piece of content
|
|
|
|
//--------------------------------------------------------------------------
|
1998-07-18 18:18:20 +00:00
|
|
|
/*PRBool IsInRange(nsIContent * aStartContent,
|
1998-05-08 18:33:42 +00:00
|
|
|
nsIContent * aEndContent,
|
|
|
|
nsIContent * aContent) {
|
1998-04-27 16:44:52 +00:00
|
|
|
// Start and End Content is the same, so check against the start
|
|
|
|
if (aStartContent == aEndContent) {
|
1998-05-12 04:17:56 +00:00
|
|
|
return aContent == aStartContent;
|
1998-04-27 16:44:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Check to see if it is equal to the start or the end
|
|
|
|
if (aContent == aStartContent || aContent == aEndContent) {
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fMax == -1) {
|
|
|
|
BuildContentList(aContent);
|
|
|
|
}
|
|
|
|
|
1998-05-08 18:33:42 +00:00
|
|
|
PRBool foundStart = PR_FALSE;
|
1998-04-27 16:44:52 +00:00
|
|
|
for (PRInt32 i=0;i<fMax;i++) {
|
|
|
|
nsIContent * node = (nsIContent *)fContentArray[i];
|
|
|
|
if (node == aStartContent) {
|
|
|
|
foundStart = PR_TRUE;
|
|
|
|
} else if (aContent == node) {
|
|
|
|
return foundStart;
|
|
|
|
} else if (aEndContent == node) {
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
1998-05-08 18:33:42 +00:00
|
|
|
|
1998-04-27 16:44:52 +00:00
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
// Determines whether a piece of content in question is inbetween the two
|
|
|
|
// piece of content
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
PRBool IsBefore(nsIContent * aNewContent,
|
|
|
|
nsIContent * aCurrentContent) {
|
|
|
|
|
|
|
|
// Start and End Content is the same, so check against the start
|
|
|
|
if (aNewContent == aCurrentContent) {
|
1998-07-18 18:18:20 +00:00
|
|
|
if (SELECTION_DEBUG) printf("IsBefore::New content equals current content\n");
|
1998-04-27 16:44:52 +00:00
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fMax == -1) {
|
|
|
|
BuildContentList(aCurrentContent);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (PRInt32 i=0;i<fMax;i++) {
|
|
|
|
nsIContent * node = (nsIContent *)fContentArray[i];
|
|
|
|
if (node == aCurrentContent) {
|
1998-07-18 18:18:20 +00:00
|
|
|
if (SELECTION_DEBUG) printf("IsBefore::Found Current content\n");
|
1998-04-27 16:44:52 +00:00
|
|
|
return PR_FALSE;
|
|
|
|
} else if (node == aNewContent) {
|
1998-07-18 18:18:20 +00:00
|
|
|
if (SELECTION_DEBUG) printf("IsBefore::Found New content\n");
|
1998-04-27 16:44:52 +00:00
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
}
|
1998-07-18 18:18:20 +00:00
|
|
|
if (SELECTION_DEBUG) printf("IsBefore::Didn't find either\n");
|
1998-04-27 16:44:52 +00:00
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
// Return the next previous piece of content
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
nsIContent * GetPrevContent(nsIContent * aContent) {
|
|
|
|
for (PRInt32 i=0;i<fMax;i++) {
|
|
|
|
if (aContent == fContentArray[i]) {
|
|
|
|
if (i == 0) {
|
|
|
|
return nsnull;
|
|
|
|
} else {
|
|
|
|
return fContentArray[i-1];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nsnull;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
// Return the next previous piece of content
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
nsIContent * GetNextContent(nsIContent * aContent) {
|
|
|
|
for (PRInt32 i=0;i<fMax;i++) {
|
|
|
|
if (aContent == fContentArray[i]) {
|
|
|
|
if (i == fMax-1) {
|
|
|
|
return nsnull;
|
|
|
|
} else {
|
|
|
|
return fContentArray[i+1];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nsnull;
|
1998-07-18 18:18:20 +00:00
|
|
|
}*/
|
1998-04-27 16:44:52 +00:00
|
|
|
|
|
|
|
|
|
|
|
/********************************************************
|
|
|
|
* Handles a when the cursor enters new content that is before
|
|
|
|
* the content that the cursor is currently in
|
|
|
|
*********************************************************/
|
|
|
|
void nsFrame::NewContentIsBefore(nsIPresContext& aPresContext,
|
|
|
|
nsGUIEvent * aEvent,
|
|
|
|
nsIContent * aNewContent,
|
|
|
|
nsIContent * aCurrentContent,
|
|
|
|
nsIFrame * aNewFrame)
|
|
|
|
{
|
1998-07-18 18:18:20 +00:00
|
|
|
if (SELECTION_DEBUG) printf("New Frame, New content is before.\n");
|
1998-04-27 16:44:52 +00:00
|
|
|
// Dragging mouse to the left or backward in content
|
|
|
|
//
|
|
|
|
// 1) The cursor is being dragged backward in the content
|
|
|
|
// and the mouse is "after" the anchor in the content
|
|
|
|
// and the current piece of content is being removed from the selection
|
|
|
|
//
|
|
|
|
// This section cover two cases:
|
|
|
|
// 2) The cursor is being dragged backward in the content
|
|
|
|
// and the mouse is "before" the anchor in the content
|
|
|
|
// and each new piece of content is being added to the selection
|
|
|
|
|
1998-07-17 23:00:54 +00:00
|
|
|
nsIPresShell * shell = aPresContext.GetShell();
|
|
|
|
nsIDocument * doc = shell->GetDocument();
|
|
|
|
PRBool inRange = doc->IsInRange(mStartSelectionPoint->GetContent(), mEndSelectionPoint->GetContent(), aNewContent);
|
1998-07-18 21:44:11 +00:00
|
|
|
|
|
|
|
#ifdef DONT_DO_THIS_USE_NSPR_LOGGING_INSTEAD
|
1998-07-17 23:00:54 +00:00
|
|
|
if (PR_TRUE == inRange)
|
|
|
|
cout << "IN" << endl;
|
|
|
|
else
|
|
|
|
cout << "OUT" << endl;
|
1998-07-18 21:44:11 +00:00
|
|
|
#endif
|
1998-04-27 16:44:52 +00:00
|
|
|
|
|
|
|
// Check to see if the new content is in the selection
|
1998-07-18 18:18:20 +00:00
|
|
|
if (inRange) {
|
1998-04-27 16:44:52 +00:00
|
|
|
|
|
|
|
// Case #1 - Remove Current Content from Selection (at End)
|
1998-07-18 18:18:20 +00:00
|
|
|
if (SELECTION_DEBUG) printf("Case #1 - (Before) New Content is in selected Range.\n");
|
1998-04-27 16:44:52 +00:00
|
|
|
|
1998-05-08 18:33:42 +00:00
|
|
|
|
|
|
|
if (aNewContent == mStartSelectionPoint->GetContent()) {
|
1998-04-27 16:44:52 +00:00
|
|
|
// [TODO] This is where we might have to delete from end to new content
|
|
|
|
|
|
|
|
// Returns the new End Point, if Start and End are on the
|
|
|
|
// same content then End Point's Cursor is set to Start's
|
1998-05-08 18:33:42 +00:00
|
|
|
mEndSelectionPoint->SetContent(mStartSelectionPoint->GetContent());
|
|
|
|
AdjustPointsInNewContent(aPresContext, aEvent, aNewFrame);
|
1998-04-27 16:44:52 +00:00
|
|
|
|
|
|
|
} else {
|
1998-07-22 21:56:48 +00:00
|
|
|
PRUint32 actualOffset = 0;
|
|
|
|
PRInt32 newPos = GetPosition(aPresContext, aEvent, aNewFrame, actualOffset);
|
1998-05-08 18:33:42 +00:00
|
|
|
mEndSelectionPoint->SetPoint(aNewContent, newPos, PR_FALSE);
|
|
|
|
mSelectionRange->SetEndPoint(mEndSelectionPoint);
|
1998-04-27 16:44:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// The current content is being removed from Selection
|
1998-05-08 18:33:42 +00:00
|
|
|
addRangeToSelectionTrackers(aNewContent, aCurrentContent, kInsertInRemoveList);
|
1998-04-27 16:44:52 +00:00
|
|
|
} else {
|
|
|
|
// Case #2 - Add new content to selection (At Start)
|
1998-07-18 18:18:20 +00:00
|
|
|
if (SELECTION_DEBUG) printf("Case #2 - (Before) New Content is NOT in selected Range. Moving Start Backward.\n");
|
1998-04-27 16:44:52 +00:00
|
|
|
|
1998-07-22 21:56:48 +00:00
|
|
|
PRUint32 actualOffset = 0;
|
|
|
|
PRInt32 newPos = GetPosition(aPresContext, aEvent, aNewFrame, actualOffset);
|
1998-04-27 16:44:52 +00:00
|
|
|
|
|
|
|
// Create new TextPoint and move Start Point backward
|
1998-05-08 18:33:42 +00:00
|
|
|
mStartSelectionPoint->SetPoint(aNewContent, newPos, PR_FALSE); // position is set correctly in adjustTextPoints
|
|
|
|
mSelectionRange->SetStartPoint(mStartSelectionPoint);
|
1998-04-27 16:44:52 +00:00
|
|
|
|
|
|
|
// The New Content is added to Tracker
|
1998-05-08 18:33:42 +00:00
|
|
|
addRangeToSelectionTrackers(aNewContent, aCurrentContent, kInsertInAddList);
|
1998-04-27 16:44:52 +00:00
|
|
|
}
|
|
|
|
//??doDragRepaint(fCurrentFrame);
|
|
|
|
//??doDragRepaint(aNewFrame);
|
1998-07-18 18:18:20 +00:00
|
|
|
//??if (SELECTION_DEBUG) mSelectionRange.printContent();
|
1998-05-08 18:33:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************
|
|
|
|
* Refreshes each content's frame
|
|
|
|
*********************************************************/
|
|
|
|
void RefreshContentFrames(nsIPresContext& aPresContext,
|
|
|
|
nsIContent * aStartContent,
|
|
|
|
nsIContent * aEndContent)
|
|
|
|
{
|
|
|
|
//-------------------------------------
|
|
|
|
// Undraw all the current selected frames
|
|
|
|
// XXX Kludge for now
|
|
|
|
nsIPresShell * shell = aPresContext.GetShell();
|
|
|
|
PRBool foundStart = PR_FALSE;
|
|
|
|
for (PRInt32 i=0;i<fMax;i++) {
|
|
|
|
nsIContent * node = (nsIContent *)fContentArray[i];
|
|
|
|
if (node == aStartContent) {
|
|
|
|
foundStart = PR_TRUE;
|
|
|
|
ForceDrawFrame((nsFrame *)shell->FindFrameWithContent(node));
|
|
|
|
if (aStartContent == aEndContent) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else if (foundStart) {
|
|
|
|
ForceDrawFrame((nsFrame *)shell->FindFrameWithContent(node));
|
|
|
|
} else if (aEndContent == node) {
|
|
|
|
ForceDrawFrame((nsFrame *)shell->FindFrameWithContent(node));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//-------------------------------------
|
1998-04-27 16:44:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************
|
|
|
|
* Handles a when the cursor enters new content that is After
|
|
|
|
* the content that the cursor is currently in
|
|
|
|
*********************************************************/
|
|
|
|
void nsFrame::NewContentIsAfter(nsIPresContext& aPresContext,
|
|
|
|
nsGUIEvent * aEvent,
|
|
|
|
nsIContent * aNewContent,
|
|
|
|
nsIContent * aCurrentContent,
|
|
|
|
nsIFrame * aNewFrame)
|
|
|
|
{
|
1998-07-18 18:18:20 +00:00
|
|
|
if (SELECTION_DEBUG) printf("New Frame, New content is after.\n");
|
1998-05-08 18:33:42 +00:00
|
|
|
|
1998-04-27 16:44:52 +00:00
|
|
|
|
|
|
|
// Dragging Mouse to the Right
|
|
|
|
//
|
|
|
|
// 3) The cursor is being dragged foward in the content
|
|
|
|
// and the mouse is "before" the anchor in the content
|
|
|
|
// and the current piece of content is being removed from the selection
|
|
|
|
//
|
|
|
|
// This section cover two cases:
|
|
|
|
// 4) The cursor is being dragged foward in the content
|
|
|
|
// and the mouse is "after" the anchor in the content
|
|
|
|
// and each new piece of content is being added to the selection
|
|
|
|
//
|
|
|
|
|
|
|
|
// Check to see if the new content is in the selection
|
1998-07-17 23:00:54 +00:00
|
|
|
nsIPresShell * shell = aPresContext.GetShell();
|
|
|
|
nsIDocument * doc = shell->GetDocument();
|
|
|
|
PRBool inRange = doc->IsInRange(mStartSelectionPoint->GetContent(), mEndSelectionPoint->GetContent(), aNewContent);
|
1998-07-18 21:44:11 +00:00
|
|
|
|
|
|
|
#ifdef DONT_DO_THIS_USE_NSPR_LOGGING_INSTEAD
|
|
|
|
if (PR_TRUE == inRange)
|
1998-07-17 23:00:54 +00:00
|
|
|
cout << "IN" << endl;
|
|
|
|
else
|
1998-07-18 21:44:11 +00:00
|
|
|
cout << "OUT" << endl;
|
|
|
|
#endif
|
1998-07-17 23:00:54 +00:00
|
|
|
|
1998-07-18 18:18:20 +00:00
|
|
|
if (inRange) {
|
1998-04-27 16:44:52 +00:00
|
|
|
|
|
|
|
// Case #3 - Remove Content (from Start)
|
1998-07-18 18:18:20 +00:00
|
|
|
if (SELECTION_DEBUG) printf("Case #3 - (After) New Content is in selected Range.\n");
|
1998-04-27 16:44:52 +00:00
|
|
|
|
1998-07-18 18:18:20 +00:00
|
|
|
//PrintIndex("Start: ", mStartSelectionPoint->GetContent());
|
|
|
|
//PrintIndex("Current: ", aNewContent);
|
1998-05-08 18:33:42 +00:00
|
|
|
// Remove Current Content in Tracker, but leave New Content in Selection
|
|
|
|
addRangeToSelectionTrackers(mStartSelectionPoint->GetContent(), aNewContent, kInsertInRemoveList);
|
|
|
|
|
1998-07-22 21:56:48 +00:00
|
|
|
PRUint32 actualOffset = 0;
|
1998-04-27 16:44:52 +00:00
|
|
|
// [TODO] Always get nearest Text content
|
1998-07-22 21:56:48 +00:00
|
|
|
PRInt32 newPos = GetPosition(aPresContext, aEvent, aNewFrame, actualOffset);
|
1998-04-27 16:44:52 +00:00
|
|
|
|
|
|
|
// Check to see if the new Content is the same as the End Point's
|
1998-05-08 18:33:42 +00:00
|
|
|
if (aNewContent == mEndSelectionPoint->GetContent()) {
|
1998-07-18 18:18:20 +00:00
|
|
|
if (SELECTION_DEBUG) printf("New Content matches End Point\n");
|
1998-04-27 16:44:52 +00:00
|
|
|
|
1998-05-08 18:33:42 +00:00
|
|
|
mStartSelectionPoint->SetContent(aNewContent);
|
|
|
|
AdjustPointsInNewContent(aPresContext, aEvent, aNewFrame);
|
1998-04-27 16:44:52 +00:00
|
|
|
|
|
|
|
} else {
|
1998-07-18 18:18:20 +00:00
|
|
|
if (SELECTION_DEBUG) printf("New Content does NOT matches End Point\n");
|
1998-05-08 18:33:42 +00:00
|
|
|
mStartSelectionPoint->SetPoint(aNewContent, newPos, PR_FALSE);
|
|
|
|
mSelectionRange->SetStartPoint(mStartSelectionPoint);
|
1998-04-27 16:44:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
1998-07-18 18:18:20 +00:00
|
|
|
if (SELECTION_DEBUG)
|
1998-04-27 16:44:52 +00:00
|
|
|
printf("Case #4 - (After) Adding New Content\n");
|
|
|
|
|
|
|
|
// Case #2 - Adding Content (at End)
|
1998-07-22 21:56:48 +00:00
|
|
|
PRUint32 actualOffset = 0;
|
1998-04-27 16:44:52 +00:00
|
|
|
// The new content is not in the selection
|
1998-07-22 21:56:48 +00:00
|
|
|
PRInt32 newPos = GetPosition(aPresContext, aEvent, aNewFrame, actualOffset);
|
1998-04-27 16:44:52 +00:00
|
|
|
|
1998-05-08 18:33:42 +00:00
|
|
|
// Check to see if we need to create a new SelectionPoint and add it
|
1998-04-27 16:44:52 +00:00
|
|
|
// or do we simply move the existing start or end point
|
1998-05-08 18:33:42 +00:00
|
|
|
if (mStartSelectionPoint->GetContent() == mEndSelectionPoint->GetContent()) {
|
1998-07-18 18:18:20 +00:00
|
|
|
if (SELECTION_DEBUG) printf("Case #4 - Start & End Content the Same\n");
|
1998-04-27 16:44:52 +00:00
|
|
|
// Move start or end point
|
|
|
|
// Get new Cursor Poition in the new content
|
|
|
|
|
1998-05-08 18:33:42 +00:00
|
|
|
if (mStartSelectionPoint->IsAnchor()) {
|
1998-07-18 18:18:20 +00:00
|
|
|
if (SELECTION_DEBUG) printf("Case #4 - Start is Anchor\n");
|
1998-04-27 16:44:52 +00:00
|
|
|
// Since the Start is the Anchor just adjust the end
|
|
|
|
// What is up Here????????
|
1998-07-18 18:18:20 +00:00
|
|
|
//if (SELECTION_DEBUG) printf("Start: %s\n", mStartSelectionPoint->ToString());
|
|
|
|
//if (SELECTION_DEBUG) printf("End: %s\n", mEndSelectionPoint->ToString());
|
|
|
|
//if (SELECTION_DEBUG) printf("---->");
|
1998-05-08 18:33:42 +00:00
|
|
|
|
|
|
|
// XXX Note this includes the current End point (it should be end->nextContent)
|
|
|
|
addRangeToSelectionTrackers(mEndSelectionPoint->GetContent(), aNewContent, kInsertInAddList);
|
|
|
|
|
|
|
|
mEndSelectionPoint->SetPoint(aNewContent, newPos, PR_FALSE);
|
|
|
|
mSelectionRange->SetEndPoint(mEndSelectionPoint);
|
1998-04-27 16:44:52 +00:00
|
|
|
|
|
|
|
|
1998-07-18 18:18:20 +00:00
|
|
|
//if (SELECTION_DEBUG) printf("Start: %s\n", mStartSelectionPoint->ToString());
|
|
|
|
//if (SELECTION_DEBUG) printf("End: %s\n", mEndSelectionPoint->ToString());
|
1998-04-27 16:44:52 +00:00
|
|
|
|
|
|
|
} else {
|
1998-07-18 18:18:20 +00:00
|
|
|
if (SELECTION_DEBUG) printf("Case #4 - Start is NOT Anchor\n");
|
1998-04-27 16:44:52 +00:00
|
|
|
// Because End was the anchor, we need to set the Start Point to
|
|
|
|
// the End's Offset and set it to be the new anchor
|
1998-05-08 18:33:42 +00:00
|
|
|
addRangeToSelectionTrackers(mStartSelectionPoint->GetContent(),
|
|
|
|
mEndSelectionPoint->GetContent(), kInsertInRemoveList);
|
1998-04-27 16:44:52 +00:00
|
|
|
|
1998-05-08 18:33:42 +00:00
|
|
|
int endPos = mEndSelectionPoint->GetOffset();
|
|
|
|
mStartSelectionPoint->SetOffset(endPos);
|
|
|
|
mStartSelectionPoint->SetAnchor(PR_TRUE);
|
1998-04-27 16:44:52 +00:00
|
|
|
|
|
|
|
// The Start point was being moved so when it jumped to the new frame
|
|
|
|
// we needed to make it the new End Point
|
1998-05-08 18:33:42 +00:00
|
|
|
mEndSelectionPoint->SetPoint(aNewContent, newPos, PR_FALSE);
|
|
|
|
mSelectionRange->SetRange(mStartSelectionPoint, mEndSelectionPoint);
|
|
|
|
|
|
|
|
addRangeToSelectionTrackers(mStartSelectionPoint->GetContent(),
|
|
|
|
mEndSelectionPoint->GetContent(), kInsertInRemoveList);
|
1998-04-27 16:44:52 +00:00
|
|
|
}
|
|
|
|
} else {
|
1998-07-18 18:18:20 +00:00
|
|
|
if (SELECTION_DEBUG) printf("Case #4 - Start & End Content NOT the Same\n");
|
1998-05-08 18:33:42 +00:00
|
|
|
nsIContent * oldEnd = mEndSelectionPoint->GetContent();
|
1998-04-27 16:44:52 +00:00
|
|
|
// Adjust the end point
|
1998-05-08 18:33:42 +00:00
|
|
|
mEndSelectionPoint->SetPoint(aNewContent, newPos, PR_FALSE);
|
|
|
|
mSelectionRange->SetRange(mStartSelectionPoint, mEndSelectionPoint);
|
1998-04-27 16:44:52 +00:00
|
|
|
|
|
|
|
// Add New Content to Selection Tracker
|
1998-05-08 18:33:42 +00:00
|
|
|
addRangeToSelectionTrackers(oldEnd, mEndSelectionPoint->GetContent(), kInsertInAddList);
|
1998-04-27 16:44:52 +00:00
|
|
|
}
|
|
|
|
}
|
1998-07-18 18:18:20 +00:00
|
|
|
//??if (SELECTION_DEBUG) mSelectionRange.printContent();
|
1998-05-08 18:33:42 +00:00
|
|
|
|
1998-04-27 16:44:52 +00:00
|
|
|
}
|
|
|
|
|
1998-05-08 18:33:42 +00:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
void ForceDrawFrame(nsFrame * aFrame)//, PRBool)
|
|
|
|
{
|
|
|
|
if (aFrame == nsnull) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
nsRect rect;
|
|
|
|
nsIView * view;
|
|
|
|
nsPoint pnt;
|
|
|
|
aFrame->GetOffsetFromView(pnt, view);
|
|
|
|
aFrame->GetRect(rect);
|
|
|
|
rect.x = pnt.x;
|
|
|
|
rect.y = pnt.y;
|
1998-07-30 17:30:44 +00:00
|
|
|
// XXX I sure hope t is code isn't actually used, because the ref counting is
|
|
|
|
// all screwed up...
|
1998-05-08 18:33:42 +00:00
|
|
|
if (view != nsnull) {
|
|
|
|
nsIViewManager * viewMgr = view->GetViewManager();
|
|
|
|
if (viewMgr != nsnull) {
|
|
|
|
viewMgr->UpdateView(view, rect, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//viewMgr->UpdateView(view, rect, NS_VMREFRESH_DOUBLE_BUFFER | NS_VMREFRESH_IMMEDIATE);
|
|
|
|
|
|
|
|
//NS_RELEASE(view);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////
|
|
|
|
// Selection Tracker Methods
|
|
|
|
/////////////////////////////////////////////////
|
|
|
|
|
|
|
|
//----------------------------
|
|
|
|
//
|
|
|
|
//----------------------------
|
|
|
|
void resetContentTrackers() {
|
|
|
|
//nsIContent * fTrackerContentArrayRemoveList[1024];
|
|
|
|
//nsIContent * fTrackerContentArrayAddList[1024];
|
|
|
|
fTrackerRemoveListMax = 0;
|
|
|
|
fTrackerAddListMax = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------
|
|
|
|
//
|
|
|
|
//----------------------------
|
|
|
|
void RefreshFromContentTrackers(nsIPresContext& aPresContext) {
|
|
|
|
/*FILE * fd = fopen("data.txt", "w");
|
|
|
|
PRBool foundStart = PR_FALSE;
|
|
|
|
for (PRInt32 j=0;j<fMax;j++) {
|
|
|
|
nsIContent * node = (nsIContent *)fContentArray[j];
|
|
|
|
if (node == mSelectionRange->GetStartContent()) {
|
|
|
|
foundStart = PR_TRUE;
|
|
|
|
printf("%d -> 0x%X\n", j, node);
|
|
|
|
} else if (mSelectionRange->GetEndContent() == node) {
|
|
|
|
printf("%d -> 0x%X\n", j, node);
|
|
|
|
break;
|
|
|
|
} else if (foundStart) {
|
|
|
|
printf("%d -> 0x%X\n", j, node);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fflush(fd);
|
|
|
|
fclose(fd);*/
|
|
|
|
|
1998-05-20 16:24:13 +00:00
|
|
|
|
1998-05-19 23:11:28 +00:00
|
|
|
PRInt32 i;
|
1998-05-08 18:33:42 +00:00
|
|
|
nsIPresShell * shell = aPresContext.GetShell();
|
1998-05-19 23:11:28 +00:00
|
|
|
for (i=0;i<fTrackerRemoveListMax;i++) {
|
1998-05-08 18:33:42 +00:00
|
|
|
ForceDrawFrame((nsFrame *)shell->FindFrameWithContent(fTrackerContentArrayRemoveList[i]));
|
1998-07-18 18:18:20 +00:00
|
|
|
if (SELECTION_DEBUG) printf("ForceDrawFrame (remove) content 0x%X\n", fTrackerContentArrayRemoveList[i]);
|
1998-05-08 18:33:42 +00:00
|
|
|
}
|
|
|
|
for (i=0;i<fTrackerAddListMax;i++) {
|
|
|
|
ForceDrawFrame((nsFrame *)shell->FindFrameWithContent(fTrackerContentArrayAddList[i]));
|
1998-07-18 18:18:20 +00:00
|
|
|
if (SELECTION_DEBUG) printf("ForceDrawFrame (add) content 0x%X\n", fTrackerContentArrayAddList[i]);
|
1998-05-08 18:33:42 +00:00
|
|
|
}
|
|
|
|
resetContentTrackers();
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------
|
|
|
|
//
|
|
|
|
//----------------------------
|
|
|
|
void addRangeToSelectionTrackers(nsIContent * aStartContent, nsIContent * aEndContent, PRUint32 aType)
|
|
|
|
{
|
|
|
|
if (aStartContent == nsnull || aEndContent == nsnull) {
|
|
|
|
return;
|
|
|
|
}
|
1998-07-18 18:18:20 +00:00
|
|
|
nsIContent ** contentList = (aType == kInsertInRemoveList?fTrackerContentArrayRemoveList:fTrackerContentArrayAddList);
|
|
|
|
int inx = (aType == kInsertInRemoveList?fTrackerRemoveListMax:fTrackerAddListMax);
|
1998-05-08 18:33:42 +00:00
|
|
|
|
|
|
|
//FILE * fd = fopen("data.txt", "w");
|
|
|
|
//fprintf(fd, "Inx before %d\n", inx);
|
|
|
|
|
1998-07-18 18:18:20 +00:00
|
|
|
nsIContent * contentPtr = aStartContent;
|
|
|
|
while (contentPtr != aEndContent) {
|
|
|
|
contentList[inx++] = contentPtr;
|
|
|
|
contentPtr = gDoc->GetNextContent(contentPtr);
|
1998-05-08 18:33:42 +00:00
|
|
|
}
|
1998-07-18 18:18:20 +00:00
|
|
|
contentList[inx++] = aEndContent;
|
|
|
|
|
|
|
|
if (SELECTION_DEBUG) printf("Adding to %s %d\n", (aType == kInsertInRemoveList?"Remove Array":"Add Array"), inx);
|
|
|
|
|
1998-05-08 18:33:42 +00:00
|
|
|
if (aType == kInsertInRemoveList) {
|
|
|
|
fTrackerRemoveListMax = inx;
|
|
|
|
} else { // kInsertInAddList
|
|
|
|
fTrackerAddListMax = inx;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-07-18 21:44:11 +00:00
|
|
|
void PrintIndex(char * aStr, nsIContent * aContent) {
|
|
|
|
#ifdef DONT_DO_THIS_USE_NSPR_LOGGING_INSTEAD
|
|
|
|
for (PRInt32 j=0;j<fMax;j++) {
|
|
|
|
nsIContent * node = (nsIContent *)fContentArray[j];
|
|
|
|
if (node == aContent) {
|
|
|
|
printf("%s %d\n", aStr, j);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
1998-05-20 16:24:13 +00:00
|
|
|
|
|
|
|
#ifdef NS_DEBUG
|
|
|
|
static void
|
|
|
|
GetTagName(nsFrame* aFrame, nsIContent* aContent, PRIntn aResultSize,
|
|
|
|
char* aResult)
|
|
|
|
{
|
|
|
|
char namebuf[40];
|
|
|
|
namebuf[0] = 0;
|
|
|
|
if (nsnull != aContent) {
|
|
|
|
nsIAtom* tag = aContent->GetTag();
|
|
|
|
if (nsnull != tag) {
|
|
|
|
nsAutoString tmp;
|
|
|
|
tag->ToString(tmp);
|
|
|
|
tmp.ToCString(namebuf, sizeof(namebuf));
|
|
|
|
NS_RELEASE(tag);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
PR_snprintf(aResult, aResultSize, "%s@%p", namebuf, aFrame);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nsFrame::Trace(const char* aMethod, PRBool aEnter)
|
|
|
|
{
|
|
|
|
if (NS_FRAME_LOG_TEST(gLogModule, NS_FRAME_TRACE_CALLS)) {
|
|
|
|
char tagbuf[40];
|
|
|
|
GetTagName(this, mContent, sizeof(tagbuf), tagbuf);
|
|
|
|
PR_LogPrint("%s: %s %s", tagbuf, aEnter ? "enter" : "exit", aMethod);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nsFrame::Trace(const char* aMethod, PRBool aEnter, nsReflowStatus aStatus)
|
|
|
|
{
|
|
|
|
if (NS_FRAME_LOG_TEST(gLogModule, NS_FRAME_TRACE_CALLS)) {
|
|
|
|
char tagbuf[40];
|
|
|
|
GetTagName(this, mContent, sizeof(tagbuf), tagbuf);
|
|
|
|
PR_LogPrint("%s: %s %s, status=%scomplete%s",
|
|
|
|
tagbuf, aEnter ? "enter" : "exit", aMethod,
|
|
|
|
NS_FRAME_IS_NOT_COMPLETE(aStatus) ? "not" : "",
|
|
|
|
(NS_FRAME_REFLOW_NEXTINFLOW & aStatus) ? "+reflow" : "");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nsFrame::TraceMsg(const char* aFormatString, ...)
|
|
|
|
{
|
|
|
|
if (NS_FRAME_LOG_TEST(gLogModule, NS_FRAME_TRACE_CALLS)) {
|
|
|
|
// Format arguments into a buffer
|
|
|
|
char argbuf[200];
|
|
|
|
va_list ap;
|
|
|
|
va_start(ap, aFormatString);
|
|
|
|
PR_vsnprintf(argbuf, sizeof(argbuf), aFormatString, ap);
|
|
|
|
va_end(ap);
|
|
|
|
|
|
|
|
char tagbuf[40];
|
|
|
|
GetTagName(this, mContent, sizeof(tagbuf), tagbuf);
|
|
|
|
PR_LogPrint("%s: %s", tagbuf, argbuf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|