зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset 2d16e9e90401 (bug 1683748) for WPT failures in html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-grid-flex-multicol.html. CLOSED TREE
This commit is contained in:
Родитель
43774473a1
Коммит
689a7c82d0
|
@ -103,26 +103,6 @@ bool HTMLLegendElement::PerformAccesskey(bool aKeyCausesActivation,
|
||||||
return NS_SUCCEEDED(rv.StealNSResult());
|
return NS_SUCCEEDED(rv.StealNSResult());
|
||||||
}
|
}
|
||||||
|
|
||||||
HTMLLegendElement::LegendAlignValue HTMLLegendElement::LogicalAlign(
|
|
||||||
mozilla::WritingMode aCBWM) const {
|
|
||||||
const nsAttrValue* attr = GetParsedAttr(nsGkAtoms::align);
|
|
||||||
if (!attr || attr->Type() != nsAttrValue::eEnum) {
|
|
||||||
return LegendAlignValue::InlineStart;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto value = static_cast<LegendAlignValue>(attr->GetEnumValue());
|
|
||||||
switch (value) {
|
|
||||||
case LegendAlignValue::Left:
|
|
||||||
return aCBWM.IsBidiLTR() ? LegendAlignValue::InlineStart
|
|
||||||
: LegendAlignValue::InlineEnd;
|
|
||||||
case LegendAlignValue::Right:
|
|
||||||
return aCBWM.IsBidiLTR() ? LegendAlignValue::InlineEnd
|
|
||||||
: LegendAlignValue::InlineStart;
|
|
||||||
default:
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<HTMLFormElement> HTMLLegendElement::GetForm() {
|
already_AddRefed<HTMLFormElement> HTMLLegendElement::GetForm() {
|
||||||
return do_AddRef(GetFormElement());
|
return do_AddRef(GetFormElement());
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,16 +57,6 @@ class HTMLLegendElement final : public nsGenericHTMLElement {
|
||||||
InlineStart,
|
InlineStart,
|
||||||
InlineEnd,
|
InlineEnd,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the align value to use for the given fieldset writing-mode.
|
|
||||||
* (This method resolves Left/Right to the appropriate InlineStart/InlineEnd).
|
|
||||||
* @param aCBWM the fieldset writing-mode
|
|
||||||
* @note we only parse left/right/center, so this method returns Center,
|
|
||||||
* InlineStart or InlineEnd.
|
|
||||||
*/
|
|
||||||
LegendAlignValue LogicalAlign(mozilla::WritingMode aCBWM) const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WebIDL Interface
|
* WebIDL Interface
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -702,10 +702,6 @@ class MOZ_STACK_CLASS nsFrameConstructorState {
|
||||||
// mode).
|
// mode).
|
||||||
bool mCreatingExtraFrames;
|
bool mCreatingExtraFrames;
|
||||||
|
|
||||||
// This keeps track of whether we have found a "rendered legend" for
|
|
||||||
// the current FieldSetFrame.
|
|
||||||
bool mHasRenderedLegend;
|
|
||||||
|
|
||||||
nsTArray<RefPtr<nsIContent>> mGeneratedContentWithInitializer;
|
nsTArray<RefPtr<nsIContent>> mGeneratedContentWithInitializer;
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
|
@ -855,8 +851,7 @@ nsFrameConstructorState::nsFrameConstructorState(
|
||||||
// frames.
|
// frames.
|
||||||
mFixedPosIsAbsPos(aFixedContainingBlock == aAbsoluteContainingBlock),
|
mFixedPosIsAbsPos(aFixedContainingBlock == aAbsoluteContainingBlock),
|
||||||
mHavePendingPopupgroup(false),
|
mHavePendingPopupgroup(false),
|
||||||
mCreatingExtraFrames(false),
|
mCreatingExtraFrames(false) {
|
||||||
mHasRenderedLegend(false) {
|
|
||||||
#ifdef MOZ_XUL
|
#ifdef MOZ_XUL
|
||||||
nsIPopupContainer* popupContainer =
|
nsIPopupContainer* popupContainer =
|
||||||
nsIPopupContainer::GetPopupContainer(aPresShell);
|
nsIPopupContainer::GetPopupContainer(aPresShell);
|
||||||
|
@ -3053,16 +3048,35 @@ nsIFrame* nsCSSFrameConstructor::ConstructFieldSetFrame(
|
||||||
absoluteSaveState);
|
absoluteSaveState);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
ProcessChildren(aState, content, computedStyle, contentFrame, true, childList,
|
||||||
AutoRestore<bool> savedHasRenderedLegend(aState.mHasRenderedLegend);
|
true);
|
||||||
aState.mHasRenderedLegend = false;
|
|
||||||
ProcessChildren(aState, content, computedStyle, contentFrame, true,
|
|
||||||
childList, true);
|
|
||||||
}
|
|
||||||
nsFrameList fieldsetKids;
|
nsFrameList fieldsetKids;
|
||||||
fieldsetKids.AppendFrame(nullptr,
|
fieldsetKids.AppendFrame(nullptr,
|
||||||
scrollFrame ? scrollFrame : contentFrameTop);
|
scrollFrame ? scrollFrame : contentFrameTop);
|
||||||
|
|
||||||
|
for (nsFrameList::Enumerator e(childList); !e.AtEnd(); e.Next()) {
|
||||||
|
nsIFrame* child = e.get();
|
||||||
|
nsContainerFrame* cif = child->GetContentInsertionFrame();
|
||||||
|
if (cif && cif->IsLegendFrame()) {
|
||||||
|
// We want the legend to be the first frame in the fieldset child list.
|
||||||
|
// That way the EventStateManager will do the right thing when tabbing
|
||||||
|
// from a selection point within the legend (bug 236071), which is
|
||||||
|
// used for implementing legend access keys (bug 81481).
|
||||||
|
// GetAdjustedParentFrame() below depends on this frame order.
|
||||||
|
childList.RemoveFrame(child);
|
||||||
|
// Make sure to reparent the legend so it has the fieldset as the parent.
|
||||||
|
fieldsetKids.InsertFrame(fieldsetFrame, nullptr, child);
|
||||||
|
// Legend is no longer in the multicol container. Remove the bit.
|
||||||
|
child->RemoveStateBits(NS_FRAME_HAS_MULTI_COLUMN_ANCESTOR);
|
||||||
|
if (scrollFrame) {
|
||||||
|
StickyScrollContainer::NotifyReparentedFrameAcrossScrollFrameBoundary(
|
||||||
|
child, contentFrame);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!MayNeedToCreateColumnSpanSiblings(contentFrame, childList)) {
|
if (!MayNeedToCreateColumnSpanSiblings(contentFrame, childList)) {
|
||||||
// Set the inner frame's initial child lists.
|
// Set the inner frame's initial child lists.
|
||||||
contentFrame->SetInitialChildList(kPrincipalList, childList);
|
contentFrame->SetInitialChildList(kPrincipalList, childList);
|
||||||
|
@ -3088,10 +3102,10 @@ nsIFrame* nsCSSFrameConstructor::ConstructFieldSetFrame(
|
||||||
FinishBuildingScrollFrame(scrollFrame, contentFrameTop);
|
FinishBuildingScrollFrame(scrollFrame, contentFrameTop);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We use AppendFrames here because the rendered legend will already
|
// Set the outer frame's initial child list
|
||||||
// be present in the principal child list if it exists.
|
fieldsetFrame->SetInitialChildList(kPrincipalList, fieldsetKids);
|
||||||
fieldsetFrame->AppendFrames(nsIFrame::kNoReflowPrincipalList, fieldsetKids);
|
|
||||||
|
|
||||||
|
// Our new frame returned is the outer frame, which is the fieldset frame.
|
||||||
return fieldsetFrame;
|
return fieldsetFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3315,11 +3329,25 @@ nsCSSFrameConstructor::FindHTMLData(const Element& aElement,
|
||||||
nsIFrame* aParentFrame,
|
nsIFrame* aParentFrame,
|
||||||
ComputedStyle& aStyle) {
|
ComputedStyle& aStyle) {
|
||||||
MOZ_ASSERT(aElement.IsHTMLElement());
|
MOZ_ASSERT(aElement.IsHTMLElement());
|
||||||
|
|
||||||
|
nsAtom* tag = aElement.NodeInfo()->NameAtom();
|
||||||
NS_ASSERTION(!aParentFrame ||
|
NS_ASSERTION(!aParentFrame ||
|
||||||
aParentFrame->Style()->GetPseudoType() !=
|
aParentFrame->Style()->GetPseudoType() !=
|
||||||
PseudoStyleType::fieldsetContent ||
|
PseudoStyleType::fieldsetContent ||
|
||||||
aParentFrame->GetParent()->IsFieldSetFrame(),
|
aParentFrame->GetParent()->IsFieldSetFrame(),
|
||||||
"Unexpected parent for fieldset content anon box");
|
"Unexpected parent for fieldset content anon box");
|
||||||
|
if (tag == nsGkAtoms::legend &&
|
||||||
|
(!aParentFrame || !IsFrameForFieldSet(aParentFrame) ||
|
||||||
|
aStyle.StyleDisplay()->IsFloatingStyle() ||
|
||||||
|
aStyle.StyleDisplay()->IsAbsolutelyPositionedStyle())) {
|
||||||
|
// <legend> is only special inside fieldset, we only check the frame tree
|
||||||
|
// parent because the content tree parent may not be a <fieldset> due to
|
||||||
|
// display:contents, or Shadow DOM. For floated or absolutely positioned
|
||||||
|
// legends we want to construct by display type and not do special legend
|
||||||
|
// stuff.
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
static const FrameConstructionDataByTag sHTMLData[] = {
|
static const FrameConstructionDataByTag sHTMLData[] = {
|
||||||
SIMPLE_TAG_CHAIN(img, nsCSSFrameConstructor::FindImgData),
|
SIMPLE_TAG_CHAIN(img, nsCSSFrameConstructor::FindImgData),
|
||||||
SIMPLE_TAG_CHAIN(mozgeneratedcontentimage,
|
SIMPLE_TAG_CHAIN(mozgeneratedcontentimage,
|
||||||
|
@ -3335,6 +3363,9 @@ nsCSSFrameConstructor::FindHTMLData(const Element& aElement,
|
||||||
SIMPLE_TAG_CHAIN(embed, nsCSSFrameConstructor::FindObjectData),
|
SIMPLE_TAG_CHAIN(embed, nsCSSFrameConstructor::FindObjectData),
|
||||||
COMPLEX_TAG_CREATE(fieldset,
|
COMPLEX_TAG_CREATE(fieldset,
|
||||||
&nsCSSFrameConstructor::ConstructFieldSetFrame),
|
&nsCSSFrameConstructor::ConstructFieldSetFrame),
|
||||||
|
{nsGkAtoms::legend,
|
||||||
|
FCDATA_DECL(FCDATA_ALLOW_BLOCK_STYLES | FCDATA_MAY_NEED_SCROLLFRAME,
|
||||||
|
NS_NewLegendFrame)},
|
||||||
SIMPLE_TAG_CREATE(frameset, NS_NewHTMLFramesetFrame),
|
SIMPLE_TAG_CREATE(frameset, NS_NewHTMLFramesetFrame),
|
||||||
SIMPLE_TAG_CREATE(iframe, NS_NewSubDocumentFrame),
|
SIMPLE_TAG_CREATE(iframe, NS_NewSubDocumentFrame),
|
||||||
{nsGkAtoms::button,
|
{nsGkAtoms::button,
|
||||||
|
@ -5217,17 +5248,6 @@ nsCSSFrameConstructor::FindElementData(const Element& aElement,
|
||||||
return &sImgData;
|
return &sImgData;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aFlags.contains(ItemFlag::IsForRenderedLegend) &&
|
|
||||||
!aStyle.StyleDisplay()->IsBlockOutsideStyle()) {
|
|
||||||
// Make a temp copy of StyleDisplay and blockify its mDisplay value.
|
|
||||||
auto display = *aStyle.StyleDisplay();
|
|
||||||
bool isRootElement = false;
|
|
||||||
uint16_t rawDisplayValue =
|
|
||||||
Servo_ComputedValues_BlockifiedDisplay(&aStyle, isRootElement);
|
|
||||||
display.mDisplay = StyleDisplay(rawDisplayValue);
|
|
||||||
return FindDisplayData(display, aElement);
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto& display = *aStyle.StyleDisplay();
|
const auto& display = *aStyle.StyleDisplay();
|
||||||
return FindDisplayData(display, aElement);
|
return FindDisplayData(display, aElement);
|
||||||
}
|
}
|
||||||
|
@ -5339,14 +5359,6 @@ void nsCSSFrameConstructor::AddFrameConstructionItemsInternal(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aContent->IsHTMLElement(nsGkAtoms::legend) && aParentFrame &&
|
|
||||||
IsFrameForFieldSet(aParentFrame) && !aState.mHasRenderedLegend &&
|
|
||||||
!aComputedStyle->StyleDisplay()->IsFloatingStyle() &&
|
|
||||||
!aComputedStyle->StyleDisplay()->IsAbsolutelyPositionedStyle()) {
|
|
||||||
aState.mHasRenderedLegend = true;
|
|
||||||
aFlags += ItemFlag::IsForRenderedLegend;
|
|
||||||
}
|
|
||||||
|
|
||||||
const FrameConstructionData* data =
|
const FrameConstructionData* data =
|
||||||
FindDataForContent(*aContent, *aComputedStyle, aParentFrame, aFlags);
|
FindDataForContent(*aContent, *aComputedStyle, aParentFrame, aFlags);
|
||||||
if (!data || data->mBits & FCDATA_SUPPRESS_FRAME) {
|
if (!data || data->mBits & FCDATA_SUPPRESS_FRAME) {
|
||||||
|
@ -5399,9 +5411,6 @@ void nsCSSFrameConstructor::AddFrameConstructionItemsInternal(
|
||||||
if (!item) {
|
if (!item) {
|
||||||
item = aItems.AppendItem(this, data, aContent, do_AddRef(aComputedStyle),
|
item = aItems.AppendItem(this, data, aContent, do_AddRef(aComputedStyle),
|
||||||
aSuppressWhiteSpaceOptimizations);
|
aSuppressWhiteSpaceOptimizations);
|
||||||
if (aFlags.contains(ItemFlag::IsForRenderedLegend)) {
|
|
||||||
item->mIsRenderedLegend = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
item->mIsText = !aContent->IsElement();
|
item->mIsText = !aContent->IsElement();
|
||||||
item->mIsGeneratedContent = isGeneratedContent;
|
item->mIsGeneratedContent = isGeneratedContent;
|
||||||
|
@ -5960,6 +5969,20 @@ bool nsCSSFrameConstructor::IsValidSibling(nsIFrame* aSibling,
|
||||||
// below.
|
// below.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsFrameForFieldSet(parentFrame)) {
|
||||||
|
// Legends can be sibling of legends but not of other content in the
|
||||||
|
// fieldset
|
||||||
|
if (nsContainerFrame* cif = aSibling->GetContentInsertionFrame()) {
|
||||||
|
aSibling = cif;
|
||||||
|
}
|
||||||
|
LayoutFrameType sibType = aSibling->Type();
|
||||||
|
bool legendContent = aContent->IsHTMLElement(nsGkAtoms::legend);
|
||||||
|
|
||||||
|
if ((legendContent && (LayoutFrameType::Legend != sibType)) ||
|
||||||
|
(!legendContent && (LayoutFrameType::Legend == sibType)))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6047,10 +6070,6 @@ nsIFrame* nsCSSFrameConstructor::AdjustSiblingFrame(
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aSibling->IsRenderedLegend()) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aSibling->HasAnyStateBits(NS_FRAME_OUT_OF_FLOW)) {
|
if (aSibling->HasAnyStateBits(NS_FRAME_OUT_OF_FLOW)) {
|
||||||
aSibling = aSibling->GetPlaceholderFrame();
|
aSibling = aSibling->GetPlaceholderFrame();
|
||||||
MOZ_ASSERT(aSibling);
|
MOZ_ASSERT(aSibling);
|
||||||
|
@ -7965,6 +7984,9 @@ nsIFrame* nsCSSFrameConstructor::CreateContinuingFrame(
|
||||||
} else if (LayoutFrameType::FieldSet == frameType) {
|
} else if (LayoutFrameType::FieldSet == frameType) {
|
||||||
newFrame = NS_NewFieldSetFrame(mPresShell, computedStyle);
|
newFrame = NS_NewFieldSetFrame(mPresShell, computedStyle);
|
||||||
newFrame->Init(content, aParentFrame, aFrame);
|
newFrame->Init(content, aParentFrame, aFrame);
|
||||||
|
} else if (LayoutFrameType::Legend == frameType) {
|
||||||
|
newFrame = NS_NewLegendFrame(mPresShell, computedStyle);
|
||||||
|
newFrame->Init(content, aParentFrame, aFrame);
|
||||||
} else if (LayoutFrameType::FlexContainer == frameType) {
|
} else if (LayoutFrameType::FlexContainer == frameType) {
|
||||||
newFrame = NS_NewFlexContainerFrame(mPresShell, computedStyle);
|
newFrame = NS_NewFlexContainerFrame(mPresShell, computedStyle);
|
||||||
newFrame->Init(content, aParentFrame, aFrame);
|
newFrame->Init(content, aParentFrame, aFrame);
|
||||||
|
@ -8223,9 +8245,12 @@ bool nsCSSFrameConstructor::MaybeRecreateContainerForFrameRemoval(
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inFlowFrame->IsRenderedLegend()) {
|
nsContainerFrame* insertionFrame = aFrame->GetContentInsertionFrame();
|
||||||
|
if (insertionFrame && insertionFrame->IsLegendFrame() &&
|
||||||
|
aFrame->GetParent()->IsFieldSetFrame()) {
|
||||||
TRACE("Fieldset / Legend");
|
TRACE("Fieldset / Legend");
|
||||||
RecreateFramesForContent(parent->GetContent(), InsertionKind::Async);
|
RecreateFramesForContent(aFrame->GetParent()->GetContent(),
|
||||||
|
InsertionKind::Async);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9330,34 +9355,6 @@ inline void nsCSSFrameConstructor::ConstructFramesFromItemList(
|
||||||
// that information offhand in many cases.
|
// that information offhand in many cases.
|
||||||
MOZ_ASSERT(ParentIsWrapperAnonBox(aParentFrame) == aParentIsWrapperAnonBox);
|
MOZ_ASSERT(ParentIsWrapperAnonBox(aParentFrame) == aParentIsWrapperAnonBox);
|
||||||
|
|
||||||
if (!aParentIsWrapperAnonBox && aState.mHasRenderedLegend &&
|
|
||||||
aParentFrame->GetContent()->IsHTMLElement(nsGkAtoms::fieldset)) {
|
|
||||||
DebugOnly<bool> found = false;
|
|
||||||
for (FCItemIterator iter(aItems); !iter.IsDone(); iter.Next()) {
|
|
||||||
if (iter.item().mIsRenderedLegend) {
|
|
||||||
// This makes the rendered legend the first frame in the fieldset child
|
|
||||||
// list which makes keyboard traversal follow the visual order.
|
|
||||||
nsContainerFrame* fieldSetFrame = aParentFrame->GetParent();
|
|
||||||
while (!fieldSetFrame->IsFieldSetFrame()) {
|
|
||||||
fieldSetFrame = fieldSetFrame->GetParent();
|
|
||||||
}
|
|
||||||
nsFrameList renderedLegend;
|
|
||||||
ConstructFramesFromItem(aState, iter, fieldSetFrame, renderedLegend);
|
|
||||||
MOZ_ASSERT(
|
|
||||||
renderedLegend.FirstChild() &&
|
|
||||||
renderedLegend.FirstChild() == renderedLegend.LastChild(),
|
|
||||||
"a rendered legend should have exactly one frame");
|
|
||||||
fieldSetFrame->SetInitialChildList(kPrincipalList, renderedLegend);
|
|
||||||
FCItemIterator next = iter;
|
|
||||||
next.Next();
|
|
||||||
iter.DeleteItemsTo(this, next);
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MOZ_ASSERT(found, "should have found our rendered legend");
|
|
||||||
}
|
|
||||||
|
|
||||||
CreateNeededPseudoContainers(aState, aItems, aParentFrame);
|
CreateNeededPseudoContainers(aState, aItems, aParentFrame);
|
||||||
CreateNeededAnonFlexOrGridItems(aState, aItems, aParentFrame);
|
CreateNeededAnonFlexOrGridItems(aState, aItems, aParentFrame);
|
||||||
CreateNeededPseudoInternalRubyBoxes(aState, aItems, aParentFrame);
|
CreateNeededPseudoInternalRubyBoxes(aState, aItems, aParentFrame);
|
||||||
|
@ -9365,9 +9362,6 @@ inline void nsCSSFrameConstructor::ConstructFramesFromItemList(
|
||||||
|
|
||||||
bool listItemListIsDirty = false;
|
bool listItemListIsDirty = false;
|
||||||
for (FCItemIterator iter(aItems); !iter.IsDone(); iter.Next()) {
|
for (FCItemIterator iter(aItems); !iter.IsDone(); iter.Next()) {
|
||||||
MOZ_ASSERT(!iter.item().mIsRenderedLegend,
|
|
||||||
"Only one item can be the rendered legend, "
|
|
||||||
"and it should've been handled above");
|
|
||||||
NS_ASSERTION(iter.item().DesiredParentType() == GetParentType(aParentFrame),
|
NS_ASSERTION(iter.item().DesiredParentType() == GetParentType(aParentFrame),
|
||||||
"Needed pseudos didn't get created; expect bad things");
|
"Needed pseudos didn't get created; expect bad things");
|
||||||
// display:list-item boxes affects the start value of the "list-item"
|
// display:list-item boxes affects the start value of the "list-item"
|
||||||
|
|
|
@ -375,8 +375,6 @@ class nsCSSFrameConstructor final : public nsFrameManager {
|
||||||
AllowTextPathChild,
|
AllowTextPathChild,
|
||||||
// The item is content created by an nsIAnonymousContentCreator frame.
|
// The item is content created by an nsIAnonymousContentCreator frame.
|
||||||
IsAnonymousContentCreatorContent,
|
IsAnonymousContentCreatorContent,
|
||||||
// The item will be the rendered legend of a <fieldset>.
|
|
||||||
IsForRenderedLegend,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using ItemFlags = mozilla::EnumSet<ItemFlag>;
|
using ItemFlags = mozilla::EnumSet<ItemFlag>;
|
||||||
|
@ -1088,8 +1086,7 @@ class nsCSSFrameConstructor final : public nsFrameManager {
|
||||||
mIsAllInline(false),
|
mIsAllInline(false),
|
||||||
mIsBlock(false),
|
mIsBlock(false),
|
||||||
mIsPopup(false),
|
mIsPopup(false),
|
||||||
mIsLineParticipant(false),
|
mIsLineParticipant(false) {
|
||||||
mIsRenderedLegend(false) {
|
|
||||||
MOZ_COUNT_CTOR(FrameConstructionItem);
|
MOZ_COUNT_CTOR(FrameConstructionItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1163,8 +1160,6 @@ class nsCSSFrameConstructor final : public nsFrameManager {
|
||||||
bool mIsPopup : 1;
|
bool mIsPopup : 1;
|
||||||
// Whether this item should be treated as a line participant
|
// Whether this item should be treated as a line participant
|
||||||
bool mIsLineParticipant : 1;
|
bool mIsLineParticipant : 1;
|
||||||
// Whether this item is the rendered legend of a <fieldset>
|
|
||||||
bool mIsRenderedLegend : 1;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Not allocated from the general heap - instead, use the new/Delete APIs
|
// Not allocated from the general heap - instead, use the new/Delete APIs
|
||||||
|
|
|
@ -27,6 +27,7 @@ UNIFIED_SOURCES += [
|
||||||
"nsGfxButtonControlFrame.cpp",
|
"nsGfxButtonControlFrame.cpp",
|
||||||
"nsHTMLButtonControlFrame.cpp",
|
"nsHTMLButtonControlFrame.cpp",
|
||||||
"nsImageControlFrame.cpp",
|
"nsImageControlFrame.cpp",
|
||||||
|
"nsLegendFrame.cpp",
|
||||||
"nsListControlFrame.cpp",
|
"nsListControlFrame.cpp",
|
||||||
"nsMeterFrame.cpp",
|
"nsMeterFrame.cpp",
|
||||||
"nsNumberControlFrame.cpp",
|
"nsNumberControlFrame.cpp",
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
#include "mozilla/PresShell.h"
|
#include "mozilla/PresShell.h"
|
||||||
#include "mozilla/Maybe.h"
|
#include "mozilla/Maybe.h"
|
||||||
#include "mozilla/webrender/WebRenderAPI.h"
|
#include "mozilla/webrender/WebRenderAPI.h"
|
||||||
#include "nsBlockFrame.h"
|
|
||||||
#include "nsCSSAnonBoxes.h"
|
#include "nsCSSAnonBoxes.h"
|
||||||
#include "nsCSSFrameConstructor.h"
|
#include "nsCSSFrameConstructor.h"
|
||||||
#include "nsCSSRendering.h"
|
#include "nsCSSRendering.h"
|
||||||
|
@ -22,6 +21,7 @@
|
||||||
#include "nsGkAtoms.h"
|
#include "nsGkAtoms.h"
|
||||||
#include "nsIFrameInlines.h"
|
#include "nsIFrameInlines.h"
|
||||||
#include "nsLayoutUtils.h"
|
#include "nsLayoutUtils.h"
|
||||||
|
#include "nsLegendFrame.h"
|
||||||
#include "nsStyleConsts.h"
|
#include "nsStyleConsts.h"
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
|
@ -445,15 +445,8 @@ void nsFieldSetFrame::Reflow(nsPresContext* aPresContext,
|
||||||
if (legend) {
|
if (legend) {
|
||||||
const auto legendWM = legend->GetWritingMode();
|
const auto legendWM = legend->GetWritingMode();
|
||||||
LogicalSize legendAvailSize = availSize.ConvertTo(legendWM, wm);
|
LogicalSize legendAvailSize = availSize.ConvertTo(legendWM, wm);
|
||||||
ComputeSizeFlags sizeFlags;
|
|
||||||
if (legend->StylePosition()->ISize(wm).IsAuto()) {
|
|
||||||
sizeFlags = ComputeSizeFlag::ShrinkWrap;
|
|
||||||
}
|
|
||||||
ReflowInput::InitFlags initFlags; // intentionally empty
|
|
||||||
StyleSizeOverrides sizeOverrides; // intentionally empty
|
|
||||||
legendReflowInput.emplace(aPresContext, aReflowInput, legend,
|
legendReflowInput.emplace(aPresContext, aReflowInput, legend,
|
||||||
legendAvailSize, Nothing(), initFlags,
|
legendAvailSize);
|
||||||
sizeOverrides, sizeFlags);
|
|
||||||
}
|
}
|
||||||
const bool avoidBreakInside = ShouldAvoidBreakInside(aReflowInput);
|
const bool avoidBreakInside = ShouldAvoidBreakInside(aReflowInput);
|
||||||
if (reflowLegend) {
|
if (reflowLegend) {
|
||||||
|
@ -682,10 +675,11 @@ void nsFieldSetFrame::Reflow(nsPresContext* aPresContext,
|
||||||
if (innerContentRect.ISize(wm) > mLegendRect.ISize(wm)) {
|
if (innerContentRect.ISize(wm) > mLegendRect.ISize(wm)) {
|
||||||
// NOTE legend @align values are: left/right/center
|
// NOTE legend @align values are: left/right/center
|
||||||
// GetLogicalAlign converts left/right to start/end for the given WM.
|
// GetLogicalAlign converts left/right to start/end for the given WM.
|
||||||
// @see HTMLLegendElement::ParseAttribute/LogicalAlign
|
// @see HTMLLegendElement::ParseAttribute, nsLegendFrame::GetLogicalAlign
|
||||||
auto* legendElement =
|
LegendAlignValue align =
|
||||||
dom::HTMLLegendElement::FromNode(legend->GetContent());
|
static_cast<nsLegendFrame*>(legend->GetContentInsertionFrame())
|
||||||
switch (legendElement->LogicalAlign(wm)) {
|
->GetLogicalAlign(wm);
|
||||||
|
switch (align) {
|
||||||
case LegendAlignValue::InlineEnd:
|
case LegendAlignValue::InlineEnd:
|
||||||
mLegendRect.IStart(wm) =
|
mLegendRect.IStart(wm) =
|
||||||
innerContentRect.IEnd(wm) - mLegendRect.ISize(wm);
|
innerContentRect.IEnd(wm) - mLegendRect.ISize(wm);
|
||||||
|
@ -795,29 +789,18 @@ void nsFieldSetFrame::Reflow(nsPresContext* aPresContext,
|
||||||
NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize);
|
NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
void nsFieldSetFrame::SetInitialChildList(ChildListID aListID,
|
void nsFieldSetFrame::SetInitialChildList(ChildListID aListID,
|
||||||
nsFrameList& aChildList) {
|
nsFrameList& aChildList) {
|
||||||
nsContainerFrame::SetInitialChildList(aListID, aChildList);
|
nsContainerFrame::SetInitialChildList(aListID, aChildList);
|
||||||
if (nsBlockFrame* legend = do_QueryFrame(GetLegend())) {
|
MOZ_ASSERT(aListID != kPrincipalList || GetInner(),
|
||||||
// A rendered legend always establish a new formatting context.
|
"Setting principal child list should populate our inner frame");
|
||||||
// https://html.spec.whatwg.org/multipage/rendering.html#rendered-legend
|
|
||||||
legend->AddStateBits(NS_BLOCK_FORMATTING_CONTEXT_STATE_BITS);
|
|
||||||
}
|
|
||||||
MOZ_ASSERT(aListID != kPrincipalList || GetInner() || GetLegend(),
|
|
||||||
"Setting principal child list should populate our inner frame "
|
|
||||||
"or our rendered legend");
|
|
||||||
}
|
}
|
||||||
void nsFieldSetFrame::AppendFrames(ChildListID aListID,
|
void nsFieldSetFrame::AppendFrames(ChildListID aListID,
|
||||||
nsFrameList& aFrameList) {
|
nsFrameList& aFrameList) {
|
||||||
MOZ_ASSERT(aListID == kNoReflowPrincipalList &&
|
MOZ_CRASH("nsFieldSetFrame::AppendFrames not supported");
|
||||||
HasAnyStateBits(NS_FRAME_FIRST_REFLOW),
|
|
||||||
"AppendFrames should only be used from "
|
|
||||||
"nsCSSFrameConstructor::ConstructFieldSetFrame");
|
|
||||||
nsContainerFrame::AppendFrames(aListID, aFrameList);
|
|
||||||
MOZ_ASSERT(GetInner(), "at this point we should have an inner frame");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
void nsFieldSetFrame::InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame,
|
void nsFieldSetFrame::InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame,
|
||||||
const nsLineList::iterator* aPrevFrameLine,
|
const nsLineList::iterator* aPrevFrameLine,
|
||||||
nsFrameList& aFrameList) {
|
nsFrameList& aFrameList) {
|
||||||
|
|
|
@ -49,11 +49,11 @@ class nsFieldSetFrame final : public nsContainerFrame {
|
||||||
gfxContext& aRenderingContext, nsPoint aPt,
|
gfxContext& aRenderingContext, nsPoint aPt,
|
||||||
const nsRect& aDirtyRect);
|
const nsRect& aDirtyRect);
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
virtual void SetInitialChildList(ChildListID aListID,
|
virtual void SetInitialChildList(ChildListID aListID,
|
||||||
nsFrameList& aChildList) override;
|
nsFrameList& aChildList) override;
|
||||||
virtual void AppendFrames(ChildListID aListID,
|
virtual void AppendFrames(ChildListID aListID,
|
||||||
nsFrameList& aFrameList) override;
|
nsFrameList& aFrameList) override;
|
||||||
#ifdef DEBUG
|
|
||||||
virtual void InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame,
|
virtual void InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame,
|
||||||
const nsLineList::iterator* aPrevFrameLine,
|
const nsLineList::iterator* aPrevFrameLine,
|
||||||
nsFrameList& aFrameList) override;
|
nsFrameList& aFrameList) override;
|
||||||
|
@ -92,8 +92,9 @@ class nsFieldSetFrame final : public nsContainerFrame {
|
||||||
nsContainerFrame* GetInner() const;
|
nsContainerFrame* GetInner() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the frame that represents the rendered legend if any.
|
* Return the frame that represents the legend if any. This may be
|
||||||
* https://html.spec.whatwg.org/multipage/rendering.html#rendered-legend
|
* a nsLegendFrame or a nsHTMLScrollFrame with the nsLegendFrame as the
|
||||||
|
* scrolled frame (aka content insertion frame).
|
||||||
*/
|
*/
|
||||||
nsIFrame* GetLegend() const;
|
nsIFrame* GetLegend() const;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "nsLegendFrame.h"
|
||||||
|
|
||||||
|
#include "mozilla/dom/HTMLLegendElement.h"
|
||||||
|
#include "mozilla/PresShell.h"
|
||||||
|
#include "ComputedStyle.h"
|
||||||
|
#include "nsIContent.h"
|
||||||
|
#include "nsGenericHTMLElement.h"
|
||||||
|
#include "nsAttrValueInlines.h"
|
||||||
|
#include "nsHTMLParts.h"
|
||||||
|
#include "nsGkAtoms.h"
|
||||||
|
#include "nsStyleConsts.h"
|
||||||
|
#include "nsCheckboxRadioFrame.h"
|
||||||
|
#include "WritingModes.h"
|
||||||
|
|
||||||
|
using namespace mozilla;
|
||||||
|
|
||||||
|
nsIFrame* NS_NewLegendFrame(PresShell* aPresShell, ComputedStyle* aStyle) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
const nsStyleDisplay* disp = aStyle->StyleDisplay();
|
||||||
|
NS_ASSERTION(!disp->IsAbsolutelyPositionedStyle() && !disp->IsFloatingStyle(),
|
||||||
|
"Legends should not be positioned and should not float");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
nsIFrame* f =
|
||||||
|
new (aPresShell) nsLegendFrame(aStyle, aPresShell->GetPresContext());
|
||||||
|
f->AddStateBits(NS_BLOCK_FORMATTING_CONTEXT_STATE_BITS);
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMPL_FRAMEARENA_HELPERS(nsLegendFrame)
|
||||||
|
|
||||||
|
void nsLegendFrame::DestroyFrom(nsIFrame* aDestructRoot,
|
||||||
|
PostDestroyData& aPostDestroyData) {
|
||||||
|
nsCheckboxRadioFrame::RegUnRegAccessKey(static_cast<nsIFrame*>(this), false);
|
||||||
|
nsBlockFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_QUERYFRAME_HEAD(nsLegendFrame)
|
||||||
|
NS_QUERYFRAME_ENTRY(nsLegendFrame)
|
||||||
|
NS_QUERYFRAME_TAIL_INHERITING(nsBlockFrame)
|
||||||
|
|
||||||
|
void nsLegendFrame::Reflow(nsPresContext* aPresContext,
|
||||||
|
ReflowOutput& aDesiredSize,
|
||||||
|
const ReflowInput& aReflowInput,
|
||||||
|
nsReflowStatus& aStatus) {
|
||||||
|
DO_GLOBAL_REFLOW_COUNT("nsLegendFrame");
|
||||||
|
DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus);
|
||||||
|
MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
|
||||||
|
if (mState & NS_FRAME_FIRST_REFLOW) {
|
||||||
|
nsCheckboxRadioFrame::RegUnRegAccessKey(static_cast<nsIFrame*>(this), true);
|
||||||
|
}
|
||||||
|
return nsBlockFrame::Reflow(aPresContext, aDesiredSize, aReflowInput,
|
||||||
|
aStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
dom::HTMLLegendElement::LegendAlignValue nsLegendFrame::GetLogicalAlign(
|
||||||
|
WritingMode aCBWM) {
|
||||||
|
using LegendAlignValue = dom::HTMLLegendElement::LegendAlignValue;
|
||||||
|
|
||||||
|
auto* element = nsGenericHTMLElement::FromNode(mContent);
|
||||||
|
if (!element) {
|
||||||
|
return LegendAlignValue::InlineStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nsAttrValue* attr = element->GetParsedAttr(nsGkAtoms::align);
|
||||||
|
if (!attr || attr->Type() != nsAttrValue::eEnum) {
|
||||||
|
return LegendAlignValue::InlineStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto value = static_cast<LegendAlignValue>(attr->GetEnumValue());
|
||||||
|
switch (value) {
|
||||||
|
case LegendAlignValue::Left:
|
||||||
|
return aCBWM.IsBidiLTR() ? LegendAlignValue::InlineStart
|
||||||
|
: LegendAlignValue::InlineEnd;
|
||||||
|
case LegendAlignValue::Right:
|
||||||
|
return aCBWM.IsBidiLTR() ? LegendAlignValue::InlineEnd
|
||||||
|
: LegendAlignValue::InlineStart;
|
||||||
|
default:
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_FRAME_DUMP
|
||||||
|
nsresult nsLegendFrame::GetFrameName(nsAString& aResult) const {
|
||||||
|
return MakeFrameName(u"Legend"_ns, aResult);
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,37 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#ifndef nsLegendFrame_h___
|
||||||
|
#define nsLegendFrame_h___
|
||||||
|
|
||||||
|
#include "mozilla/Attributes.h"
|
||||||
|
#include "mozilla/dom/HTMLLegendElement.h"
|
||||||
|
#include "nsBlockFrame.h"
|
||||||
|
|
||||||
|
class nsLegendFrame final : public nsBlockFrame {
|
||||||
|
public:
|
||||||
|
NS_DECL_QUERYFRAME
|
||||||
|
NS_DECL_FRAMEARENA_HELPERS(nsLegendFrame)
|
||||||
|
|
||||||
|
explicit nsLegendFrame(ComputedStyle* aStyle, nsPresContext* aPresContext)
|
||||||
|
: nsBlockFrame(aStyle, aPresContext, kClassID) {}
|
||||||
|
|
||||||
|
virtual void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize,
|
||||||
|
const ReflowInput& aReflowInput,
|
||||||
|
nsReflowStatus& aStatus) override;
|
||||||
|
|
||||||
|
virtual void DestroyFrom(nsIFrame* aDestructRoot,
|
||||||
|
PostDestroyData& aPostDestroyData) override;
|
||||||
|
|
||||||
|
#ifdef DEBUG_FRAME_DUMP
|
||||||
|
virtual nsresult GetFrameName(nsAString& aResult) const override;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
mozilla::dom::HTMLLegendElement::LegendAlignValue GetLogicalAlign(
|
||||||
|
mozilla::WritingMode aCBWM);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // guard
|
|
@ -45,6 +45,7 @@ FRAME_CLASSES = [
|
||||||
Frame("nsImageFrame", "Image", LEAF),
|
Frame("nsImageFrame", "Image", LEAF),
|
||||||
Frame("nsInlineFrame", "Inline", NOT_LEAF),
|
Frame("nsInlineFrame", "Inline", NOT_LEAF),
|
||||||
Frame("nsLeafBoxFrame", "LeafBox", LEAF),
|
Frame("nsLeafBoxFrame", "LeafBox", LEAF),
|
||||||
|
Frame("nsLegendFrame", "Legend", NOT_LEAF),
|
||||||
Frame("nsListControlFrame", "ListControl", NOT_LEAF),
|
Frame("nsListControlFrame", "ListControl", NOT_LEAF),
|
||||||
Frame("nsMathMLFrame", "None", NOT_LEAF),
|
Frame("nsMathMLFrame", "None", NOT_LEAF),
|
||||||
Frame("nsMathMLmactionFrame", "None", NOT_LEAF),
|
Frame("nsMathMLmactionFrame", "None", NOT_LEAF),
|
||||||
|
|
|
@ -2314,9 +2314,17 @@ void ReflowInput::InitConstraints(
|
||||||
mComputeSizeFlags += ComputeSizeFlag::ShrinkWrap;
|
mComputeSizeFlags += ComputeSizeFlag::ShrinkWrap;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Shrink-wrap blocks that are orthogonal to their container.
|
// Make sure legend frames with display:block and width:auto still
|
||||||
if (isBlockLevel && mCBReflowInput &&
|
// shrink-wrap.
|
||||||
mCBReflowInput->GetWritingMode().IsOrthogonalTo(mWritingMode)) {
|
// Also shrink-wrap blocks that are orthogonal to their container.
|
||||||
|
if (isBlockLevel &&
|
||||||
|
((aFrameType == LayoutFrameType::Legend &&
|
||||||
|
mFrame->Style()->GetPseudoType() !=
|
||||||
|
PseudoStyleType::scrolledContent) ||
|
||||||
|
(aFrameType == LayoutFrameType::Scroll &&
|
||||||
|
mFrame->GetContentInsertionFrame()->IsLegendFrame()) ||
|
||||||
|
(mCBReflowInput &&
|
||||||
|
mCBReflowInput->GetWritingMode().IsOrthogonalTo(mWritingMode)))) {
|
||||||
mComputeSizeFlags += ComputeSizeFlag::ShrinkWrap;
|
mComputeSizeFlags += ComputeSizeFlag::ShrinkWrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -138,6 +138,8 @@ nsIFrame* NS_NewFileControlFrame(mozilla::PresShell* aPresShell,
|
||||||
mozilla::ComputedStyle* aStyle);
|
mozilla::ComputedStyle* aStyle);
|
||||||
nsIFrame* NS_NewColorControlFrame(mozilla::PresShell* aPresShell,
|
nsIFrame* NS_NewColorControlFrame(mozilla::PresShell* aPresShell,
|
||||||
mozilla::ComputedStyle* aStyle);
|
mozilla::ComputedStyle* aStyle);
|
||||||
|
nsIFrame* NS_NewLegendFrame(mozilla::PresShell* aPresShell,
|
||||||
|
mozilla::ComputedStyle* aStyle);
|
||||||
nsIFrame* NS_NewTextControlFrame(mozilla::PresShell* aPresShell,
|
nsIFrame* NS_NewTextControlFrame(mozilla::PresShell* aPresShell,
|
||||||
mozilla::ComputedStyle* aStyle);
|
mozilla::ComputedStyle* aStyle);
|
||||||
nsContainerFrame* NS_NewListControlFrame(mozilla::PresShell* aPresShell,
|
nsContainerFrame* NS_NewListControlFrame(mozilla::PresShell* aPresShell,
|
||||||
|
|
|
@ -38,7 +38,6 @@
|
||||||
#include "mozilla/ViewportUtils.h"
|
#include "mozilla/ViewportUtils.h"
|
||||||
|
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsFieldSetFrame.h"
|
|
||||||
#include "nsFlexContainerFrame.h"
|
#include "nsFlexContainerFrame.h"
|
||||||
#include "nsFrameList.h"
|
#include "nsFrameList.h"
|
||||||
#include "nsPlaceholderFrame.h"
|
#include "nsPlaceholderFrame.h"
|
||||||
|
@ -630,13 +629,6 @@ bool nsIFrame::IsPrimaryFrameOfRootOrBodyElement() const {
|
||||||
content == document->GetBodyElement();
|
content == document->GetBodyElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nsIFrame::IsRenderedLegend() const {
|
|
||||||
if (auto* parent = GetParent(); parent && parent->IsFieldSetFrame()) {
|
|
||||||
return static_cast<nsFieldSetFrame*>(parent)->GetLegend() == this;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsIFrame::Init(nsIContent* aContent, nsContainerFrame* aParent,
|
void nsIFrame::Init(nsIContent* aContent, nsContainerFrame* aParent,
|
||||||
nsIFrame* aPrevInFlow) {
|
nsIFrame* aPrevInFlow) {
|
||||||
MOZ_ASSERT(nsQueryFrame::FrameIID(mClass) == GetFrameId());
|
MOZ_ASSERT(nsQueryFrame::FrameIID(mClass) == GetFrameId());
|
||||||
|
|
|
@ -2377,11 +2377,6 @@ class nsIFrame : public nsQueryFrame {
|
||||||
|
|
||||||
bool IsPrimaryFrameOfRootOrBodyElement() const;
|
bool IsPrimaryFrameOfRootOrBodyElement() const;
|
||||||
|
|
||||||
/**
|
|
||||||
* @return true if this frame is used as a fieldset's rendered legend.
|
|
||||||
*/
|
|
||||||
bool IsRenderedLegend() const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This call is invoked on the primary frame for a character data content
|
* This call is invoked on the primary frame for a character data content
|
||||||
* node, when it is changed in the content tree.
|
* node, when it is changed in the content tree.
|
||||||
|
|
|
@ -838,9 +838,7 @@ static bool IsNonReplacedInline(nsIFrame* aFrame) {
|
||||||
// FIXME: this should be IsInlineInsideStyle() since width/height
|
// FIXME: this should be IsInlineInsideStyle() since width/height
|
||||||
// doesn't apply to ruby boxes.
|
// doesn't apply to ruby boxes.
|
||||||
return aFrame->StyleDisplay()->IsInlineFlow() &&
|
return aFrame->StyleDisplay()->IsInlineFlow() &&
|
||||||
!aFrame->IsFrameOfType(nsIFrame::eReplaced) &&
|
!aFrame->IsFrameOfType(nsIFrame::eReplaced);
|
||||||
!aFrame->IsBlockFrame() && !aFrame->IsScrollFrame() &&
|
|
||||||
!aFrame->IsColumnSetWrapperFrame();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Side SideForPaddingOrMarginOrInsetProperty(nsCSSPropertyID aPropID) {
|
static Side SideForPaddingOrMarginOrInsetProperty(nsCSSPropertyID aPropID) {
|
||||||
|
|
|
@ -55,6 +55,10 @@
|
||||||
|
|
||||||
/* Miscellaneous form elements */
|
/* Miscellaneous form elements */
|
||||||
|
|
||||||
|
fieldset > legend {
|
||||||
|
inline-size: -moz-fit-content;
|
||||||
|
}
|
||||||
|
|
||||||
legend {
|
legend {
|
||||||
display: block;
|
display: block;
|
||||||
padding-inline: 2px;
|
padding-inline: 2px;
|
||||||
|
|
|
@ -265,12 +265,6 @@ impl Display {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the raw underlying u16 value.
|
|
||||||
#[inline]
|
|
||||||
pub const fn to_u16(&self) -> u16 {
|
|
||||||
self.0
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Whether this is `display: inline` (or `inline list-item`).
|
/// Whether this is `display: inline` (or `inline list-item`).
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_inline_flow(&self) -> bool {
|
pub fn is_inline_flow(&self) -> bool {
|
||||||
|
|
|
@ -4024,16 +4024,6 @@ pub extern "C" fn Servo_ComputedValues_EqualForCachedAnonymousContentStyle(
|
||||||
differing_properties.is_empty()
|
differing_properties.is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn Servo_ComputedValues_BlockifiedDisplay(
|
|
||||||
style: &ComputedValues,
|
|
||||||
is_root_element : bool,
|
|
||||||
) -> u16 {
|
|
||||||
let display = style.get_box().clone_display();
|
|
||||||
let blockified_display = display.equivalent_block_display(is_root_element);
|
|
||||||
blockified_display.to_u16()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn Servo_StyleSet_Init(doc: &structs::Document) -> *mut RawServoStyleSet {
|
pub extern "C" fn Servo_StyleSet_Init(doc: &structs::Document) -> *mut RawServoStyleSet {
|
||||||
let data = Box::new(PerDocumentStyleData::new(doc));
|
let data = Box::new(PerDocumentStyleData::new(doc));
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
[nested-at-outer-boundary-as-legend.html]
|
||||||
|
expected: FAIL
|
|
@ -0,0 +1,7 @@
|
||||||
|
[legend-block-formatting-context.html]
|
||||||
|
[in-fieldset-second-child]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[in-fieldset-descendant]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
[legend-display.html]
|
[legend-display.html]
|
||||||
|
[rendered legend with display: flow]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
[rendered legend with display: run-in]
|
[rendered legend with display: run-in]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[rendered legend with display: run-in; overflow:hidden]
|
[rendered legend with display: inline]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[rendered legend with display: run-in; columns:1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[rendered legend with display: run-in; overflow:hidden;columns:1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,5 +1,16 @@
|
||||||
[legend-grid-flex-multicol.html]
|
[legend-grid-flex-multicol.html]
|
||||||
[offsetHeight]
|
[flex]
|
||||||
expected:
|
expected: FAIL
|
||||||
if os == "mac": FAIL
|
|
||||||
bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1689619
|
[multicol]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[inline-grid]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[grid]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[inline-flex]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
[legend.html]
|
||||||
|
[in-fieldset-second-child: width]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -2,9 +2,6 @@
|
||||||
<title>rendered legend and CSS display</title>
|
<title>rendered legend and CSS display</title>
|
||||||
<script src=/resources/testharness.js></script>
|
<script src=/resources/testharness.js></script>
|
||||||
<script src=/resources/testharnessreport.js></script>
|
<script src=/resources/testharnessreport.js></script>
|
||||||
<style>
|
|
||||||
legend { width:initial; }
|
|
||||||
</style>
|
|
||||||
<fieldset><legend id="ref">x</legend></fieldset>
|
<fieldset><legend id="ref">x</legend></fieldset>
|
||||||
<fieldset><legend id="test">x</legend></fieldset>
|
<fieldset><legend id="test">x</legend></fieldset>
|
||||||
<script>
|
<script>
|
||||||
|
@ -13,28 +10,22 @@ legend { width:initial; }
|
||||||
const testElm = document.querySelector('#test');
|
const testElm = document.querySelector('#test');
|
||||||
const values = ['block', 'table', 'table-row-group', 'table-header-group', 'table-footer-group', 'table-row', 'table-cell',
|
const values = ['block', 'table', 'table-row-group', 'table-header-group', 'table-footer-group', 'table-row', 'table-cell',
|
||||||
'table-column-group', 'table-column', 'table-caption', 'list-item', 'flow', 'flow-root','run-in','inline',
|
'table-column-group', 'table-column', 'table-caption', 'list-item', 'flow', 'flow-root','run-in','inline',
|
||||||
'inline-block', 'inline-table', 'block ruby', 'ruby', 'ruby-base', 'ruby-text', 'ruby-base-container', 'ruby-text-container',
|
'inline-block', 'inline-table', 'ruby', 'ruby-base', 'ruby-text', 'ruby-base-container', 'ruby-text-container',
|
||||||
'grid', 'inline-grid', 'flex', 'inline-flex'];
|
'grid', 'inline-grid', 'flex', 'inline-flex'];
|
||||||
const extraStyle = ['', 'overflow:hidden', 'columns:1', 'overflow:hidden;columns:1'];
|
|
||||||
|
|
||||||
for (const style of extraStyle) {
|
for (const val of values) {
|
||||||
for (const val of values) {
|
test(() => {
|
||||||
test(() => {
|
testElm.style.removeProperty('display');
|
||||||
testElm.style.removeProperty('display');
|
testElm.style.display = val;
|
||||||
testElm.style = style;
|
const computed = getComputedStyle(testElm);
|
||||||
testElm.style.display = val;
|
// Note that computed value is different from the used value.
|
||||||
const computed = getComputedStyle(testElm);
|
// E.g., if ruby is not supported, the following assertion will
|
||||||
// Note that computed value is different from the used value.
|
// fail as the computed value of display will be block.
|
||||||
// E.g., if ruby is not supported, the following assertion will
|
// If ruby is supported, computed.display will return "ruby",
|
||||||
// fail as the computed value of display will be block.
|
// but the used value is supposed to be "block".
|
||||||
// If ruby is supported, computed.display will return "ruby",
|
assert_equals(computed.display, val, `display: ${val} is not supported`);
|
||||||
// but the used value is supposed to be "block ruby".
|
assert_equals(computed.width, refStyle.width, 'width');
|
||||||
// Also, 'flow' is serialized as 'block' for legacy reasons.
|
assert_equals(testElm.offsetLeft, refElm.offsetLeft, 'offsetLeft');
|
||||||
let expected = val == 'flow' ? 'block' : val;
|
}, `rendered legend with display: ${val}`);
|
||||||
assert_equals(computed.display, expected, `display: ${val} is not supported`);
|
|
||||||
assert_equals(computed.width, refStyle.width, 'width');
|
|
||||||
assert_equals(testElm.offsetLeft, refElm.offsetLeft, 'offsetLeft');
|
|
||||||
}, `rendered legend with display: ${val}` + (style == '' ? '' : "; " + style));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
Загрузка…
Ссылка в новой задаче