diff --git a/dom/html/HTMLLegendElement.cpp b/dom/html/HTMLLegendElement.cpp
index 253c9bdff5b3..93b5200f96e7 100644
--- a/dom/html/HTMLLegendElement.cpp
+++ b/dom/html/HTMLLegendElement.cpp
@@ -103,26 +103,6 @@ bool HTMLLegendElement::PerformAccesskey(bool aKeyCausesActivation,
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(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 HTMLLegendElement::GetForm() {
return do_AddRef(GetFormElement());
}
diff --git a/dom/html/HTMLLegendElement.h b/dom/html/HTMLLegendElement.h
index b239a7183475..2a8230c112e3 100644
--- a/dom/html/HTMLLegendElement.h
+++ b/dom/html/HTMLLegendElement.h
@@ -57,16 +57,6 @@ class HTMLLegendElement final : public nsGenericHTMLElement {
InlineStart,
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
*/
diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp
index 9b77941596ff..6e394bb22972 100644
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -702,10 +702,6 @@ class MOZ_STACK_CLASS nsFrameConstructorState {
// mode).
bool mCreatingExtraFrames;
- // This keeps track of whether we have found a "rendered legend" for
- // the current FieldSetFrame.
- bool mHasRenderedLegend;
-
nsTArray> mGeneratedContentWithInitializer;
// Constructor
@@ -855,8 +851,7 @@ nsFrameConstructorState::nsFrameConstructorState(
// frames.
mFixedPosIsAbsPos(aFixedContainingBlock == aAbsoluteContainingBlock),
mHavePendingPopupgroup(false),
- mCreatingExtraFrames(false),
- mHasRenderedLegend(false) {
+ mCreatingExtraFrames(false) {
#ifdef MOZ_XUL
nsIPopupContainer* popupContainer =
nsIPopupContainer::GetPopupContainer(aPresShell);
@@ -3053,16 +3048,35 @@ nsIFrame* nsCSSFrameConstructor::ConstructFieldSetFrame(
absoluteSaveState);
}
- {
- AutoRestore savedHasRenderedLegend(aState.mHasRenderedLegend);
- aState.mHasRenderedLegend = false;
- ProcessChildren(aState, content, computedStyle, contentFrame, true,
- childList, true);
- }
+ ProcessChildren(aState, content, computedStyle, contentFrame, true, childList,
+ true);
+
nsFrameList fieldsetKids;
fieldsetKids.AppendFrame(nullptr,
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)) {
// Set the inner frame's initial child lists.
contentFrame->SetInitialChildList(kPrincipalList, childList);
@@ -3088,10 +3102,10 @@ nsIFrame* nsCSSFrameConstructor::ConstructFieldSetFrame(
FinishBuildingScrollFrame(scrollFrame, contentFrameTop);
}
- // We use AppendFrames here because the rendered legend will already
- // be present in the principal child list if it exists.
- fieldsetFrame->AppendFrames(nsIFrame::kNoReflowPrincipalList, fieldsetKids);
+ // Set the outer frame's initial child list
+ fieldsetFrame->SetInitialChildList(kPrincipalList, fieldsetKids);
+ // Our new frame returned is the outer frame, which is the fieldset frame.
return fieldsetFrame;
}
@@ -3315,11 +3329,25 @@ nsCSSFrameConstructor::FindHTMLData(const Element& aElement,
nsIFrame* aParentFrame,
ComputedStyle& aStyle) {
MOZ_ASSERT(aElement.IsHTMLElement());
+
+ nsAtom* tag = aElement.NodeInfo()->NameAtom();
NS_ASSERTION(!aParentFrame ||
aParentFrame->Style()->GetPseudoType() !=
PseudoStyleType::fieldsetContent ||
aParentFrame->GetParent()->IsFieldSetFrame(),
"Unexpected parent for fieldset content anon box");
+ if (tag == nsGkAtoms::legend &&
+ (!aParentFrame || !IsFrameForFieldSet(aParentFrame) ||
+ aStyle.StyleDisplay()->IsFloatingStyle() ||
+ aStyle.StyleDisplay()->IsAbsolutelyPositionedStyle())) {
+ //