Phase one of frame construction changes

This commit is contained in:
troy%netscape.com 1998-09-10 19:32:14 +00:00
parent a8df12702b
commit effef91cf6
73 changed files with 5162 additions and 96 deletions

View File

@ -163,7 +163,8 @@ public:
virtual void ContentChanged(nsIContent* aContent,
nsISupports* aSubContent) = 0;
virtual void ContentAppended(nsIContent* aContainer) = 0;
virtual void ContentAppended(nsIContent* aContainer,
PRInt32 aNewIndexInContainer) = 0;
virtual void ContentInserted(nsIContent* aContainer,
nsIContent* aChild,

View File

@ -98,9 +98,12 @@ public:
*
* @param aDocument The document being observed
* @param aContainer the container that had a new child appended
* @param aNewIndexInContainer the index in the container of the first
* new child
*/
NS_IMETHOD ContentAppended(nsIDocument *aDocument,
nsIContent* aContainer) = 0;
nsIContent* aContainer,
PRInt32 aNewIndexInContainer) = 0;
/**
* Notification that content has been inserted. This method is called

View File

@ -277,7 +277,8 @@ void nsContentList::PopulateSelf(nsIContent *aContent)
NS_IMETHODIMP
nsContentList::ContentAppended(nsIDocument *aDocument,
nsIContent* aContainer)
nsIContent* aContainer,
PRInt32 aNewIndexInContainer)
{
PRInt32 count;
aContainer->ChildCount(count);

View File

@ -69,7 +69,8 @@ public:
nsIContent* aContent,
nsISupports* aSubContent) { return NS_OK; }
NS_IMETHOD ContentAppended(nsIDocument *aDocument,
nsIContent* aContainer);
nsIContent* aContainer,
PRInt32 aNewIndexInContainer);
NS_IMETHOD ContentInserted(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild,

View File

@ -507,12 +507,13 @@ void nsDocument::ContentChanged(nsIContent* aContent,
}
}
void nsDocument::ContentAppended(nsIContent* aContainer)
void nsDocument::ContentAppended(nsIContent* aContainer,
PRInt32 aNewIndexInContainer)
{
PRInt32 count = mObservers.Count();
for (PRInt32 i = 0; i < count; i++) {
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
observer->ContentAppended(this, aContainer);
observer->ContentAppended(this, aContainer, aNewIndexInContainer);
}
}

View File

@ -140,7 +140,8 @@ public:
virtual void ContentChanged(nsIContent* aContent,
nsISupports* aSubContent);
virtual void ContentAppended(nsIContent* aContainer);
virtual void ContentAppended(nsIContent* aContainer,
PRInt32 aNewIndexInContainer);
virtual void ContentInserted(nsIContent* aContainer,
nsIContent* aChild,

View File

@ -22,8 +22,13 @@
#include "nsISupportsArray.h"
#include "nsIFrame.h"
#include "nsHashtable.h"
#include "nsIPresContext.h"
#include "nsIPresShell.h"
#include "nsIContent.h"
#include "nsIStyleFrameConstruction.h"
static NS_DEFINE_IID(kIStyleSetIID, NS_ISTYLE_SET_IID);
static NS_DEFINE_IID(kIStyleFrameConstructionIID, NS_ISTYLE_FRAME_CONSTRUCTION_IID);
class ContextKey : public nsHashKey {
public:
@ -207,6 +212,31 @@ public:
nsIFrame* aParentFrame,
PRBool aForceUnique = PR_FALSE);
NS_IMETHODIMP ConstructFrame(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParentFrame,
nsIFrame*& aFrameSubTree);
NS_IMETHOD ContentAppended(nsIPresContext* aPresContext,
nsIDocument* aDocument,
nsIContent* aContainer,
PRInt32 aNewIndexInContainer);
NS_IMETHOD ContentInserted(nsIPresContext* aPresContext,
nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer);
NS_IMETHOD ContentReplaced(nsIPresContext* aPresContext,
nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aOldChild,
nsIContent* aNewChild,
PRInt32 aIndexInContainer);
NS_IMETHOD ContentRemoved(nsIPresContext* aPresContext,
nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer);
// xxx style rules enumeration
virtual void List(FILE* out = stdout, PRInt32 aIndent = 0);
@ -240,13 +270,15 @@ protected:
nsISupportsArray* mDocSheets;
nsISupportsArray* mBackstopSheets;
nsHashtable mStyleContexts;
nsIStyleFrameConstruction* mFrameConstructor;
};
StyleSetImpl::StyleSetImpl()
: mOverrideSheets(nsnull),
mDocSheets(nsnull),
mBackstopSheets(nsnull)
mBackstopSheets(nsnull),
mFrameConstructor(nsnull)
{
NS_INIT_REFCNT();
}
@ -262,6 +294,7 @@ StyleSetImpl::~StyleSetImpl()
NS_IF_RELEASE(mOverrideSheets);
NS_IF_RELEASE(mDocSheets);
NS_IF_RELEASE(mBackstopSheets);
NS_IF_RELEASE(mFrameConstructor);
mStyleContexts.Enumerate(ReleaseContext);
}
@ -340,6 +373,9 @@ void StyleSetImpl::AppendDocStyleSheet(nsIStyleSheet* aSheet)
NS_PRECONDITION(nsnull != aSheet, "null arg");
if (EnsureArray(&mDocSheets)) {
mDocSheets->AppendElement(aSheet);
if (nsnull == mFrameConstructor) {
aSheet->QueryInterface(kIStyleFrameConstructionIID, (void **)&mFrameConstructor);
}
}
}
@ -350,6 +386,9 @@ void StyleSetImpl::InsertDocStyleSheetAfter(nsIStyleSheet* aSheet,
if (EnsureArray(&mDocSheets)) {
PRInt32 index = mDocSheets->IndexOf(aAfterSheet);
mDocSheets->InsertElementAt(aSheet, ++index);
if (nsnull == mFrameConstructor) {
aSheet->QueryInterface(kIStyleFrameConstructionIID, (void **)&mFrameConstructor);
}
}
}
@ -360,6 +399,9 @@ void StyleSetImpl::InsertDocStyleSheetBefore(nsIStyleSheet* aSheet,
if (EnsureArray(&mDocSheets)) {
PRInt32 index = mDocSheets->IndexOf(aBeforeSheet);
mDocSheets->InsertElementAt(aSheet, ((-1 < index) ? index : 0));
if (nsnull == mFrameConstructor) {
aSheet->QueryInterface(kIStyleFrameConstructionIID, (void **)&mFrameConstructor);
}
}
}
@ -665,6 +707,67 @@ nsIStyleContext* StyleSetImpl::ProbePseudoStyleFor(nsIPresContext* aPresContext,
return result;
}
NS_IMETHODIMP StyleSetImpl::ConstructFrame(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParentFrame,
nsIFrame*& aFrameSubTree)
{
return mFrameConstructor->ConstructFrame(aPresContext, aContent,
aParentFrame, aFrameSubTree);
}
NS_IMETHODIMP StyleSetImpl::ContentAppended(nsIPresContext* aPresContext,
nsIDocument* aDocument,
nsIContent* aContainer,
PRInt32 aNewIndexInContainer)
{
return mFrameConstructor->ContentAppended(aPresContext, aDocument,
aContainer, aNewIndexInContainer);
}
NS_IMETHODIMP StyleSetImpl::ContentInserted(nsIPresContext* aPresContext,
nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer)
{
#if 0
return mFrameConstructor->ContentInserted(aPresContext, aDocument, aContainer,
aChild, aIndexInContainer);
#else
return NS_OK;
#endif
}
NS_IMETHODIMP StyleSetImpl::ContentReplaced(nsIPresContext* aPresContext,
nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aOldChild,
nsIContent* aNewChild,
PRInt32 aIndexInContainer)
{
#if 0
return mFrameConstructor->ContentReplaced(aPresContext, aDocument, aContainer,
aOldChild, aNewChild, aIndexInContainer);
#else
return NS_OK;
#endif
}
NS_IMETHODIMP StyleSetImpl::ContentRemoved(nsIPresContext* aPresContext,
nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer)
{
#if 0
return mFrameConstructor->ContentRemoved(aPresContext, aDocument, aContainer,
aChild, aIndexInContainer);
#else
return NS_OK;
#endif
}
// xxx style rules enumeration
void StyleSetImpl::List(FILE* out, PRInt32 aIndent, nsISupportsArray* aSheets)

View File

@ -3266,7 +3266,7 @@ nsGenericHTMLContainerElement::AppendChildTo(nsIContent* aKid, PRBool aNotify)
if (nsnull != doc) {
aKid->SetDocument(doc);
if (aNotify) {
doc->ContentAppended(mContent);
doc->ContentAppended(mContent, mChildren->Count() - 1);
}
}
}

View File

@ -107,6 +107,7 @@ nsIAtom* nsHTMLAtoms::id;
nsIAtom* nsHTMLAtoms::iframe;
nsIAtom* nsHTMLAtoms::img;
nsIAtom* nsHTMLAtoms::index;
nsIAtom* nsHTMLAtoms::input;
nsIAtom* nsHTMLAtoms::ismap;
nsIAtom* nsHTMLAtoms::label;
nsIAtom* nsHTMLAtoms::lang;
@ -171,6 +172,7 @@ nsIAtom* nsHTMLAtoms::rules;
nsIAtom* nsHTMLAtoms::scheme;
nsIAtom* nsHTMLAtoms::scope;
nsIAtom* nsHTMLAtoms::scrolling;
nsIAtom* nsHTMLAtoms::select;
nsIAtom* nsHTMLAtoms::selected;
nsIAtom* nsHTMLAtoms::selectedindex;
nsIAtom* nsHTMLAtoms::shape;
@ -189,6 +191,7 @@ nsIAtom* nsHTMLAtoms::tabstop;
nsIAtom* nsHTMLAtoms::target;
nsIAtom* nsHTMLAtoms::td;
nsIAtom* nsHTMLAtoms::text;
nsIAtom* nsHTMLAtoms::textarea;
nsIAtom* nsHTMLAtoms::th;
nsIAtom* nsHTMLAtoms::title;
nsIAtom* nsHTMLAtoms::top;
@ -304,6 +307,7 @@ void nsHTMLAtoms::AddrefAtoms()
iframe = NS_NewAtom("IFRAME");
img = NS_NewAtom("IMG");
index = NS_NewAtom("INDEX");
input = NS_NewAtom("INPUT");
ismap = NS_NewAtom("ISMAP");
label = NS_NewAtom("LABEL");
lang = NS_NewAtom("LANG");
@ -367,6 +371,7 @@ void nsHTMLAtoms::AddrefAtoms()
scheme = NS_NewAtom("SCHEME");
scope = NS_NewAtom("SCOPE");
scrolling = NS_NewAtom("SCROLLING");
select = NS_NewAtom("SELECT");
selected = NS_NewAtom("SELECTED");
selectedindex = NS_NewAtom("SELECTEDINDEX");
shape = NS_NewAtom("SHAPE");
@ -385,6 +390,7 @@ void nsHTMLAtoms::AddrefAtoms()
target = NS_NewAtom("TARGET");
td = NS_NewAtom("TD");
text = NS_NewAtom("TEXT");
textarea = NS_NewAtom("TEXTAREA");
th = NS_NewAtom("TH");
title = NS_NewAtom("TITLE");
top = NS_NewAtom("TOP");
@ -493,6 +499,8 @@ void nsHTMLAtoms::ReleaseAtoms()
NS_RELEASE(id);
NS_RELEASE(iframe);
NS_RELEASE(img);
NS_RELEASE(index);
NS_RELEASE(input);
NS_RELEASE(ismap);
NS_RELEASE(label);
NS_RELEASE(lang);
@ -555,6 +563,7 @@ void nsHTMLAtoms::ReleaseAtoms()
NS_RELEASE(scheme);
NS_RELEASE(scope);
NS_RELEASE(scrolling);
NS_RELEASE(select);
NS_RELEASE(selected);
NS_RELEASE(selectedindex);
NS_RELEASE(shape);
@ -572,6 +581,7 @@ void nsHTMLAtoms::ReleaseAtoms()
NS_RELEASE(target);
NS_RELEASE(td);
NS_RELEASE(text);
NS_RELEASE(textarea);
NS_RELEASE(th);
NS_RELEASE(top);
NS_RELEASE(toppadding);

View File

@ -134,6 +134,7 @@ public:
static nsIAtom* iframe;
static nsIAtom* img;
static nsIAtom* index;
static nsIAtom* input;
static nsIAtom* ismap;
static nsIAtom* label;
@ -205,6 +206,7 @@ public:
static nsIAtom* scheme;
static nsIAtom* scope;
static nsIAtom* scrolling;
static nsIAtom* select;
static nsIAtom* selected;
static nsIAtom* selectedindex;
static nsIAtom* shape;
@ -224,6 +226,7 @@ public:
static nsIAtom* target;
static nsIAtom* td;
static nsIAtom* text;
static nsIAtom* textarea;
static nsIAtom* th;
static nsIAtom* title;
static nsIAtom* top;

View File

@ -170,6 +170,7 @@ public:
nsIHTMLContent* mRoot;
nsIHTMLContent* mBody;
PRInt32 mBodyChildCount;
nsIHTMLContent* mFrameset;
nsIHTMLContent* mHead;
nsString* mTitle;
@ -1378,7 +1379,8 @@ HTMLContentSink::DidBuildModel(PRInt32 aQualityLevel)
("HTMLContentSink::DidBuildModel: layout final content"));
// Reflow the last batch of content
mDocument->ContentAppended(mBody);
mDocument->ContentAppended(mBody, mBodyChildCount);
mBody->ChildCount(mBodyChildCount);
ScrollToRef();
mDocument->EndLoad();
@ -1391,7 +1393,8 @@ HTMLContentSink::WillInterrupt()
SINK_TRACE(SINK_TRACE_CALLS,
("HTMLContentSink::WillInterrupt: this=%p", this));
if (mDirty && !mInMonolithicContainer) {
mDocument->ContentAppended(mBody);
mDocument->ContentAppended(mBody, mBodyChildCount);
mBody->ChildCount(mBodyChildCount);
mDirty = PR_FALSE;
}
return NS_OK;
@ -1571,6 +1574,7 @@ HTMLContentSink::OpenBody(const nsIParserNode& aNode)
return rv;
}
mBody = mCurrentContext->mStack[mCurrentContext->mStackPos - 1].mContent;
mBodyChildCount = 0;
NS_ADDREF(mBody);
StartLayout();
@ -1592,7 +1596,8 @@ HTMLContentSink::CloseBody(const nsIParserNode& aNode)
if (didFlush) {
// Trigger a reflow for the flushed text
mDocument->ContentAppended(mBody);
mDocument->ContentAppended(mBody, mBodyChildCount);
mBody->ChildCount(mBodyChildCount);
}
return NS_OK;
@ -1815,7 +1820,7 @@ HTMLContentSink::StartLayout()
nsIPresContext* cx = shell->GetPresContext();
nsRect r;
cx->GetVisibleArea(r);
shell->ResizeReflow(r.width, r.height);
shell->InitialReflow(r.width, r.height);
NS_RELEASE(cx);
// Now trigger a refresh

View File

@ -35,10 +35,17 @@
#include "nsTableColFrame.h"
#include "nsTableFrame.h"
#include "nsHTMLIIDs.h"
#include "nsIStyleFrameConstruction.h"
#include "nsHTMLParts.h"
#include "nsIPresShell.h"
#include "nsIViewManager.h"
#include "nsStyleConsts.h"
#include "nsTableOuterFrame.h"
static NS_DEFINE_IID(kIHTMLStyleSheetIID, NS_IHTML_STYLE_SHEET_IID);
static NS_DEFINE_IID(kIStyleSheetIID, NS_ISTYLE_SHEET_IID);
static NS_DEFINE_IID(kIStyleRuleIID, NS_ISTYLE_RULE_IID);
static NS_DEFINE_IID(kIStyleFrameConstructionIID, NS_ISTYLE_FRAME_CONSTRUCTION_IID);
class HTMLAnchorRule : public nsIStyleRule {
@ -173,7 +180,8 @@ nsHashKey* AttributeKey::Clone(void) const
// -----------------------------------------------------------
class HTMLStyleSheetImpl : public nsIHTMLStyleSheet {
class HTMLStyleSheetImpl : public nsIHTMLStyleSheet,
public nsIStyleFrameConstruction {
public:
void* operator new(size_t size);
void* operator new(size_t size, nsIArena* aArena);
@ -217,6 +225,15 @@ public:
NS_IMETHOD UnsetAttributeFor(nsIAtom* aAttribute, nsIHTMLContent* aContent,
nsIHTMLAttributes*& aAttributes);
NS_IMETHOD ConstructFrame(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParentFrame,
nsIFrame*& aFrameSubTree);
NS_IMETHOD ContentAppended(nsIPresContext* aPresContext,
nsIDocument* aDocument,
nsIContent* aContainer,
PRInt32 aNewIndexInContainer);
// XXX style rule enumerations
@ -239,6 +256,14 @@ protected:
PRInt32 aAttrCount,
nsIHTMLAttributes*& aAttributes);
nsresult ProcessChildren(nsIPresContext* aPresContext,
nsIFrame* aFrame,
nsIContent* aContent);
nsresult CreateInputFrame(nsIContent* aContent,
nsIFrame* aParentFrame,
nsIFrame*& aFrame);
protected:
PRUint32 mInHeap : 1;
PRUint32 mRefCnt : 31;
@ -330,8 +355,13 @@ nsresult HTMLStyleSheetImpl::QueryInterface(const nsIID& aIID,
AddRef();
return NS_OK;
}
if (aIID.Equals(kIStyleFrameConstructionIID)) {
*aInstancePtrResult = (void*) ((nsIStyleFrameConstruction*)this);
AddRef();
return NS_OK;
}
if (aIID.Equals(kISupportsIID)) {
*aInstancePtrResult = (void*) ((nsISupports*)this);
*aInstancePtrResult = (void*) this;
AddRef();
return NS_OK;
}
@ -816,6 +846,316 @@ NS_IMETHODIMP HTMLStyleSheetImpl::UnsetAttributeFor(nsIAtom* aAttribute,
}
nsresult HTMLStyleSheetImpl::ProcessChildren(nsIPresContext* aPresContext,
nsIFrame* aFrame,
nsIContent* aContent)
{
nsIFrame* childList = nsnull;
nsIFrame* lastChildFrame = nsnull;
PRInt32 count;
aContent->ChildCount(count);
for (PRInt32 i = 0; i < count; i++) {
nsIContent* childContent;
aContent->ChildAt(i, childContent);
if (nsnull != childContent) {
nsIFrame* childFrame;
// Construct a child frame
ConstructFrame(aPresContext, childContent, aFrame, childFrame);
if (nsnull != childFrame) {
// Link the frame into the child list
if (nsnull == lastChildFrame) {
childList = childFrame;
} else {
lastChildFrame->SetNextSibling(childFrame);
}
lastChildFrame = childFrame;
}
NS_RELEASE(childContent);
}
}
// Initialize the frame giving it its child list.
// XXX Should we call Init(), or just return the child list and let the
// caller call Init()?
aFrame->Init(*aPresContext, childList);
return NS_OK;
}
nsresult
HTMLStyleSheetImpl::CreateInputFrame(nsIContent* aContent,
nsIFrame* aParentFrame,
nsIFrame*& aFrame)
{
nsresult rv;
// Figure out which type of input frame to create
nsAutoString val;
if (NS_OK == aContent->GetAttribute(nsAutoString("type"), val)) {
if (val.EqualsIgnoreCase("submit")) {
rv = NS_NewInputButtonFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("reset")) {
rv = NS_NewInputButtonFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("button")) {
rv = NS_NewInputButtonFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("checkbox")) {
rv = NS_NewInputCheckboxFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("file")) {
rv = NS_NewInputFileFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("hidden")) {
rv = NS_NewInputButtonFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("image")) {
rv = NS_NewInputButtonFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("password")) {
rv = NS_NewInputTextFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("radio")) {
rv = NS_NewInputRadioFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("text")) {
rv = NS_NewInputTextFrame(aContent, aParentFrame, aFrame);
}
else {
rv = NS_NewInputTextFrame(aContent, aParentFrame, aFrame);
}
} else {
rv = NS_NewInputTextFrame(aContent, aParentFrame, aFrame);
}
return rv;
}
NS_IMETHODIMP HTMLStyleSheetImpl::ConstructFrame(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParentFrame,
nsIFrame*& aFrameSubTree)
{
// Get the tag
nsIAtom* tag;
aContent->GetTag(tag);
aFrameSubTree = nsnull;
// Resolve the style context.
// XXX Cheesy hack for text
nsIStyleContext* styleContext;
if (nsnull == tag) {
styleContext = aPresContext->ResolvePseudoStyleContextFor(nsHTMLAtoms::text, aParentFrame);
} else {
styleContext = aPresContext->ResolveStyleContextFor(aContent, aParentFrame);
}
// Create a frame.
if (nsnull == aParentFrame) {
// This should only be the case for the root content object.
// XXX Add assertion...
nsIFrame* rootFrame;
// Create the root frame and set its style context
NS_NewHTMLFrame(aContent, nsnull, rootFrame);
rootFrame->SetStyleContext(aPresContext, styleContext);
// Bind root frame to root view (and root window)
nsIPresShell* presShell = aPresContext->GetShell();
nsIViewManager* viewManager = presShell->GetViewManager();
nsIView* rootView;
NS_RELEASE(presShell);
viewManager->GetRootView(rootView);
rootFrame->SetView(rootView);
NS_RELEASE(viewManager);
// Process the children
ProcessChildren(aPresContext, rootFrame, aContent);
// Return the frame sub-tree
aFrameSubTree = rootFrame;
} else {
nsIFrame* frame = nsnull;
nsresult rv = NS_OK;
// Handle specific frame types
if (nsnull == tag) {
rv = NS_NewTextFrame(aContent, aParentFrame, frame);
}
else if (nsHTMLAtoms::applet == tag) {
rv = NS_NewObjectFrame(aContent, aParentFrame, frame);
}
else if (nsHTMLAtoms::body == tag) {
rv = NS_NewBodyFrame(aContent, aParentFrame, frame);
// Process the children
ProcessChildren(aPresContext, frame, aContent);
}
else if (nsHTMLAtoms::frameset == tag) {
rv = NS_NewHTMLFramesetFrame(aContent, aParentFrame, frame);
}
else if (nsHTMLAtoms::br == tag) {
rv = NS_NewBRFrame(aContent, aParentFrame, frame);
}
else if (nsHTMLAtoms::embed == tag) {
rv = NS_NewObjectFrame(aContent, aParentFrame, frame);
}
else if (nsHTMLAtoms::hr == tag) {
rv = NS_NewHRFrame(aContent, aParentFrame, frame);
}
else if (nsHTMLAtoms::img == tag) {
rv = NS_NewImageFrame(aContent, aParentFrame, frame);
}
else if (nsHTMLAtoms::object == tag) {
rv = NS_NewObjectFrame(aContent, aParentFrame, frame);
}
else if (nsHTMLAtoms::spacer == tag) {
rv = NS_NewSpacerFrame(aContent, aParentFrame, frame);
}
else if (nsHTMLAtoms::wbr == tag) {
rv = NS_NewWBRFrame(aContent, aParentFrame, frame);
}
else if (nsHTMLAtoms::table == tag) {
rv = nsTableOuterFrame::NewFrame(&frame, aContent, aParentFrame);
}
else if (nsHTMLAtoms::input == tag) {
rv = CreateInputFrame(aContent, aParentFrame, frame);
}
else if (nsHTMLAtoms::textarea == tag) {
rv = NS_NewInputTextFrame(aContent, aParentFrame, frame);
}
else if (nsHTMLAtoms::select == tag) {
rv = NS_NewHTMLSelectFrame(aContent, aParentFrame, frame);
}
if (NS_OK != rv) {
NS_RELEASE(styleContext);
NS_IF_RELEASE(tag);
return rv;
}
// XXX add code in here to force the odd ones into the empty frame?
// AREA, HEAD, META, MAP, etc...
if (nsnull == frame) {
// When there is no explicit frame to create, assume it's a
// container and let style dictate the rest.
const nsStyleDisplay* styleDisplay = (const nsStyleDisplay*)
styleContext->GetStyleData(eStyleStruct_Display);
// Use style to choose what kind of frame to create
nsresult rv;
switch (styleDisplay->mDisplay) {
case NS_STYLE_DISPLAY_BLOCK:
case NS_STYLE_DISPLAY_LIST_ITEM:
rv = NS_NewCSSBlockFrame(&frame, aContent, aParentFrame);
ProcessChildren(aPresContext, frame, aContent);
break;
case NS_STYLE_DISPLAY_INLINE:
rv = NS_NewCSSInlineFrame(&frame, aContent, aParentFrame);
break;
default:
// XXX Don't create a placeholder frame for content that's not
// displayed...
#if 0
// Create an empty frame for holding content that is not being
// reflowed.
rv = nsFrame::NewFrame(&frame, aContent, aParentFrame);
#endif
break;
}
if (NS_OK != rv) {
NS_RELEASE(styleContext);
NS_IF_RELEASE(tag);
return rv;
}
}
if (nsnull != frame) {
frame->SetStyleContext(aPresContext, styleContext);
}
aFrameSubTree = frame;
}
NS_RELEASE(styleContext);
NS_IF_RELEASE(tag);
return NS_OK;
}
NS_IMETHODIMP HTMLStyleSheetImpl::ContentAppended(nsIPresContext* aPresContext,
nsIDocument* aDocument,
nsIContent* aContainer,
PRInt32 aNewIndexInContainer)
{
nsIPresShell* shell = aPresContext->GetShell();
nsIContent* parentContainer = aContainer;
while (nsnull != parentContainer) {
nsIFrame* parentFrame = shell->FindFrameWithContent(parentContainer);
if (nsnull != parentFrame) {
// Get the parent frame's last-in-flow
nsIFrame* nextInFlow = parentFrame;
while (nsnull != nextInFlow) {
parentFrame->GetNextInFlow(nextInFlow);
if (nsnull != nextInFlow) {
parentFrame = nextInFlow;
}
}
// Create some new frames
PRInt32 count;
nsIFrame* lastChildFrame = nsnull;
nsIFrame* firstAppendedFrame = nsnull;
aContainer->ChildCount(count);
for (PRInt32 i = aNewIndexInContainer; i < count; i++) {
nsIContent* child;
nsIFrame* frame;
aContainer->ChildAt(i, child);
ConstructFrame(aPresContext, child, parentFrame, frame);
// Link the frame into the child frame list
if (nsnull == lastChildFrame) {
firstAppendedFrame = frame;
} else {
lastChildFrame->SetNextSibling(frame);
}
// XXX We should probably mark the frame as being dirty: that way the
// parent frame can easily identify the newly added frames. Either that
// or pass along in count in which case they must be contiguus...
lastChildFrame = frame;
}
// Notify the parent frame with a reflow command, passing it the list of
// new frames.
nsIReflowCommand* reflowCmd;
nsresult result;
result = NS_NewHTMLReflowCommand(&reflowCmd, parentFrame,
nsIReflowCommand::FrameAppended,
firstAppendedFrame);
if (NS_SUCCEEDED(result)) {
shell->AppendReflowCommand(reflowCmd);
}
break;
}
parentContainer->GetParent(parentContainer);
}
NS_RELEASE(shell);
return NS_OK;
}
void HTMLStyleSheetImpl::List(FILE* out, PRInt32 aIndent) const
{

View File

@ -134,6 +134,7 @@ public:
static nsIAtom* iframe;
static nsIAtom* img;
static nsIAtom* index;
static nsIAtom* input;
static nsIAtom* ismap;
static nsIAtom* label;
@ -205,6 +206,7 @@ public:
static nsIAtom* scheme;
static nsIAtom* scope;
static nsIAtom* scrolling;
static nsIAtom* select;
static nsIAtom* selected;
static nsIAtom* selectedindex;
static nsIAtom* shape;
@ -224,6 +226,7 @@ public:
static nsIAtom* target;
static nsIAtom* td;
static nsIAtom* text;
static nsIAtom* textarea;
static nsIAtom* th;
static nsIAtom* title;
static nsIAtom* top;

View File

@ -107,6 +107,7 @@ nsIAtom* nsHTMLAtoms::id;
nsIAtom* nsHTMLAtoms::iframe;
nsIAtom* nsHTMLAtoms::img;
nsIAtom* nsHTMLAtoms::index;
nsIAtom* nsHTMLAtoms::input;
nsIAtom* nsHTMLAtoms::ismap;
nsIAtom* nsHTMLAtoms::label;
nsIAtom* nsHTMLAtoms::lang;
@ -171,6 +172,7 @@ nsIAtom* nsHTMLAtoms::rules;
nsIAtom* nsHTMLAtoms::scheme;
nsIAtom* nsHTMLAtoms::scope;
nsIAtom* nsHTMLAtoms::scrolling;
nsIAtom* nsHTMLAtoms::select;
nsIAtom* nsHTMLAtoms::selected;
nsIAtom* nsHTMLAtoms::selectedindex;
nsIAtom* nsHTMLAtoms::shape;
@ -189,6 +191,7 @@ nsIAtom* nsHTMLAtoms::tabstop;
nsIAtom* nsHTMLAtoms::target;
nsIAtom* nsHTMLAtoms::td;
nsIAtom* nsHTMLAtoms::text;
nsIAtom* nsHTMLAtoms::textarea;
nsIAtom* nsHTMLAtoms::th;
nsIAtom* nsHTMLAtoms::title;
nsIAtom* nsHTMLAtoms::top;
@ -304,6 +307,7 @@ void nsHTMLAtoms::AddrefAtoms()
iframe = NS_NewAtom("IFRAME");
img = NS_NewAtom("IMG");
index = NS_NewAtom("INDEX");
input = NS_NewAtom("INPUT");
ismap = NS_NewAtom("ISMAP");
label = NS_NewAtom("LABEL");
lang = NS_NewAtom("LANG");
@ -367,6 +371,7 @@ void nsHTMLAtoms::AddrefAtoms()
scheme = NS_NewAtom("SCHEME");
scope = NS_NewAtom("SCOPE");
scrolling = NS_NewAtom("SCROLLING");
select = NS_NewAtom("SELECT");
selected = NS_NewAtom("SELECTED");
selectedindex = NS_NewAtom("SELECTEDINDEX");
shape = NS_NewAtom("SHAPE");
@ -385,6 +390,7 @@ void nsHTMLAtoms::AddrefAtoms()
target = NS_NewAtom("TARGET");
td = NS_NewAtom("TD");
text = NS_NewAtom("TEXT");
textarea = NS_NewAtom("TEXTAREA");
th = NS_NewAtom("TH");
title = NS_NewAtom("TITLE");
top = NS_NewAtom("TOP");
@ -493,6 +499,8 @@ void nsHTMLAtoms::ReleaseAtoms()
NS_RELEASE(id);
NS_RELEASE(iframe);
NS_RELEASE(img);
NS_RELEASE(index);
NS_RELEASE(input);
NS_RELEASE(ismap);
NS_RELEASE(label);
NS_RELEASE(lang);
@ -555,6 +563,7 @@ void nsHTMLAtoms::ReleaseAtoms()
NS_RELEASE(scheme);
NS_RELEASE(scope);
NS_RELEASE(scrolling);
NS_RELEASE(select);
NS_RELEASE(selected);
NS_RELEASE(selectedindex);
NS_RELEASE(shape);
@ -572,6 +581,7 @@ void nsHTMLAtoms::ReleaseAtoms()
NS_RELEASE(target);
NS_RELEASE(td);
NS_RELEASE(text);
NS_RELEASE(textarea);
NS_RELEASE(th);
NS_RELEASE(top);
NS_RELEASE(toppadding);

View File

@ -71,6 +71,15 @@ public:
// Make shell stop being a document observer
virtual void EndObservingDocument() = 0;
/**
* Perform the initial reflow. Constructs the frame for the root content
* object and then reflows the frame model into the specified width and
* height.
*
* The coordinates for aWidth and aHeight must be in standard nscoord's.
*/
NS_IMETHOD InitialReflow(nscoord aWidth, nscoord aHeight) = 0;
/**
* Reflow the frame model into a new width and height. The
* coordinates for aWidth and aHeight must be in standard nscoord's.

View File

@ -551,3 +551,83 @@ nsPresContext::GetEventStateManager(nsIEventStateManager** aManager)
return NS_OK;
}
NS_IMETHODIMP
nsPresContext::ConstructFrame(nsIContent* aContent,
nsIFrame* aParentFrame,
nsIFrame*& aFrameSubTree)
{
nsIStyleSet* set = mShell->GetStyleSet();
if (nsnull != set) {
nsresult rv = set->ConstructFrame(this, aContent, aParentFrame, aFrameSubTree);
NS_RELEASE(set);
return rv;
}
return NS_ERROR_UNEXPECTED;
}
NS_IMETHODIMP
nsPresContext::ContentAppended(nsIDocument* aDocument,
nsIContent* aContainer,
PRInt32 aNewIndexInContainer)
{
nsIStyleSet* set = mShell->GetStyleSet();
if (nsnull != set) {
nsresult rv = set->ContentAppended(this, aDocument, aContainer, aNewIndexInContainer);
NS_RELEASE(set);
return rv;
}
return NS_ERROR_UNEXPECTED;
}
NS_IMETHODIMP
nsPresContext::ContentInserted(nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer)
{
nsIStyleSet* set = mShell->GetStyleSet();
if (nsnull != set) {
nsresult rv = set->ContentInserted(this, aDocument, aContainer, aChild, aIndexInContainer);
NS_RELEASE(set);
return rv;
}
return NS_ERROR_UNEXPECTED;
}
NS_IMETHODIMP
nsPresContext::ContentReplaced(nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aOldChild,
nsIContent* aNewChild,
PRInt32 aIndexInContainer)
{
nsIStyleSet* set = mShell->GetStyleSet();
if (nsnull != set) {
nsresult rv = set->ContentReplaced(this, aDocument, aContainer, aOldChild,
aNewChild, aIndexInContainer);
NS_RELEASE(set);
return rv;
}
return NS_ERROR_UNEXPECTED;
}
NS_IMETHODIMP
nsPresContext::ContentRemoved(nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer)
{
nsIStyleSet* set = mShell->GetStyleSet();
if (nsnull != set) {
nsresult rv = set->ContentRemoved(this, aDocument, aContainer, aChild, aIndexInContainer);
NS_RELEASE(set);
return rv;
}
return NS_ERROR_UNEXPECTED;
}

View File

@ -26,6 +26,7 @@
struct nsFont;
class nsIContent;
class nsIDocument;
class nsIDeviceContext;
class nsIFontMetrics;
class nsIFrame;
@ -214,6 +215,35 @@ public:
virtual nsIDeviceContext * GetDeviceContext() const = 0;
NS_IMETHOD GetEventStateManager(nsIEventStateManager** aManager) = 0;
/**
* Handles association of elements in the content model to frames. Finds the
* applicable construction rule, applies the action, and produces a sub-tree
* of frame objects. Can return nsnull.
*/
NS_IMETHOD ConstructFrame(nsIContent* aContent,
nsIFrame* aParentFrame,
nsIFrame*& aFrameSubTree) = 0;
/**
* Notifications of content changes
*/
NS_IMETHOD ContentAppended(nsIDocument* aDocument,
nsIContent* aContainer,
PRInt32 aNewIndexInContainer) = 0;
NS_IMETHOD ContentInserted(nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer) = 0;
NS_IMETHOD ContentReplaced(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aOldChild,
nsIContent* aNewChild,
PRInt32 aIndexInContainer) = 0;
NS_IMETHOD ContentRemoved(nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer) = 0;
};
// Bit values for StartLoadImage's aImageStatus

