Work on generated content

git-svn-id: svn://10.0.0.236/trunk@26266 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
troy%netscape.com
1999-04-05 02:53:07 +00:00
parent adc05c03c1
commit 17fdb38b65
4 changed files with 698 additions and 202 deletions

View File

@@ -248,6 +248,239 @@ nsCSSFrameConstructor::Init(nsIDocument* aDocument)
return NS_OK;
}
class nsAttrValueContent : public nsIContent, public nsITextContent
{
public:
NS_IMETHOD GetTag(nsIAtom *&aResult) const {
aResult = nsnull;
return NS_OK;
}
NS_IMETHOD GetDocument(nsIDocument *&aResult) const {
aResult = nsnull;
return NS_OK;
}
NS_IMETHOD SetDocument(nsIDocument *aDocument, PRBool aDeep) {
return NS_OK;
}
NS_IMETHOD CanContainChildren(PRBool &aResult) const {
aResult = PR_FALSE;
return NS_OK;
}
NS_IMETHOD GetParent(nsIContent *&aResult) const {
aResult = nsnull;
return NS_OK;
}
NS_IMETHOD SetParent(nsIContent *aParent) {
return NS_OK;
}
NS_IMETHOD GetNameSpaceID(PRInt32 &aResult) const {
aResult = kNameSpaceID_None;
return NS_OK;
}
NS_IMETHOD IndexOf(nsIContent *aPossibleChild, PRInt32 &aIndex) const {
aIndex = -1;
return NS_OK;
}
NS_IMETHOD InsertChildAt(nsIContent *aKid, PRInt32 aIndex, PRBool aNotify) {
return NS_OK;
}
NS_IMETHOD ChildCount(PRInt32 &aResult) const {
aResult = 0;
return NS_OK;
}
NS_IMETHOD ChildAt(PRInt32 aIndex, nsIContent *&aResult) const {
aResult = nsnull;
return NS_OK;
}
NS_IMETHOD RemoveChildAt(PRInt32 aIndex, PRBool aNotify) {
return NS_OK;
}
NS_IMETHOD IsSynthetic(PRBool &aResult) {
aResult = PR_TRUE;
return NS_OK;
}
NS_IMETHOD ReplaceChildAt(nsIContent *aKid, PRInt32 aIndex, PRBool aNotify) {
return NS_OK;
}
NS_IMETHOD AppendChildTo(nsIContent *aKid, PRBool aNotify) {
return NS_OK;
}
NS_IMETHOD SetAttribute(PRInt32 aNameSpaceID, nsIAtom *aName, const nsString &aValue, PRBool aNotify) {
return NS_OK;
}
NS_IMETHOD GetAttribute(PRInt32 aNameSpaceID, nsIAtom *aName, nsString &aResult) const {
return NS_CONTENT_ATTR_NOT_THERE;
}
NS_IMETHOD ParseAttributeString(const nsString &aStr, nsIAtom *&aName, PRInt32 &aNameSpaceID) {
aName = nsnull;
aNameSpaceID = kNameSpaceID_None;
return NS_OK;
}
NS_IMETHOD GetNameSpacePrefixFromId(PRInt32 aNameSpaceID, nsIAtom *&aPrefix) {
aPrefix = nsnull;
return NS_OK;
}
NS_IMETHOD GetAttributeCount(PRInt32 &aCountResult) const {
aCountResult = 0;
return NS_OK;
}
NS_IMETHOD List(FILE *out=stdout, PRInt32 aIndent=0) const {
return NS_OK;
}
NS_IMETHOD UnsetAttribute(PRInt32 aNameSpaceID, nsIAtom *aAttribute, PRBool aNotify) {
return NS_OK;
}
NS_IMETHOD GetAttributeNameAt(PRInt32 aIndex, PRInt32 &aNameSpaceID, nsIAtom *&aName) const {
aName = nsnull;
return NS_ERROR_ILLEGAL_VALUE;
}
NS_IMETHOD RangeAdd(nsIDOMRange &aRange) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHOD RangeRemove(nsIDOMRange &aRange) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHOD GetRangeList(nsVoidArray *&aResult) const {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHOD BeginConvertToXIF(nsXIFConverter &aConverter) const {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHOD ConvertContentToXIF(nsXIFConverter &aConverter) const {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHOD FinishConvertToXIF(nsXIFConverter &aConverter) const {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHOD HandleDOMEvent(nsIPresContext &aPresContext, nsEvent *aEvent, nsIDOMEvent **aDOMEvent, PRUint32 aFlags, nsEventStatus &aEventStatus) {
return NS_OK;
}
NS_IMETHOD GetText(const nsTextFragment *&aFragmentsResult, PRInt32 &aNumFragmentsResult) {
// XXX ???;
aNumFragmentsResult = 1;
return NS_OK;
}
NS_IMETHOD SetText(const PRUnichar *aBuffer, PRInt32 aLength, PRBool aNotify) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHOD SetText(const char *aBuffer, PRInt32 aLength, PRBool aNotify) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHOD IsOnlyWhitespace(PRBool *aResult) {
*aResult = PR_FALSE;
return NS_OK;
}
protected:
nsIContent* mContent;
const char* mAttr;
};
nsresult
nsCSSFrameConstructor::CreateGeneratedFrameFor(nsIPresContext* aPresContext,
nsIFrame* aParentFrame,
nsIContent* aContent,
nsIStyleContext* aStyleContext,
const nsStyleContent* aStyleContent,
PRUint32 aContentIndex,
nsIFrame** aFrame)
{
*aFrame = nsnull; // initialize OUT parameter
// Get the content value
nsStyleContentType type;
nsAutoString contentString;
aStyleContent->GetContentAt(aContentIndex, type, contentString);
if (eStyleContentType_URL == type) {
nsIHTMLContent* imageContent;
// Create an HTML image content object, and set the SRC.
// XXX Check if it's an image type we can handle...
NS_NewHTMLImageElement(&imageContent, nsHTMLAtoms::img);
imageContent->SetHTMLAttribute(nsHTMLAtoms::src, contentString, PR_FALSE);
// Create an image frame and initialize it
nsIFrame* imageFrame;
NS_NewImageFrame(imageFrame);
imageFrame->Init(*aPresContext, imageContent, aParentFrame, aStyleContext, nsnull);
NS_RELEASE(imageContent);
// Return the image frame
*aFrame = imageFrame;
} else {
switch (type) {
case eStyleContentType_String:
break;
case eStyleContentType_Attr:
{ // XXX for now, prefetch the attr value, this needs to be a special content node
nsIAtom* attrName = NS_NewAtom(contentString);
aContent->GetAttribute(kNameSpaceID_None, attrName, contentString); // XXX need attr namespace from style
NS_RELEASE(attrName);
}
break;
case eStyleContentType_Counter:
case eStyleContentType_Counters:
return NS_ERROR_NOT_IMPLEMENTED; // XXX not supported yet...
case eStyleContentType_OpenQuote:
case eStyleContentType_CloseQuote:
{
PRUint32 quotesCount = aStyleContent->QuotesCount();
if (quotesCount > 0) {
nsAutoString openQuote, closeQuote;
// If the depth is greater than the number of pairs, the last pair
// is repeated
PRUint32 quoteDepth = 0; // XXX really track the nested quotes...
if (quoteDepth > quotesCount) {
quoteDepth = quotesCount - 1;
}
aStyleContent->GetQuotesAt(quoteDepth, openQuote, closeQuote);
if (eStyleContentType_OpenQuote == type) {
contentString = openQuote;
} else {
contentString = closeQuote;
}
} else {
contentString = '"';
}
}
break;
case eStyleContentType_NoOpenQuote:
case eStyleContentType_NoCloseQuote:
// XXX Adjust quote depth...
return NS_OK;
}
// Create a text content node
nsIContent* textContent;
nsIDOMCharacterData* domData;
NS_NewTextNode(&textContent);
textContent->QueryInterface(kIDOMCharacterDataIID, (void**)&domData);
domData->SetData(contentString);
NS_RELEASE(domData);
// Create a text frame and initialize it
nsIFrame* textFrame;
NS_NewTextFrame(textFrame);
textFrame->Init(*aPresContext, textContent, aParentFrame, aStyleContext, nsnull);
NS_RELEASE(textContent);
// Return the text frame
*aFrame = textFrame;
}
return NS_OK;
}
PRBool
nsCSSFrameConstructor::CreateGeneratedContentFrame(nsIPresContext* aPresContext,
nsIFrame* aFrame,
@@ -264,93 +497,89 @@ nsCSSFrameConstructor::CreateGeneratedContentFrame(nsIPresContext* aPresContext
PR_FALSE, &pseudoStyleContext);
if (pseudoStyleContext) {
nsIContent* textContent;
nsIDOMCharacterData* domData;
const nsStyleDisplay* display;
// See whether the generated content should be displayed.
display = (const nsStyleDisplay*)pseudoStyleContext->GetStyleData(eStyleStruct_Display);
if (NS_STYLE_DISPLAY_NONE != display->mDisplay) {
PRUint8 displayValue = display->mDisplay;
// Make sure the 'display' property value is allowable
const nsStyleDisplay* subjectDisplay = (const nsStyleDisplay*)
aStyleContext->GetStyleData(eStyleStruct_Display);
if (subjectDisplay->IsBlockLevel()) {
// For block-level elements the only allowed 'display' values are:
// 'none', 'inline', 'block', and 'marker'
if ((NS_STYLE_DISPLAY_INLINE != displayValue) &&
(NS_STYLE_DISPLAY_BLOCK != displayValue) &&
(NS_STYLE_DISPLAY_MARKER != displayValue)) {
// Pseudo-element behaves as if the value were 'block'
displayValue = NS_STYLE_DISPLAY_BLOCK;
}
} else {
// For inline-level elements the only allowed 'display' values are
// 'none' and 'inline'
displayValue = NS_STYLE_DISPLAY_INLINE;
}
if (display->mDisplay != displayValue) {
// Reset the value
nsStyleDisplay* mutableDisplay = (nsStyleDisplay*)
pseudoStyleContext->GetMutableStyleData(eStyleStruct_Display);
mutableDisplay->mDisplay = displayValue;
}
// Now create the content object and frame based on the 'content' property
// XXX For the time being just pretend it's text
// XXX this needs to create a wrapper frame, then a collection of text frames to contain the
// generated content nodes.
// for now, create a single text frame
// See if there was any content specified
const nsStyleContent* styleContent;
styleContent = (const nsStyleContent*)pseudoStyleContext->GetStyleData(eStyleStruct_Content);
PRUint32 contentCount = styleContent->ContentCount();
if (contentCount) {
nsStyleContentType type;
nsAutoString contentString;
styleContent->GetContentAt(0, type, contentString);
switch (type) {
case eStyleContentType_String:
break;
case eStyleContentType_Attr:
{ // XXX for now, prefetch the attr value, this needs to be a special content node
nsIAtom* attrName = NS_NewAtom(contentString);
aContent->GetAttribute(kNameSpaceID_None, attrName, contentString); // XXX need attr namespace from style
NS_RELEASE(attrName);
}
break;
case eStyleContentType_URL: // XXX need to handle these differently than simple text
case eStyleContentType_Counter:
case eStyleContentType_Counters:
case eStyleContentType_OpenQuote:
case eStyleContentType_CloseQuote:
case eStyleContentType_NoOpenQuote:
case eStyleContentType_NoCloseQuote:
contentString.Append("GENERATED");
break;
if (contentCount > 0) {
PRUint8 displayValue = display->mDisplay;
// Make sure the 'display' property value is allowable
const nsStyleDisplay* subjectDisplay = (const nsStyleDisplay*)
aStyleContext->GetStyleData(eStyleStruct_Display);
if (subjectDisplay->IsBlockLevel()) {
// For block-level elements the only allowed 'display' values are:
// 'none', 'inline', 'block', and 'marker'
if ((NS_STYLE_DISPLAY_INLINE != displayValue) &&
(NS_STYLE_DISPLAY_BLOCK != displayValue) &&
(NS_STYLE_DISPLAY_MARKER != displayValue)) {
// Pseudo-element behaves as if the value were 'block'
displayValue = NS_STYLE_DISPLAY_BLOCK;
}
} else {
// For inline-level elements the only allowed 'display' values are
// 'none' and 'inline'
displayValue = NS_STYLE_DISPLAY_INLINE;
}
NS_NewTextNode(&textContent);
textContent->QueryInterface(kIDOMCharacterDataIID, (void**)&domData);
domData->SetData(contentString);
NS_RELEASE(domData);
// Create a text frame and initialize it
nsIFrame* textFrame;
NS_NewTextFrame(textFrame);
textFrame->Init(*aPresContext, textContent, aFrame, pseudoStyleContext, nsnull);
if (display->mDisplay != displayValue) {
// Reset the value
nsStyleDisplay* mutableDisplay = (nsStyleDisplay*)
pseudoStyleContext->GetMutableStyleData(eStyleStruct_Display);
mutableDisplay->mDisplay = displayValue;
}
// Create a block box or an inline box depending on the value of
// the 'display' property
nsIFrame* containerFrame;
nsFrameItems childFrames;
if (NS_STYLE_DISPLAY_BLOCK == displayValue) {
NS_NewBlockFrame(containerFrame, 0);
} else {
NS_NewInlineFrame(containerFrame);
}
containerFrame->Init(*aPresContext, aContent, aFrame, pseudoStyleContext, nsnull);
// Create another pseudo style context to use for all the generated child
// frames
nsIStyleContext* textStyleContext;
aPresContext->ResolvePseudoStyleContextFor(aContent, nsHTMLAtoms::textPseudo,
pseudoStyleContext, PR_FALSE,
&textStyleContext);
// Now create content objects (and child frames) for each value of the
// 'content' property
for (PRUint32 contentIndex = 0; contentIndex < contentCount; contentIndex++) {
nsIFrame* frame;
nsresult result;
// Create a frame
result = CreateGeneratedFrameFor(aPresContext, containerFrame, aContent,
textStyleContext, styleContent,
contentIndex, &frame);
if (NS_SUCCEEDED(result) && frame) {
// Add it to the list of child frames
childFrames.AddChild(frame);
}
}
NS_RELEASE(textStyleContext);
NS_RELEASE(pseudoStyleContext);
NS_RELEASE(textContent);
*aResult = textFrame;
if (childFrames.childList) {
containerFrame->SetInitialChildList(*aPresContext, nsnull, childFrames.childList);
}
*aResult = containerFrame;
return PR_TRUE;
}
}
@@ -374,14 +603,12 @@ nsCSSFrameConstructor::ProcessChildren(nsIPresContext* aPresContext,
nsAbsoluteItems& aAbsoluteItems,
nsFrameItems& aFrameItems,
nsAbsoluteItems& aFixedItems,
nsAbsoluteItems& aFloatingItems)
nsAbsoluteItems& aFloatingItems,
PRBool aCanHaveGeneratedContent)
{
// If the content can contain children, then check for generated content
nsIStyleContext* styleContext = nsnull;
PRBool canContainChildren;
aContent->CanContainChildren(canContainChildren);
if (canContainChildren) {
if (aCanHaveGeneratedContent) {
nsIFrame* generatedFrame;
// Probe for generated content before
@@ -406,7 +633,7 @@ nsCSSFrameConstructor::ProcessChildren(nsIPresContext* aPresContext,
}
}
if (canContainChildren) {
if (aCanHaveGeneratedContent) {
nsIFrame* generatedFrame;
// Probe for generated content after
@@ -810,7 +1037,7 @@ nsCSSFrameConstructor::ConstructTableCaptionFrame(nsIPresContext* aPresContext,
nsFrameItems childItems;
nsAbsoluteItems floatingKids(aNewCaptionFrame);
ProcessChildren(aPresContext, aContent, aNewCaptionFrame, aAbsoluteItems,
childItems, aFixedItems, floatingKids);
childItems, aFixedItems, floatingKids, PR_TRUE);
aNewCaptionFrame->SetInitialChildList(*aPresContext, nsnull, childItems.childList);
if (floatingKids.childList) {
aNewCaptionFrame->SetInitialChildList(*aPresContext,
@@ -1248,7 +1475,7 @@ nsCSSFrameConstructor::ConstructTableCellFrameOnly(nsIPresContext* aPresContext
nsFrameItems childItems;
nsAbsoluteItems floaterList(aNewCellBodyFrame);
rv = ProcessChildren(aPresContext, aContent, aNewCellBodyFrame, aAbsoluteItems,
childItems, aFixedItems, floaterList);
childItems, aFixedItems, floaterList, PR_TRUE);
if (NS_FAILED(rv)) return rv;
aNewCellBodyFrame->SetInitialChildList(*aPresContext, nsnull, childItems.childList);
if (floaterList.childList) {
@@ -1535,7 +1762,7 @@ nsCSSFrameConstructor::ConstructDocElementFrame(nsIPresContext* aPresContext,
nsFrameItems childItems;
ProcessChildren(aPresContext, aDocElement, areaFrame, absoluteItems,
childItems, aFixedItems, floaterList);
childItems, aFixedItems, floaterList, PR_TRUE);
// Set the initial child lists
areaFrame->SetInitialChildList(*aPresContext, nsnull,
@@ -1598,7 +1825,7 @@ nsCSSFrameConstructor::ConstructDocElementFrame(nsIPresContext* aPresContext,
nsFrameItems childItems;
ProcessChildren(aPresContext, aDocElement, areaFrame, absoluteItems,
childItems, aFixedItems, floatingItems);
childItems, aFixedItems, floatingItems, PR_TRUE);
// Set the initial child lists
areaFrame->SetInitialChildList(*aPresContext, nsnull,
@@ -2004,6 +2231,7 @@ nsCSSFrameConstructor::ConstructFrameByTag(nsIPresContext* aPresContext,
nsIFrame* newFrame = nsnull; // the frame we construct
PRBool newFrameIsFloaterContainer = PR_FALSE;
PRBool isReplaced = PR_FALSE;
PRBool canHaveGeneratedContent = PR_FALSE; // ignore things like text
nsIFrame* beforeGenerated = nsnull;
nsIFrame* afterGenerated = nsnull;
nsresult rv = NS_OK;
@@ -2034,6 +2262,9 @@ nsCSSFrameConstructor::ConstructFrameByTag(nsIPresContext* aPresContext,
isFloating = PR_TRUE;
}
// Most things in here can have generated content
canHaveGeneratedContent = PR_TRUE;
// Create a frame based on the tag
if (nsHTMLAtoms::img == aTag) {
isReplaced = PR_TRUE;
@@ -2083,10 +2314,16 @@ nsCSSFrameConstructor::ConstructFrameByTag(nsIPresContext* aPresContext,
rv = NS_NewLegendFrame(newFrame);
processChildren = PR_TRUE;
canBePositioned = PR_FALSE;
canHaveGeneratedContent = PR_FALSE;
}
else if (nsHTMLAtoms::object == aTag) {
isReplaced = PR_TRUE;
rv = NS_NewObjectFrame(newFrame);
// Note: if we can render the OBJECT element, then the generated content
// goes before and after the replaced element (as sibling frames) because
// we're ignoring the OBJECT element's content.
// If we can't render the OBJECT element, then the generated content goes
// before and after the OBJECT element's content
}
else if (nsHTMLAtoms::form == aTag) {
rv = NS_NewFormFrame(newFrame);
@@ -2094,6 +2331,7 @@ nsCSSFrameConstructor::ConstructFrameByTag(nsIPresContext* aPresContext,
else if (nsHTMLAtoms::frameset == aTag) {
rv = NS_NewHTMLFramesetFrame(newFrame);
canBePositioned = PR_FALSE;
canHaveGeneratedContent = PR_FALSE;
}
else if (nsHTMLAtoms::iframe == aTag) {
isReplaced = PR_TRUE;
@@ -2148,6 +2386,15 @@ nsCSSFrameConstructor::ConstructFrameByTag(nsIPresContext* aPresContext,
nsHTMLContainerFrame::CreateViewForFrame(*aPresContext, newFrame,
aStyleContext, PR_FALSE);
// If it's allowed to have generated content, then check for :before
// and :after pseudo-elements
if (canHaveGeneratedContent) {
CreateGeneratedContentFrame(aPresContext, newFrame, aContent, aStyleContext,
nsCSSAtoms::beforePseudo, &beforeGenerated);
CreateGeneratedContentFrame(aPresContext, newFrame, aContent, aStyleContext,
nsCSSAtoms::afterPseudo, &afterGenerated);
}
// Process the child content if requested
nsFrameItems childItems;
nsAbsoluteItems floaterList(newFrame);
@@ -2155,22 +2402,13 @@ nsCSSFrameConstructor::ConstructFrameByTag(nsIPresContext* aPresContext,
if (newFrameIsFloaterContainer) {
rv = ProcessChildren(aPresContext, aContent, newFrame,
aAbsoluteItems, childItems, aFixedItems,
floaterList);
floaterList, PR_TRUE);
}
else {
rv = ProcessChildren(aPresContext, aContent, newFrame,
aAbsoluteItems, childItems, aFixedItems,
aFloatingItems);
aFloatingItems, PR_TRUE);
}
} else {
// Check for generated content before and after.
// Note: we don't need to do this in the case where we're processing
// children, because ProcessChildren() takes care of this...
CreateGeneratedContentFrame(aPresContext, newFrame, aContent, aStyleContext,
nsCSSAtoms::beforePseudo, &beforeGenerated);
CreateGeneratedContentFrame(aPresContext, newFrame, aContent, aStyleContext,
nsCSSAtoms::afterPseudo, &afterGenerated);
}
// Set the frame's initial child list
@@ -2663,7 +2901,7 @@ nsCSSFrameConstructor::ConstructFrameByDisplayType(nsIPresContext* aPresCo
nsAbsoluteItems floaterList(newFrame);
ProcessChildren(aPresContext, aContent, newFrame, absoluteItems,
childItems, aFixedItems, floaterList);
childItems, aFixedItems, floaterList, PR_TRUE);
// Set the frame's initial child list(s)
newFrame->SetInitialChildList(*aPresContext, nsnull, childItems.childList);
@@ -2696,7 +2934,7 @@ nsCSSFrameConstructor::ConstructFrameByDisplayType(nsIPresContext* aPresCo
nsFrameItems childItems;
nsAbsoluteItems floaterList(newFrame);
ProcessChildren(aPresContext, aContent, newFrame, aAbsoluteItems,
childItems, aFixedItems, floaterList);
childItems, aFixedItems, floaterList, PR_TRUE);
// Set the frame's initial child list(s)
newFrame->SetInitialChildList(*aPresContext, nsnull, childItems.childList);
@@ -2724,7 +2962,7 @@ nsCSSFrameConstructor::ConstructFrameByDisplayType(nsIPresContext* aPresCo
nsAbsoluteItems floaterList(newFrame);
nsFrameItems childItems;
ProcessChildren(aPresContext, aContent, newFrame, absoluteItems,
childItems, aFixedItems, floaterList);
childItems, aFixedItems, floaterList, PR_TRUE);
// Set the frame's initial child list
newFrame->SetInitialChildList(*aPresContext, nsnull, childItems.childList);
@@ -2843,7 +3081,7 @@ nsCSSFrameConstructor::ConstructFrameByDisplayType(nsIPresContext* aPresCo
nsAbsoluteItems floaterList(newFrame);
rv = ProcessChildren(aPresContext, aContent, newFrame,
aAbsoluteItems, childItems, aFixedItems,
aFloatingItems);
aFloatingItems, PR_TRUE);
// Set the frame's initial child list
newFrame->SetInitialChildList(*aPresContext, nsnull,
@@ -2857,7 +3095,7 @@ nsCSSFrameConstructor::ConstructFrameByDisplayType(nsIPresContext* aPresCo
else {
rv = ProcessChildren(aPresContext, aContent, newFrame,
aAbsoluteItems, childItems, aFixedItems,
aFloatingItems);
aFloatingItems, PR_TRUE);
// Set the frame's initial child list
newFrame->SetInitialChildList(*aPresContext, nsnull,
@@ -4523,7 +4761,7 @@ nsCSSFrameConstructor::CreateContinuingOuterTableFrame(nsIPresContext* aPresCon
NS_NewAreaFrame(captionFrame, 0);
captionFrame->Init(*aPresContext, caption, newFrame, captionStyle, nsnull);
ProcessChildren(aPresContext, caption, captionFrame, absoluteItems,
childItems, fixedItems, floaterList);
childItems, fixedItems, floaterList, PR_TRUE);
captionFrame->SetInitialChildList(*aPresContext, nsnull, childItems.childList);
// XXX Deal with absolute and fixed frames...
if (floaterList.childList) {

View File

@@ -27,6 +27,7 @@ struct nsAbsoluteItems;
struct nsTableCreator;
class nsIStyleContext;
struct nsTableList;
struct nsStyleContent;
struct nsStyleDisplay;
class nsIPresShell;
class nsVoidArray;
@@ -131,6 +132,14 @@ protected:
nsIFrame*& aNewFrame,
nsAbsoluteItems& aFixedItems);
nsresult CreateGeneratedFrameFor(nsIPresContext* aPresContext,
nsIFrame* aParentFrame,
nsIContent* aContent,
nsIStyleContext* aStyleContext,
const nsStyleContent* aStyleContent,
PRUint32 aContentIndex,
nsIFrame** aFrame);
PRBool CreateGeneratedContentFrame(nsIPresContext* aPresContext,
nsIFrame* aFrame,
nsIContent* aContent,
@@ -363,7 +372,8 @@ protected:
nsAbsoluteItems& aAbsoluteItems,
nsFrameItems& aFrameItems,
nsAbsoluteItems& aFixedItems,
nsAbsoluteItems& aFloatingItems);
nsAbsoluteItems& aFloatingItems,
PRBool aCanHaveGeneratedContent = PR_FALSE);
nsresult CreateInputFrame(nsIContent* aContent, nsIFrame*& aFrame);

View File

@@ -248,6 +248,239 @@ nsCSSFrameConstructor::Init(nsIDocument* aDocument)
return NS_OK;
}
class nsAttrValueContent : public nsIContent, public nsITextContent
{
public:
NS_IMETHOD GetTag(nsIAtom *&aResult) const {
aResult = nsnull;
return NS_OK;
}
NS_IMETHOD GetDocument(nsIDocument *&aResult) const {
aResult = nsnull;
return NS_OK;
}
NS_IMETHOD SetDocument(nsIDocument *aDocument, PRBool aDeep) {
return NS_OK;
}
NS_IMETHOD CanContainChildren(PRBool &aResult) const {
aResult = PR_FALSE;
return NS_OK;
}
NS_IMETHOD GetParent(nsIContent *&aResult) const {
aResult = nsnull;
return NS_OK;
}
NS_IMETHOD SetParent(nsIContent *aParent) {
return NS_OK;
}
NS_IMETHOD GetNameSpaceID(PRInt32 &aResult) const {
aResult = kNameSpaceID_None;
return NS_OK;
}
NS_IMETHOD IndexOf(nsIContent *aPossibleChild, PRInt32 &aIndex) const {
aIndex = -1;
return NS_OK;
}
NS_IMETHOD InsertChildAt(nsIContent *aKid, PRInt32 aIndex, PRBool aNotify) {
return NS_OK;
}
NS_IMETHOD ChildCount(PRInt32 &aResult) const {
aResult = 0;
return NS_OK;
}
NS_IMETHOD ChildAt(PRInt32 aIndex, nsIContent *&aResult) const {
aResult = nsnull;
return NS_OK;
}
NS_IMETHOD RemoveChildAt(PRInt32 aIndex, PRBool aNotify) {
return NS_OK;
}
NS_IMETHOD IsSynthetic(PRBool &aResult) {
aResult = PR_TRUE;
return NS_OK;
}
NS_IMETHOD ReplaceChildAt(nsIContent *aKid, PRInt32 aIndex, PRBool aNotify) {
return NS_OK;
}
NS_IMETHOD AppendChildTo(nsIContent *aKid, PRBool aNotify) {
return NS_OK;
}
NS_IMETHOD SetAttribute(PRInt32 aNameSpaceID, nsIAtom *aName, const nsString &aValue, PRBool aNotify) {
return NS_OK;
}
NS_IMETHOD GetAttribute(PRInt32 aNameSpaceID, nsIAtom *aName, nsString &aResult) const {
return NS_CONTENT_ATTR_NOT_THERE;
}
NS_IMETHOD ParseAttributeString(const nsString &aStr, nsIAtom *&aName, PRInt32 &aNameSpaceID) {
aName = nsnull;
aNameSpaceID = kNameSpaceID_None;
return NS_OK;
}
NS_IMETHOD GetNameSpacePrefixFromId(PRInt32 aNameSpaceID, nsIAtom *&aPrefix) {
aPrefix = nsnull;
return NS_OK;
}
NS_IMETHOD GetAttributeCount(PRInt32 &aCountResult) const {
aCountResult = 0;
return NS_OK;
}
NS_IMETHOD List(FILE *out=stdout, PRInt32 aIndent=0) const {
return NS_OK;
}
NS_IMETHOD UnsetAttribute(PRInt32 aNameSpaceID, nsIAtom *aAttribute, PRBool aNotify) {
return NS_OK;
}
NS_IMETHOD GetAttributeNameAt(PRInt32 aIndex, PRInt32 &aNameSpaceID, nsIAtom *&aName) const {
aName = nsnull;
return NS_ERROR_ILLEGAL_VALUE;
}
NS_IMETHOD RangeAdd(nsIDOMRange &aRange) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHOD RangeRemove(nsIDOMRange &aRange) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHOD GetRangeList(nsVoidArray *&aResult) const {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHOD BeginConvertToXIF(nsXIFConverter &aConverter) const {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHOD ConvertContentToXIF(nsXIFConverter &aConverter) const {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHOD FinishConvertToXIF(nsXIFConverter &aConverter) const {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHOD HandleDOMEvent(nsIPresContext &aPresContext, nsEvent *aEvent, nsIDOMEvent **aDOMEvent, PRUint32 aFlags, nsEventStatus &aEventStatus) {
return NS_OK;
}
NS_IMETHOD GetText(const nsTextFragment *&aFragmentsResult, PRInt32 &aNumFragmentsResult) {
// XXX ???;
aNumFragmentsResult = 1;
return NS_OK;
}
NS_IMETHOD SetText(const PRUnichar *aBuffer, PRInt32 aLength, PRBool aNotify) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHOD SetText(const char *aBuffer, PRInt32 aLength, PRBool aNotify) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHOD IsOnlyWhitespace(PRBool *aResult) {
*aResult = PR_FALSE;
return NS_OK;
}
protected:
nsIContent* mContent;
const char* mAttr;
};
nsresult
nsCSSFrameConstructor::CreateGeneratedFrameFor(nsIPresContext* aPresContext,
nsIFrame* aParentFrame,
nsIContent* aContent,
nsIStyleContext* aStyleContext,
const nsStyleContent* aStyleContent,
PRUint32 aContentIndex,
nsIFrame** aFrame)
{
*aFrame = nsnull; // initialize OUT parameter
// Get the content value
nsStyleContentType type;
nsAutoString contentString;
aStyleContent->GetContentAt(aContentIndex, type, contentString);
if (eStyleContentType_URL == type) {
nsIHTMLContent* imageContent;
// Create an HTML image content object, and set the SRC.
// XXX Check if it's an image type we can handle...
NS_NewHTMLImageElement(&imageContent, nsHTMLAtoms::img);
imageContent->SetHTMLAttribute(nsHTMLAtoms::src, contentString, PR_FALSE);
// Create an image frame and initialize it
nsIFrame* imageFrame;
NS_NewImageFrame(imageFrame);
imageFrame->Init(*aPresContext, imageContent, aParentFrame, aStyleContext, nsnull);
NS_RELEASE(imageContent);
// Return the image frame
*aFrame = imageFrame;
} else {
switch (type) {
case eStyleContentType_String:
break;
case eStyleContentType_Attr:
{ // XXX for now, prefetch the attr value, this needs to be a special content node
nsIAtom* attrName = NS_NewAtom(contentString);
aContent->GetAttribute(kNameSpaceID_None, attrName, contentString); // XXX need attr namespace from style
NS_RELEASE(attrName);
}
break;
case eStyleContentType_Counter:
case eStyleContentType_Counters:
return NS_ERROR_NOT_IMPLEMENTED; // XXX not supported yet...
case eStyleContentType_OpenQuote:
case eStyleContentType_CloseQuote:
{
PRUint32 quotesCount = aStyleContent->QuotesCount();
if (quotesCount > 0) {
nsAutoString openQuote, closeQuote;
// If the depth is greater than the number of pairs, the last pair
// is repeated
PRUint32 quoteDepth = 0; // XXX really track the nested quotes...
if (quoteDepth > quotesCount) {
quoteDepth = quotesCount - 1;
}
aStyleContent->GetQuotesAt(quoteDepth, openQuote, closeQuote);
if (eStyleContentType_OpenQuote == type) {
contentString = openQuote;
} else {
contentString = closeQuote;
}
} else {
contentString = '"';
}
}
break;
case eStyleContentType_NoOpenQuote:
case eStyleContentType_NoCloseQuote:
// XXX Adjust quote depth...
return NS_OK;
}
// Create a text content node
nsIContent* textContent;
nsIDOMCharacterData* domData;
NS_NewTextNode(&textContent);
textContent->QueryInterface(kIDOMCharacterDataIID, (void**)&domData);
domData->SetData(contentString);
NS_RELEASE(domData);
// Create a text frame and initialize it
nsIFrame* textFrame;
NS_NewTextFrame(textFrame);
textFrame->Init(*aPresContext, textContent, aParentFrame, aStyleContext, nsnull);
NS_RELEASE(textContent);
// Return the text frame
*aFrame = textFrame;
}
return NS_OK;
}
PRBool
nsCSSFrameConstructor::CreateGeneratedContentFrame(nsIPresContext* aPresContext,
nsIFrame* aFrame,
@@ -264,93 +497,89 @@ nsCSSFrameConstructor::CreateGeneratedContentFrame(nsIPresContext* aPresContext
PR_FALSE, &pseudoStyleContext);
if (pseudoStyleContext) {
nsIContent* textContent;
nsIDOMCharacterData* domData;
const nsStyleDisplay* display;
// See whether the generated content should be displayed.
display = (const nsStyleDisplay*)pseudoStyleContext->GetStyleData(eStyleStruct_Display);
if (NS_STYLE_DISPLAY_NONE != display->mDisplay) {
PRUint8 displayValue = display->mDisplay;
// Make sure the 'display' property value is allowable
const nsStyleDisplay* subjectDisplay = (const nsStyleDisplay*)
aStyleContext->GetStyleData(eStyleStruct_Display);
if (subjectDisplay->IsBlockLevel()) {
// For block-level elements the only allowed 'display' values are:
// 'none', 'inline', 'block', and 'marker'
if ((NS_STYLE_DISPLAY_INLINE != displayValue) &&
(NS_STYLE_DISPLAY_BLOCK != displayValue) &&
(NS_STYLE_DISPLAY_MARKER != displayValue)) {
// Pseudo-element behaves as if the value were 'block'
displayValue = NS_STYLE_DISPLAY_BLOCK;
}
} else {
// For inline-level elements the only allowed 'display' values are
// 'none' and 'inline'
displayValue = NS_STYLE_DISPLAY_INLINE;
}
if (display->mDisplay != displayValue) {
// Reset the value
nsStyleDisplay* mutableDisplay = (nsStyleDisplay*)
pseudoStyleContext->GetMutableStyleData(eStyleStruct_Display);
mutableDisplay->mDisplay = displayValue;
}
// Now create the content object and frame based on the 'content' property
// XXX For the time being just pretend it's text
// XXX this needs to create a wrapper frame, then a collection of text frames to contain the
// generated content nodes.
// for now, create a single text frame
// See if there was any content specified
const nsStyleContent* styleContent;
styleContent = (const nsStyleContent*)pseudoStyleContext->GetStyleData(eStyleStruct_Content);
PRUint32 contentCount = styleContent->ContentCount();
if (contentCount) {
nsStyleContentType type;
nsAutoString contentString;
styleContent->GetContentAt(0, type, contentString);
switch (type) {
case eStyleContentType_String:
break;
case eStyleContentType_Attr:
{ // XXX for now, prefetch the attr value, this needs to be a special content node
nsIAtom* attrName = NS_NewAtom(contentString);
aContent->GetAttribute(kNameSpaceID_None, attrName, contentString); // XXX need attr namespace from style
NS_RELEASE(attrName);
}
break;
case eStyleContentType_URL: // XXX need to handle these differently than simple text
case eStyleContentType_Counter:
case eStyleContentType_Counters:
case eStyleContentType_OpenQuote:
case eStyleContentType_CloseQuote:
case eStyleContentType_NoOpenQuote:
case eStyleContentType_NoCloseQuote:
contentString.Append("GENERATED");
break;
if (contentCount > 0) {
PRUint8 displayValue = display->mDisplay;
// Make sure the 'display' property value is allowable
const nsStyleDisplay* subjectDisplay = (const nsStyleDisplay*)
aStyleContext->GetStyleData(eStyleStruct_Display);
if (subjectDisplay->IsBlockLevel()) {
// For block-level elements the only allowed 'display' values are:
// 'none', 'inline', 'block', and 'marker'
if ((NS_STYLE_DISPLAY_INLINE != displayValue) &&
(NS_STYLE_DISPLAY_BLOCK != displayValue) &&
(NS_STYLE_DISPLAY_MARKER != displayValue)) {
// Pseudo-element behaves as if the value were 'block'
displayValue = NS_STYLE_DISPLAY_BLOCK;
}
} else {
// For inline-level elements the only allowed 'display' values are
// 'none' and 'inline'
displayValue = NS_STYLE_DISPLAY_INLINE;
}
NS_NewTextNode(&textContent);
textContent->QueryInterface(kIDOMCharacterDataIID, (void**)&domData);
domData->SetData(contentString);
NS_RELEASE(domData);
// Create a text frame and initialize it
nsIFrame* textFrame;
NS_NewTextFrame(textFrame);
textFrame->Init(*aPresContext, textContent, aFrame, pseudoStyleContext, nsnull);
if (display->mDisplay != displayValue) {
// Reset the value
nsStyleDisplay* mutableDisplay = (nsStyleDisplay*)
pseudoStyleContext->GetMutableStyleData(eStyleStruct_Display);
mutableDisplay->mDisplay = displayValue;
}
// Create a block box or an inline box depending on the value of
// the 'display' property
nsIFrame* containerFrame;
nsFrameItems childFrames;
if (NS_STYLE_DISPLAY_BLOCK == displayValue) {
NS_NewBlockFrame(containerFrame, 0);
} else {
NS_NewInlineFrame(containerFrame);
}
containerFrame->Init(*aPresContext, aContent, aFrame, pseudoStyleContext, nsnull);
// Create another pseudo style context to use for all the generated child
// frames
nsIStyleContext* textStyleContext;
aPresContext->ResolvePseudoStyleContextFor(aContent, nsHTMLAtoms::textPseudo,
pseudoStyleContext, PR_FALSE,
&textStyleContext);
// Now create content objects (and child frames) for each value of the
// 'content' property
for (PRUint32 contentIndex = 0; contentIndex < contentCount; contentIndex++) {
nsIFrame* frame;
nsresult result;
// Create a frame
result = CreateGeneratedFrameFor(aPresContext, containerFrame, aContent,
textStyleContext, styleContent,
contentIndex, &frame);
if (NS_SUCCEEDED(result) && frame) {
// Add it to the list of child frames
childFrames.AddChild(frame);
}
}
NS_RELEASE(textStyleContext);
NS_RELEASE(pseudoStyleContext);
NS_RELEASE(textContent);
*aResult = textFrame;
if (childFrames.childList) {
containerFrame->SetInitialChildList(*aPresContext, nsnull, childFrames.childList);
}
*aResult = containerFrame;
return PR_TRUE;
}
}
@@ -374,14 +603,12 @@ nsCSSFrameConstructor::ProcessChildren(nsIPresContext* aPresContext,
nsAbsoluteItems& aAbsoluteItems,
nsFrameItems& aFrameItems,
nsAbsoluteItems& aFixedItems,
nsAbsoluteItems& aFloatingItems)
nsAbsoluteItems& aFloatingItems,
PRBool aCanHaveGeneratedContent)
{
// If the content can contain children, then check for generated content
nsIStyleContext* styleContext = nsnull;
PRBool canContainChildren;
aContent->CanContainChildren(canContainChildren);
if (canContainChildren) {
if (aCanHaveGeneratedContent) {
nsIFrame* generatedFrame;
// Probe for generated content before
@@ -406,7 +633,7 @@ nsCSSFrameConstructor::ProcessChildren(nsIPresContext* aPresContext,
}
}
if (canContainChildren) {
if (aCanHaveGeneratedContent) {
nsIFrame* generatedFrame;
// Probe for generated content after
@@ -810,7 +1037,7 @@ nsCSSFrameConstructor::ConstructTableCaptionFrame(nsIPresContext* aPresContext,
nsFrameItems childItems;
nsAbsoluteItems floatingKids(aNewCaptionFrame);
ProcessChildren(aPresContext, aContent, aNewCaptionFrame, aAbsoluteItems,
childItems, aFixedItems, floatingKids);
childItems, aFixedItems, floatingKids, PR_TRUE);
aNewCaptionFrame->SetInitialChildList(*aPresContext, nsnull, childItems.childList);
if (floatingKids.childList) {
aNewCaptionFrame->SetInitialChildList(*aPresContext,
@@ -1248,7 +1475,7 @@ nsCSSFrameConstructor::ConstructTableCellFrameOnly(nsIPresContext* aPresContext
nsFrameItems childItems;
nsAbsoluteItems floaterList(aNewCellBodyFrame);
rv = ProcessChildren(aPresContext, aContent, aNewCellBodyFrame, aAbsoluteItems,
childItems, aFixedItems, floaterList);
childItems, aFixedItems, floaterList, PR_TRUE);
if (NS_FAILED(rv)) return rv;
aNewCellBodyFrame->SetInitialChildList(*aPresContext, nsnull, childItems.childList);
if (floaterList.childList) {
@@ -1535,7 +1762,7 @@ nsCSSFrameConstructor::ConstructDocElementFrame(nsIPresContext* aPresContext,
nsFrameItems childItems;
ProcessChildren(aPresContext, aDocElement, areaFrame, absoluteItems,
childItems, aFixedItems, floaterList);
childItems, aFixedItems, floaterList, PR_TRUE);
// Set the initial child lists
areaFrame->SetInitialChildList(*aPresContext, nsnull,
@@ -1598,7 +1825,7 @@ nsCSSFrameConstructor::ConstructDocElementFrame(nsIPresContext* aPresContext,
nsFrameItems childItems;
ProcessChildren(aPresContext, aDocElement, areaFrame, absoluteItems,
childItems, aFixedItems, floatingItems);
childItems, aFixedItems, floatingItems, PR_TRUE);
// Set the initial child lists
areaFrame->SetInitialChildList(*aPresContext, nsnull,
@@ -2004,6 +2231,7 @@ nsCSSFrameConstructor::ConstructFrameByTag(nsIPresContext* aPresContext,
nsIFrame* newFrame = nsnull; // the frame we construct
PRBool newFrameIsFloaterContainer = PR_FALSE;
PRBool isReplaced = PR_FALSE;
PRBool canHaveGeneratedContent = PR_FALSE; // ignore things like text
nsIFrame* beforeGenerated = nsnull;
nsIFrame* afterGenerated = nsnull;
nsresult rv = NS_OK;
@@ -2034,6 +2262,9 @@ nsCSSFrameConstructor::ConstructFrameByTag(nsIPresContext* aPresContext,
isFloating = PR_TRUE;
}
// Most things in here can have generated content
canHaveGeneratedContent = PR_TRUE;
// Create a frame based on the tag
if (nsHTMLAtoms::img == aTag) {
isReplaced = PR_TRUE;
@@ -2083,10 +2314,16 @@ nsCSSFrameConstructor::ConstructFrameByTag(nsIPresContext* aPresContext,
rv = NS_NewLegendFrame(newFrame);
processChildren = PR_TRUE;
canBePositioned = PR_FALSE;
canHaveGeneratedContent = PR_FALSE;
}
else if (nsHTMLAtoms::object == aTag) {
isReplaced = PR_TRUE;
rv = NS_NewObjectFrame(newFrame);
// Note: if we can render the OBJECT element, then the generated content
// goes before and after the replaced element (as sibling frames) because
// we're ignoring the OBJECT element's content.
// If we can't render the OBJECT element, then the generated content goes
// before and after the OBJECT element's content
}
else if (nsHTMLAtoms::form == aTag) {
rv = NS_NewFormFrame(newFrame);
@@ -2094,6 +2331,7 @@ nsCSSFrameConstructor::ConstructFrameByTag(nsIPresContext* aPresContext,
else if (nsHTMLAtoms::frameset == aTag) {
rv = NS_NewHTMLFramesetFrame(newFrame);
canBePositioned = PR_FALSE;
canHaveGeneratedContent = PR_FALSE;
}
else if (nsHTMLAtoms::iframe == aTag) {
isReplaced = PR_TRUE;
@@ -2148,6 +2386,15 @@ nsCSSFrameConstructor::ConstructFrameByTag(nsIPresContext* aPresContext,
nsHTMLContainerFrame::CreateViewForFrame(*aPresContext, newFrame,
aStyleContext, PR_FALSE);
// If it's allowed to have generated content, then check for :before
// and :after pseudo-elements
if (canHaveGeneratedContent) {
CreateGeneratedContentFrame(aPresContext, newFrame, aContent, aStyleContext,
nsCSSAtoms::beforePseudo, &beforeGenerated);
CreateGeneratedContentFrame(aPresContext, newFrame, aContent, aStyleContext,
nsCSSAtoms::afterPseudo, &afterGenerated);
}
// Process the child content if requested
nsFrameItems childItems;
nsAbsoluteItems floaterList(newFrame);
@@ -2155,22 +2402,13 @@ nsCSSFrameConstructor::ConstructFrameByTag(nsIPresContext* aPresContext,
if (newFrameIsFloaterContainer) {
rv = ProcessChildren(aPresContext, aContent, newFrame,
aAbsoluteItems, childItems, aFixedItems,
floaterList);
floaterList, PR_TRUE);
}
else {
rv = ProcessChildren(aPresContext, aContent, newFrame,
aAbsoluteItems, childItems, aFixedItems,
aFloatingItems);
aFloatingItems, PR_TRUE);
}
} else {
// Check for generated content before and after.
// Note: we don't need to do this in the case where we're processing
// children, because ProcessChildren() takes care of this...
CreateGeneratedContentFrame(aPresContext, newFrame, aContent, aStyleContext,
nsCSSAtoms::beforePseudo, &beforeGenerated);
CreateGeneratedContentFrame(aPresContext, newFrame, aContent, aStyleContext,
nsCSSAtoms::afterPseudo, &afterGenerated);
}
// Set the frame's initial child list
@@ -2663,7 +2901,7 @@ nsCSSFrameConstructor::ConstructFrameByDisplayType(nsIPresContext* aPresCo
nsAbsoluteItems floaterList(newFrame);
ProcessChildren(aPresContext, aContent, newFrame, absoluteItems,
childItems, aFixedItems, floaterList);
childItems, aFixedItems, floaterList, PR_TRUE);
// Set the frame's initial child list(s)
newFrame->SetInitialChildList(*aPresContext, nsnull, childItems.childList);
@@ -2696,7 +2934,7 @@ nsCSSFrameConstructor::ConstructFrameByDisplayType(nsIPresContext* aPresCo
nsFrameItems childItems;
nsAbsoluteItems floaterList(newFrame);
ProcessChildren(aPresContext, aContent, newFrame, aAbsoluteItems,
childItems, aFixedItems, floaterList);
childItems, aFixedItems, floaterList, PR_TRUE);
// Set the frame's initial child list(s)
newFrame->SetInitialChildList(*aPresContext, nsnull, childItems.childList);
@@ -2724,7 +2962,7 @@ nsCSSFrameConstructor::ConstructFrameByDisplayType(nsIPresContext* aPresCo
nsAbsoluteItems floaterList(newFrame);
nsFrameItems childItems;
ProcessChildren(aPresContext, aContent, newFrame, absoluteItems,
childItems, aFixedItems, floaterList);
childItems, aFixedItems, floaterList, PR_TRUE);
// Set the frame's initial child list
newFrame->SetInitialChildList(*aPresContext, nsnull, childItems.childList);
@@ -2843,7 +3081,7 @@ nsCSSFrameConstructor::ConstructFrameByDisplayType(nsIPresContext* aPresCo
nsAbsoluteItems floaterList(newFrame);
rv = ProcessChildren(aPresContext, aContent, newFrame,
aAbsoluteItems, childItems, aFixedItems,
aFloatingItems);
aFloatingItems, PR_TRUE);
// Set the frame's initial child list
newFrame->SetInitialChildList(*aPresContext, nsnull,
@@ -2857,7 +3095,7 @@ nsCSSFrameConstructor::ConstructFrameByDisplayType(nsIPresContext* aPresCo
else {
rv = ProcessChildren(aPresContext, aContent, newFrame,
aAbsoluteItems, childItems, aFixedItems,
aFloatingItems);
aFloatingItems, PR_TRUE);
// Set the frame's initial child list
newFrame->SetInitialChildList(*aPresContext, nsnull,
@@ -4523,7 +4761,7 @@ nsCSSFrameConstructor::CreateContinuingOuterTableFrame(nsIPresContext* aPresCon
NS_NewAreaFrame(captionFrame, 0);
captionFrame->Init(*aPresContext, caption, newFrame, captionStyle, nsnull);
ProcessChildren(aPresContext, caption, captionFrame, absoluteItems,
childItems, fixedItems, floaterList);
childItems, fixedItems, floaterList, PR_TRUE);
captionFrame->SetInitialChildList(*aPresContext, nsnull, childItems.childList);
// XXX Deal with absolute and fixed frames...
if (floaterList.childList) {

View File

@@ -27,6 +27,7 @@ struct nsAbsoluteItems;
struct nsTableCreator;
class nsIStyleContext;
struct nsTableList;
struct nsStyleContent;
struct nsStyleDisplay;
class nsIPresShell;
class nsVoidArray;
@@ -131,6 +132,14 @@ protected:
nsIFrame*& aNewFrame,
nsAbsoluteItems& aFixedItems);
nsresult CreateGeneratedFrameFor(nsIPresContext* aPresContext,
nsIFrame* aParentFrame,
nsIContent* aContent,
nsIStyleContext* aStyleContext,
const nsStyleContent* aStyleContent,
PRUint32 aContentIndex,
nsIFrame** aFrame);
PRBool CreateGeneratedContentFrame(nsIPresContext* aPresContext,
nsIFrame* aFrame,
nsIContent* aContent,
@@ -363,7 +372,8 @@ protected:
nsAbsoluteItems& aAbsoluteItems,
nsFrameItems& aFrameItems,
nsAbsoluteItems& aFixedItems,
nsAbsoluteItems& aFloatingItems);
nsAbsoluteItems& aFloatingItems,
PRBool aCanHaveGeneratedContent = PR_FALSE);
nsresult CreateInputFrame(nsIContent* aContent, nsIFrame*& aFrame);