зеркало из https://github.com/mozilla/gecko-dev.git
Bug 473390 part 7. Switch HTML frame construction over to the new setup. r+sr=roc
This commit is contained in:
Родитель
225d63e68a
Коммит
c5143ee137
|
@ -1149,8 +1149,7 @@ public:
|
|||
|
||||
// Function to return the proper geometric parent for a frame with display
|
||||
// struct given by aStyleDisplay and parent's frame given by
|
||||
// aContentParentFrame. If the frame is not allowed to be positioned, pass
|
||||
// false for aCanBePositioned.
|
||||
// aContentParentFrame.
|
||||
nsIFrame* GetGeometricParent(const nsStyleDisplay* aStyleDisplay,
|
||||
nsIFrame* aContentParentFrame);
|
||||
|
||||
|
@ -2183,99 +2182,6 @@ nsCSSFrameConstructor::CreateGeneratedContentFrame(nsFrameConstructorState& aSta
|
|||
aState.mAdditionalStateBits = savedStateBits;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsCSSFrameConstructor::CreateInputFrame(nsFrameConstructorState& aState,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParentFrame,
|
||||
nsIAtom* aTag,
|
||||
nsStyleContext* aStyleContext,
|
||||
nsIFrame** aFrame,
|
||||
const nsStyleDisplay* aStyleDisplay,
|
||||
PRBool& aFrameHasBeenInitialized,
|
||||
PRBool& aAddedToFrameList,
|
||||
nsFrameItems& aFrameItems,
|
||||
PRBool aHasPseudoParent)
|
||||
{
|
||||
// Make sure to keep IsSpecialContent in synch with this code
|
||||
|
||||
// Note: do not do anything in this method that assumes pseudo-frames have
|
||||
// been processed. If you feel the urge to do something like that, fix
|
||||
// callers accordingly.
|
||||
nsCOMPtr<nsIFormControl> control = do_QueryInterface(aContent);
|
||||
if (!control) {
|
||||
NS_ERROR("input doesn't implement nsIFormControl?");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
switch (control->GetType()) {
|
||||
case NS_FORM_INPUT_SUBMIT:
|
||||
case NS_FORM_INPUT_RESET:
|
||||
case NS_FORM_INPUT_BUTTON:
|
||||
{
|
||||
nsresult rv = ConstructButtonFrame(aState, aContent, aParentFrame,
|
||||
aTag, aStyleContext, aFrame,
|
||||
aStyleDisplay, aFrameItems,
|
||||
aHasPseudoParent);
|
||||
aAddedToFrameList = PR_TRUE;
|
||||
aFrameHasBeenInitialized = PR_TRUE;
|
||||
return rv;
|
||||
}
|
||||
|
||||
case NS_FORM_INPUT_CHECKBOX:
|
||||
*aFrame = NS_NewGfxCheckboxControlFrame(mPresShell, aStyleContext);
|
||||
return *aFrame ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
case NS_FORM_INPUT_RADIO:
|
||||
*aFrame = NS_NewGfxRadioControlFrame(mPresShell, aStyleContext);
|
||||
return *aFrame ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
case NS_FORM_INPUT_FILE:
|
||||
{
|
||||
*aFrame = NS_NewFileControlFrame(mPresShell, aStyleContext);
|
||||
return *aFrame ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
case NS_FORM_INPUT_HIDDEN:
|
||||
return NS_OK; // this does not create a frame so it needs special handling
|
||||
// in IsSpecialContent
|
||||
|
||||
case NS_FORM_INPUT_IMAGE:
|
||||
return CreateHTMLImageFrame(aContent, aStyleContext,
|
||||
NS_NewImageControlFrame, aFrame);
|
||||
|
||||
case NS_FORM_INPUT_TEXT:
|
||||
case NS_FORM_INPUT_PASSWORD:
|
||||
{
|
||||
*aFrame = NS_NewTextControlFrame(mPresShell, aStyleContext);
|
||||
|
||||
return NS_UNLIKELY(!*aFrame) ? NS_ERROR_OUT_OF_MEMORY : NS_OK;
|
||||
}
|
||||
|
||||
default:
|
||||
NS_ASSERTION(0, "Unknown input type!");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsCSSFrameConstructor::CreateHTMLImageFrame(nsIContent* aContent,
|
||||
nsStyleContext* aStyleContext,
|
||||
ImageFrameCreatorFunc aFunc,
|
||||
nsIFrame** aFrame)
|
||||
{
|
||||
*aFrame = nsnull;
|
||||
|
||||
// Make sure to keep IsSpecialContent in synch with this code
|
||||
if (nsImageFrame::ShouldCreateImageFrameFor(aContent, aStyleContext)) {
|
||||
*aFrame = (*aFunc)(mPresShell, aStyleContext);
|
||||
|
||||
if (NS_UNLIKELY(!*aFrame))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static PRBool
|
||||
TextIsOnlyWhitespace(nsIContent* aContent)
|
||||
{
|
||||
|
@ -3192,66 +3098,18 @@ nsCSSFrameConstructor::GetParentFrame(PRInt32 aNameSpaceID,
|
|||
return rv;
|
||||
}
|
||||
|
||||
static PRBool
|
||||
IsSpecialContent(nsIContent* aContent,
|
||||
nsIAtom* aTag,
|
||||
PRInt32 aNameSpaceID,
|
||||
nsStyleContext* aStyleContext)
|
||||
/* static */
|
||||
PRBool
|
||||
nsCSSFrameConstructor::IsSpecialContent(nsIContent* aContent,
|
||||
nsIAtom* aTag,
|
||||
PRInt32 aNameSpaceID,
|
||||
nsStyleContext* aStyleContext)
|
||||
{
|
||||
// Gross hack. Return true if this is a content node that we'd create a
|
||||
// frame for based on something other than display -- in other words if this
|
||||
// is a node that could never have a nsTableCellFrame, for example.
|
||||
if (aContent->IsNodeOfType(nsINode::eHTML) ||
|
||||
aNameSpaceID == kNameSpaceID_XHTML) {
|
||||
// XXXbz this is duplicating some logic from ConstructHTMLFrame....
|
||||
// Would be nice to avoid that. :(
|
||||
|
||||
if (aTag == nsGkAtoms::input) {
|
||||
nsCOMPtr<nsIFormControl> control = do_QueryInterface(aContent);
|
||||
if (control) {
|
||||
PRInt32 type = control->GetType();
|
||||
if (NS_FORM_INPUT_HIDDEN == type) {
|
||||
return PR_FALSE; // input hidden does not create a special frame
|
||||
}
|
||||
else if (NS_FORM_INPUT_IMAGE == type) {
|
||||
return nsImageFrame::ShouldCreateImageFrameFor(aContent, aStyleContext);
|
||||
}
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
if (aTag == nsGkAtoms::img ||
|
||||
aTag == nsGkAtoms::mozgeneratedcontentimage) {
|
||||
return nsImageFrame::ShouldCreateImageFrameFor(aContent, aStyleContext);
|
||||
}
|
||||
|
||||
if (aTag == nsGkAtoms::object ||
|
||||
aTag == nsGkAtoms::applet ||
|
||||
aTag == nsGkAtoms::embed) {
|
||||
return !(aContent->IntrinsicState() &
|
||||
(NS_EVENT_STATE_BROKEN | NS_EVENT_STATE_USERDISABLED |
|
||||
NS_EVENT_STATE_SUPPRESSED));
|
||||
}
|
||||
|
||||
return
|
||||
aTag == nsGkAtoms::br ||
|
||||
aTag == nsGkAtoms::wbr ||
|
||||
aTag == nsGkAtoms::textarea ||
|
||||
aTag == nsGkAtoms::select ||
|
||||
aTag == nsGkAtoms::fieldset ||
|
||||
aTag == nsGkAtoms::legend ||
|
||||
aTag == nsGkAtoms::frameset ||
|
||||
aTag == nsGkAtoms::iframe ||
|
||||
aTag == nsGkAtoms::spacer ||
|
||||
aTag == nsGkAtoms::button ||
|
||||
aTag == nsGkAtoms::isindex ||
|
||||
aTag == nsGkAtoms::canvas ||
|
||||
#if defined(MOZ_MEDIA)
|
||||
aTag == nsGkAtoms::video ||
|
||||
aTag == nsGkAtoms::audio ||
|
||||
#endif
|
||||
PR_FALSE;
|
||||
if (FindHTMLData(aContent, aTag, aNameSpaceID, aStyleContext)) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -3936,15 +3794,6 @@ NeedFrameFor(nsIFrame* aParentFrame,
|
|||
|| aParentFrame->IsGeneratedContentFrame();
|
||||
}
|
||||
|
||||
const nsStyleDisplay*
|
||||
nsCSSFrameConstructor::GetDisplay(nsIFrame* aFrame)
|
||||
{
|
||||
if (nsnull == aFrame) {
|
||||
return nsnull;
|
||||
}
|
||||
return aFrame->GetStyleContext()->GetStyleDisplay();
|
||||
}
|
||||
|
||||
/***********************************************
|
||||
* END TABLE SECTION
|
||||
***********************************************/
|
||||
|
@ -4642,15 +4491,10 @@ nsCSSFrameConstructor::ConstructButtonFrame(nsFrameConstructorState& aState,
|
|||
nsIFrame* aParentFrame,
|
||||
nsIAtom* aTag,
|
||||
nsStyleContext* aStyleContext,
|
||||
nsIFrame** aNewFrame,
|
||||
const nsStyleDisplay* aStyleDisplay,
|
||||
nsFrameItems& aFrameItems,
|
||||
PRBool aHasPseudoParent)
|
||||
nsIFrame** aNewFrame)
|
||||
{
|
||||
if (!aHasPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
|
||||
ProcessPseudoFrames(aState, aFrameItems);
|
||||
}
|
||||
|
||||
*aNewFrame = nsnull;
|
||||
nsIFrame* buttonFrame = nsnull;
|
||||
|
||||
|
@ -4766,10 +4610,9 @@ nsCSSFrameConstructor::ConstructSelectFrame(nsFrameConstructorState& aState,
|
|||
nsIFrame* aParentFrame,
|
||||
nsIAtom* aTag,
|
||||
nsStyleContext* aStyleContext,
|
||||
nsIFrame*& aNewFrame,
|
||||
const nsStyleDisplay* aStyleDisplay,
|
||||
PRBool& aFrameHasBeenInitialized,
|
||||
nsFrameItems& aFrameItems)
|
||||
nsFrameItems& aFrameItems,
|
||||
nsIFrame** aNewFrame)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
const PRInt32 kNoSizeSpecified = -1;
|
||||
|
@ -4867,8 +4710,7 @@ nsCSSFrameConstructor::ConstructSelectFrame(nsFrameConstructorState& aState,
|
|||
comboboxFrame->SetInitialChildList(nsGkAtoms::selectPopupList,
|
||||
popupItems.childList);
|
||||
|
||||
aNewFrame = comboboxFrame;
|
||||
aFrameHasBeenInitialized = PR_TRUE;
|
||||
*aNewFrame = comboboxFrame;
|
||||
aState.mFrameState = historyState;
|
||||
if (aState.mFrameState && aState.mFrameManager) {
|
||||
// Restore frame state for the entire subtree of |comboboxFrame|.
|
||||
|
@ -4896,9 +4738,7 @@ nsCSSFrameConstructor::ConstructSelectFrame(nsFrameConstructorState& aState,
|
|||
InitializeSelectFrame(aState, listFrame, scrolledFrame, aContent,
|
||||
aParentFrame, aStyleContext, PR_FALSE, aFrameItems);
|
||||
|
||||
aNewFrame = listFrame;
|
||||
|
||||
aFrameHasBeenInitialized = PR_TRUE;
|
||||
*aNewFrame = listFrame;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
|
@ -4995,10 +4835,9 @@ nsCSSFrameConstructor::ConstructFieldSetFrame(nsFrameConstructorState& aState,
|
|||
nsIFrame* aParentFrame,
|
||||
nsIAtom* aTag,
|
||||
nsStyleContext* aStyleContext,
|
||||
nsIFrame*& aNewFrame,
|
||||
nsFrameItems& aFrameItems,
|
||||
const nsStyleDisplay* aStyleDisplay,
|
||||
PRBool& aFrameHasBeenInitialized)
|
||||
nsFrameItems& aFrameItems,
|
||||
nsIFrame** aNewFrame)
|
||||
{
|
||||
nsIFrame* newFrame = NS_NewFieldSetFrame(mPresShell, aStyleContext);
|
||||
if (NS_UNLIKELY(!newFrame)) {
|
||||
|
@ -5077,10 +4916,7 @@ nsCSSFrameConstructor::ConstructFieldSetFrame(nsFrameConstructorState& aState,
|
|||
newFrame->SetInitialChildList(nsnull, legendFrame ? legendFrame : blockFrame);
|
||||
|
||||
// our new frame returned is the top frame which is the list frame.
|
||||
aNewFrame = newFrame;
|
||||
|
||||
// yes we have already initialized our frame
|
||||
aFrameHasBeenInitialized = PR_TRUE;
|
||||
*aNewFrame = newFrame;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -5168,259 +5004,281 @@ nsCSSFrameConstructor::ConstructTextFrame(nsFrameConstructorState& aState,
|
|||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsCSSFrameConstructor::ConstructHTMLFrame(nsFrameConstructorState& aState,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParentFrame,
|
||||
nsIAtom* aTag,
|
||||
PRInt32 aNameSpaceID,
|
||||
nsStyleContext* aStyleContext,
|
||||
nsFrameItems& aFrameItems,
|
||||
PRBool aHasPseudoParent)
|
||||
/* static */
|
||||
const nsCSSFrameConstructor::FrameConstructionData*
|
||||
nsCSSFrameConstructor::FindDataByInt(PRInt32 aInt,
|
||||
nsIContent* aContent,
|
||||
nsStyleContext* aStyleContext,
|
||||
const FrameConstructionDataByInt* aDataPtr,
|
||||
PRUint32 aDataLength)
|
||||
{
|
||||
for (const FrameConstructionDataByInt *curData = aDataPtr,
|
||||
*endData = aDataPtr + aDataLength;
|
||||
curData != endData;
|
||||
++curData) {
|
||||
if (curData->mInt == aInt) {
|
||||
const FrameConstructionData* data = &curData->mData;
|
||||
if (data->mBits & FCDATA_FUNC_IS_DATA_GETTER) {
|
||||
return data->mFunc.mDataGetter(aContent, aStyleContext);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
/* static */
|
||||
const nsCSSFrameConstructor::FrameConstructionData*
|
||||
nsCSSFrameConstructor::FindDataByTag(nsIAtom* aTag,
|
||||
nsIContent* aContent,
|
||||
nsStyleContext* aStyleContext,
|
||||
const FrameConstructionDataByTag* aDataPtr,
|
||||
PRUint32 aDataLength)
|
||||
{
|
||||
for (const FrameConstructionDataByTag *curData = aDataPtr,
|
||||
*endData = aDataPtr + aDataLength;
|
||||
curData != endData;
|
||||
++curData) {
|
||||
if (*curData->mTag == aTag) {
|
||||
const FrameConstructionData* data = &curData->mData;
|
||||
if (data->mBits & FCDATA_FUNC_IS_DATA_GETTER) {
|
||||
return data->mFunc.mDataGetter(aContent, aStyleContext);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
#define FCDATA_DECL(_flags, _func) \
|
||||
{ _flags, { (FrameCreationFunc)_func } }
|
||||
#define SIMPLE_FCDATA(_func) FCDATA_DECL(0, _func)
|
||||
#define SIMPLE_INT_CREATE(_int, _func) { _int, SIMPLE_FCDATA(_func) }
|
||||
#define SIMPLE_INT_CHAIN(_int, _func) \
|
||||
{ _int, FCDATA_DECL(FCDATA_FUNC_IS_DATA_GETTER, _func) }
|
||||
#define COMPLEX_INT_CREATE(_int, _func) \
|
||||
{ _int, { FCDATA_FUNC_IS_FULL_CTOR, { nsnull }, _func } }
|
||||
|
||||
#define SIMPLE_TAG_CREATE(_tag, _func) \
|
||||
{ &nsGkAtoms::_tag, SIMPLE_FCDATA(_func) }
|
||||
#define SIMPLE_TAG_CHAIN(_tag, _func) \
|
||||
{ &nsGkAtoms::_tag, FCDATA_DECL(FCDATA_FUNC_IS_DATA_GETTER, _func) }
|
||||
#define COMPLEX_TAG_CREATE(_tag, _func) \
|
||||
{ &nsGkAtoms::_tag, { FCDATA_FUNC_IS_FULL_CTOR, { nsnull }, _func } }
|
||||
|
||||
/* static */
|
||||
const nsCSSFrameConstructor::FrameConstructionData*
|
||||
nsCSSFrameConstructor::FindHTMLData(nsIContent* aContent,
|
||||
nsIAtom* aTag,
|
||||
PRInt32 aNameSpaceID,
|
||||
nsStyleContext* aStyleContext)
|
||||
{
|
||||
// Ignore the tag if it's not HTML content and if it doesn't extend (via XBL)
|
||||
// a valid HTML namespace. This check must match the one in
|
||||
// ShouldHaveFirstLineStyle.
|
||||
if (!aContent->IsNodeOfType(nsINode::eHTML) &&
|
||||
aNameSpaceID != kNameSpaceID_XHTML) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
static const FrameConstructionDataByTag sHTMLData[] = {
|
||||
SIMPLE_TAG_CHAIN(img, nsCSSFrameConstructor::FindImgData),
|
||||
SIMPLE_TAG_CHAIN(mozgeneratedcontentimage,
|
||||
nsCSSFrameConstructor::FindImgData),
|
||||
{ &nsGkAtoms::br, FCDATA_DECL(FCDATA_SKIP_FRAMEMAP, NS_NewBRFrame) },
|
||||
SIMPLE_TAG_CREATE(wbr, NS_NewBRFrame),
|
||||
SIMPLE_TAG_CHAIN(input, nsCSSFrameConstructor::FindInputData),
|
||||
SIMPLE_TAG_CREATE(textarea, NS_NewTextControlFrame),
|
||||
COMPLEX_TAG_CREATE(select, &nsCSSFrameConstructor::ConstructSelectFrame),
|
||||
SIMPLE_TAG_CHAIN(object, nsCSSFrameConstructor::FindObjectData),
|
||||
SIMPLE_TAG_CHAIN(applet, nsCSSFrameConstructor::FindObjectData),
|
||||
SIMPLE_TAG_CHAIN(embed, nsCSSFrameConstructor::FindObjectData),
|
||||
COMPLEX_TAG_CREATE(fieldset,
|
||||
&nsCSSFrameConstructor::ConstructFieldSetFrame),
|
||||
SIMPLE_TAG_CREATE(legend, NS_NewLegendFrame),
|
||||
SIMPLE_TAG_CREATE(frameset, NS_NewHTMLFramesetFrame),
|
||||
SIMPLE_TAG_CREATE(iframe, NS_NewSubDocumentFrame),
|
||||
SIMPLE_TAG_CREATE(spacer, NS_NewSpacerFrame),
|
||||
COMPLEX_TAG_CREATE(button, &nsCSSFrameConstructor::ConstructButtonFrame),
|
||||
SIMPLE_TAG_CREATE(canvas, NS_NewHTMLCanvasFrame),
|
||||
#if defined(MOZ_MEDIA)
|
||||
SIMPLE_TAG_CREATE(video, NS_NewHTMLVideoFrame),
|
||||
SIMPLE_TAG_CREATE(audio, NS_NewHTMLVideoFrame),
|
||||
#endif
|
||||
SIMPLE_TAG_CREATE(isindex, NS_NewIsIndexFrame)
|
||||
};
|
||||
|
||||
return FindDataByTag(aTag, aContent, aStyleContext, sHTMLData,
|
||||
NS_ARRAY_LENGTH(sHTMLData));
|
||||
}
|
||||
|
||||
/* static */
|
||||
const nsCSSFrameConstructor::FrameConstructionData*
|
||||
nsCSSFrameConstructor::FindImgData(nsIContent* aContent,
|
||||
nsStyleContext* aStyleContext)
|
||||
{
|
||||
if (!nsImageFrame::ShouldCreateImageFrameFor(aContent, aStyleContext)) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
static const FrameConstructionData sImgData = SIMPLE_FCDATA(NS_NewImageFrame);
|
||||
return &sImgData;
|
||||
}
|
||||
|
||||
/* static */
|
||||
const nsCSSFrameConstructor::FrameConstructionData*
|
||||
nsCSSFrameConstructor::FindImgControlData(nsIContent* aContent,
|
||||
nsStyleContext* aStyleContext)
|
||||
{
|
||||
if (!nsImageFrame::ShouldCreateImageFrameFor(aContent, aStyleContext)) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
static const FrameConstructionData sImgControlData =
|
||||
SIMPLE_FCDATA(NS_NewImageControlFrame);
|
||||
return &sImgControlData;
|
||||
}
|
||||
|
||||
/* static */
|
||||
const nsCSSFrameConstructor::FrameConstructionData*
|
||||
nsCSSFrameConstructor::FindInputData(nsIContent* aContent,
|
||||
nsStyleContext* aStyleContext)
|
||||
{
|
||||
static const FrameConstructionDataByInt sInputData[] = {
|
||||
SIMPLE_INT_CREATE(NS_FORM_INPUT_CHECKBOX, NS_NewGfxCheckboxControlFrame),
|
||||
SIMPLE_INT_CREATE(NS_FORM_INPUT_RADIO, NS_NewGfxRadioControlFrame),
|
||||
SIMPLE_INT_CREATE(NS_FORM_INPUT_FILE, NS_NewFileControlFrame),
|
||||
SIMPLE_INT_CHAIN(NS_FORM_INPUT_IMAGE,
|
||||
nsCSSFrameConstructor::FindImgControlData),
|
||||
SIMPLE_INT_CREATE(NS_FORM_INPUT_TEXT, NS_NewTextControlFrame),
|
||||
SIMPLE_INT_CREATE(NS_FORM_INPUT_PASSWORD, NS_NewTextControlFrame),
|
||||
COMPLEX_INT_CREATE(NS_FORM_INPUT_SUBMIT,
|
||||
&nsCSSFrameConstructor::ConstructButtonFrame),
|
||||
COMPLEX_INT_CREATE(NS_FORM_INPUT_RESET,
|
||||
&nsCSSFrameConstructor::ConstructButtonFrame),
|
||||
COMPLEX_INT_CREATE(NS_FORM_INPUT_BUTTON,
|
||||
&nsCSSFrameConstructor::ConstructButtonFrame)
|
||||
// Keeping hidden inputs out of here on purpose for so they get frames by
|
||||
// display (in practice, none).
|
||||
};
|
||||
|
||||
nsCOMPtr<nsIFormControl> control = do_QueryInterface(aContent);
|
||||
NS_ASSERTION(control, "input doesn't implement nsIFormControl?");
|
||||
|
||||
return FindDataByInt(control->GetType(), aContent, aStyleContext,
|
||||
sInputData, NS_ARRAY_LENGTH(sInputData));
|
||||
}
|
||||
|
||||
/* static */
|
||||
const nsCSSFrameConstructor::FrameConstructionData*
|
||||
nsCSSFrameConstructor::FindObjectData(nsIContent* aContent,
|
||||
nsStyleContext* aStyleContext)
|
||||
{
|
||||
// GetDisplayedType isn't necessarily nsIObjectLoadingContent::TYPE_NULL for
|
||||
// cases when the object is broken/suppressed/etc (e.g. a broken image), but
|
||||
// we want to treat those cases as TYPE_NULL
|
||||
PRUint32 type;
|
||||
if (aContent->IntrinsicState() &
|
||||
(NS_EVENT_STATE_BROKEN | NS_EVENT_STATE_USERDISABLED |
|
||||
NS_EVENT_STATE_SUPPRESSED)) {
|
||||
type = nsIObjectLoadingContent::TYPE_NULL;
|
||||
} else {
|
||||
nsCOMPtr<nsIObjectLoadingContent> objContent(do_QueryInterface(aContent));
|
||||
NS_ASSERTION(objContent,
|
||||
"applet, embed and object must implement "
|
||||
"nsIObjectLoadingContent!");
|
||||
|
||||
objContent->GetDisplayedType(&type);
|
||||
}
|
||||
|
||||
static const FrameConstructionDataByInt sObjectData[] = {
|
||||
SIMPLE_INT_CREATE(nsIObjectLoadingContent::TYPE_LOADING,
|
||||
NS_NewEmptyFrame),
|
||||
SIMPLE_INT_CREATE(nsIObjectLoadingContent::TYPE_PLUGIN,
|
||||
NS_NewObjectFrame),
|
||||
SIMPLE_INT_CREATE(nsIObjectLoadingContent::TYPE_IMAGE,
|
||||
NS_NewImageFrame),
|
||||
SIMPLE_INT_CREATE(nsIObjectLoadingContent::TYPE_DOCUMENT,
|
||||
NS_NewSubDocumentFrame)
|
||||
// Nothing for TYPE_NULL so we'll construct frames by display there
|
||||
};
|
||||
|
||||
return FindDataByInt((PRInt32)type, aContent, aStyleContext,
|
||||
sObjectData, NS_ARRAY_LENGTH(sObjectData));
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsCSSFrameConstructor::ConstructFrameFromData(const FrameConstructionData* aData,
|
||||
nsFrameConstructorState& aState,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParentFrame,
|
||||
nsIAtom* aTag,
|
||||
nsStyleContext* aStyleContext,
|
||||
nsFrameItems& aFrameItems,
|
||||
PRBool aHasPseudoParent)
|
||||
{
|
||||
if (!aData) {
|
||||
// nothing to do
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool frameHasBeenInitialized = PR_FALSE;
|
||||
nsIFrame* newFrame = nsnull; // the frame we construct
|
||||
PRBool addToHashTable = PR_TRUE;
|
||||
PRBool addedToFrameList = PR_FALSE;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
PRBool triedFrame = PR_FALSE;
|
||||
PRUint32 bits = aData->mBits;
|
||||
|
||||
NS_ASSERTION(!(bits & FCDATA_FUNC_IS_DATA_GETTER),
|
||||
"Should have dealt with this inside the data finder");
|
||||
|
||||
// We found something, so not creating by display type. Process
|
||||
// pseudo-frames now.
|
||||
if (!aHasPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
|
||||
ProcessPseudoFrames(aState, aFrameItems);
|
||||
}
|
||||
|
||||
// See if the element is absolute or fixed positioned
|
||||
const nsStyleDisplay* display = aStyleContext->GetStyleDisplay();
|
||||
|
||||
// Create a frame based on the tag
|
||||
if (nsGkAtoms::img == aTag || nsGkAtoms::mozgeneratedcontentimage == aTag) {
|
||||
// Make sure to keep IsSpecialContent in synch with this code
|
||||
rv = CreateHTMLImageFrame(aContent, aStyleContext, NS_NewImageFrame,
|
||||
&newFrame);
|
||||
if (newFrame) {
|
||||
if (!aHasPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
|
||||
ProcessPseudoFrames(aState, aFrameItems);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (nsGkAtoms::br == aTag) {
|
||||
if (!aHasPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
|
||||
ProcessPseudoFrames(aState, aFrameItems);
|
||||
}
|
||||
newFrame = NS_NewBRFrame(mPresShell, aStyleContext);
|
||||
triedFrame = PR_TRUE;
|
||||
|
||||
// BR frames don't go in the content->frame hash table: typically
|
||||
// there are many BR content objects and this would increase the size
|
||||
// of the hash table, and it's doubtful we need the mapping anyway
|
||||
addToHashTable = PR_FALSE;
|
||||
}
|
||||
else if (nsGkAtoms::wbr == aTag) {
|
||||
if (!aHasPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
|
||||
ProcessPseudoFrames(aState, aFrameItems);
|
||||
}
|
||||
newFrame = NS_NewWBRFrame(mPresShell, aStyleContext);
|
||||
triedFrame = PR_TRUE;
|
||||
}
|
||||
else if (nsGkAtoms::input == aTag) {
|
||||
// Make sure to keep IsSpecialContent in synch with this code
|
||||
rv = CreateInputFrame(aState, aContent, aParentFrame,
|
||||
aTag, aStyleContext, &newFrame,
|
||||
display, frameHasBeenInitialized,
|
||||
addedToFrameList, aFrameItems,
|
||||
aHasPseudoParent);
|
||||
if (!aHasPseudoParent && !aState.mPseudoFrames.IsEmpty() &&
|
||||
newFrame && !addedToFrameList) {
|
||||
// We'll still be adding this new frame, and it's a replaced
|
||||
// element, so process pseudo-frames now.
|
||||
ProcessPseudoFrames(aState, aFrameItems);
|
||||
}
|
||||
}
|
||||
else if (nsGkAtoms::textarea == aTag) {
|
||||
if (!aHasPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
|
||||
ProcessPseudoFrames(aState, aFrameItems);
|
||||
}
|
||||
newFrame = NS_NewTextControlFrame(mPresShell, aStyleContext);
|
||||
triedFrame = PR_TRUE;
|
||||
}
|
||||
else if (nsGkAtoms::select == aTag) {
|
||||
if (!aHasPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
|
||||
ProcessPseudoFrames(aState, aFrameItems);
|
||||
}
|
||||
rv = ConstructSelectFrame(aState, aContent, aParentFrame,
|
||||
aTag, aStyleContext, newFrame,
|
||||
display, frameHasBeenInitialized,
|
||||
aFrameItems);
|
||||
if (newFrame) {
|
||||
NS_ASSERTION(nsPlaceholderFrame::GetRealFrameFor(aFrameItems.lastChild) ==
|
||||
newFrame,
|
||||
"Frame didn't get added to aFrameItems?");
|
||||
addedToFrameList = PR_TRUE;
|
||||
}
|
||||
}
|
||||
else if (nsGkAtoms::object == aTag ||
|
||||
nsGkAtoms::applet == aTag ||
|
||||
nsGkAtoms::embed == aTag) {
|
||||
// Make sure to keep IsSpecialContent in synch with this code
|
||||
if (!(aContent->IntrinsicState() &
|
||||
(NS_EVENT_STATE_BROKEN | NS_EVENT_STATE_USERDISABLED |
|
||||
NS_EVENT_STATE_SUPPRESSED))) {
|
||||
if (!aHasPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
|
||||
ProcessPseudoFrames(aState, aFrameItems);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIObjectLoadingContent> objContent(do_QueryInterface(aContent));
|
||||
NS_ASSERTION(objContent,
|
||||
"applet, embed and object must implement nsIObjectLoadingContent!");
|
||||
if (!objContent) {
|
||||
// XBL might trigger this...
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
PRUint32 type;
|
||||
objContent->GetDisplayedType(&type);
|
||||
if (type == nsIObjectLoadingContent::TYPE_LOADING) {
|
||||
// Ideally, this should show the standby attribute
|
||||
// XXX Should we return something that is replaced, or make
|
||||
// nsFrame replaced but not its subclasses?
|
||||
newFrame = NS_NewEmptyFrame(mPresShell, aStyleContext);
|
||||
}
|
||||
else if (type == nsIObjectLoadingContent::TYPE_PLUGIN)
|
||||
newFrame = NS_NewObjectFrame(mPresShell, aStyleContext);
|
||||
else if (type == nsIObjectLoadingContent::TYPE_IMAGE)
|
||||
newFrame = NS_NewImageFrame(mPresShell, aStyleContext);
|
||||
else if (type == nsIObjectLoadingContent::TYPE_DOCUMENT)
|
||||
newFrame = NS_NewSubDocumentFrame(mPresShell, aStyleContext);
|
||||
#ifdef DEBUG
|
||||
else
|
||||
NS_ERROR("Shouldn't get here if we're not broken and not "
|
||||
"suppressed and not blocked");
|
||||
#endif
|
||||
|
||||
triedFrame = PR_TRUE;
|
||||
}
|
||||
}
|
||||
else if (nsGkAtoms::fieldset == aTag) {
|
||||
if (!aHasPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
|
||||
ProcessPseudoFrames(aState, aFrameItems);
|
||||
}
|
||||
rv = ConstructFieldSetFrame(aState, aContent, aParentFrame,
|
||||
aTag, aStyleContext, newFrame,
|
||||
aFrameItems, display, frameHasBeenInitialized);
|
||||
NS_ASSERTION(nsPlaceholderFrame::GetRealFrameFor(aFrameItems.lastChild) ==
|
||||
newFrame,
|
||||
"Frame didn't get added to aFrameItems?");
|
||||
addedToFrameList = PR_TRUE;
|
||||
}
|
||||
else if (nsGkAtoms::legend == aTag) {
|
||||
if (!aHasPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
|
||||
ProcessPseudoFrames(aState, aFrameItems);
|
||||
}
|
||||
newFrame = NS_NewLegendFrame(mPresShell, aStyleContext);
|
||||
triedFrame = PR_TRUE;
|
||||
}
|
||||
else if (nsGkAtoms::frameset == aTag) {
|
||||
if (!aHasPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
|
||||
ProcessPseudoFrames(aState, aFrameItems);
|
||||
}
|
||||
|
||||
newFrame = NS_NewHTMLFramesetFrame(mPresShell, aStyleContext);
|
||||
triedFrame = PR_TRUE;
|
||||
}
|
||||
else if (nsGkAtoms::iframe == aTag) {
|
||||
if (!aHasPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
|
||||
ProcessPseudoFrames(aState, aFrameItems);
|
||||
}
|
||||
|
||||
newFrame = NS_NewSubDocumentFrame(mPresShell, aStyleContext);
|
||||
triedFrame = PR_TRUE;
|
||||
}
|
||||
else if (nsGkAtoms::spacer == aTag) {
|
||||
if (!aHasPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
|
||||
ProcessPseudoFrames(aState, aFrameItems);
|
||||
}
|
||||
newFrame = NS_NewSpacerFrame(mPresShell, aStyleContext);
|
||||
triedFrame = PR_TRUE;
|
||||
}
|
||||
else if (nsGkAtoms::button == aTag) {
|
||||
rv = ConstructButtonFrame(aState, aContent, aParentFrame,
|
||||
aTag, aStyleContext, &newFrame,
|
||||
display, aFrameItems, aHasPseudoParent);
|
||||
// the html4 button needs to act just like a
|
||||
// regular button except contain html content
|
||||
// so it must be replaced or html outside it will
|
||||
// draw into its borders. -EDV
|
||||
frameHasBeenInitialized = PR_TRUE;
|
||||
addedToFrameList = PR_TRUE;
|
||||
}
|
||||
else if (nsGkAtoms::isindex == aTag) {
|
||||
if (!aHasPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
|
||||
ProcessPseudoFrames(aState, aFrameItems);
|
||||
}
|
||||
newFrame = NS_NewIsIndexFrame(mPresShell, aStyleContext);
|
||||
triedFrame = PR_TRUE;
|
||||
}
|
||||
else if (nsGkAtoms::canvas == aTag) {
|
||||
if (!aHasPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
|
||||
ProcessPseudoFrames(aState, aFrameItems);
|
||||
}
|
||||
newFrame = NS_NewHTMLCanvasFrame(mPresShell, aStyleContext);
|
||||
triedFrame = PR_TRUE;
|
||||
}
|
||||
#if defined(MOZ_MEDIA)
|
||||
else if (nsGkAtoms::video == aTag || nsGkAtoms::audio == aTag) {
|
||||
// We create video frames for audio elements so we can show controls.
|
||||
// Note that html.css specifies display:none for audio elements
|
||||
// without the "controls" attribute.
|
||||
if (!aHasPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
|
||||
ProcessPseudoFrames(aState, aFrameItems);
|
||||
}
|
||||
newFrame = NS_NewHTMLVideoFrame(mPresShell, aStyleContext);
|
||||
triedFrame = PR_TRUE;
|
||||
}
|
||||
#endif
|
||||
if (NS_UNLIKELY(triedFrame && !newFrame)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
else if (NS_FAILED(rv) || !newFrame) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// If we succeeded in creating a frame then initialize it, process its
|
||||
// children (if requested), and set the initial child list
|
||||
|
||||
// Note: at this point we should construct kids for newFrame only if
|
||||
// it's not a leaf and hasn't been initialized yet.
|
||||
|
||||
if (!frameHasBeenInitialized) {
|
||||
NS_ASSERTION(!addedToFrameList,
|
||||
"Frames that were already added to the frame list should be "
|
||||
"initialized by now!");
|
||||
nsIFrame* geometricParent = aState.GetGeometricParent(display,
|
||||
aParentFrame);
|
||||
|
||||
rv = InitAndRestoreFrame(aState, aContent, geometricParent, nsnull, newFrame);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "InitAndRestoreFrame failed");
|
||||
// See if we need to create a view
|
||||
nsHTMLContainerFrame::CreateViewForFrame(newFrame, PR_FALSE);
|
||||
|
||||
rv = aState.AddChild(newFrame, aFrameItems, aContent, aStyleContext,
|
||||
aParentFrame);
|
||||
nsIFrame* newFrame;
|
||||
if (bits & FCDATA_FUNC_IS_FULL_CTOR) {
|
||||
nsresult rv =
|
||||
(this->*(aData->mFullConstructor))(aState, aContent, aParentFrame,
|
||||
aTag, aStyleContext, display,
|
||||
aFrameItems, &newFrame);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
addedToFrameList = PR_TRUE;
|
||||
|
||||
} else {
|
||||
newFrame =
|
||||
(*aData->mFunc.mCreationFunc)(mPresShell, aStyleContext);
|
||||
if (!newFrame) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
PRBool allowOutOfFlow = !(bits & FCDATA_DISALLOW_OUT_OF_FLOW);
|
||||
|
||||
nsIFrame* geometricParent =
|
||||
allowOutOfFlow ? aState.GetGeometricParent(display, aParentFrame)
|
||||
: aParentFrame;
|
||||
nsresult rv = InitAndRestoreFrame(aState, aContent, geometricParent, nsnull,
|
||||
newFrame);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "InitAndRestoreFrame failed");
|
||||
// See whether we need to create a view
|
||||
nsHTMLContainerFrame::CreateViewForFrame(newFrame, PR_FALSE);
|
||||
|
||||
rv = aState.AddChild(newFrame, aFrameItems, aContent, aStyleContext,
|
||||
aParentFrame, allowOutOfFlow, allowOutOfFlow);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Process the child content if requested
|
||||
nsFrameItems childItems;
|
||||
nsFrameConstructorSaveState absoluteSaveState;
|
||||
|
||||
if (display->IsPositioned()) {
|
||||
if (bits & FCDATA_FORCE_NULL_ABSPOS_CONTAINER) {
|
||||
aState.PushAbsoluteContainingBlock(nsnull, absoluteSaveState);
|
||||
} else if (display->IsPositioned()) {
|
||||
aState.PushAbsoluteContainingBlock(newFrame, absoluteSaveState);
|
||||
}
|
||||
|
||||
|
@ -5433,25 +5291,11 @@ nsCSSFrameConstructor::ConstructHTMLFrame(nsFrameConstructorState& aState,
|
|||
newFrame->SetInitialChildList(nsnull, childItems.childList);
|
||||
}
|
||||
|
||||
if (!addedToFrameList) {
|
||||
// Gotta do it here. Note that things like absolutely positioned replaced
|
||||
// elements and the like will end up in this code. So use the AddChild
|
||||
// on the state.
|
||||
rv = aState.AddChild(newFrame, aFrameItems, aContent, aStyleContext,
|
||||
aParentFrame);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
if (addToHashTable) {
|
||||
// Add a mapping from content object to primary frame. Note that for
|
||||
// floated and positioned frames this is the out-of-flow frame and not
|
||||
// the placeholder frame
|
||||
if (!(bits & FCDATA_SKIP_FRAMEMAP)) {
|
||||
aState.mFrameManager->SetPrimaryFrameFor(aContent, newFrame);
|
||||
}
|
||||
|
||||
return rv;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -7280,8 +7124,10 @@ nsCSSFrameConstructor::ConstructFrameInternal( nsFrameConstructorState& aState,
|
|||
nsIFrame* lastChild = frameItems->lastChild;
|
||||
|
||||
// Handle specific frame types
|
||||
rv = ConstructHTMLFrame(aState, aContent, adjParentFrame, aTag, aNameSpaceID,
|
||||
styleContext, *frameItems, pseudoParent);
|
||||
rv = ConstructFrameFromData(FindHTMLData(aContent, aTag, aNameSpaceID,
|
||||
styleContext),
|
||||
aState, aContent, adjParentFrame, aTag,
|
||||
styleContext, *frameItems, pseudoParent);
|
||||
|
||||
// Failing to find a matching HTML frame, try creating a specialized
|
||||
// XUL frame. This is temporary, pending planned factoring of this
|
||||
|
@ -10999,7 +10845,7 @@ nsCSSFrameConstructor::ShouldHaveFirstLineStyle(nsIContent* aContent,
|
|||
PRInt32 namespaceID;
|
||||
nsIAtom* tag = mDocument->BindingManager()->ResolveTag(aContent,
|
||||
&namespaceID);
|
||||
// This check must match the one in ConstructHTMLFrame.
|
||||
// This check must match the one in FindHTMLData.
|
||||
hasFirstLine = tag != nsGkAtoms::fieldset ||
|
||||
(namespaceID != kNameSpaceID_XHTML &&
|
||||
!aContent->IsNodeOfType(nsINode::eHTML));
|
||||
|
|
|
@ -512,6 +512,139 @@ private:
|
|||
nsIFrame*& aParentFrame,
|
||||
PRBool& aIsPseudoParent);
|
||||
|
||||
private:
|
||||
/* A constructor function that just creates an nsIFrame object. The caller
|
||||
is responsible for initializing the object, adding it to frame lists,
|
||||
constructing frames for the children, etc.
|
||||
|
||||
@param nsIPresShell the presshell whose arena should be used to allocate
|
||||
the frame.
|
||||
@param nsStyleContext the style context to use for the frame. */
|
||||
typedef nsIFrame* (* FrameCreationFunc)(nsIPresShell*, nsStyleContext*);
|
||||
|
||||
/* A function that can be used to get a FrameConstructionData. Such
|
||||
a function is allowed to return null.
|
||||
|
||||
@param nsIContent the node for which the frame is being constructed.
|
||||
@param nsStyleContext the style context to be used for the frame.
|
||||
*/
|
||||
struct FrameConstructionData;
|
||||
typedef const FrameConstructionData*
|
||||
(* FrameConstructionDataGetter)(nsIContent*, nsStyleContext*);
|
||||
|
||||
/* A constructor function that's used for complicated construction tasks.
|
||||
This is expected to create the new frame, initialize it, add whatever
|
||||
needs to be added to aFrameItems (XXXbz is that really necessary? Could
|
||||
caller add? Might there be cases when *aNewFrame or its placeholder is
|
||||
not the thing that ends up in aFrameItems? If not, would it be safe to do
|
||||
the add into the frame construction state after processing kids? Look
|
||||
into this as a followup!), process children as needed, etc. It is NOT
|
||||
expected to deal with the primary frame map.
|
||||
|
||||
@param aState the frame construction state to use.
|
||||
@param aContent the content node to construct the frame for.
|
||||
@param aParentFrame the frame to set as the parent of the
|
||||
newly-constructed frame.
|
||||
@param aTag the content's XBL-resolved tag.
|
||||
@param aStyleContext the style context to use for the new frame.
|
||||
@param aFrameItems the frame list to add the new frame (or its
|
||||
placeholder) to.
|
||||
@param aFrame out param handing out the frame that was constructed. This
|
||||
frame is what the caller will add to the primary frame map.
|
||||
*/
|
||||
typedef nsresult
|
||||
(nsCSSFrameConstructor::* FrameFullConstructor)(nsFrameConstructorState& aState,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParentFrame,
|
||||
nsIAtom* aTag,
|
||||
nsStyleContext* aStyleContext,
|
||||
const nsStyleDisplay* aStyleDisplay,
|
||||
nsFrameItems& aFrameItems,
|
||||
nsIFrame** aFrame);
|
||||
|
||||
/* Bits that modify the way a FrameConstructionData is handled */
|
||||
|
||||
/* If the FCDATA_SKIP_FRAMEMAP bit is set, then the frame created should not
|
||||
be added to the primary frame map */
|
||||
#define FCDATA_SKIP_FRAMEMAP 0x1
|
||||
/* If the FCDATA_FUNC_IS_DATA_GETTER bit is set, then the mFunc of the
|
||||
FrameConstructionData is a getter function that can be used to get the
|
||||
actual FrameConstructionData to use. */
|
||||
#define FCDATA_FUNC_IS_DATA_GETTER 0x2
|
||||
/* If the FCDATA_FUNC_IS_FULL_CTOR bit is set, then the FrameConstructionData
|
||||
has an mFullConstructor. In this case, there is no relevant mData or
|
||||
mFunc */
|
||||
#define FCDATA_FUNC_IS_FULL_CTOR 0x4
|
||||
/* If FCDATA_DISALLOW_OUT_OF_FLOW is set, do not allow the frame to
|
||||
float or be absolutely positioned. This cannot be used with
|
||||
FCDATA_FUNC_IS_FULL_CTOR */
|
||||
#define FCDATA_DISALLOW_OUT_OF_FLOW 0x8
|
||||
/* If FCDATA_FORCE_NULL_ABSPOS_CONTAINER is set, make sure to push a
|
||||
null absolute containing block before processing children for this
|
||||
frame. If this is not set, the frame will be pushed as the
|
||||
absolute containing block as needed, based on its style */
|
||||
#define FCDATA_FORCE_NULL_ABSPOS_CONTAINER 0x10
|
||||
|
||||
/* Structure representing information about how a frame should be
|
||||
constructed. */
|
||||
struct FrameConstructionData {
|
||||
// Flag bits that can modify the way the construction happens
|
||||
PRUint32 mBits;
|
||||
// We have exactly one of three types of functions, so use a union for
|
||||
// better cache locality for the ones that aren't pointer-to-member. That
|
||||
// one needs to be separate, because we can't cast between it and the
|
||||
// others and hence wouldn't be able to initialize the union without a
|
||||
// constructor and all the resulting generated code. See documentation
|
||||
// above for FrameCreationFunc, FrameConstructionDataGetter, and
|
||||
// FrameFullConstructor to see what the functions would do.
|
||||
union Func {
|
||||
FrameCreationFunc mCreationFunc;
|
||||
FrameConstructionDataGetter mDataGetter;
|
||||
} mFunc;
|
||||
FrameFullConstructor mFullConstructor;
|
||||
};
|
||||
|
||||
/* Structure representing a mapping of an atom to a FrameConstructionData.
|
||||
This can be used with non-static atoms, assuming that the nsIAtom* is
|
||||
stored somewhere that this struct can point to (that is, a static
|
||||
nsIAtom*) and that it's allocated before the struct is ever used. */
|
||||
struct FrameConstructionDataByTag {
|
||||
// Pointer to nsIAtom* is used because we want to initialize this
|
||||
// statically, so before our atom tables are set up.
|
||||
const nsIAtom * const * const mTag;
|
||||
const FrameConstructionData mData;
|
||||
};
|
||||
|
||||
/* Structure representing a mapping of an integer to a
|
||||
FrameConstructionData. There are no magic integer values here. */
|
||||
struct FrameConstructionDataByInt {
|
||||
/* Could be used for display or whatever else */
|
||||
const PRInt32 mInt;
|
||||
const FrameConstructionData mData;
|
||||
};
|
||||
|
||||
/* A function that takes an integer, content, style context, and array of
|
||||
FrameConstructionDataByInts and finds the appropriate frame construction
|
||||
data to use and returns it. This can return null if none of the integers
|
||||
match or if the matching integer has a FrameConstructionDataGetter that
|
||||
returns null. */
|
||||
static const FrameConstructionData*
|
||||
FindDataByInt(PRInt32 aInt, nsIContent* aContent,
|
||||
nsStyleContext* aStyleContext,
|
||||
const FrameConstructionDataByInt* aDataPtr,
|
||||
PRUint32 aDataLength);
|
||||
|
||||
/* A function that takes a tag, content, style context, and array of
|
||||
FrameConstructionDataByTags and finds the appropriate frame construction
|
||||
data to use and returns it. This can return null if none of the tags
|
||||
match or if the matching tag has a FrameConstructionDataGetter that
|
||||
returns null. */
|
||||
static const FrameConstructionData*
|
||||
FindDataByTag(nsIAtom* aTag, nsIContent* aContent,
|
||||
nsStyleContext* aStyleContext,
|
||||
const FrameConstructionDataByTag* aDataPtr,
|
||||
PRUint32 aDataLength);
|
||||
|
||||
/**
|
||||
* Function to adjust aParentFrame and aFrameItems to deal with table
|
||||
* pseudo-frames that may have to be inserted.
|
||||
|
@ -547,8 +680,6 @@ private:
|
|||
PRBool& aSuppressFrame,
|
||||
PRBool& aCreatedPseudo);
|
||||
|
||||
const nsStyleDisplay* GetDisplay(nsIFrame* aFrame);
|
||||
|
||||
// END TABLE SECTION
|
||||
|
||||
protected:
|
||||
|
@ -568,10 +699,9 @@ private:
|
|||
nsIFrame* aParentFrame,
|
||||
nsIAtom* aTag,
|
||||
nsStyleContext* aStyleContext,
|
||||
nsIFrame** aNewFrame,
|
||||
const nsStyleDisplay* aStyleDisplay,
|
||||
nsFrameItems& aFrameItems,
|
||||
PRBool aHasPseudoParent);
|
||||
nsIFrame** aNewFrame);
|
||||
|
||||
// ConstructSelectFrame puts the new frame in aFrameItems and
|
||||
// handles the kids of the select.
|
||||
|
@ -580,10 +710,9 @@ private:
|
|||
nsIFrame* aParentFrame,
|
||||
nsIAtom* aTag,
|
||||
nsStyleContext* aStyleContext,
|
||||
nsIFrame*& aNewFrame,
|
||||
const nsStyleDisplay* aStyleDisplay,
|
||||
PRBool& aFrameHasBeenInitialized,
|
||||
nsFrameItems& aFrameItems);
|
||||
nsFrameItems& aFrameItems,
|
||||
nsIFrame** aNewFrame);
|
||||
|
||||
// ConstructFieldSetFrame puts the new frame in aFrameItems and
|
||||
// handles the kids of the fieldset
|
||||
|
@ -592,10 +721,9 @@ private:
|
|||
nsIFrame* aParentFrame,
|
||||
nsIAtom* aTag,
|
||||
nsStyleContext* aStyleContext,
|
||||
nsIFrame*& aNewFrame,
|
||||
nsFrameItems& aFrameItems,
|
||||
const nsStyleDisplay* aStyleDisplay,
|
||||
PRBool& aFrameHasBeenInitialized);
|
||||
nsFrameItems& aFrameItems,
|
||||
nsIFrame** aNewFrame);
|
||||
|
||||
nsresult ConstructTextFrame(nsFrameConstructorState& aState,
|
||||
nsIContent* aContent,
|
||||
|
@ -619,14 +747,50 @@ private:
|
|||
nsStyleContext* aStyleContext,
|
||||
nsFrameItems& aFrameItems);
|
||||
|
||||
nsresult ConstructHTMLFrame(nsFrameConstructorState& aState,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParentFrame,
|
||||
nsIAtom* aTag,
|
||||
PRInt32 aNameSpaceID,
|
||||
nsStyleContext* aStyleContext,
|
||||
nsFrameItems& aFrameItems,
|
||||
PRBool aHasPseudoParent);
|
||||
static PRBool IsSpecialContent(nsIContent* aContent,
|
||||
nsIAtom* aTag,
|
||||
PRInt32 aNameSpaceID,
|
||||
nsStyleContext* aStyleContext);
|
||||
|
||||
// Function to find FrameConstructionData for aContent. Will return
|
||||
// null if aContent is not HTML.
|
||||
static const FrameConstructionData* FindHTMLData(nsIContent* aContent,
|
||||
nsIAtom* aTag,
|
||||
PRInt32 aNameSpaceID,
|
||||
nsStyleContext* aStyleContext);
|
||||
// HTML data-finding helper functions
|
||||
static const FrameConstructionData*
|
||||
FindImgData(nsIContent* aContent, nsStyleContext* aStyleContext);
|
||||
static const FrameConstructionData*
|
||||
FindImgControlData(nsIContent* aContent, nsStyleContext* aStyleContext);
|
||||
static const FrameConstructionData*
|
||||
FindInputData(nsIContent* aContent, nsStyleContext* aStyleContext);
|
||||
static const FrameConstructionData*
|
||||
FindObjectData(nsIContent* aContent, nsStyleContext* aStyleContext);
|
||||
|
||||
/* Construct a frame from the given FrameConstructionData. This function
|
||||
will handle adding the frame to frame lists, processing children, adding
|
||||
it to the primary frame map, and so forth.
|
||||
|
||||
@param aData the FrameConstructionData to use.
|
||||
@param aState the frame construction state to use.
|
||||
@param aContent the content node to construct the frame for.
|
||||
@param aParentFrame the frame to set as the parent of the
|
||||
newly-constructed frame.
|
||||
@param aTag the content's XBL-resolved tag.
|
||||
@param aStyleContext the style context to use for the new frame.
|
||||
@param aFrameItems the frame list to add the new frame (or its
|
||||
placeholder) to.
|
||||
@param aHasPseudoParent whether aParentFrame is a table pseudo-frame.
|
||||
*/
|
||||
nsresult ConstructFrameFromData(const FrameConstructionData* aData,
|
||||
nsFrameConstructorState& aState,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParentFrame,
|
||||
nsIAtom* aTag,
|
||||
nsStyleContext* aStyleContext,
|
||||
nsFrameItems& aFrameItems,
|
||||
PRBool aHasPseudoParent);
|
||||
|
||||
nsresult ConstructFrameInternal( nsFrameConstructorState& aState,
|
||||
nsIContent* aContent,
|
||||
|
@ -743,33 +907,6 @@ private:
|
|||
nsFrameItems& aFrameItems,
|
||||
PRBool aAllowBlockStyles);
|
||||
|
||||
// @param OUT aFrame the newly created frame
|
||||
nsresult CreateInputFrame(nsFrameConstructorState& aState,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParentFrame,
|
||||
nsIAtom* aTag,
|
||||
nsStyleContext* aStyleContext,
|
||||
nsIFrame** aFrame,
|
||||
const nsStyleDisplay* aStyleDisplay,
|
||||
PRBool& aFrameHasBeenInitialized,
|
||||
PRBool& aAddedToFrameList,
|
||||
nsFrameItems& aFrameItems,
|
||||
PRBool aHasPseudoParent);
|
||||
|
||||
// A function that can be invoked to create some sort of image frame.
|
||||
typedef nsIFrame* (* ImageFrameCreatorFunc)(nsIPresShell*, nsStyleContext*);
|
||||
|
||||
/**
|
||||
* CreateHTMLImageFrame will do some tests on aContent, and if it determines
|
||||
* that the content should get an image frame it'll create one via aFunc and
|
||||
* return it in *aFrame. Note that if this content node isn't supposed to
|
||||
* have an image frame this method will return NS_OK and set *aFrame to null.
|
||||
*/
|
||||
nsresult CreateHTMLImageFrame(nsIContent* aContent,
|
||||
nsStyleContext* aStyleContext,
|
||||
ImageFrameCreatorFunc aFunc,
|
||||
nsIFrame** aFrame);
|
||||
|
||||
nsIFrame* GetFrameFor(nsIContent* aContent);
|
||||
|
||||
/**
|
||||
|
|
Загрузка…
Ссылка в новой задаче