View File

@ -41,6 +41,7 @@ EXPORTS = \
nsIStyleSet.h \
nsIStyleSheet.h \
nsITextContent.h \
nsIStyleFrameConstruction.h \
$(NULL)
include $(DEPTH)/config/config.mk

View File

@ -39,6 +39,7 @@ EXPORTS = \
nsIStyleSet.h \
nsIStyleSheet.h \
nsITextContent.h \
nsIStyleFrameConstruction.h \
$(NULL)
MODULE=raptor

View File

@ -163,7 +163,8 @@ public:
virtual void ContentChanged(nsIContent* aContent,
nsISupports* aSubContent) = 0;
virtual void ContentAppended(nsIContent* aContainer) = 0;
virtual void ContentAppended(nsIContent* aContainer,
PRInt32 aNewIndexInContainer) = 0;
virtual void ContentInserted(nsIContent* aContainer,
nsIContent* aChild,

View File

@ -98,9 +98,12 @@ public:
*
* @param aDocument The document being observed
* @param aContainer the container that had a new child appended
* @param aNewIndexInContainer the index in the container of the first
* new child
*/
NS_IMETHOD ContentAppended(nsIDocument *aDocument,
nsIContent* aContainer) = 0;
nsIContent* aContainer,
PRInt32 aNewIndexInContainer) = 0;
/**
* Notification that content has been inserted. This method is called

View File

@ -260,10 +260,29 @@ typedef PRBool nsDidReflowStatus;
*
* Frames are NOT reference counted. Use the DeleteFrame() member function
* to delete a frame
*
* XXX This should probably be changed so it's consistent with the way nsIView
* (which is also not reference counted) is defined...
*/
class nsIFrame : private nsISupports
{
public:
/**
* Initialize the frame passing it its child frame list.
*
* This member function is called for all frames just after the frame is
* constructed.
*
* You should reflow the frames when you get your 'initial' reflow
* notification.
*
* XXX Should we also pass in the child count?
*
* @param aChildList list of child frames. May be NULL
* @see #Reflow()
*/
NS_IMETHOD Init(nsIPresContext& aPresContext, nsIFrame* aChildList) = 0;
/**
* QueryInterface() defined in nsISupports. This is the only member
* function of nsISupports that is public.
@ -466,9 +485,12 @@ public:
* FrameAppended incremental reflow command. You then handle the incremental
* reflow command by creating frames for the appended content.
*/
// XXX CONSTRUCTION
#if 0
NS_IMETHOD ContentAppended(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aContainer) = 0;
#endif
/**
* This call is invoked when content is inserted in the content

View File

@ -26,6 +26,7 @@
struct nsFont;
class nsIContent;
class nsIDocument;
class nsIDeviceContext;
class nsIFontMetrics;
class nsIFrame;
@ -214,6 +215,35 @@ public:
virtual nsIDeviceContext * GetDeviceContext() const = 0;
NS_IMETHOD GetEventStateManager(nsIEventStateManager** aManager) = 0;
/**
* Handles association of elements in the content model to frames. Finds the
* applicable construction rule, applies the action, and produces a sub-tree
* of frame objects. Can return nsnull.
*/
NS_IMETHOD ConstructFrame(nsIContent* aContent,
nsIFrame* aParentFrame,
nsIFrame*& aFrameSubTree) = 0;
/**
* Notifications of content changes
*/
NS_IMETHOD ContentAppended(nsIDocument* aDocument,
nsIContent* aContainer,
PRInt32 aNewIndexInContainer) = 0;
NS_IMETHOD ContentInserted(nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer) = 0;
NS_IMETHOD ContentReplaced(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aOldChild,
nsIContent* aNewChild,
PRInt32 aIndexInContainer) = 0;
NS_IMETHOD ContentRemoved(nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer) = 0;
};
// Bit values for StartLoadImage's aImageStatus

