зеркало из https://github.com/mozilla/gecko-dev.git
755 строки
21 KiB
C++
755 строки
21 KiB
C++
/* -*- 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 <stdio.h>
|
|
#include "nscore.h"
|
|
#include "nsCRT.h"
|
|
#include "nscoord.h"
|
|
#include "nsContainerFrame.h"
|
|
#include "nsIContent.h"
|
|
|
|
static NS_DEFINE_IID(kIContentIID, NS_ICONTENT_IID);
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// Helper functions
|
|
|
|
// Compute the number of frames in the list
|
|
static PRInt32
|
|
LengthOf(nsIFrame* aChildList)
|
|
{
|
|
PRInt32 result = 0;
|
|
|
|
while (nsnull != aChildList) {
|
|
aChildList->GetNextSibling(aChildList);
|
|
result++;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
class SimpleContent : public nsIContent {
|
|
public:
|
|
SimpleContent();
|
|
|
|
NS_IMETHOD GetDocument(nsIDocument*& adoc) const {
|
|
adoc = mDocument;
|
|
return NS_OK;
|
|
}
|
|
|
|
void SetDocument(nsIDocument* aDocument) {mDocument = aDocument;}
|
|
|
|
nsIContent* GetParent() const { return nsnull; }
|
|
void SetParent(nsIContent* aParent) {}
|
|
|
|
PRBool CanContainChildren() const {return PR_FALSE;}
|
|
PRInt32 ChildCount() const {return 0;}
|
|
nsIContent* ChildAt(PRInt32 aIndex) const {return nsnull;}
|
|
PRInt32 IndexOf(nsIContent* aPossibleChild) const {return -1;}
|
|
NS_IMETHOD InsertChildAt(nsIContent* aKid, PRInt32 aIndex,
|
|
PRBool aNotify) { return NS_OK; }
|
|
NS_IMETHOD ReplaceChildAt(nsIContent* aKid, PRInt32 aIndex,
|
|
PRBool aNotify){ return NS_OK; }
|
|
NS_IMETHOD AppendChild(nsIContent* aKid, PRBool aNotify) {return NS_OK;}
|
|
NS_IMETHOD RemoveChildAt(PRInt32 aIndex, PRBool aNotify) {return NS_OK;}
|
|
|
|
NS_IMETHOD IsSynthetic(PRBool& aResult) {
|
|
aResult = PR_FALSE;
|
|
return NS_OK;
|
|
}
|
|
|
|
virtual void BeginConvertToXIF(nsXIFConverter& aConverter) const;
|
|
virtual void ConvertContentToXIF(nsXIFConverter& aConverter) const;
|
|
virtual void FinishConvertToXIF(nsXIFConverter& aConverter) const;
|
|
|
|
|
|
nsIAtom* GetTag() const {return nsnull;}
|
|
void SetAttribute(const nsString& aName,const nsString& aValue) {;}
|
|
nsContentAttr GetAttribute(const nsString& aName, nsString& aRet) const {return eContentAttr_NotThere;}
|
|
|
|
nsIContentDelegate* GetDelegate(nsIPresContext* aCX) {return nsnull;}
|
|
|
|
void List(FILE* out = stdout, PRInt32 aIndent = 0) const {;}
|
|
NS_IMETHOD SizeOf(nsISizeOfHandler* aHandler) const { return NS_OK; }
|
|
NS_IMETHOD HandleDOMEvent(nsIPresContext& aPresContext, nsEvent* aEvent, nsIDOMEvent** aDOMEvent, PRUint32 aFlags, nsEventStatus& aEventStatus)
|
|
{return NS_OK;}
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
protected:
|
|
nsIDocument* mDocument;
|
|
};
|
|
|
|
SimpleContent::SimpleContent()
|
|
{
|
|
}
|
|
|
|
void SimpleContent::BeginConvertToXIF(nsXIFConverter& aConverter) const
|
|
{
|
|
}
|
|
|
|
void SimpleContent::FinishConvertToXIF(nsXIFConverter& aConverter) const
|
|
{
|
|
}
|
|
|
|
void SimpleContent::ConvertContentToXIF(nsXIFConverter& aConverter) const
|
|
{
|
|
}
|
|
|
|
NS_IMPL_ISUPPORTS(SimpleContent, kIContentIID);
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
class SimpleContainer : public nsContainerFrame
|
|
{
|
|
public:
|
|
SimpleContainer(nsIContent* aContent);
|
|
|
|
void SetFirstChild(nsIFrame* aChild, PRInt32 aChildCount);
|
|
nsIFrame* GetOverflowList() {return mOverflowList;}
|
|
void SetOverflowList(nsIFrame* aChildList) {mOverflowList = aChildList;}
|
|
|
|
// Allow public access to protected member functions
|
|
void PushChildren(nsIFrame* aFromChild, nsIFrame* aPrevSibling, PRBool aLastIsComplete);
|
|
PRBool DeleteChildsNextInFlow(nsIFrame* aChild);
|
|
};
|
|
|
|
SimpleContainer::SimpleContainer(nsIContent* aContent)
|
|
: nsContainerFrame(aContent, nsnull)
|
|
{
|
|
}
|
|
|
|
// Sets mFirstChild and mChildCount, but not mContentOffset, mContentLength,
|
|
// or mLastContentIsComplete
|
|
void SimpleContainer::SetFirstChild(nsIFrame* aChild, PRInt32 aChildCount)
|
|
{
|
|
mFirstChild = aChild;
|
|
mChildCount = aChildCount;
|
|
NS_ASSERTION(LengthOf(mFirstChild) == aChildCount, "bad child count argument");
|
|
}
|
|
|
|
void SimpleContainer::PushChildren(nsIFrame* aFromChild, nsIFrame* aPrevSibling, PRBool aLastIsComplete)
|
|
{
|
|
nsContainerFrame::PushChildren(aFromChild, aPrevSibling, aLastIsComplete);
|
|
}
|
|
|
|
PRBool SimpleContainer::DeleteChildsNextInFlow(nsIFrame* aChild)
|
|
{
|
|
return nsContainerFrame::DeleteChildsNextInFlow(aChild);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
class SimpleSplittableFrame : public nsSplittableFrame {
|
|
public:
|
|
SimpleSplittableFrame(nsIContent* aContent, nsIFrame* aParent);
|
|
};
|
|
|
|
SimpleSplittableFrame::SimpleSplittableFrame(nsIContent* aContent,
|
|
nsIFrame* aParent)
|
|
: nsSplittableFrame(aContent, aParent)
|
|
{
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
// Basic test of the child enumeration member functions
|
|
static PRBool
|
|
TestChildEnumeration()
|
|
{
|
|
// Create a simple test container
|
|
SimpleContent* content = new SimpleContent;
|
|
SimpleContainer* f = new SimpleContainer(content);
|
|
|
|
// Add three child frames
|
|
SimpleContent* childContent = new SimpleContent();
|
|
nsFrame* c1;
|
|
nsFrame* c2;
|
|
nsFrame* c3;
|
|
|
|
nsFrame::NewFrame((nsIFrame**)&c1, childContent, f);
|
|
nsFrame::NewFrame((nsIFrame**)&c2, childContent, f);
|
|
nsFrame::NewFrame((nsIFrame**)&c3, childContent, f);
|
|
|
|
c1->SetNextSibling(c2);
|
|
c2->SetNextSibling(c3);
|
|
f->SetFirstChild(c1, 3);
|
|
f->SetLastContentOffset(2);
|
|
|
|
// Make sure the child count is correct
|
|
PRInt32 childCount;
|
|
f->ChildCount(childCount);
|
|
if (childCount != 3) {
|
|
printf("ChildEnumeration: wrong child count: %d\n", childCount);
|
|
return PR_FALSE;
|
|
}
|
|
|
|
// Test indexing of child frames. nsnull should be returned for index
|
|
// values that are out of range
|
|
nsIFrame* child;
|
|
f->ChildAt(-1, child);
|
|
if (nsnull != child) {
|
|
printf("ChildEnumeration: child index failed for index < 0\n");
|
|
return PR_FALSE;
|
|
}
|
|
f->ChildAt(0, child);
|
|
if (c1 != child) {
|
|
printf("ChildEnumeration: wrong child at index: %d\n", 0);
|
|
return PR_FALSE;
|
|
}
|
|
f->ChildAt(1, child);
|
|
if (c2 != child) {
|
|
printf("ChildEnumeration: wrong child at index: %d\n", 1);
|
|
return PR_FALSE;
|
|
}
|
|
f->ChildAt(2, child);
|
|
if (c3 != child) {
|
|
printf("ChildEnumeration: wrong child at index: %d\n", 2);
|
|
return PR_FALSE;
|
|
}
|
|
f->ChildAt(3, child);
|
|
if (nsnull != child) {
|
|
printf("ChildEnumeration: child index failed for index >= child countn");
|
|
return PR_FALSE;
|
|
}
|
|
|
|
// Test first and last child member functions
|
|
f->FirstChild(child);
|
|
if (child != c1) {
|
|
printf("ChildEnumeration: wrong first child\n");
|
|
return PR_FALSE;
|
|
}
|
|
f->LastChild(child);
|
|
if (child != c3) {
|
|
printf("ChildEnumeration: wrong last child\n");
|
|
return PR_FALSE;
|
|
}
|
|
|
|
// Test IndexOf()
|
|
PRInt32 index;
|
|
f->IndexOf(c1, index);
|
|
if (index != 0) {
|
|
printf("ChildEnumeration: index of c1 failed\n");
|
|
return PR_FALSE;
|
|
}
|
|
f->IndexOf(c2, index);
|
|
if (index != 1) {
|
|
printf("ChildEnumeration: index of c2 failed\n");
|
|
return PR_FALSE;
|
|
}
|
|
f->IndexOf(c3, index);
|
|
if (index != 2) {
|
|
printf("ChildEnumeration: index of c3 failed\n");
|
|
return PR_FALSE;
|
|
}
|
|
|
|
return PR_TRUE;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
// Test the push children method
|
|
//
|
|
// This tests the following:
|
|
// 1. pushing children to the overflow list when there's no next-in-flow
|
|
// 2. pushing to a next-in-flow that's empty
|
|
// 3. pushing to a next-in-flow that isn't empty
|
|
static PRBool
|
|
TestPushChildren()
|
|
{
|
|
// Create a simple test container
|
|
SimpleContent* content = new SimpleContent;
|
|
SimpleContainer* f = new SimpleContainer(content);
|
|
|
|
// Add five child frames
|
|
SimpleContent* childContent = new SimpleContent;
|
|
nsFrame* c1;
|
|
nsFrame* c2;
|
|
nsFrame* c3;
|
|
nsFrame* c4;
|
|
nsFrame* c5;
|
|
|
|
nsFrame::NewFrame((nsIFrame**)&c1, childContent, f);
|
|
nsFrame::NewFrame((nsIFrame**)&c2, childContent, f);
|
|
nsFrame::NewFrame((nsIFrame**)&c3, childContent, f);
|
|
nsFrame::NewFrame((nsIFrame**)&c4, childContent, f);
|
|
nsFrame::NewFrame((nsIFrame**)&c5, childContent, f);
|
|
|
|
c1->SetNextSibling(c2);
|
|
c2->SetNextSibling(c3);
|
|
c3->SetNextSibling(c4);
|
|
c4->SetNextSibling(c5);
|
|
f->SetFirstChild(c1, 5);
|
|
f->SetLastContentOffset(4);
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// #1
|
|
|
|
// Push the last two children. Since there's no next-in-flow the children
|
|
// should be placed on the overflow list
|
|
f->PushChildren(c4, c3, PR_TRUE);
|
|
|
|
// Verify that the next sibling pointer of c3 has been cleared
|
|
nsIFrame* nextSibling;
|
|
c3->GetNextSibling(nextSibling);
|
|
if (nsnull != nextSibling) {
|
|
printf("PushChildren: sibling pointer isn't null\n");
|
|
return PR_FALSE;
|
|
}
|
|
|
|
// Verify that there are two frames on the overflow list
|
|
nsIFrame* overflowList = f->GetOverflowList();
|
|
if ((nsnull == overflowList) || (LengthOf(overflowList) != 2)) {
|
|
printf("PushChildren: bad overflow list\n");
|
|
return PR_FALSE;
|
|
}
|
|
|
|
// and that the children on the overflow still have the same geometric parent
|
|
while (nsnull != overflowList) {
|
|
nsIFrame* parent;
|
|
|
|
overflowList->GetGeometricParent(parent);
|
|
if (f != parent) {
|
|
printf("PushChildren: bad geometric parent\n");
|
|
return PR_FALSE;
|
|
}
|
|
|
|
overflowList->GetNextSibling(overflowList);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// #2
|
|
|
|
// Link the overflow list back into the child list
|
|
c3->SetNextSibling(f->GetOverflowList());
|
|
f->SetOverflowList(nsnull);
|
|
|
|
// Create a continuing frame
|
|
SimpleContainer* f1 = new SimpleContainer(content);
|
|
|
|
// Link it into the flow
|
|
f->SetNextInFlow(f1);
|
|
f1->SetPrevInFlow(f);
|
|
|
|
// Push the last two children to the next-in-flow which is empty.
|
|
f->PushChildren(c4, c3, PR_TRUE);
|
|
|
|
// Verify there are two children in f1
|
|
PRInt32 childCount;
|
|
f1->ChildCount(childCount);
|
|
if (childCount != 2) {
|
|
printf("PushChildren: continuing frame bad child count: %d\n", childCount);
|
|
return PR_FALSE;
|
|
}
|
|
|
|
// Verify the content offsets are correct
|
|
if (f1->GetFirstContentOffset() != 3) {
|
|
printf("PushChildren: continuing frame bad first content offset\n");
|
|
return PR_FALSE;
|
|
}
|
|
if (f1->GetLastContentOffset() != 4) {
|
|
printf("PushChildren: continuing frame bad last content offset\n");
|
|
return PR_FALSE;
|
|
}
|
|
|
|
// Verify that the first child is correct
|
|
nsIFrame* firstChild;
|
|
f1->FirstChild(firstChild);
|
|
if (c4 != firstChild) {
|
|
printf("PushChildren: continuing frame first child is wrong\n");
|
|
return PR_FALSE;
|
|
}
|
|
|
|
// Verify that the next sibling pointer of c3 has been cleared
|
|
c3->GetNextSibling(nextSibling);
|
|
if (nsnull != nextSibling) {
|
|
printf("PushChildren: sibling pointer isn't null\n");
|
|
return PR_FALSE;
|
|
}
|
|
|
|
// Verify that the geometric parent and content parent have been changed
|
|
f1->FirstChild(firstChild);
|
|
while (nsnull != firstChild) {
|
|
nsIFrame* parent;
|
|
firstChild->GetGeometricParent(parent);
|
|
if (f1 != parent) {
|
|
printf("PushChildren: bad geometric parent\n");
|
|
return PR_FALSE;
|
|
}
|
|
|
|
firstChild->GetContentParent(parent);
|
|
if (f1 != parent) {
|
|
printf("PushChildren: bad content parent\n");
|
|
return PR_FALSE;
|
|
}
|
|
|
|
firstChild->GetNextSibling(firstChild);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// #3
|
|
|
|
// Test pushing two children to a next-in-flow that already has children
|
|
f->PushChildren(c2, c1, PR_TRUE);
|
|
|
|
// Verify there are four children in f1
|
|
f1->ChildCount(childCount);
|
|
if (childCount != 4) {
|
|
printf("PushChildren: continuing frame bad child count: %d\n", childCount);
|
|
return PR_FALSE;
|
|
}
|
|
|
|
// Verify the content offset/length are correct
|
|
if (f1->GetFirstContentOffset() != 1) {
|
|
printf("PushChildren: continuing frame bad first content offset\n");
|
|
return PR_FALSE;
|
|
}
|
|
if (f1->GetLastContentOffset() != 4) {
|
|
printf("PushChildren: continuing frame bad last content offset\n");
|
|
return PR_FALSE;
|
|
}
|
|
|
|
// Verify that the first child is correct
|
|
f1->FirstChild(firstChild);
|
|
if (c2 != firstChild) {
|
|
printf("PushChildren: continuing frame first child is wrong\n");
|
|
return PR_FALSE;
|
|
}
|
|
|
|
// Verify that c3 points to c4
|
|
c3->GetNextSibling(nextSibling);
|
|
if (c4 != nextSibling) {
|
|
printf("PushChildren: bad sibling pointers\n");
|
|
return PR_FALSE;
|
|
}
|
|
|
|
return PR_TRUE;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
// Test the delete child's next-in-flow method
|
|
//
|
|
// This tests the following:
|
|
// 1. one next-in-flow in same geometric parent
|
|
// a) next-in-flow is parent's last child
|
|
// b) next-in-flow is not the parent's last child
|
|
// 2. one next-in-flow in different geometric parents
|
|
// a) next-in-flow is parent's first and last child
|
|
// b) next-in-flow is not the parent's last child
|
|
// 3. multiple next-in-flow frames
|
|
static PRBool
|
|
TestDeleteChildsNext()
|
|
{
|
|
// Create two simple test containers
|
|
SimpleContent* content = new SimpleContent;
|
|
SimpleContainer* f = new SimpleContainer(content);
|
|
|
|
// Create two child frames
|
|
SimpleContent* childContent = new SimpleContent;
|
|
nsFrame* c1 = new SimpleSplittableFrame(childContent, f);
|
|
nsFrame* c11 = new SimpleSplittableFrame(childContent, f);
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// #1a
|
|
|
|
// Make the child frames siblings and in the same flow
|
|
c1->SetNextSibling(c11);
|
|
c11->AppendToFlow(c1);
|
|
f->SetFirstChild(c1, 2);
|
|
|
|
// Delete the next-in-flow
|
|
f->DeleteChildsNextInFlow(c1);
|
|
|
|
// Verify the child count
|
|
PRInt32 childCount;
|
|
f->ChildCount(childCount);
|
|
if (childCount != 1) {
|
|
printf("DeleteNextInFlow: bad child count (#1a): %d\n", childCount);
|
|
return PR_FALSE;
|
|
}
|
|
|
|
// Verify the sibling pointer is null
|
|
nsIFrame* nextSibling;
|
|
c1->GetNextSibling(nextSibling);
|
|
if (nsnull != nextSibling) {
|
|
printf("DeleteNextInFlow: bad sibling pointer (#1a):\n");
|
|
return PR_FALSE;
|
|
}
|
|
|
|
// Verify the next-in-flow pointer is null
|
|
nsIFrame* nextInFlow;
|
|
c1->GetNextInFlow(nextInFlow);
|
|
if (nsnull != nextInFlow) {
|
|
printf("DeleteNextInFlow: bad next-in-flow (#1a)\n");
|
|
return PR_FALSE;
|
|
}
|
|
|
|
// Verify the first/last content offsets are still 0
|
|
if ((f->GetFirstContentOffset() != 0) || (f->GetLastContentOffset() != 0)) {
|
|
printf("DeleteNextInFlow: bad content mapping (#1a)\n");
|
|
return PR_FALSE;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// #2a
|
|
|
|
// Create a second container frame
|
|
SimpleContainer* f1 = new SimpleContainer(content);
|
|
|
|
// Re-create the continuing child frame
|
|
c11 = new SimpleSplittableFrame(childContent, f1);
|
|
|
|
// Put the first child in the first container and the continuing child frame in
|
|
// the second container
|
|
c11->AppendToFlow(c1);
|
|
f->SetFirstChild(c1, 1);
|
|
f->SetLastContentOffset(0);
|
|
f1->SetFirstChild(c11, 1);
|
|
|
|
// Link the containers together
|
|
f1->AppendToFlow(f);
|
|
|
|
// Delete the next-in-flow
|
|
f->DeleteChildsNextInFlow(c1);
|
|
|
|
// Verify that the second container frame is empty
|
|
nsIFrame* firstChild;
|
|
|
|
f1->ChildCount(childCount);
|
|
f1->FirstChild(firstChild);
|
|
if ((childCount != 0) || (firstChild != nsnull)) {
|
|
printf("DeleteNextInFlow: continuing frame not empty (#2a)\n");
|
|
return PR_FALSE;
|
|
}
|
|
|
|
// Verify the next-in-flow pointer is null
|
|
c1->GetNextInFlow(nextInFlow);
|
|
if (nsnull != nextInFlow) {
|
|
printf("DeleteNextInFlow: bad next-in-flow (#1b)\n");
|
|
return PR_FALSE;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// #1b
|
|
|
|
// Re-create the continuing child frame
|
|
c11 = new SimpleSplittableFrame(childContent, f);
|
|
|
|
// Create a third child frame
|
|
nsFrame* c2 = new SimpleSplittableFrame(childContent, f);
|
|
|
|
c1->SetNextSibling(c11);
|
|
c11->AppendToFlow(c1);
|
|
c11->SetNextSibling(c2);
|
|
f->SetFirstChild(c1, 3);
|
|
f->SetLastContentOffset(1);
|
|
|
|
// Delete the next-in-flow
|
|
f->DeleteChildsNextInFlow(c1);
|
|
|
|
// Verify the child count
|
|
f->ChildCount(childCount);
|
|
if (childCount != 2) {
|
|
printf("DeleteNextInFlow: bad child count (#1b): %d\n", childCount);
|
|
return PR_FALSE;
|
|
}
|
|
|
|
// Verify the sibling pointer is correct
|
|
c1->GetNextSibling(nextSibling);
|
|
if (nextSibling != c2) {
|
|
printf("DeleteNextInFlow: bad sibling pointer (#1b):\n");
|
|
return PR_FALSE;
|
|
}
|
|
|
|
// Verify the next-in-flow pointer is correct
|
|
c1->GetNextInFlow(nextInFlow);
|
|
if (nsnull != nextInFlow) {
|
|
printf("DeleteNextInFlow: bad next-in-flow (#1b)\n");
|
|
return PR_FALSE;
|
|
}
|
|
|
|
// Verify the first/last content offsets are correct
|
|
if ((f->GetFirstContentOffset() != 0) || (f->GetLastContentOffset() != 1)) {
|
|
printf("DeleteNextInFlow: bad content mapping (#1a)\n");
|
|
return PR_FALSE;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// #2b
|
|
|
|
// Re-create the continuing frame and the third child frame
|
|
c11 = new SimpleSplittableFrame(childContent, f1);
|
|
c2 = new SimpleSplittableFrame(childContent, f1);
|
|
|
|
// Put the first child in the first container, and the continuing child frame
|
|
// and the third frame in the second container
|
|
c1->SetNextSibling(nsnull);
|
|
c11->AppendToFlow(c1);
|
|
f->SetFirstChild(c1, 1);
|
|
f->SetLastContentOffset(0);
|
|
|
|
c11->SetNextSibling(c2);
|
|
f1->SetFirstChild(c11, 2);
|
|
f1->SetFirstContentOffset(0);
|
|
f1->SetLastContentOffset(1);
|
|
|
|
// Link the containers together
|
|
f1->AppendToFlow(f);
|
|
|
|
// Delete the next-in-flow
|
|
f->DeleteChildsNextInFlow(c1);
|
|
|
|
// Verify the next-in-flow pointer is null
|
|
c1->GetNextInFlow(nextInFlow);
|
|
if (nsnull != nextInFlow) {
|
|
printf("DeleteNextInFlow: bad next-in-flow (#2b)\n");
|
|
return PR_FALSE;
|
|
}
|
|
|
|
// Verify that the second container frame has one child
|
|
f1->ChildCount(childCount);
|
|
if (childCount != 1) {
|
|
printf("DeleteNextInFlow: continuing frame bad child count (#2b): %d\n", childCount);
|
|
return PR_FALSE;
|
|
}
|
|
|
|
// Verify that the second container's first child is correct
|
|
f1->FirstChild(firstChild);
|
|
if (firstChild != c2) {
|
|
printf("DeleteNextInFlow: continuing frame bad first child (#2b)\n");
|
|
return PR_FALSE;
|
|
}
|
|
|
|
// Verify the second container's first content offset
|
|
if (f1->GetFirstContentOffset() != 1) {
|
|
printf("DeleteNextInFlow: continuing frame bad first content offset (#2b): %d\n",
|
|
f1->GetFirstContentOffset());
|
|
return PR_FALSE;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// #3
|
|
|
|
// Re-create the continuing frame and the third child frame
|
|
c11 = new SimpleSplittableFrame(childContent, f);
|
|
c2 = new SimpleSplittableFrame(childContent, f);
|
|
|
|
// Create a second continuing frame
|
|
SimpleSplittableFrame* c12 = new SimpleSplittableFrame(childContent, f);
|
|
|
|
// Put all the child frames in the first container
|
|
c1->SetNextSibling(c11);
|
|
c11->SetNextSibling(c12);
|
|
c12->SetNextSibling(c2);
|
|
c11->AppendToFlow(c1);
|
|
c12->AppendToFlow(c11);
|
|
f->SetFirstChild(c1, 4);
|
|
f->SetLastContentOffset(1);
|
|
|
|
// Delete the next-in-flow
|
|
f->DeleteChildsNextInFlow(c1);
|
|
|
|
// Verify the next-in-flow pointer is null
|
|
c1->GetNextInFlow(nextInFlow);
|
|
if (nsnull != nextInFlow) {
|
|
printf("DeleteNextInFlow: bad next-in-flow (#3)\n");
|
|
return PR_FALSE;
|
|
}
|
|
|
|
// Verify the child count is correct
|
|
f->ChildCount(childCount);
|
|
if (childCount != 2) {
|
|
printf("DeleteNextInFlow: bad child count (#3): %d\n", childCount);
|
|
return PR_FALSE;
|
|
}
|
|
|
|
// and the last content offset is still correct
|
|
if (f->GetLastContentOffset() != 1) {
|
|
printf("DeleteNextInFlow: bad last content offset (#3): %d\n", f->GetLastContentOffset());
|
|
return PR_FALSE;
|
|
}
|
|
|
|
// Verify the sibling list is correct
|
|
c1->GetNextSibling(nextSibling);
|
|
if (nextSibling != c2) {
|
|
printf("DeleteNextInFlow: bad sibling list (#3)\n");
|
|
return PR_FALSE;
|
|
}
|
|
c2->GetNextSibling(nextSibling);
|
|
if (nextSibling != nsnull) {
|
|
printf("DeleteNextInFlow: bad sibling list (#3)\n");
|
|
return PR_FALSE;
|
|
}
|
|
|
|
// Verify the next-in-flow pointer is null
|
|
c1->GetNextInFlow(nextInFlow);
|
|
if (nsnull != nextInFlow) {
|
|
printf("DeleteNextInFlow: bad next-in-flow (#3)\n");
|
|
return PR_FALSE;
|
|
}
|
|
|
|
return PR_TRUE;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
// Test the container frame being used as a pseudo frame
|
|
static PRBool
|
|
TestAsPseudo()
|
|
{
|
|
return PR_TRUE;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
int main(int argc, char** argv)
|
|
{
|
|
// Test the child frame enumeration member functions
|
|
if (!TestChildEnumeration()) {
|
|
return -1;
|
|
}
|
|
|
|
#if 0
|
|
// Test the push children method
|
|
if (!TestPushChildren()) {
|
|
return -1;
|
|
}
|
|
|
|
// Test the push children method
|
|
if (!TestDeleteChildsNext()) {
|
|
return -1;
|
|
}
|
|
#endif
|
|
|
|
// Test being used as a pseudo frame
|
|
if (!TestAsPseudo()) {
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|