View File

@ -71,6 +71,15 @@ public:
// Make shell stop being a document observer
virtual void EndObservingDocument() = 0;
/**
* Perform the initial reflow. Constructs the frame for the root content
* object and then reflows the frame model into the specified width and
* height.
*
* The coordinates for aWidth and aHeight must be in standard nscoord's.
*/
NS_IMETHOD InitialReflow(nscoord aWidth, nscoord aHeight) = 0;
/**
* Reflow the frame model into a new width and height. The
* coordinates for aWidth and aHeight must be in standard nscoord's.

View File

@ -102,6 +102,11 @@ public:
*/
NS_IMETHOD GetTarget(nsIFrame*& aTargetFrame) const = 0;
/**
* Change the target of the reflow command.
*/
NS_IMETHOD SetTarget(nsIFrame* aTargetFrame) = 0;
/**
* Get the type of reflow command.
*/

View File

@ -0,0 +1,47 @@
/* -*- 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.
*/
#ifndef nsIStyleFrameConstruction_h___
#define nsIStyleFrameConstruction_h___
class nsIPresContext;
class nsIContent;
class nsIFrame;
// IID for the nsIStyleSet interface {a6cf9066-15b3-11d2-932e-00805f8add32}
#define NS_ISTYLE_FRAME_CONSTRUCTION_IID \
{0xa6cf9066, 0x15b3, 0x11d2, {0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32}}
class nsIStyleFrameConstruction : public nsISupports {
public:
/**
* Handles association of elements in the content model to frames. Finds the
* applicable construction rule, applies the action, and produces a sub-tree
* of frame objects. Can return nsnull.
*/
NS_IMETHOD ConstructFrame(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParentFrame,
nsIFrame*& aFrameSubTree) = 0;
NS_IMETHOD ContentAppended(nsIPresContext* aPresContext,
nsIDocument* aDocument,
nsIContent* aContainer,
PRInt32 aNewIndexInContainer) = 0;
};
#endif /* nsIStyleFrameConstruction_h___ */

View File

@ -30,6 +30,7 @@ class nsIStyleContext;
class nsIPresContext;
class nsIContent;
class nsIFrame;
class nsIDocument;
// IID for the nsIStyleSet interface {e59396b0-b244-11d1-8031-006008159b5a}
@ -87,6 +88,36 @@ public:
nsIFrame* aParentFrame,
PRBool aForceUnique = PR_FALSE) = 0;
// Handles association of elements in the content model to frames. Finds the
// applicable construction rule, applies the action, and produces a sub-tree
// of frame objects. Can return nsnull.
NS_IMETHOD ConstructFrame(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParentFrame,
nsIFrame*& aFrameSubTree) = 0;
// Notifications of changes to the content mpodel
NS_IMETHOD ContentAppended(nsIPresContext* aPresContext,
nsIDocument* aDocument,
nsIContent* aContainer,
PRInt32 aNewIndexInContainer) = 0;
NS_IMETHOD ContentInserted(nsIPresContext* aPresContext,
nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer) = 0;
NS_IMETHOD ContentReplaced(nsIPresContext* aPresContext,
nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aOldChild,
nsIContent* aNewChild,
PRInt32 aIndexInContainer) = 0;
NS_IMETHOD ContentRemoved(nsIPresContext* aPresContext,
nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer) = 0;
// xxx style rules enumeration
virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) = 0;

View File

@ -26,6 +26,7 @@
struct nsFont;
class nsIContent;
class nsIDocument;
class nsIDeviceContext;
class nsIFontMetrics;
class nsIFrame;
@ -214,6 +215,35 @@ public:
virtual nsIDeviceContext * GetDeviceContext() const = 0;
NS_IMETHOD GetEventStateManager(nsIEventStateManager** aManager) = 0;
/**
* Handles association of elements in the content model to frames. Finds the
* applicable construction rule, applies the action, and produces a sub-tree
* of frame objects. Can return nsnull.
*/
NS_IMETHOD ConstructFrame(nsIContent* aContent,
nsIFrame* aParentFrame,
nsIFrame*& aFrameSubTree) = 0;
/**
* Notifications of content changes
*/
NS_IMETHOD ContentAppended(nsIDocument* aDocument,
nsIContent* aContainer,
PRInt32 aNewIndexInContainer) = 0;
NS_IMETHOD ContentInserted(nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer) = 0;
NS_IMETHOD ContentReplaced(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aOldChild,
nsIContent* aNewChild,
PRInt32 aIndexInContainer) = 0;
NS_IMETHOD ContentRemoved(nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer) = 0;
};
// Bit values for StartLoadImage's aImageStatus

View File

@ -55,6 +55,16 @@ nsContainerFrame::SizeOf(nsISizeOfHandler* aHandler) const
return NS_OK;
}
NS_IMETHODIMP
nsContainerFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList)
{
NS_PRECONDITION(nsnull == mFirstChild, "already initialized");
mFirstChild = aChildList;
mChildCount = LengthOf(mFirstChild);
return NS_OK;
}
NS_IMETHODIMP
nsContainerFrame::DeleteFrame(nsIPresContext& aPresContext)
{
@ -1239,6 +1249,8 @@ void nsContainerFrame::CheckContentOffsets()
void nsContainerFrame::PreReflowCheck()
{
// XXX CONSTRUCTION
#if 0
PRInt32 len = LengthOf(mFirstChild);
NS_ASSERTION(len == mChildCount, "bad child count");
@ -1249,10 +1261,13 @@ void nsContainerFrame::PreReflowCheck()
CheckContentOffsets();
}
VerifyLastIsComplete();
#endif
}
void nsContainerFrame::PostReflowCheck(nsReflowStatus aStatus)
{
// XXX CONSTRUCTION
#if 0
PRInt32 len = LengthOf(mFirstChild) ;
NS_ASSERTION(len == mChildCount, "bad child count");
@ -1263,6 +1278,7 @@ void nsContainerFrame::PostReflowCheck(nsReflowStatus aStatus)
CheckContentOffsets();
}
VerifyLastIsComplete();
#endif
}
/**

View File

@ -107,6 +107,8 @@ class nsContainerFrame : public nsSplittableFrame
public:
NS_IMETHOD SizeOf(nsISizeOfHandler* aHandler) const;
NS_IMETHOD Init(nsIPresContext& aPresContext, nsIFrame* aChildList);
NS_IMETHOD DeleteFrame(nsIPresContext& aPresContext);
/**
* Default implementation is to use the content delegate to create a new

View File

@ -277,7 +277,8 @@ void nsContentList::PopulateSelf(nsIContent *aContent)
NS_IMETHODIMP
nsContentList::ContentAppended(nsIDocument *aDocument,
nsIContent* aContainer)
nsIContent* aContainer,
PRInt32 aNewIndexInContainer)
{
PRInt32 count;
aContainer->ChildCount(count);

View File

@ -69,7 +69,8 @@ public:
nsIContent* aContent,
nsISupports* aSubContent) { return NS_OK; }
NS_IMETHOD ContentAppended(nsIDocument *aDocument,
nsIContent* aContainer);
nsIContent* aContainer,
PRInt32 aNewIndexInContainer);
NS_IMETHOD ContentInserted(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild,

View File

@ -507,12 +507,13 @@ void nsDocument::ContentChanged(nsIContent* aContent,
}
}
void nsDocument::ContentAppended(nsIContent* aContainer)
void nsDocument::ContentAppended(nsIContent* aContainer,
PRInt32 aNewIndexInContainer)
{
PRInt32 count = mObservers.Count();
for (PRInt32 i = 0; i < count; i++) {
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
observer->ContentAppended(this, aContainer);
observer->ContentAppended(this, aContainer, aNewIndexInContainer);
}
}

View File

@ -140,7 +140,8 @@ public:
virtual void ContentChanged(nsIContent* aContent,
nsISupports* aSubContent);
virtual void ContentAppended(nsIContent* aContainer);
virtual void ContentAppended(nsIContent* aContainer,
PRInt32 aNewIndexInContainer);
virtual void ContentInserted(nsIContent* aContainer,
nsIContent* aChild,

View File

@ -289,6 +289,16 @@ nsrefcnt nsFrame::Release(void)
/////////////////////////////////////////////////////////////////////////////
// nsIFrame
NS_IMETHODIMP nsFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList)
{
if (nsnull != aChildList) {
NS_ERROR("not a container");
return NS_ERROR_UNEXPECTED;
}
return NS_OK;
}
NS_METHOD nsFrame::DeleteFrame(nsIPresContext& aPresContext)
{
//XXX Why is this done in nsFrame instead of some frame class
@ -1172,12 +1182,15 @@ NS_METHOD nsFrame::Reflow(nsIPresContext& aPresContext,
return NS_OK;
}
// XXX CONSTRUCTION
#if 0
NS_METHOD nsFrame::ContentAppended(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aContainer)
{
return NS_OK;
}
#endif
NS_METHOD nsFrame::ContentInserted(nsIPresShell* aShell,
nsIPresContext* aPresContext,

View File

@ -105,6 +105,7 @@ public:
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
// nsIFrame
NS_IMETHOD Init(nsIPresContext& aPresContext, nsIFrame* aChildList);
NS_IMETHOD DeleteFrame(nsIPresContext& aPresContext);
NS_IMETHOD SizeOf(nsISizeOfHandler* aHandler) const;
NS_IMETHOD GetContent(nsIContent*& aContent) const;
@ -152,9 +153,12 @@ public:
nsReflowMetrics& aDesiredSize,
const nsReflowState& aReflowState,
nsReflowStatus& aStatus);
// XXX CONSTRUCTION
#if 0
NS_IMETHOD ContentAppended(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aContainer);
#endif
NS_IMETHOD ContentInserted(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aContainer,

View File

@ -551,3 +551,83 @@ nsPresContext::GetEventStateManager(nsIEventStateManager** aManager)
return NS_OK;
}
NS_IMETHODIMP
nsPresContext::ConstructFrame(nsIContent* aContent,
nsIFrame* aParentFrame,
nsIFrame*& aFrameSubTree)
{
nsIStyleSet* set = mShell->GetStyleSet();
if (nsnull != set) {
nsresult rv = set->ConstructFrame(this, aContent, aParentFrame, aFrameSubTree);
NS_RELEASE(set);
return rv;
}
return NS_ERROR_UNEXPECTED;
}
NS_IMETHODIMP
nsPresContext::ContentAppended(nsIDocument* aDocument,
nsIContent* aContainer,
PRInt32 aNewIndexInContainer)
{
nsIStyleSet* set = mShell->GetStyleSet();
if (nsnull != set) {
nsresult rv = set->ContentAppended(this, aDocument, aContainer, aNewIndexInContainer);
NS_RELEASE(set);
return rv;
}
return NS_ERROR_UNEXPECTED;
}
NS_IMETHODIMP
nsPresContext::ContentInserted(nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer)
{
nsIStyleSet* set = mShell->GetStyleSet();
if (nsnull != set) {
nsresult rv = set->ContentInserted(this, aDocument, aContainer, aChild, aIndexInContainer);
NS_RELEASE(set);
return rv;
}
return NS_ERROR_UNEXPECTED;
}
NS_IMETHODIMP
nsPresContext::ContentReplaced(nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aOldChild,
nsIContent* aNewChild,
PRInt32 aIndexInContainer)
{
nsIStyleSet* set = mShell->GetStyleSet();
if (nsnull != set) {
nsresult rv = set->ContentReplaced(this, aDocument, aContainer, aOldChild,
aNewChild, aIndexInContainer);
NS_RELEASE(set);
return rv;
}
return NS_ERROR_UNEXPECTED;
}
NS_IMETHODIMP
nsPresContext::ContentRemoved(nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer)
{
nsIStyleSet* set = mShell->GetStyleSet();
if (nsnull != set) {
nsresult rv = set->ContentRemoved(this, aDocument, aContainer, aChild, aIndexInContainer);
NS_RELEASE(set);
return rv;
}
return NS_ERROR_UNEXPECTED;
}

View File

@ -74,6 +74,27 @@ public:
virtual nsIDeviceContext* GetDeviceContext() const;
NS_IMETHOD GetEventStateManager(nsIEventStateManager** aManager);
NS_IMETHOD ConstructFrame(nsIContent* aContent,
nsIFrame* aParentFrame,
nsIFrame*& aFrameSubTree);
NS_IMETHOD ContentAppended(nsIDocument* aDocument,
nsIContent* aContainer,
PRInt32 aNewIndexInContainer);
NS_IMETHOD ContentInserted(nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer);
NS_IMETHOD ContentReplaced(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aOldChild,
nsIContent* aNewChild,
PRInt32 aIndexInContainer);
NS_IMETHOD ContentRemoved(nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer);
protected:
nsPresContext();
virtual ~nsPresContext();

View File

@ -163,7 +163,8 @@ public:
nsIContent* aContent,
nsISupports* aSubContent);
NS_IMETHOD ContentAppended(nsIDocument *aDocument,
nsIContent* aContainer);
nsIContent* aContainer,
PRInt32 aNewIndexInContainer);
NS_IMETHOD ContentInserted(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild,
@ -198,6 +199,7 @@ public:
NS_IMETHOD ExitReflowLock();
virtual void BeginObservingDocument();
virtual void EndObservingDocument();
NS_IMETHOD InitialReflow(nscoord aWidth, nscoord aHeight);
NS_IMETHOD ResizeReflow(nscoord aWidth, nscoord aHeight);
virtual nsIFrame* GetRootFrame();
virtual nsIFrame* FindFrameWithContent(nsIContent* aContent);
@ -447,6 +449,79 @@ PresShell::EndObservingDocument()
}
}
NS_IMETHODIMP
PresShell::InitialReflow(nscoord aWidth, nscoord aHeight)
{
NS_PRECONDITION(nsnull == mRootFrame, "unexpected root frame");
EnterReflowLock();
if (nsnull != mPresContext) {
nsRect r(0, 0, aWidth, aHeight);
mPresContext->SetVisibleArea(r);
}
if (nsnull == mRootFrame) {
if (nsnull != mDocument) {
nsIContent* root = mDocument->GetRootContent();
if (nsnull != root) {
// XXX CONSTRUCTION
#if 0
nsIContentDelegate* cd = root->GetDelegate(mPresContext);
if (nsnull != cd) {
nsIStyleContext* rootSC =
mPresContext->ResolveStyleContextFor(root, nsnull);
nsresult rv = cd->CreateFrame(mPresContext, root, nsnull,
rootSC, mRootFrame);
NS_RELEASE(rootSC);
NS_RELEASE(cd);
// Bind root frame to root view (and root window)
nsIView* rootView;
mViewManager->GetRootView(rootView);
mRootFrame->SetView(rootView);
}
#else
// Have style sheet processor construct a frame for the
// root content object
mPresContext->ConstructFrame(root, nsnull, mRootFrame);
#endif
NS_RELEASE(root);
}
}
}
if (nsnull != mRootFrame) {
// Kick off a top-down reflow
NS_FRAME_LOG(NS_FRAME_TRACE_CALLS,
("enter nsPresShell::InitialReflow: %d,%d", aWidth, aHeight));
#ifdef NS_DEBUG
if (nsIFrame::GetVerifyTreeEnable()) {
mRootFrame->VerifyTree();
}
#endif
nsRect bounds;
mPresContext->GetVisibleArea(bounds);
nsSize maxSize(bounds.width, bounds.height);
nsReflowMetrics desiredSize(nsnull);
nsReflowStatus status;
nsReflowState reflowState(mRootFrame, eReflowReason_Initial, maxSize);
mRootFrame->Reflow(*mPresContext, desiredSize, reflowState, status);
mRootFrame->SizeTo(desiredSize.width, desiredSize.height);
#ifdef NS_DEBUG
if (nsIFrame::GetVerifyTreeEnable()) {
mRootFrame->VerifyTree();
}
#endif
NS_FRAME_LOG(NS_FRAME_TRACE_CALLS, ("exit nsPresShell::InitialReflow"));
}
ExitReflowLock();
return NS_OK; //XXX this needs to be real. MMP
}
NS_IMETHODIMP
PresShell::ResizeReflow(nscoord aWidth, nscoord aHeight)
{
@ -457,32 +532,8 @@ PresShell::ResizeReflow(nscoord aWidth, nscoord aHeight)
mPresContext->SetVisibleArea(r);
}
nsReflowReason reflowReason = eReflowReason_Resize;
if (nsnull == mRootFrame) {
if (nsnull != mDocument) {
nsIContent* root = mDocument->GetRootContent();
if (nsnull != root) {
nsIContentDelegate* cd = root->GetDelegate(mPresContext);
if (nsnull != cd) {
nsIStyleContext* rootSC =
mPresContext->ResolveStyleContextFor(root, nsnull);
nsresult rv = cd->CreateFrame(mPresContext, root, nsnull,
rootSC, mRootFrame);
NS_RELEASE(rootSC);
NS_RELEASE(cd);
reflowReason = eReflowReason_Initial;
// Bind root frame to root view (and root window)
nsIView* rootView;
mViewManager->GetRootView(rootView);
mRootFrame->SetView(rootView);
}
NS_RELEASE(root);
}
}
}
// If we don't have a root frame yet, that means we haven't had our initial
// reflow...
if (nsnull != mRootFrame) {
// Kick off a top-down reflow
NS_FRAME_LOG(NS_FRAME_TRACE_CALLS,
@ -497,7 +548,7 @@ PresShell::ResizeReflow(nscoord aWidth, nscoord aHeight)
nsSize maxSize(bounds.width, bounds.height);
nsReflowMetrics desiredSize(nsnull);
nsReflowStatus status;
nsReflowState reflowState(mRootFrame, reflowReason, maxSize);
nsReflowState reflowState(mRootFrame, eReflowReason_Resize, maxSize);
mRootFrame->Reflow(*mPresContext, desiredSize, reflowState, status);
mRootFrame->SizeTo(desiredSize.width, desiredSize.height);
@ -663,35 +714,27 @@ PresShell::ContentChanged(nsIDocument *aDocument,
NS_IMETHODIMP
PresShell::ContentAppended(nsIDocument *aDocument,
nsIContent* aContainer)
nsIContent* aContainer,
PRInt32 aNewIndexInContainer)
{
NS_PRECONDITION(nsnull != mRootFrame, "null root frame");
EnterReflowLock();
nsIContent* parentContainer = aContainer;
while (nsnull != parentContainer) {
nsIFrame* frame = FindFrameWithContent(parentContainer);
if (nsnull != frame) {
NS_FRAME_LOG(NS_FRAME_TRACE_CALLS,
("PresShell::ContentAppended: container=%p[%s] frame=%p",
aContainer, ContentTag(aContainer, 0), frame));
frame->ContentAppended(this, mPresContext, aContainer);
break;
}
parentContainer->GetParent(parentContainer);
}
nsresult rv = mPresContext->ContentAppended(aDocument, aContainer, aNewIndexInContainer);
ExitReflowLock();
return NS_OK;
return rv;
}
NS_IMETHODIMP
PresShell::ContentInserted(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer)
PresShell::ContentInserted(nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer)
{
#ifdef FRAME_CONSTRUCTION
EnterReflowLock();
nsresult rv = mPresContext->ContentInserted(aDocument, aContainer, aChild, aIndexInContainer);
ExitReflowLock();
return rv;
#else
NS_PRECONDITION(nsnull != mRootFrame, "null root frame");
EnterReflowLock();
@ -708,15 +751,23 @@ PresShell::ContentInserted(nsIDocument *aDocument,
ExitReflowLock();
return NS_OK;
#endif
}
NS_IMETHODIMP
PresShell::ContentReplaced(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aOldChild,
nsIContent* aNewChild,
PRInt32 aIndexInContainer)
PresShell::ContentReplaced(nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aOldChild,
nsIContent* aNewChild,
PRInt32 aIndexInContainer)
{
#ifdef FRAME_CONSTRUCTION
EnterReflowLock();
nsresult rv = mPresContext->ContentReplaced(aDocument, aContainer, aOldChild,
aNewChild, aIndexInContainer);
ExitReflowLock();
return rv;
#else
NS_PRECONDITION(nsnull != mRootFrame, "null root frame");
EnterReflowLock();
@ -733,6 +784,7 @@ PresShell::ContentReplaced(nsIDocument *aDocument,
ExitReflowLock();
return NS_OK;
#endif
}
// XXX keep this?
@ -755,6 +807,12 @@ PresShell::ContentHasBeenRemoved(nsIDocument *aDocument,
nsIContent* aChild,
PRInt32 aIndexInContainer)
{
#ifdef FRAME_CONSTRUCTION
nsresult rv = mPresContext->ContentRemoved(aDocument, aContainer,
aChild, aIndexInContainer);
ProcessReflowCommands();
return rv;
#else
NS_PRECONDITION(nsnull != mRootFrame, "null root frame");
nsIFrame* frame = FindFrameWithContent(aContainer);
@ -766,6 +824,7 @@ PresShell::ContentHasBeenRemoved(nsIDocument *aDocument,
aIndexInContainer);
ProcessReflowCommands();
return NS_OK;
#endif
}
NS_IMETHODIMP

View File

@ -22,8 +22,13 @@
#include "nsISupportsArray.h"
#include "nsIFrame.h"
#include "nsHashtable.h"
#include "nsIPresContext.h"
#include "nsIPresShell.h"
#include "nsIContent.h"
#include "nsIStyleFrameConstruction.h"
static NS_DEFINE_IID(kIStyleSetIID, NS_ISTYLE_SET_IID);
static NS_DEFINE_IID(kIStyleFrameConstructionIID, NS_ISTYLE_FRAME_CONSTRUCTION_IID);
class ContextKey : public nsHashKey {
public:
@ -207,6 +212,31 @@ public:
nsIFrame* aParentFrame,
PRBool aForceUnique = PR_FALSE);
NS_IMETHODIMP ConstructFrame(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParentFrame,
nsIFrame*& aFrameSubTree);
NS_IMETHOD ContentAppended(nsIPresContext* aPresContext,
nsIDocument* aDocument,
nsIContent* aContainer,
PRInt32 aNewIndexInContainer);
NS_IMETHOD ContentInserted(nsIPresContext* aPresContext,
nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer);
NS_IMETHOD ContentReplaced(nsIPresContext* aPresContext,
nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aOldChild,
nsIContent* aNewChild,
PRInt32 aIndexInContainer);
NS_IMETHOD ContentRemoved(nsIPresContext* aPresContext,
nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer);
// xxx style rules enumeration
virtual void List(FILE* out = stdout, PRInt32 aIndent = 0);
@ -240,13 +270,15 @@ protected:
nsISupportsArray* mDocSheets;
nsISupportsArray* mBackstopSheets;
nsHashtable mStyleContexts;
nsIStyleFrameConstruction* mFrameConstructor;
};
StyleSetImpl::StyleSetImpl()
: mOverrideSheets(nsnull),
mDocSheets(nsnull),
mBackstopSheets(nsnull)
mBackstopSheets(nsnull),
mFrameConstructor(nsnull)
{
NS_INIT_REFCNT();
}
@ -262,6 +294,7 @@ StyleSetImpl::~StyleSetImpl()
NS_IF_RELEASE(mOverrideSheets);
NS_IF_RELEASE(mDocSheets);
NS_IF_RELEASE(mBackstopSheets);
NS_IF_RELEASE(mFrameConstructor);
mStyleContexts.Enumerate(ReleaseContext);
}
@ -340,6 +373,9 @@ void StyleSetImpl::AppendDocStyleSheet(nsIStyleSheet* aSheet)
NS_PRECONDITION(nsnull != aSheet, "null arg");
if (EnsureArray(&mDocSheets)) {
mDocSheets->AppendElement(aSheet);
if (nsnull == mFrameConstructor) {
aSheet->QueryInterface(kIStyleFrameConstructionIID, (void **)&mFrameConstructor);
}
}
}
@ -350,6 +386,9 @@ void StyleSetImpl::InsertDocStyleSheetAfter(nsIStyleSheet* aSheet,
if (EnsureArray(&mDocSheets)) {
PRInt32 index = mDocSheets->IndexOf(aAfterSheet);
mDocSheets->InsertElementAt(aSheet, ++index);
if (nsnull == mFrameConstructor) {
aSheet->QueryInterface(kIStyleFrameConstructionIID, (void **)&mFrameConstructor);
}
}
}
@ -360,6 +399,9 @@ void StyleSetImpl::InsertDocStyleSheetBefore(nsIStyleSheet* aSheet,
if (EnsureArray(&mDocSheets)) {
PRInt32 index = mDocSheets->IndexOf(aBeforeSheet);
mDocSheets->InsertElementAt(aSheet, ((-1 < index) ? index : 0));
if (nsnull == mFrameConstructor) {
aSheet->QueryInterface(kIStyleFrameConstructionIID, (void **)&mFrameConstructor);
}
}
}
@ -665,6 +707,67 @@ nsIStyleContext* StyleSetImpl::ProbePseudoStyleFor(nsIPresContext* aPresContext,
return result;
}
NS_IMETHODIMP StyleSetImpl::ConstructFrame(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParentFrame,
nsIFrame*& aFrameSubTree)
{
return mFrameConstructor->ConstructFrame(aPresContext, aContent,
aParentFrame, aFrameSubTree);
}
NS_IMETHODIMP StyleSetImpl::ContentAppended(nsIPresContext* aPresContext,
nsIDocument* aDocument,
nsIContent* aContainer,
PRInt32 aNewIndexInContainer)
{
return mFrameConstructor->ContentAppended(aPresContext, aDocument,
aContainer, aNewIndexInContainer);
}
NS_IMETHODIMP StyleSetImpl::ContentInserted(nsIPresContext* aPresContext,
nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer)
{
#if 0
return mFrameConstructor->ContentInserted(aPresContext, aDocument, aContainer,
aChild, aIndexInContainer);
#else
return NS_OK;
#endif
}
NS_IMETHODIMP StyleSetImpl::ContentReplaced(nsIPresContext* aPresContext,
nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aOldChild,
nsIContent* aNewChild,
PRInt32 aIndexInContainer)
{
#if 0
return mFrameConstructor->ContentReplaced(aPresContext, aDocument, aContainer,
aOldChild, aNewChild, aIndexInContainer);
#else
return NS_OK;
#endif
}
NS_IMETHODIMP StyleSetImpl::ContentRemoved(nsIPresContext* aPresContext,
nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer)
{
#if 0
return mFrameConstructor->ContentRemoved(aPresContext, aDocument, aContainer,
aChild, aIndexInContainer);
#else
return NS_OK;
#endif
}
// xxx style rules enumeration
void StyleSetImpl::List(FILE* out, PRInt32 aIndent, nsISupportsArray* aSheets)

View File

@ -113,6 +113,7 @@ public:
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
// nsIFrame
NS_IMETHOD Init(nsIPresContext& aPresContext, nsIFrame* aChildList);
NS_IMETHOD DeleteFrame(nsIPresContext& aPresContext);
NS_IMETHOD ChildCount(PRInt32& aChildCount) const;
NS_IMETHOD ChildAt(PRInt32 aIndex, nsIFrame*& aFrame) const;
@ -129,9 +130,12 @@ public:
NS_IMETHOD Paint(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect);
// XXX CONSTRUCTION
#if 0
NS_IMETHOD ContentAppended(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aContainer);
#endif
NS_IMETHOD ContentInserted(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aContainer,
@ -267,6 +271,8 @@ protected:
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect);
nsresult AddNewFrames(nsIFrame*);
#ifdef NS_DEBUG
PRBool IsChild(nsIFrame* aFrame);
#endif
@ -281,6 +287,9 @@ protected:
// Text run information
nsCSSTextRun* mTextRuns;
// XXX TEMP
PRBool mHasBeenInitialized;
friend struct nsCSSBlockReflowState;
};
@ -502,7 +511,6 @@ LineData::Contains(nsIFrame* aFrame) const
return PR_FALSE;
}
#ifdef NS_DEBUG
static PRInt32
LengthOf(nsIFrame* aFrame)
{
@ -514,6 +522,7 @@ LengthOf(nsIFrame* aFrame)
return result;
}
#ifdef NS_DEBUG
void
LineData::Verify()
{
@ -957,6 +966,7 @@ NS_NewCSSBlockFrame(nsIFrame** aInstancePtrResult,
nsCSSBlockFrame::nsCSSBlockFrame(nsIContent* aContent, nsIFrame* aParent)
: nsCSSBlockFrameSuper(aContent, aParent)
{
mHasBeenInitialized = PR_FALSE;
}
nsCSSBlockFrame::~nsCSSBlockFrame()
@ -990,6 +1000,13 @@ nsCSSBlockFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
return nsCSSBlockFrameSuper::QueryInterface(aIID, aInstancePtr);
}
NS_IMETHODIMP
nsCSSBlockFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList)
{
mHasBeenInitialized = PR_TRUE;
return AddNewFrames(aChildList);
}
NS_IMETHODIMP
nsCSSBlockFrame::DeleteFrame(nsIPresContext& aPresContext)
{
@ -1620,6 +1637,110 @@ nsCSSBlockFrame::ComputeFinalSize(nsCSSBlockReflowState& aState,
NS_ASSERTION(aDesiredRect.width < 1000000, "whoops");
}
nsresult
nsCSSBlockFrame::AddNewFrames(nsIFrame* aNewFrame)
{
// Get our last line and then get its last child
nsIFrame* lastFrame;
LineData* lastLine = LastLine(mLines);
if (nsnull != lastLine) {
lastFrame = lastLine->LastChild();
} else {
lastFrame = nsnull;
}
// Add the new frames to the sibling list
if (nsnull != lastFrame) {
lastFrame->SetNextSibling(aNewFrame);
}
// Make sure that new inlines go onto the end of the lastLine when
// the lastLine is mapping inline frames.
PRInt32 pendingInlines = 0;
if (nsnull != lastLine) {
if (!lastLine->IsBlock()) {
pendingInlines = 1;
}
}
// Now create some lines for the new frames
nsresult rv;
for (nsIFrame* frame = aNewFrame; nsnull != frame; frame->GetNextSibling(frame)) {
// See if the child is a block or non-block
const nsStyleDisplay* kidDisplay;
rv = frame->GetStyleData(eStyleStruct_Display,
(const nsStyleStruct*&) kidDisplay);
if (NS_OK != rv) {
return rv;
}
const nsStylePosition* kidPosition;
rv = frame->GetStyleData(eStyleStruct_Position,
(const nsStyleStruct*&) kidPosition);
if (NS_OK != rv) {
return rv;
}
PRBool isBlock =
nsCSSLineLayout::TreatFrameAsBlock(kidDisplay, kidPosition);
// If the child is an inline then add it to the lastLine (if it's
// an inline line, otherwise make a new line). If the child is a
// block then make a new line and put the child in that line.
if (isBlock) {
// If the previous line has pending inline data to be reflowed,
// do so now.
if (0 != pendingInlines) {
// Set this to true in case we don't end up reflowing all of the
// frames on the line (because they end up being pushed).
lastLine->SetLastContentIsComplete();
lastLine->MarkDirty();
pendingInlines = 0;
}
// Create a line for the block
LineData* line = new LineData(frame, 1,
(LINE_IS_BLOCK |
LINE_LAST_CONTENT_IS_COMPLETE));
if (nsnull == line) {
return NS_ERROR_OUT_OF_MEMORY;
}
if (nsnull == lastLine) {
mLines = line;
}
else {
lastLine->mNext = line;
}
lastLine = line;
}
else {
// Queue up the inlines for reflow later on
if (0 == pendingInlines) {
LineData* line = new LineData(frame, 0, 0);
if (nsnull == line) {
return NS_ERROR_OUT_OF_MEMORY;
}
if (nsnull == lastLine) {
mLines = line;
}
else {
lastLine->mNext = line;
}
lastLine = line;
}
lastLine->mChildCount++;
pendingInlines++;
}
}
if (0 != pendingInlines) {
// Set this to true in case we don't end up reflowing all of the
// frames on the line (because they end up being pushed).
lastLine->SetLastContentIsComplete();
lastLine->MarkDirty();
}
return NS_OK;
}
nsresult
nsCSSBlockFrame::InitialReflow(nsCSSBlockReflowState& aState)
{
@ -1629,11 +1750,17 @@ nsCSSBlockFrame::InitialReflow(nsCSSBlockReflowState& aState)
return rv;
}
// XXX CONSTRUCTION
// Temporary hack. If we haven't had Init() called then go ahead and create
// frames the old way. This is needed until tables get converted...
// Create new frames
if (nsnull == mNextInFlow) {
rv = CreateNewFrames(aState.mPresContext);
if (NS_OK != rv) {
return rv;
if (!mHasBeenInitialized) {
if (nsnull == mNextInFlow) {
rv = CreateNewFrames(aState.mPresContext);
if (NS_OK != rv) {
return rv;
}
}
}
@ -1651,12 +1778,25 @@ nsCSSBlockFrame::InitialReflow(nsCSSBlockReflowState& aState)
nsresult
nsCSSBlockFrame::FrameAppendedReflow(nsCSSBlockReflowState& aState)
{
// XXX CONSTRUCTION
#if 0
// Create new frames for the appended content. Each line that is
// impacted by this will be marked dirty.
nsresult rv = CreateNewFrames(aState.mPresContext);
if (NS_OK != rv) {
return rv;
}
#else
nsresult rv = NS_OK;
// Get the first of the newly appended frames
nsIFrame* firstAppendedFrame;
aState.reflowCommand->GetChildFrame(firstAppendedFrame);
// Add the new frames to the child list, and create new lines. Each
// impacted line will be marked dirty
AddNewFrames(firstAppendedFrame);
#endif
// Generate text-run information
rv = FindTextRuns(aState);
@ -3061,6 +3201,8 @@ nsCSSBlockFrame::DrainOverflowLines()
return drained;
}
// XXX CONSTRUCTION
#if 0
// XXX a copy of nsHTMLContainerFrame's
NS_IMETHODIMP
nsCSSBlockFrame::ContentAppended(nsIPresShell* aShell,
@ -3083,6 +3225,7 @@ nsCSSBlockFrame::ContentAppended(nsIPresShell* aShell,
return NS_OK;
}
#endif
// XXX we assume that the insertion is really an assertion and never an append
// XXX what about zero lines case

View File

@ -42,6 +42,8 @@ class RootFrame : public nsContainerFrame {
public:
RootFrame(nsIContent* aContent);
NS_IMETHOD Init(nsIPresContext& aPresContext, nsIFrame* aChildList);
NS_IMETHOD Reflow(nsIPresContext& aPresContext,
nsReflowMetrics& aDesiredSize,
const nsReflowState& aReflowState,
@ -93,6 +95,27 @@ RootFrame::RootFrame(nsIContent* aContent)
{
}
NS_IMETHODIMP
RootFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList)
{
// Construct the root content frame and set its style context
mFirstChild = new RootContentFrame(mContent, this);
mChildCount = 1;
nsIStyleContext* pseudoStyleContext =
aPresContext.ResolvePseudoStyleContextFor(nsHTMLAtoms::rootContentPseudo, this);
mFirstChild->SetStyleContext(&aPresContext, pseudoStyleContext);
NS_RELEASE(pseudoStyleContext);
// Set the geometric and content parent for each of the child frames
for (nsIFrame* frame = aChildList; nsnull != frame; frame->GetNextSibling(frame)) {
frame->SetGeometricParent(mFirstChild);
frame->SetContentParent(mFirstChild);
}
// Queue up the frames for the root content frame
return mFirstChild->Init(aPresContext, aChildList);
}
NS_IMETHODIMP
RootFrame::Reflow(nsIPresContext& aPresContext,
nsReflowMetrics& aDesiredSize,
@ -122,6 +145,8 @@ RootFrame::Reflow(nsIPresContext& aPresContext,
aReflowState.reflowCommand->GetNext(next);
NS_ASSERTION(next == mFirstChild, "unexpected next reflow command frame");
// XXX CONSTRUCTION
#if 0
} else {
// Do we have any children?
if (nsnull == mFirstChild) {
@ -133,6 +158,7 @@ RootFrame::Reflow(nsIPresContext& aPresContext,
mFirstChild->SetStyleContext(&aPresContext,style);
NS_RELEASE(style);
}
#endif
}
// Reflow our pseudo frame. It will choose whetever height its child frame
@ -353,12 +379,15 @@ RootContentFrame::Reflow(nsIPresContext& aPresContext,
} else {
nsReflowReason reflowReason = aReflowState.reason;
// XXX CONSTRUCTION
#if 0
// Do we have any children?
if (nsnull == mFirstChild) {
// No, create the first child frame
reflowReason = eReflowReason_Initial;
CreateFirstChild(&aPresContext);
}
#endif
// Resize our frames
if (nsnull != mFirstChild) {

View File

@ -282,6 +282,40 @@ nsresult
NS_NewWBRFrame(nsIContent* aContent, nsIFrame* aParentFrame,
nsIFrame*& aResult);
extern nsresult
NS_NewCSSInlineFrame(nsIFrame** aInstancePtrResult,
nsIContent* aContent,
nsIFrame* aParent);
extern nsresult
NS_NewCSSBlockFrame(nsIFrame** aInstancePtrResult,
nsIContent* aContent,
nsIFrame* aParent);
extern nsresult
NS_NewInputButtonFrame(nsIContent* aContent, nsIFrame* aParentFrame,
nsIFrame*& aResult);
extern nsresult
NS_NewInputCheckboxFrame(nsIContent* aContent, nsIFrame* aParentFrame,
nsIFrame*& aResult);
extern nsresult
NS_NewInputFileFrame(nsIContent* aContent, nsIFrame* aParentFrame,
nsIFrame*& aResult);
extern nsresult
NS_NewInputTextFrame(nsIContent* aContent, nsIFrame* aParentFrame,
nsIFrame*& aResult);
extern nsresult
NS_NewInputRadioFrame(nsIContent* aContent, nsIFrame* aParentFrame,
nsIFrame*& aResult);
extern nsresult
NS_NewHTMLSelectFrame(nsIContent* aContent, nsIFrame* aParentFrame,
nsIFrame*& aResult);
// Everything below this line is obsolete...
//----------------------------------------------------------------------
// XXX naming consistency puhleeze!

View File

@ -151,6 +151,12 @@ NS_IMETHODIMP nsHTMLReflowCommand::GetTarget(nsIFrame*& aTargetFrame) const
return NS_OK;
}
NS_IMETHODIMP nsHTMLReflowCommand::SetTarget(nsIFrame* aTargetFrame)
{
mTargetFrame = aTargetFrame;
return NS_OK;
}
NS_IMETHODIMP nsHTMLReflowCommand::GetType(ReflowType& aReflowType) const
{
aReflowType = mType;

View File

@ -46,6 +46,7 @@ public:
const nsSize& aMaxSize);
NS_IMETHOD GetNext(nsIFrame*& aNextFrame);
NS_IMETHOD GetTarget(nsIFrame*& aTargetFrame) const;
NS_IMETHOD SetTarget(nsIFrame* aTargetFrame);
NS_IMETHOD GetType(ReflowType& aReflowType) const;
NS_IMETHOD GetChildFrame(nsIFrame*& aChildFrame) const;

View File

@ -260,10 +260,29 @@ typedef PRBool nsDidReflowStatus;
*
* Frames are NOT reference counted. Use the DeleteFrame() member function
* to delete a frame
*
* XXX This should probably be changed so it's consistent with the way nsIView
* (which is also not reference counted) is defined...
*/
class nsIFrame : private nsISupports
{
public:
/**
* Initialize the frame passing it its child frame list.
*
* This member function is called for all frames just after the frame is
* constructed.
*
* You should reflow the frames when you get your 'initial' reflow
* notification.
*
* XXX Should we also pass in the child count?
*
* @param aChildList list of child frames. May be NULL
* @see #Reflow()
*/
NS_IMETHOD Init(nsIPresContext& aPresContext, nsIFrame* aChildList) = 0;
/**
* QueryInterface() defined in nsISupports. This is the only member
* function of nsISupports that is public.
@ -466,9 +485,12 @@ public:
* FrameAppended incremental reflow command. You then handle the incremental
* reflow command by creating frames for the appended content.
*/
// XXX CONSTRUCTION
#if 0
NS_IMETHOD ContentAppended(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aContainer) = 0;
#endif
/**
* This call is invoked when content is inserted in the content

View File

@ -175,6 +175,8 @@ nsPlaceholderFrame::Paint(nsIPresContext& aPresContext,
return NS_OK;
}
// XXX CONSTRUCTION
#if 0
NS_IMETHODIMP nsPlaceholderFrame::ContentAppended(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aContainer)
@ -188,6 +190,7 @@ NS_IMETHODIMP nsPlaceholderFrame::ContentAppended(nsIPresShell* aShell,
return NS_OK;
}
#endif
NS_IMETHODIMP nsPlaceholderFrame::ContentInserted(nsIPresShell* aShell,
nsIPresContext* aPresContext,

View File

@ -47,9 +47,12 @@ public:
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect);
// XXX CONSTRUCTION
#if 0
NS_IMETHOD ContentAppended(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aContainer);
#endif
NS_IMETHOD ContentInserted(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aContainer,

View File

@ -95,6 +95,8 @@ NS_IMETHODIMP nsAbsoluteFrame::Reflow(nsIPresContext& aPresContext,
return nsFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
}
// XXX CONSTRUCTION
#if 0
NS_IMETHODIMP nsAbsoluteFrame::ContentAppended(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aContainer)
@ -108,6 +110,7 @@ NS_IMETHODIMP nsAbsoluteFrame::ContentAppended(nsIPresShell* aShell,
return NS_OK;
}
#endif
NS_IMETHODIMP nsAbsoluteFrame::ContentInserted(nsIPresShell* aShell,
nsIPresContext* aPresContext,

View File

@ -43,9 +43,12 @@ public:
const nsReflowState& aReflowState,
nsReflowStatus& aStatus);
// XXX CONSTRUCTION
#if 0
NS_IMETHOD ContentAppended(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aContainer);
#endif
NS_IMETHOD ContentInserted(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aContainer,

View File

@ -86,6 +86,27 @@ nsBodyFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
/////////////////////////////////////////////////////////////////////////////
// nsIFrame
NS_IMETHODIMP
nsBodyFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList)
{
// Create a block frame and set its style context
NS_NewCSSBlockFrame(&mFirstChild, mContent, this);
mChildCount = 1;
nsIStyleContext* pseudoStyleContext =
aPresContext.ResolvePseudoStyleContextFor(nsHTMLAtoms::columnPseudo, this);
mFirstChild->SetStyleContext(&aPresContext, pseudoStyleContext);
NS_RELEASE(pseudoStyleContext);
// Set the geometric and content parent for each of the child frames
for (nsIFrame* frame = aChildList; nsnull != frame; frame->GetNextSibling(frame)) {
frame->SetGeometricParent(mFirstChild);
frame->SetContentParent(mFirstChild);
}
// Queue up the frames for the block frame
return mFirstChild->Init(aPresContext, aChildList);
}
NS_METHOD nsBodyFrame::Reflow(nsIPresContext& aPresContext,
nsReflowMetrics& aDesiredSize,
const nsReflowState& aReflowState,
@ -98,15 +119,20 @@ NS_METHOD nsBodyFrame::Reflow(nsIPresContext& aPresContext,
aStatus = NS_FRAME_COMPLETE; // initialize out parameter
// XXX CONSTRUCTION
// Do we have any children?
if (nsnull == mFirstChild) {
// No, create a pseudo block frame
// No, create a pseudo block frame.
// XXX Temp hack until all frame construction work is complete. This is needed
// in case the Init() member function wasn't called...
NS_ASSERTION(eReflowReason_Initial == aReflowState.reason, "bad reason");
CreateColumnFrame(&aPresContext);
}
#if 0
else {
NS_ASSERTION(eReflowReason_Initial != aReflowState.reason, "bad reason");
}
#endif
nsIFrame* reflowCmdTarget;
nsIReflowCommand::ReflowType reflowCmdType;
@ -118,6 +144,27 @@ NS_METHOD nsBodyFrame::Reflow(nsIPresContext& aPresContext,
aReflowState.reflowCommand->GetTarget(reflowCmdTarget);
aReflowState.reflowCommand->GetType(reflowCmdType);
// XXX CONSTRUCTION
if (this == reflowCmdTarget) {
NS_ASSERTION(nsIReflowCommand::FrameAppended == reflowCmdType,
"unexpected reflow command");
// Append reflow commands will be targeted at us. Reset the target and
// send the reflow command.
// XXX Would it be better to have the frame generate the reflow command
// that way it could correctly set the target?
reflowCmdTarget = mFirstChild;
aReflowState.reflowCommand->SetTarget(mFirstChild);
// Reset the geometric and content parent for each of the child frames
nsIFrame* childList;
aReflowState.reflowCommand->GetChildFrame(childList);
for (nsIFrame* frame = childList; nsnull != frame; frame->GetNextSibling(frame)) {
frame->SetGeometricParent(mFirstChild);
frame->SetContentParent(mFirstChild);
}
}
// The reflow command should never be target for us
#ifdef NS_DEBUG
NS_ASSERTION(this != reflowCmdTarget, "bad reflow command target");
@ -131,7 +178,7 @@ NS_METHOD nsBodyFrame::Reflow(nsIPresContext& aPresContext,
// positioned elements...
nsIFrame* nextFrame;
aReflowState.reflowCommand->GetNext(nextFrame);
if (mFirstChild != nextFrame) {
if ((nsnull != nextFrame) && (mFirstChild != nextFrame)) {
NS_ASSERTION(this != nextFrame, "huh?");
NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,
("nsBodyFrame::Reflow: reflowing frame=%p",
@ -296,6 +343,8 @@ NS_METHOD nsBodyFrame::Reflow(nsIPresContext& aPresContext,
return NS_OK;
}
// XXX CONSTRUCTION
#if 0
NS_METHOD nsBodyFrame::ContentAppended(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aContainer)
@ -306,6 +355,7 @@ NS_METHOD nsBodyFrame::ContentAppended(nsIPresShell* aShell,
// reflow command
return mFirstChild->ContentAppended(aShell, aPresContext, aContainer);
}
#endif
NS_METHOD nsBodyFrame::ContentInserted(nsIPresShell* aShell,
nsIPresContext* aPresContext,
@ -1045,3 +1095,4 @@ NS_METHOD nsBodyFrame::VerifyTree() const
return NS_OK;
}

View File

@ -38,14 +38,19 @@ public:
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
NS_IMETHOD Init(nsIPresContext& aPresContext, nsIFrame* aChildList);
NS_IMETHOD Reflow(nsIPresContext& aPresContext,
nsReflowMetrics& aDesiredSize,
const nsReflowState& aReflowState,
nsReflowStatus& aStatus);
// XXX CONSTRUCTION
#if 0
NS_IMETHOD ContentAppended(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aContainer);
#endif
NS_IMETHOD ContentInserted(nsIPresShell* aShell,
nsIPresContext* aPresContext,

View File

@ -107,6 +107,7 @@ nsIAtom* nsHTMLAtoms::id;
nsIAtom* nsHTMLAtoms::iframe;
nsIAtom* nsHTMLAtoms::img;
nsIAtom* nsHTMLAtoms::index;
nsIAtom* nsHTMLAtoms::input;
nsIAtom* nsHTMLAtoms::ismap;
nsIAtom* nsHTMLAtoms::label;
nsIAtom* nsHTMLAtoms::lang;
@ -171,6 +172,7 @@ nsIAtom* nsHTMLAtoms::rules;
nsIAtom* nsHTMLAtoms::scheme;
nsIAtom* nsHTMLAtoms::scope;
nsIAtom* nsHTMLAtoms::scrolling;
nsIAtom* nsHTMLAtoms::select;
nsIAtom* nsHTMLAtoms::selected;
nsIAtom* nsHTMLAtoms::selectedindex;
nsIAtom* nsHTMLAtoms::shape;
@ -189,6 +191,7 @@ nsIAtom* nsHTMLAtoms::tabstop;
nsIAtom* nsHTMLAtoms::target;
nsIAtom* nsHTMLAtoms::td;
nsIAtom* nsHTMLAtoms::text;
nsIAtom* nsHTMLAtoms::textarea;
nsIAtom* nsHTMLAtoms::th;
nsIAtom* nsHTMLAtoms::title;
nsIAtom* nsHTMLAtoms::top;
@ -304,6 +307,7 @@ void nsHTMLAtoms::AddrefAtoms()
iframe = NS_NewAtom("IFRAME");
img = NS_NewAtom("IMG");
index = NS_NewAtom("INDEX");
input = NS_NewAtom("INPUT");
ismap = NS_NewAtom("ISMAP");
label = NS_NewAtom("LABEL");
lang = NS_NewAtom("LANG");
@ -367,6 +371,7 @@ void nsHTMLAtoms::AddrefAtoms()
scheme = NS_NewAtom("SCHEME");
scope = NS_NewAtom("SCOPE");
scrolling = NS_NewAtom("SCROLLING");
select = NS_NewAtom("SELECT");
selected = NS_NewAtom("SELECTED");
selectedindex = NS_NewAtom("SELECTEDINDEX");
shape = NS_NewAtom("SHAPE");
@ -385,6 +390,7 @@ void nsHTMLAtoms::AddrefAtoms()
target = NS_NewAtom("TARGET");
td = NS_NewAtom("TD");
text = NS_NewAtom("TEXT");
textarea = NS_NewAtom("TEXTAREA");
th = NS_NewAtom("TH");
title = NS_NewAtom("TITLE");
top = NS_NewAtom("TOP");
@ -493,6 +499,8 @@ void nsHTMLAtoms::ReleaseAtoms()
NS_RELEASE(id);
NS_RELEASE(iframe);
NS_RELEASE(img);
NS_RELEASE(index);
NS_RELEASE(input);
NS_RELEASE(ismap);
NS_RELEASE(label);
NS_RELEASE(lang);
@ -555,6 +563,7 @@ void nsHTMLAtoms::ReleaseAtoms()
NS_RELEASE(scheme);
NS_RELEASE(scope);
NS_RELEASE(scrolling);
NS_RELEASE(select);
NS_RELEASE(selected);
NS_RELEASE(selectedindex);
NS_RELEASE(shape);
@ -572,6 +581,7 @@ void nsHTMLAtoms::ReleaseAtoms()
NS_RELEASE(target);
NS_RELEASE(td);
NS_RELEASE(text);
NS_RELEASE(textarea);
NS_RELEASE(th);
NS_RELEASE(top);
NS_RELEASE(toppadding);

View File

@ -134,6 +134,7 @@ public:
static nsIAtom* iframe;
static nsIAtom* img;
static nsIAtom* index;
static nsIAtom* input;
static nsIAtom* ismap;
static nsIAtom* label;
@ -205,6 +206,7 @@ public:
static nsIAtom* scheme;
static nsIAtom* scope;
static nsIAtom* scrolling;
static nsIAtom* select;
static nsIAtom* selected;
static nsIAtom* selectedindex;
static nsIAtom* shape;
@ -224,6 +226,7 @@ public:
static nsIAtom* target;
static nsIAtom* td;
static nsIAtom* text;
static nsIAtom* textarea;
static nsIAtom* th;
static nsIAtom* title;
static nsIAtom* top;

View File

@ -203,7 +203,7 @@ nsHTMLContainer::AppendChildTo(nsIContent* aKid, PRBool aNotify)
if (nsnull != doc) {
aKid->SetDocument(doc);
if (aNotify) {
doc->ContentAppended(this);
doc->ContentAppended(this, mChildren.Count() - 1);
}
}
}

View File

@ -42,6 +42,8 @@ class RootFrame : public nsContainerFrame {
public:
RootFrame(nsIContent* aContent);
NS_IMETHOD Init(nsIPresContext& aPresContext, nsIFrame* aChildList);
NS_IMETHOD Reflow(nsIPresContext& aPresContext,
nsReflowMetrics& aDesiredSize,
const nsReflowState& aReflowState,
@ -93,6 +95,27 @@ RootFrame::RootFrame(nsIContent* aContent)
{
}
NS_IMETHODIMP
RootFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList)
{
// Construct the root content frame and set its style context
mFirstChild = new RootContentFrame(mContent, this);
mChildCount = 1;
nsIStyleContext* pseudoStyleContext =
aPresContext.ResolvePseudoStyleContextFor(nsHTMLAtoms::rootContentPseudo, this);
mFirstChild->SetStyleContext(&aPresContext, pseudoStyleContext);
NS_RELEASE(pseudoStyleContext);
// Set the geometric and content parent for each of the child frames
for (nsIFrame* frame = aChildList; nsnull != frame; frame->GetNextSibling(frame)) {
frame->SetGeometricParent(mFirstChild);
frame->SetContentParent(mFirstChild);
}
// Queue up the frames for the root content frame
return mFirstChild->Init(aPresContext, aChildList);
}
NS_IMETHODIMP
RootFrame::Reflow(nsIPresContext& aPresContext,
nsReflowMetrics& aDesiredSize,
@ -122,6 +145,8 @@ RootFrame::Reflow(nsIPresContext& aPresContext,
aReflowState.reflowCommand->GetNext(next);
NS_ASSERTION(next == mFirstChild, "unexpected next reflow command frame");
// XXX CONSTRUCTION
#if 0
} else {
// Do we have any children?
if (nsnull == mFirstChild) {
@ -133,6 +158,7 @@ RootFrame::Reflow(nsIPresContext& aPresContext,
mFirstChild->SetStyleContext(&aPresContext,style);
NS_RELEASE(style);
}
#endif
}
// Reflow our pseudo frame. It will choose whetever height its child frame
@ -353,12 +379,15 @@ RootContentFrame::Reflow(nsIPresContext& aPresContext,
} else {
nsReflowReason reflowReason = aReflowState.reason;
// XXX CONSTRUCTION
#if 0
// Do we have any children?
if (nsnull == mFirstChild) {
// No, create the first child frame
reflowReason = eReflowReason_Initial;
CreateFirstChild(&aPresContext);
}
#endif
// Resize our frames
if (nsnull != mFirstChild) {

View File

@ -282,6 +282,40 @@ nsresult
NS_NewWBRFrame(nsIContent* aContent, nsIFrame* aParentFrame,
nsIFrame*& aResult);
extern nsresult
NS_NewCSSInlineFrame(nsIFrame** aInstancePtrResult,
nsIContent* aContent,
nsIFrame* aParent);
extern nsresult
NS_NewCSSBlockFrame(nsIFrame** aInstancePtrResult,
nsIContent* aContent,
nsIFrame* aParent);
extern nsresult
NS_NewInputButtonFrame(nsIContent* aContent, nsIFrame* aParentFrame,
nsIFrame*& aResult);
extern nsresult
NS_NewInputCheckboxFrame(nsIContent* aContent, nsIFrame* aParentFrame,
nsIFrame*& aResult);
extern nsresult
NS_NewInputFileFrame(nsIContent* aContent, nsIFrame* aParentFrame,
nsIFrame*& aResult);
extern nsresult
NS_NewInputTextFrame(nsIContent* aContent, nsIFrame* aParentFrame,
nsIFrame*& aResult);
extern nsresult
NS_NewInputRadioFrame(nsIContent* aContent, nsIFrame* aParentFrame,
nsIFrame*& aResult);
extern nsresult
NS_NewHTMLSelectFrame(nsIContent* aContent, nsIFrame* aParentFrame,
nsIFrame*& aResult);
// Everything below this line is obsolete...
//----------------------------------------------------------------------
// XXX naming consistency puhleeze!

View File

@ -151,6 +151,12 @@ NS_IMETHODIMP nsHTMLReflowCommand::GetTarget(nsIFrame*& aTargetFrame) const
return NS_OK;
}
NS_IMETHODIMP nsHTMLReflowCommand::SetTarget(nsIFrame* aTargetFrame)
{
mTargetFrame = aTargetFrame;
return NS_OK;
}
NS_IMETHODIMP nsHTMLReflowCommand::GetType(ReflowType& aReflowType) const
{
aReflowType = mType;

View File

@ -46,6 +46,7 @@ public:
const nsSize& aMaxSize);
NS_IMETHOD GetNext(nsIFrame*& aNextFrame);
NS_IMETHOD GetTarget(nsIFrame*& aTargetFrame) const;
NS_IMETHOD SetTarget(nsIFrame* aTargetFrame);
NS_IMETHOD GetType(ReflowType& aReflowType) const;
NS_IMETHOD GetChildFrame(nsIFrame*& aChildFrame) const;

View File

@ -175,6 +175,8 @@ nsPlaceholderFrame::Paint(nsIPresContext& aPresContext,
return NS_OK;
}
// XXX CONSTRUCTION
#if 0
NS_IMETHODIMP nsPlaceholderFrame::ContentAppended(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aContainer)
@ -188,6 +190,7 @@ NS_IMETHODIMP nsPlaceholderFrame::ContentAppended(nsIPresShell* aShell,
return NS_OK;
}
#endif
NS_IMETHODIMP nsPlaceholderFrame::ContentInserted(nsIPresShell* aShell,
nsIPresContext* aPresContext,

View File

@ -47,9 +47,12 @@ public:
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect);
// XXX CONSTRUCTION
#if 0
NS_IMETHOD ContentAppended(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aContainer);
#endif
NS_IMETHOD ContentInserted(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aContainer,

View File

@ -3266,7 +3266,7 @@ nsGenericHTMLContainerElement::AppendChildTo(nsIContent* aKid, PRBool aNotify)
if (nsnull != doc) {
aKid->SetDocument(doc);
if (aNotify) {
doc->ContentAppended(mContent);
doc->ContentAppended(mContent, mChildren->Count() - 1);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -170,6 +170,7 @@ public:
nsIHTMLContent* mRoot;
nsIHTMLContent* mBody;
PRInt32 mBodyChildCount;
nsIHTMLContent* mFrameset;
nsIHTMLContent* mHead;
nsString* mTitle;
@ -1378,7 +1379,8 @@ HTMLContentSink::DidBuildModel(PRInt32 aQualityLevel)
("HTMLContentSink::DidBuildModel: layout final content"));
// Reflow the last batch of content
mDocument->ContentAppended(mBody);
mDocument->ContentAppended(mBody, mBodyChildCount);
mBody->ChildCount(mBodyChildCount);
ScrollToRef();
mDocument->EndLoad();
@ -1391,7 +1393,8 @@ HTMLContentSink::WillInterrupt()
SINK_TRACE(SINK_TRACE_CALLS,
("HTMLContentSink::WillInterrupt: this=%p", this));
if (mDirty && !mInMonolithicContainer) {
mDocument->ContentAppended(mBody);
mDocument->ContentAppended(mBody, mBodyChildCount);
mBody->ChildCount(mBodyChildCount);
mDirty = PR_FALSE;
}
return NS_OK;
@ -1571,6 +1574,7 @@ HTMLContentSink::OpenBody(const nsIParserNode& aNode)
return rv;
}
mBody = mCurrentContext->mStack[mCurrentContext->mStackPos - 1].mContent;
mBodyChildCount = 0;
NS_ADDREF(mBody);
StartLayout();
@ -1592,7 +1596,8 @@ HTMLContentSink::CloseBody(const nsIParserNode& aNode)
if (didFlush) {
// Trigger a reflow for the flushed text
mDocument->ContentAppended(mBody);
mDocument->ContentAppended(mBody, mBodyChildCount);
mBody->ChildCount(mBodyChildCount);
}
return NS_OK;
@ -1815,7 +1820,7 @@ HTMLContentSink::StartLayout()
nsIPresContext* cx = shell->GetPresContext();
nsRect r;
cx->GetVisibleArea(r);
shell->ResizeReflow(r.width, r.height);
shell->InitialReflow(r.width, r.height);
NS_RELEASE(cx);
// Now trigger a refresh

View File

@ -351,6 +351,18 @@ nsInputButton::GetAttributeMappingFunction(nsMapAttributesFunc& aMapFunc) const
//----------------------------------------------------------------------
// nsInputButtonFrame Implementation
nsresult
NS_NewInputButtonFrame(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame*& aResult)
{
aResult = new nsInputButtonFrame(aContent, aParent);
if (nsnull == aResult) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
nsInputButtonFrame::nsInputButtonFrame(nsIContent* aContent,
nsIFrame* aParentFrame)
: nsInputFrame(aContent, aParentFrame)

View File

@ -53,6 +53,18 @@ protected:
nsSize& aDesiredWidgetSize);
};
nsresult
NS_NewInputCheckboxFrame(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame*& aResult)
{
aResult = new nsInputCheckboxFrame(aContent, aParent);
if (nsnull == aResult) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
nsInputCheckboxFrame::nsInputCheckboxFrame(nsIContent* aContent, nsIFrame* aParentFrame)
: nsInputFrame(aContent, aParentFrame)
{

View File

@ -36,6 +36,18 @@
PRInt32 nsInputFileFrame::gSpacing = 40;
nsString* nsInputFile::gFILE_TYPE = new nsString("file");
nsresult
NS_NewInputFileFrame(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame*& aResult)
{
aResult = new nsInputFileFrame(aContent, aParent);
if (nsnull == aResult) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
nsInputFileFrame::nsInputFileFrame(nsIContent* aContent, nsIFrame* aParentFrame)
: nsHTMLContainerFrame(aContent, aParentFrame)
{

View File

@ -57,6 +57,18 @@ protected:
nsSize& aDesiredWidgetSize);
};
nsresult
NS_NewInputRadioFrame(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame*& aResult)
{
aResult = new nsInputRadioFrame(aContent, aParent);
if (nsnull == aResult) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
nsInputRadioFrame::nsInputRadioFrame(nsIContent* aContent, nsIFrame* aParentFrame)
: nsInputFrame(aContent, aParentFrame)
{

View File

@ -73,6 +73,18 @@ protected:
nsSize& aDesiredWidgetSize);
};
nsresult
NS_NewInputTextFrame(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame*& aResult)
{
aResult = new nsInputTextFrame(aContent, aParent);
if (nsnull == aResult) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
nsInputTextFrame::nsInputTextFrame(nsIContent* aContent,
nsIFrame* aParentFrame)
: nsInputFrame(aContent, aParentFrame)

View File

@ -163,6 +163,17 @@ protected:
nsString* mContent;
};
nsresult
NS_NewHTMLSelectFrame(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame*& aResult)
{
aResult = new nsSelectFrame(aContent, aParent);
if (nsnull == aResult) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
nsSelectFrame::nsSelectFrame(nsIContent* aContent,
nsIFrame* aParentFrame)

View File

@ -35,10 +35,17 @@
#include "nsTableColFrame.h"
#include "nsTableFrame.h"
#include "nsHTMLIIDs.h"
#include "nsIStyleFrameConstruction.h"
#include "nsHTMLParts.h"
#include "nsIPresShell.h"
#include "nsIViewManager.h"
#include "nsStyleConsts.h"
#include "nsTableOuterFrame.h"
static NS_DEFINE_IID(kIHTMLStyleSheetIID, NS_IHTML_STYLE_SHEET_IID);
static NS_DEFINE_IID(kIStyleSheetIID, NS_ISTYLE_SHEET_IID);
static NS_DEFINE_IID(kIStyleRuleIID, NS_ISTYLE_RULE_IID);
static NS_DEFINE_IID(kIStyleFrameConstructionIID, NS_ISTYLE_FRAME_CONSTRUCTION_IID);
class HTMLAnchorRule : public nsIStyleRule {
@ -173,7 +180,8 @@ nsHashKey* AttributeKey::Clone(void) const
// -----------------------------------------------------------
class HTMLStyleSheetImpl : public nsIHTMLStyleSheet {
class HTMLStyleSheetImpl : public nsIHTMLStyleSheet,
public nsIStyleFrameConstruction {
public:
void* operator new(size_t size);
void* operator new(size_t size, nsIArena* aArena);
@ -217,6 +225,15 @@ public:
NS_IMETHOD UnsetAttributeFor(nsIAtom* aAttribute, nsIHTMLContent* aContent,
nsIHTMLAttributes*& aAttributes);
NS_IMETHOD ConstructFrame(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParentFrame,
nsIFrame*& aFrameSubTree);
NS_IMETHOD ContentAppended(nsIPresContext* aPresContext,
nsIDocument* aDocument,
nsIContent* aContainer,
PRInt32 aNewIndexInContainer);
// XXX style rule enumerations
@ -239,6 +256,14 @@ protected:
PRInt32 aAttrCount,
nsIHTMLAttributes*& aAttributes);
nsresult ProcessChildren(nsIPresContext* aPresContext,
nsIFrame* aFrame,
nsIContent* aContent);
nsresult CreateInputFrame(nsIContent* aContent,
nsIFrame* aParentFrame,
nsIFrame*& aFrame);
protected:
PRUint32 mInHeap : 1;
PRUint32 mRefCnt : 31;
@ -330,8 +355,13 @@ nsresult HTMLStyleSheetImpl::QueryInterface(const nsIID& aIID,
AddRef();
return NS_OK;
}
if (aIID.Equals(kIStyleFrameConstructionIID)) {
*aInstancePtrResult = (void*) ((nsIStyleFrameConstruction*)this);
AddRef();
return NS_OK;
}
if (aIID.Equals(kISupportsIID)) {
*aInstancePtrResult = (void*) ((nsISupports*)this);
*aInstancePtrResult = (void*) this;
AddRef();
return NS_OK;
}
@ -816,6 +846,316 @@ NS_IMETHODIMP HTMLStyleSheetImpl::UnsetAttributeFor(nsIAtom* aAttribute,
}
nsresult HTMLStyleSheetImpl::ProcessChildren(nsIPresContext* aPresContext,
nsIFrame* aFrame,
nsIContent* aContent)
{
nsIFrame* childList = nsnull;
nsIFrame* lastChildFrame = nsnull;
PRInt32 count;
aContent->ChildCount(count);
for (PRInt32 i = 0; i < count; i++) {
nsIContent* childContent;
aContent->ChildAt(i, childContent);
if (nsnull != childContent) {
nsIFrame* childFrame;
// Construct a child frame
ConstructFrame(aPresContext, childContent, aFrame, childFrame);
if (nsnull != childFrame) {
// Link the frame into the child list
if (nsnull == lastChildFrame) {
childList = childFrame;
} else {
lastChildFrame->SetNextSibling(childFrame);
}
lastChildFrame = childFrame;
}
NS_RELEASE(childContent);
}
}
// Initialize the frame giving it its child list.
// XXX Should we call Init(), or just return the child list and let the
// caller call Init()?
aFrame->Init(*aPresContext, childList);
return NS_OK;
}
nsresult
HTMLStyleSheetImpl::CreateInputFrame(nsIContent* aContent,
nsIFrame* aParentFrame,
nsIFrame*& aFrame)
{
nsresult rv;
// Figure out which type of input frame to create
nsAutoString val;
if (NS_OK == aContent->GetAttribute(nsAutoString("type"), val)) {
if (val.EqualsIgnoreCase("submit")) {
rv = NS_NewInputButtonFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("reset")) {
rv = NS_NewInputButtonFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("button")) {
rv = NS_NewInputButtonFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("checkbox")) {
rv = NS_NewInputCheckboxFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("file")) {
rv = NS_NewInputFileFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("hidden")) {
rv = NS_NewInputButtonFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("image")) {
rv = NS_NewInputButtonFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("password")) {
rv = NS_NewInputTextFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("radio")) {
rv = NS_NewInputRadioFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("text")) {
rv = NS_NewInputTextFrame(aContent, aParentFrame, aFrame);
}
else {
rv = NS_NewInputTextFrame(aContent, aParentFrame, aFrame);
}
} else {
rv = NS_NewInputTextFrame(aContent, aParentFrame, aFrame);
}
return rv;
}
NS_IMETHODIMP HTMLStyleSheetImpl::ConstructFrame(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParentFrame,
nsIFrame*& aFrameSubTree)
{
// Get the tag
nsIAtom* tag;
aContent->GetTag(tag);
aFrameSubTree = nsnull;
// Resolve the style context.
// XXX Cheesy hack for text
nsIStyleContext* styleContext;
if (nsnull == tag) {
styleContext = aPresContext->ResolvePseudoStyleContextFor(nsHTMLAtoms::text, aParentFrame);
} else {
styleContext = aPresContext->ResolveStyleContextFor(aContent, aParentFrame);
}
// Create a frame.
if (nsnull == aParentFrame) {
// This should only be the case for the root content object.
// XXX Add assertion...
nsIFrame* rootFrame;
// Create the root frame and set its style context
NS_NewHTMLFrame(aContent, nsnull, rootFrame);
rootFrame->SetStyleContext(aPresContext, styleContext);
// Bind root frame to root view (and root window)
nsIPresShell* presShell = aPresContext->GetShell();
nsIViewManager* viewManager = presShell->GetViewManager();
nsIView* rootView;
NS_RELEASE(presShell);
viewManager->GetRootView(rootView);
rootFrame->SetView(rootView);
NS_RELEASE(viewManager);
// Process the children
ProcessChildren(aPresContext, rootFrame, aContent);
// Return the frame sub-tree
aFrameSubTree = rootFrame;
} else {
nsIFrame* frame = nsnull;
nsresult rv = NS_OK;
// Handle specific frame types
if (nsnull == tag) {
rv = NS_NewTextFrame(aContent, aParentFrame, frame);
}
else if (nsHTMLAtoms::applet == tag) {
rv = NS_NewObjectFrame(aContent, aParentFrame, frame);
}
else if (nsHTMLAtoms::body == tag) {
rv = NS_NewBodyFrame(aContent, aParentFrame, frame);
// Process the children
ProcessChildren(aPresContext, frame, aContent);
}
else if (nsHTMLAtoms::frameset == tag) {
rv = NS_NewHTMLFramesetFrame(aContent, aParentFrame, frame);
}
else if (nsHTMLAtoms::br == tag) {
rv = NS_NewBRFrame(aContent, aParentFrame, frame);
}
else if (nsHTMLAtoms::embed == tag) {
rv = NS_NewObjectFrame(aContent, aParentFrame, frame);
}
else if (nsHTMLAtoms::hr == tag) {
rv = NS_NewHRFrame(aContent, aParentFrame, frame);
}
else if (nsHTMLAtoms::img == tag) {
rv = NS_NewImageFrame(aContent, aParentFrame, frame);
}
else if (nsHTMLAtoms::object == tag) {
rv = NS_NewObjectFrame(aContent, aParentFrame, frame);
}
else if (nsHTMLAtoms::spacer == tag) {
rv = NS_NewSpacerFrame(aContent, aParentFrame, frame);
}
else if (nsHTMLAtoms::wbr == tag) {
rv = NS_NewWBRFrame(aContent, aParentFrame, frame);
}
else if (nsHTMLAtoms::table == tag) {
rv = nsTableOuterFrame::NewFrame(&frame, aContent, aParentFrame);
}
else if (nsHTMLAtoms::input == tag) {
rv = CreateInputFrame(aContent, aParentFrame, frame);
}
else if (nsHTMLAtoms::textarea == tag) {
rv = NS_NewInputTextFrame(aContent, aParentFrame, frame);
}
else if (nsHTMLAtoms::select == tag) {
rv = NS_NewHTMLSelectFrame(aContent, aParentFrame, frame);
}
if (NS_OK != rv) {
NS_RELEASE(styleContext);
NS_IF_RELEASE(tag);
return rv;
}
// XXX add code in here to force the odd ones into the empty frame?
// AREA, HEAD, META, MAP, etc...
if (nsnull == frame) {
// When there is no explicit frame to create, assume it's a
// container and let style dictate the rest.
const nsStyleDisplay* styleDisplay = (const nsStyleDisplay*)
styleContext->GetStyleData(eStyleStruct_Display);
// Use style to choose what kind of frame to create
nsresult rv;
switch (styleDisplay->mDisplay) {
case NS_STYLE_DISPLAY_BLOCK:
case NS_STYLE_DISPLAY_LIST_ITEM:
rv = NS_NewCSSBlockFrame(&frame, aContent, aParentFrame);
ProcessChildren(aPresContext, frame, aContent);
break;
case NS_STYLE_DISPLAY_INLINE:
rv = NS_NewCSSInlineFrame(&frame, aContent, aParentFrame);
break;
default:
// XXX Don't create a placeholder frame for content that's not
// displayed...
#if 0
// Create an empty frame for holding content that is not being
// reflowed.
rv = nsFrame::NewFrame(&frame, aContent, aParentFrame);
#endif
break;
}
if (NS_OK != rv) {
NS_RELEASE(styleContext);
NS_IF_RELEASE(tag);
return rv;
}
}
if (nsnull != frame) {
frame->SetStyleContext(aPresContext, styleContext);
}
aFrameSubTree = frame;
}
NS_RELEASE(styleContext);
NS_IF_RELEASE(tag);
return NS_OK;
}
NS_IMETHODIMP HTMLStyleSheetImpl::ContentAppended(nsIPresContext* aPresContext,
nsIDocument* aDocument,
nsIContent* aContainer,
PRInt32 aNewIndexInContainer)
{
nsIPresShell* shell = aPresContext->GetShell();
nsIContent* parentContainer = aContainer;
while (nsnull != parentContainer) {
nsIFrame* parentFrame = shell->FindFrameWithContent(parentContainer);
if (nsnull != parentFrame) {
// Get the parent frame's last-in-flow
nsIFrame* nextInFlow = parentFrame;
while (nsnull != nextInFlow) {
parentFrame->GetNextInFlow(nextInFlow);
if (nsnull != nextInFlow) {
parentFrame = nextInFlow;
}
}
// Create some new frames
PRInt32 count;
nsIFrame* lastChildFrame = nsnull;
nsIFrame* firstAppendedFrame = nsnull;
aContainer->ChildCount(count);
for (PRInt32 i = aNewIndexInContainer; i < count; i++) {
nsIContent* child;
nsIFrame* frame;
aContainer->ChildAt(i, child);
ConstructFrame(aPresContext, child, parentFrame, frame);
// Link the frame into the child frame list
if (nsnull == lastChildFrame) {
firstAppendedFrame = frame;
} else {
lastChildFrame->SetNextSibling(frame);
}
// XXX We should probably mark the frame as being dirty: that way the
// parent frame can easily identify the newly added frames. Either that
// or pass along in count in which case they must be contiguus...
lastChildFrame = frame;
}
// Notify the parent frame with a reflow command, passing it the list of
// new frames.
nsIReflowCommand* reflowCmd;
nsresult result;
result = NS_NewHTMLReflowCommand(&reflowCmd, parentFrame,
nsIReflowCommand::FrameAppended,
firstAppendedFrame);
if (NS_SUCCEEDED(result)) {
shell->AppendReflowCommand(reflowCmd);
}
break;
}
parentContainer->GetParent(parentContainer);
}
NS_RELEASE(shell);
return NS_OK;
}
void HTMLStyleSheetImpl::List(FILE* out, PRInt32 aIndent) const
{

View File

@ -35,10 +35,17 @@
#include "nsTableColFrame.h"
#include "nsTableFrame.h"
#include "nsHTMLIIDs.h"
#include "nsIStyleFrameConstruction.h"
#include "nsHTMLParts.h"
#include "nsIPresShell.h"
#include "nsIViewManager.h"
#include "nsStyleConsts.h"
#include "nsTableOuterFrame.h"
static NS_DEFINE_IID(kIHTMLStyleSheetIID, NS_IHTML_STYLE_SHEET_IID);
static NS_DEFINE_IID(kIStyleSheetIID, NS_ISTYLE_SHEET_IID);
static NS_DEFINE_IID(kIStyleRuleIID, NS_ISTYLE_RULE_IID);
static NS_DEFINE_IID(kIStyleFrameConstructionIID, NS_ISTYLE_FRAME_CONSTRUCTION_IID);
class HTMLAnchorRule : public nsIStyleRule {
@ -173,7 +180,8 @@ nsHashKey* AttributeKey::Clone(void) const
// -----------------------------------------------------------
class HTMLStyleSheetImpl : public nsIHTMLStyleSheet {
class HTMLStyleSheetImpl : public nsIHTMLStyleSheet,
public nsIStyleFrameConstruction {
public:
void* operator new(size_t size);
void* operator new(size_t size, nsIArena* aArena);
@ -217,6 +225,15 @@ public:
NS_IMETHOD UnsetAttributeFor(nsIAtom* aAttribute, nsIHTMLContent* aContent,
nsIHTMLAttributes*& aAttributes);
NS_IMETHOD ConstructFrame(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParentFrame,
nsIFrame*& aFrameSubTree);
NS_IMETHOD ContentAppended(nsIPresContext* aPresContext,
nsIDocument* aDocument,
nsIContent* aContainer,
PRInt32 aNewIndexInContainer);
// XXX style rule enumerations
@ -239,6 +256,14 @@ protected:
PRInt32 aAttrCount,
nsIHTMLAttributes*& aAttributes);
nsresult ProcessChildren(nsIPresContext* aPresContext,
nsIFrame* aFrame,
nsIContent* aContent);
nsresult CreateInputFrame(nsIContent* aContent,
nsIFrame* aParentFrame,
nsIFrame*& aFrame);
protected:
PRUint32 mInHeap : 1;
PRUint32 mRefCnt : 31;
@ -330,8 +355,13 @@ nsresult HTMLStyleSheetImpl::QueryInterface(const nsIID& aIID,
AddRef();
return NS_OK;
}
if (aIID.Equals(kIStyleFrameConstructionIID)) {
*aInstancePtrResult = (void*) ((nsIStyleFrameConstruction*)this);
AddRef();
return NS_OK;
}
if (aIID.Equals(kISupportsIID)) {
*aInstancePtrResult = (void*) ((nsISupports*)this);
*aInstancePtrResult = (void*) this;
AddRef();
return NS_OK;
}
@ -816,6 +846,316 @@ NS_IMETHODIMP HTMLStyleSheetImpl::UnsetAttributeFor(nsIAtom* aAttribute,
}
nsresult HTMLStyleSheetImpl::ProcessChildren(nsIPresContext* aPresContext,
nsIFrame* aFrame,
nsIContent* aContent)
{
nsIFrame* childList = nsnull;
nsIFrame* lastChildFrame = nsnull;
PRInt32 count;
aContent->ChildCount(count);
for (PRInt32 i = 0; i < count; i++) {
nsIContent* childContent;
aContent->ChildAt(i, childContent);
if (nsnull != childContent) {
nsIFrame* childFrame;
// Construct a child frame
ConstructFrame(aPresContext, childContent, aFrame, childFrame);
if (nsnull != childFrame) {
// Link the frame into the child list
if (nsnull == lastChildFrame) {
childList = childFrame;
} else {
lastChildFrame->SetNextSibling(childFrame);
}
lastChildFrame = childFrame;
}
NS_RELEASE(childContent);
}
}
// Initialize the frame giving it its child list.
// XXX Should we call Init(), or just return the child list and let the
// caller call Init()?
aFrame->Init(*aPresContext, childList);
return NS_OK;
}
nsresult
HTMLStyleSheetImpl::CreateInputFrame(nsIContent* aContent,
nsIFrame* aParentFrame,
nsIFrame*& aFrame)
{
nsresult rv;
// Figure out which type of input frame to create
nsAutoString val;
if (NS_OK == aContent->GetAttribute(nsAutoString("type"), val)) {
if (val.EqualsIgnoreCase("submit")) {
rv = NS_NewInputButtonFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("reset")) {
rv = NS_NewInputButtonFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("button")) {
rv = NS_NewInputButtonFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("checkbox")) {
rv = NS_NewInputCheckboxFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("file")) {
rv = NS_NewInputFileFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("hidden")) {
rv = NS_NewInputButtonFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("image")) {
rv = NS_NewInputButtonFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("password")) {
rv = NS_NewInputTextFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("radio")) {
rv = NS_NewInputRadioFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("text")) {
rv = NS_NewInputTextFrame(aContent, aParentFrame, aFrame);
}
else {
rv = NS_NewInputTextFrame(aContent, aParentFrame, aFrame);
}
} else {
rv = NS_NewInputTextFrame(aContent, aParentFrame, aFrame);
}
return rv;
}
NS_IMETHODIMP HTMLStyleSheetImpl::ConstructFrame(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParentFrame,
nsIFrame*& aFrameSubTree)
{
// Get the tag
nsIAtom* tag;
aContent->GetTag(tag);
aFrameSubTree = nsnull;
// Resolve the style context.
// XXX Cheesy hack for text
nsIStyleContext* styleContext;
if (nsnull == tag) {
styleContext = aPresContext->ResolvePseudoStyleContextFor(nsHTMLAtoms::text, aParentFrame);
} else {
styleContext = aPresContext->ResolveStyleContextFor(aContent, aParentFrame);
}
// Create a frame.
if (nsnull == aParentFrame) {
// This should only be the case for the root content object.
// XXX Add assertion...
nsIFrame* rootFrame;
// Create the root frame and set its style context
NS_NewHTMLFrame(aContent, nsnull, rootFrame);
rootFrame->SetStyleContext(aPresContext, styleContext);
// Bind root frame to root view (and root window)
nsIPresShell* presShell = aPresContext->GetShell();
nsIViewManager* viewManager = presShell->GetViewManager();
nsIView* rootView;
NS_RELEASE(presShell);
viewManager->GetRootView(rootView);
rootFrame->SetView(rootView);
NS_RELEASE(viewManager);
// Process the children
ProcessChildren(aPresContext, rootFrame, aContent);
// Return the frame sub-tree
aFrameSubTree = rootFrame;
} else {
nsIFrame* frame = nsnull;
nsresult rv = NS_OK;
// Handle specific frame types
if (nsnull == tag) {
rv = NS_NewTextFrame(aContent, aParentFrame, frame);
}
else if (nsHTMLAtoms::applet == tag) {
rv = NS_NewObjectFrame(aContent, aParentFrame, frame);
}
else if (nsHTMLAtoms::body == tag) {
rv = NS_NewBodyFrame(aContent, aParentFrame, frame);
// Process the children
ProcessChildren(aPresContext, frame, aContent);
}
else if (nsHTMLAtoms::frameset == tag) {
rv = NS_NewHTMLFramesetFrame(aContent, aParentFrame, frame);
}
else if (nsHTMLAtoms::br == tag) {
rv = NS_NewBRFrame(aContent, aParentFrame, frame);
}
else if (nsHTMLAtoms::embed == tag) {
rv = NS_NewObjectFrame(aContent, aParentFrame, frame);
}
else if (nsHTMLAtoms::hr == tag) {
rv = NS_NewHRFrame(aContent, aParentFrame, frame);
}
else if (nsHTMLAtoms::img == tag) {
rv = NS_NewImageFrame(aContent, aParentFrame, frame);
}
else if (nsHTMLAtoms::object == tag) {
rv = NS_NewObjectFrame(aContent, aParentFrame, frame);
}
else if (nsHTMLAtoms::spacer == tag) {
rv = NS_NewSpacerFrame(aContent, aParentFrame, frame);
}
else if (nsHTMLAtoms::wbr == tag) {
rv = NS_NewWBRFrame(aContent, aParentFrame, frame);
}
else if (nsHTMLAtoms::table == tag) {
rv = nsTableOuterFrame::NewFrame(&frame, aContent, aParentFrame);
}
else if (nsHTMLAtoms::input == tag) {
rv = CreateInputFrame(aContent, aParentFrame, frame);
}
else if (nsHTMLAtoms::textarea == tag) {
rv = NS_NewInputTextFrame(aContent, aParentFrame, frame);
}
else if (nsHTMLAtoms::select == tag) {
rv = NS_NewHTMLSelectFrame(aContent, aParentFrame, frame);
}
if (NS_OK != rv) {
NS_RELEASE(styleContext);
NS_IF_RELEASE(tag);
return rv;
}
// XXX add code in here to force the odd ones into the empty frame?
// AREA, HEAD, META, MAP, etc...
if (nsnull == frame) {
// When there is no explicit frame to create, assume it's a
// container and let style dictate the rest.
const nsStyleDisplay* styleDisplay = (const nsStyleDisplay*)
styleContext->GetStyleData(eStyleStruct_Display);
// Use style to choose what kind of frame to create
nsresult rv;
switch (styleDisplay->mDisplay) {
case NS_STYLE_DISPLAY_BLOCK:
case NS_STYLE_DISPLAY_LIST_ITEM:
rv = NS_NewCSSBlockFrame(&frame, aContent, aParentFrame);
ProcessChildren(aPresContext, frame, aContent);
break;
case NS_STYLE_DISPLAY_INLINE:
rv = NS_NewCSSInlineFrame(&frame, aContent, aParentFrame);
break;
default:
// XXX Don't create a placeholder frame for content that's not
// displayed...
#if 0
// Create an empty frame for holding content that is not being
// reflowed.
rv = nsFrame::NewFrame(&frame, aContent, aParentFrame);
#endif
break;
}
if (NS_OK != rv) {
NS_RELEASE(styleContext);
NS_IF_RELEASE(tag);
return rv;
}
}
if (nsnull != frame) {
frame->SetStyleContext(aPresContext, styleContext);
}
aFrameSubTree = frame;
}
NS_RELEASE(styleContext);
NS_IF_RELEASE(tag);
return NS_OK;
}
NS_IMETHODIMP HTMLStyleSheetImpl::ContentAppended(nsIPresContext* aPresContext,
nsIDocument* aDocument,
nsIContent* aContainer,
PRInt32 aNewIndexInContainer)
{
nsIPresShell* shell = aPresContext->GetShell();
nsIContent* parentContainer = aContainer;
while (nsnull != parentContainer) {
nsIFrame* parentFrame = shell->FindFrameWithContent(parentContainer);
if (nsnull != parentFrame) {
// Get the parent frame's last-in-flow
nsIFrame* nextInFlow = parentFrame;
while (nsnull != nextInFlow) {
parentFrame->GetNextInFlow(nextInFlow);
if (nsnull != nextInFlow) {
parentFrame = nextInFlow;
}
}
// Create some new frames
PRInt32 count;
nsIFrame* lastChildFrame = nsnull;
nsIFrame* firstAppendedFrame = nsnull;
aContainer->ChildCount(count);
for (PRInt32 i = aNewIndexInContainer; i < count; i++) {
nsIContent* child;
nsIFrame* frame;
aContainer->ChildAt(i, child);
ConstructFrame(aPresContext, child, parentFrame, frame);
// Link the frame into the child frame list
if (nsnull == lastChildFrame) {
firstAppendedFrame = frame;
} else {
lastChildFrame->SetNextSibling(frame);
}
// XXX We should probably mark the frame as being dirty: that way the
// parent frame can easily identify the newly added frames. Either that
// or pass along in count in which case they must be contiguus...
lastChildFrame = frame;
}
// Notify the parent frame with a reflow command, passing it the list of
// new frames.
nsIReflowCommand* reflowCmd;
nsresult result;
result = NS_NewHTMLReflowCommand(&reflowCmd, parentFrame,
nsIReflowCommand::FrameAppended,
firstAppendedFrame);
if (NS_SUCCEEDED(result)) {
shell->AppendReflowCommand(reflowCmd);
}
break;
}
parentContainer->GetParent(parentContainer);
}
NS_RELEASE(shell);
return NS_OK;
}
void HTMLStyleSheetImpl::List(FILE* out, PRInt32 aIndent) const
{

View File

@ -22,8 +22,13 @@
#include "nsISupportsArray.h"
#include "nsIFrame.h"
#include "nsHashtable.h"
#include "nsIPresContext.h"
#include "nsIPresShell.h"
#include "nsIContent.h"
#include "nsIStyleFrameConstruction.h"
static NS_DEFINE_IID(kIStyleSetIID, NS_ISTYLE_SET_IID);
static NS_DEFINE_IID(kIStyleFrameConstructionIID, NS_ISTYLE_FRAME_CONSTRUCTION_IID);
class ContextKey : public nsHashKey {
public:
@ -207,6 +212,31 @@ public:
nsIFrame* aParentFrame,
PRBool aForceUnique = PR_FALSE);
NS_IMETHODIMP ConstructFrame(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParentFrame,
nsIFrame*& aFrameSubTree);
NS_IMETHOD ContentAppended(nsIPresContext* aPresContext,
nsIDocument* aDocument,
nsIContent* aContainer,
PRInt32 aNewIndexInContainer);
NS_IMETHOD ContentInserted(nsIPresContext* aPresContext,
nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer);
NS_IMETHOD ContentReplaced(nsIPresContext* aPresContext,
nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aOldChild,
nsIContent* aNewChild,
PRInt32 aIndexInContainer);
NS_IMETHOD ContentRemoved(nsIPresContext* aPresContext,
nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer);
// xxx style rules enumeration
virtual void List(FILE* out = stdout, PRInt32 aIndent = 0);
@ -240,13 +270,15 @@ protected:
nsISupportsArray* mDocSheets;
nsISupportsArray* mBackstopSheets;
nsHashtable mStyleContexts;
nsIStyleFrameConstruction* mFrameConstructor;
};
StyleSetImpl::StyleSetImpl()
: mOverrideSheets(nsnull),
mDocSheets(nsnull),
mBackstopSheets(nsnull)
mBackstopSheets(nsnull),
mFrameConstructor(nsnull)
{
NS_INIT_REFCNT();
}
@ -262,6 +294,7 @@ StyleSetImpl::~StyleSetImpl()
NS_IF_RELEASE(mOverrideSheets);
NS_IF_RELEASE(mDocSheets);
NS_IF_RELEASE(mBackstopSheets);
NS_IF_RELEASE(mFrameConstructor);
mStyleContexts.Enumerate(ReleaseContext);
}
@ -340,6 +373,9 @@ void StyleSetImpl::AppendDocStyleSheet(nsIStyleSheet* aSheet)
NS_PRECONDITION(nsnull != aSheet, "null arg");
if (EnsureArray(&mDocSheets)) {
mDocSheets->AppendElement(aSheet);
if (nsnull == mFrameConstructor) {
aSheet->QueryInterface(kIStyleFrameConstructionIID, (void **)&mFrameConstructor);
}
}
}
@ -350,6 +386,9 @@ void StyleSetImpl::InsertDocStyleSheetAfter(nsIStyleSheet* aSheet,
if (EnsureArray(&mDocSheets)) {
PRInt32 index = mDocSheets->IndexOf(aAfterSheet);
mDocSheets->InsertElementAt(aSheet, ++index);
if (nsnull == mFrameConstructor) {
aSheet->QueryInterface(kIStyleFrameConstructionIID, (void **)&mFrameConstructor);
}
}
}
@ -360,6 +399,9 @@ void StyleSetImpl::InsertDocStyleSheetBefore(nsIStyleSheet* aSheet,
if (EnsureArray(&mDocSheets)) {
PRInt32 index = mDocSheets->IndexOf(aBeforeSheet);
mDocSheets->InsertElementAt(aSheet, ((-1 < index) ? index : 0));
if (nsnull == mFrameConstructor) {
aSheet->QueryInterface(kIStyleFrameConstructionIID, (void **)&mFrameConstructor);
}
}
}
@ -665,6 +707,67 @@ nsIStyleContext* StyleSetImpl::ProbePseudoStyleFor(nsIPresContext* aPresContext,
return result;
}
NS_IMETHODIMP StyleSetImpl::ConstructFrame(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParentFrame,
nsIFrame*& aFrameSubTree)
{
return mFrameConstructor->ConstructFrame(aPresContext, aContent,
aParentFrame, aFrameSubTree);
}
NS_IMETHODIMP StyleSetImpl::ContentAppended(nsIPresContext* aPresContext,
nsIDocument* aDocument,
nsIContent* aContainer,
PRInt32 aNewIndexInContainer)
{
return mFrameConstructor->ContentAppended(aPresContext, aDocument,
aContainer, aNewIndexInContainer);
}
NS_IMETHODIMP StyleSetImpl::ContentInserted(nsIPresContext* aPresContext,
nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer)
{
#if 0
return mFrameConstructor->ContentInserted(aPresContext, aDocument, aContainer,
aChild, aIndexInContainer);
#else
return NS_OK;
#endif
}
NS_IMETHODIMP StyleSetImpl::ContentReplaced(nsIPresContext* aPresContext,
nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aOldChild,
nsIContent* aNewChild,
PRInt32 aIndexInContainer)
{
#if 0
return mFrameConstructor->ContentReplaced(aPresContext, aDocument, aContainer,
aOldChild, aNewChild, aIndexInContainer);
#else
return NS_OK;
#endif
}
NS_IMETHODIMP StyleSetImpl::ContentRemoved(nsIPresContext* aPresContext,
nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer)
{
#if 0
return mFrameConstructor->ContentRemoved(aPresContext, aDocument, aContainer,
aChild, aIndexInContainer);
#else
return NS_OK;
#endif
}
// xxx style rules enumeration
void StyleSetImpl::List(FILE* out, PRInt32 aIndent, nsISupportsArray* aSheets)