Bug 1799343 - Simplify XUL popup handling. r=TYLin

* Make non-menulist popups just absolute positioned top-layer items.
 * Simplify menulist popups to just be static-positioned items under
   nsMenuFrame.

We need to keep kPopupList only for nsMenuFrame. In the future it can be
removed, see TODO in xul.css

Differential Revision: https://phabricator.services.mozilla.com/D161404
This commit is contained in:
Emilio Cobos Álvarez 2022-11-09 14:19:22 +00:00
Родитель 57e9eb5281
Коммит 5c5c337a98
28 изменённых файлов: 156 добавлений и 567 удалений

Просмотреть файл

@ -22,7 +22,6 @@
// CSS display
testCSSAttrs("display_mozbox");
testCSSAttrs("display_mozinlinebox");
testCSSAttrs("display_mozpopup");
SimpleTest.finish();
}
@ -49,7 +48,6 @@
<vbox id="display_mozbox" style="display: -moz-box;" role="img"/>
<vbox id="display_mozinlinebox" style="display: -moz-inline-box;" role="img"/>
<vbox id="display_mozpopup" style="display: -moz-popup;" role="img"/>
</hbox>
</window>

Просмотреть файл

@ -1147,6 +1147,7 @@ toolbarpaletteitem[place="palette"] > #downloads-button[indicator] > .toolbarbut
transition-duration: 0.18s, 0.18s;
transition-timing-function:
var(--animation-easing-function), ease-out;
will-change: transform, opacity;
}
#BMB_bookmarksPopup[side="bottom"]:not([animate="false"]) {

Просмотреть файл

@ -35,7 +35,7 @@ let whitelist = [
isFromDevTools: false,
},
{
sourceName: /\b(minimal-xul|html|mathml|ua|forms|svg|manageDialog|autocomplete-item-shared|formautofill)\.css$/i,
sourceName: /\b(xul|minimal-xul|html|mathml|ua|forms|svg|manageDialog|autocomplete-item-shared|formautofill)\.css$/i,
errorMessage: /Unknown property.*-moz-/i,
isFromDevTools: false,
},

Просмотреть файл

@ -975,8 +975,11 @@ static bool ContainingBlockChangeAffectsDescendants(
// they ignore their position style ... but they can't.
NS_ASSERTION(!SVGUtils::IsInSVGTextSubtree(outOfFlow),
"SVG text frames can't be out of flow");
// Top-layer frames don't change containing block based on direct
// ancestors.
auto* display = outOfFlow->StyleDisplay();
if (display->IsAbsolutelyPositionedStyle()) {
if (display->IsAbsolutelyPositionedStyle() &&
display->mTopLayer == StyleTopLayer::None) {
const bool isContainingBlock =
aIsFixedPosContainingBlock ||
(aIsAbsPosContainingBlock &&

Просмотреть файл

@ -1,29 +0,0 @@
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:math="http://www.w3.org/1998/Math/MathML"
class="reftest-wait"
onload="boom();">
<html:style type="text/css">
[class="mp"] { display: -moz-popup; }
</html:style>
<script>
function boom()
{
document.getElementById("mtd").setAttribute("class", "mp");
setTimeout(boom2, 30);
}
function boom2()
{
document.getElementById("mtd").setAttribute("class", "");
document.documentElement.removeAttribute("class");
}
</script>
<math:mtd id="mtd" />
</window>

Просмотреть файл

@ -179,7 +179,6 @@ load 399951-1.html
load 399994-1.html
load 400445-1.xhtml
load 400904-1.xhtml
load chrome://reftest/content/crashtests/layout/base/crashtests/401589-1.xhtml
load 401734-1.html
load 401734-2.html
needs-focus pref(accessibility.browsewithcaret,true) load 403048.html

Просмотреть файл

@ -204,7 +204,6 @@ static FrameCtorDebugFlags gFlags[] = {
#endif
#include "nsMenuFrame.h"
#include "nsPopupSetFrame.h"
#include "nsTreeColFrame.h"
//------------------------------------------------------------------
@ -221,8 +220,6 @@ nsIFrame* NS_NewSplitterFrame(PresShell* aPresShell, ComputedStyle* aStyle);
nsIFrame* NS_NewMenuPopupFrame(PresShell* aPresShell, ComputedStyle* aStyle);
nsIFrame* NS_NewPopupSetFrame(PresShell* aPresShell, ComputedStyle* aStyle);
nsIFrame* NS_NewMenuFrame(PresShell* aPresShell, ComputedStyle* aStyle,
uint32_t aFlags);
@ -604,9 +601,6 @@ class MOZ_STACK_CLASS nsFrameConstructorState {
PresShell* mPresShell;
nsFrameManager* mFrameManager;
// Frames destined for the kPopupList.
AbsoluteFrameList mPopupList;
// Containing block information for out-of-flow frames.
AbsoluteFrameList mFixedList;
AbsoluteFrameList mAbsoluteList;
@ -638,11 +632,6 @@ class MOZ_STACK_CLASS nsFrameConstructorState {
// abs-pos lists together.
bool mFixedPosIsAbsPos;
// A boolean to indicate whether we have a "pending" popupgroup. That is, we
// have already created the FrameConstructionItem for the root popupgroup but
// we have not yet created the relevant frame.
bool mHavePendingPopupgroup;
// If false (which is the default) then call SetPrimaryFrame() as needed
// during frame construction. If true, don't make any SetPrimaryFrame()
// calls, except for generated content which doesn't have a primary frame
@ -745,13 +734,11 @@ class MOZ_STACK_CLASS nsFrameConstructorState {
* positioned
* @param aCanBeFloated pass false if the frame isn't allowed to be
* floated
* @param aIsOutOfFlowPopup pass true if the frame is an out-of-flow popup
* (XUL-only)
*/
void AddChild(nsIFrame* aNewFrame, nsFrameList& aFrameList,
nsIContent* aContent, nsContainerFrame* aParentFrame,
bool aCanBePositioned = true, bool aCanBeFloated = true,
bool aIsOutOfFlowPopup = false, bool aInsertAfter = false,
bool aInsertAfter = false,
nsIFrame* aInsertAfterFrame = nullptr);
/**
@ -789,7 +776,6 @@ class MOZ_STACK_CLASS nsFrameConstructorState {
AbsoluteFrameList* GetOutOfFlowFrameList(nsIFrame* aNewFrame,
bool aCanBePositioned,
bool aCanBeFloated,
bool aIsOutOfFlowPopup,
nsFrameState* aPlaceholderType);
void ConstructBackdropFrameFor(nsIContent* aContent, nsIFrame* aFrame);
@ -803,7 +789,6 @@ nsFrameConstructorState::nsFrameConstructorState(
: mPresContext(aPresShell->GetPresContext()),
mPresShell(aPresShell),
mFrameManager(aPresShell->FrameConstructor()),
mPopupList(nullptr),
mFixedList(aFixedContainingBlock),
mAbsoluteList(aAbsoluteContainingBlock),
mFloatedList(aFloatContainingBlock),
@ -820,14 +805,8 @@ nsFrameConstructorState::nsFrameConstructorState(
// block, use the abs-pos containing block's abs-pos list for fixed-pos
// frames.
mFixedPosIsAbsPos(aFixedContainingBlock == aAbsoluteContainingBlock),
mHavePendingPopupgroup(false),
mCreatingExtraFrames(false),
mHasRenderedLegend(false) {
nsIPopupContainer* popupContainer =
nsIPopupContainer::GetPopupContainer(aPresShell);
if (popupContainer) {
mPopupList.mContainingBlock = popupContainer->GetPopupSetFrame();
}
MOZ_COUNT_CTOR(nsFrameConstructorState);
}
@ -854,7 +833,6 @@ void nsFrameConstructorState::ProcessFrameInsertionsForAllLists() {
ProcessFrameInsertions(mFloatedList, nsIFrame::kFloatList);
ProcessFrameInsertions(mAbsoluteList, nsIFrame::kAbsoluteList);
ProcessFrameInsertions(mFixedList, nsIFrame::kFixedList);
ProcessFrameInsertions(mPopupList, nsIFrame::kPopupList);
}
void nsFrameConstructorState::PushAbsoluteContainingBlock(
@ -1054,12 +1032,7 @@ void nsFrameConstructorState::ReparentFloats(nsContainerFrame* aNewParent) {
AbsoluteFrameList* nsFrameConstructorState::GetOutOfFlowFrameList(
nsIFrame* aNewFrame, bool aCanBePositioned, bool aCanBeFloated,
bool aIsOutOfFlowPopup, nsFrameState* aPlaceholderType) {
if (MOZ_UNLIKELY(aIsOutOfFlowPopup)) {
MOZ_ASSERT(mPopupList.mContainingBlock, "Must have a popup set frame!");
*aPlaceholderType = PLACEHOLDER_FOR_POPUP;
return &mPopupList;
}
nsFrameState* aPlaceholderType) {
const nsStyleDisplay* disp = aNewFrame->StyleDisplay();
if (aCanBeFloated && disp->IsFloatingStyle()) {
*aPlaceholderType = PLACEHOLDER_FOR_FLOAT;
@ -1111,7 +1084,7 @@ void nsFrameConstructorState::ConstructBackdropFrameFor(nsIContent* aContent,
nsFrameState placeholderType;
AbsoluteFrameList* frameList =
GetOutOfFlowFrameList(backdropFrame, true, true, false, &placeholderType);
GetOutOfFlowFrameList(backdropFrame, true, true, &placeholderType);
MOZ_ASSERT(placeholderType & PLACEHOLDER_FOR_TOPLAYER);
nsIFrame* placeholder = nsCSSFrameConstructor::CreatePlaceholderFrameFor(
@ -1125,13 +1098,12 @@ void nsFrameConstructorState::ConstructBackdropFrameFor(nsIContent* aContent,
void nsFrameConstructorState::AddChild(
nsIFrame* aNewFrame, nsFrameList& aFrameList, nsIContent* aContent,
nsContainerFrame* aParentFrame, bool aCanBePositioned, bool aCanBeFloated,
bool aIsOutOfFlowPopup, bool aInsertAfter, nsIFrame* aInsertAfterFrame) {
bool aInsertAfter, nsIFrame* aInsertAfterFrame) {
MOZ_ASSERT(!aNewFrame->GetNextSibling(), "Shouldn't happen");
nsFrameState placeholderType;
AbsoluteFrameList* outOfFlowFrameList =
GetOutOfFlowFrameList(aNewFrame, aCanBePositioned, aCanBeFloated,
aIsOutOfFlowPopup, &placeholderType);
AbsoluteFrameList* outOfFlowFrameList = GetOutOfFlowFrameList(
aNewFrame, aCanBePositioned, aCanBeFloated, &placeholderType);
// The comments in GetGeometricParent regarding root table frames
// all apply here, unfortunately. Thus, we need to check whether
@ -1188,8 +1160,7 @@ MOZ_NEVER_INLINE void nsFrameConstructorState::ProcessFrameInsertions(
aChildListID == nsIFrame::kAbsoluteList) || \
((&aFrameList == &mFixedList || &aFrameList == &mTopLayerFixedList) && \
aChildListID == nsIFrame::kFixedList)
MOZ_ASSERT(NS_NONXUL_LIST_TEST || (&aFrameList == &mPopupList &&
aChildListID == nsIFrame::kPopupList),
MOZ_ASSERT(NS_NONXUL_LIST_TEST,
"Unexpected aFrameList/aChildListID combination");
if (aFrameList.IsEmpty()) {
@ -2538,9 +2509,6 @@ nsIFrame* nsCSSFrameConstructor::ConstructDocElementFrame(
mDocElementContainingBlock->AppendFrames(kPrincipalList,
std::move(frameList));
MOZ_ASSERT(!state.mHavePendingPopupgroup,
"Should have proccessed pending popup group by now");
return newFrame;
}
@ -3685,18 +3653,13 @@ void nsCSSFrameConstructor::ConstructFrameFromItemInternal(
} else {
newFrame = (*data->mFunc.mCreationFunc)(mPresShell, computedStyle);
bool allowOutOfFlow = !(bits & FCDATA_DISALLOW_OUT_OF_FLOW);
bool isPopup = aItem.mIsPopup;
NS_ASSERTION(
!isPopup || (aState.mPopupList.mContainingBlock &&
aState.mPopupList.mContainingBlock->IsPopupSetFrame()),
"Should have a containing block here!");
const bool allowOutOfFlow = !(bits & FCDATA_DISALLOW_OUT_OF_FLOW);
const bool isPopup = aItem.mIsPopup;
nsContainerFrame* geometricParent =
isPopup ? aState.mPopupList.mContainingBlock
: (allowOutOfFlow
? aState.GetGeometricParent(*display, aParentFrame)
: aParentFrame);
(isPopup || allowOutOfFlow)
? aState.GetGeometricParent(*display, aParentFrame)
: aParentFrame;
// In the non-scrollframe case, primaryFrame and newFrame are equal; in the
// scrollframe case, newFrame is the scrolled frame while primaryFrame is
@ -3777,21 +3740,10 @@ void nsCSSFrameConstructor::ConstructFrameFromItemInternal(
}
aState.AddChild(primaryFrame, aFrameList, content, aParentFrame,
allowOutOfFlow, allowOutOfFlow, isPopup);
allowOutOfFlow, allowOutOfFlow);
nsContainerFrame* newFrameAsContainer = do_QueryFrame(newFrame);
if (newFrameAsContainer) {
// Icky XUL stuff, sadly
if (aItem.mIsRootPopupgroup) {
NS_ASSERTION(nsIPopupContainer::GetPopupContainer(mPresShell) &&
nsIPopupContainer::GetPopupContainer(mPresShell)
->GetPopupSetFrame() == newFrame,
"Unexpected PopupSetFrame");
aState.mPopupList.mContainingBlock = newFrameAsContainer;
aState.mHavePendingPopupgroup = false;
}
// Process the child content if requested
nsFrameList childList;
nsFrameConstructorSaveState absoluteSaveState;
@ -4089,7 +4041,6 @@ nsCSSFrameConstructor::FindXULTagData(const Element& aElement,
#else
SIMPLE_XUL_CREATE(menubar, NS_NewMenuBarFrame),
#endif /* XP_MACOSX */
SIMPLE_TAG_CHAIN(popupgroup, nsCSSFrameConstructor::FindPopupGroupData),
SIMPLE_XUL_CREATE(iframe, NS_NewSubDocumentFrame),
SIMPLE_XUL_CREATE(editor, NS_NewSubDocumentFrame),
SIMPLE_XUL_CREATE(browser, NS_NewSubDocumentFrame),
@ -4101,19 +4052,6 @@ nsCSSFrameConstructor::FindXULTagData(const Element& aElement,
return FindDataByTag(aElement, aStyle, sXULTagData, ArrayLength(sXULTagData));
}
/* static */
const nsCSSFrameConstructor::FrameConstructionData*
nsCSSFrameConstructor::FindPopupGroupData(const Element& aElement,
ComputedStyle&) {
if (!aElement.IsRootOfNativeAnonymousSubtree()) {
return nullptr;
}
static constexpr FrameConstructionData sPopupSetData =
SIMPLE_XUL_FCDATA(NS_NewPopupSetFrame);
return &sPopupSetData;
}
/* static */
const nsCSSFrameConstructor::FrameConstructionData*
nsCSSFrameConstructor::FindXULButtonData(const Element& aElement,
@ -4521,8 +4459,7 @@ nsCSSFrameConstructor::FindDisplayData(const nsStyleDisplay& aDisplay,
}
case StyleDisplayInside::MozPopup: {
static constexpr FrameConstructionData data(
NS_NewMenuPopupFrame, FCDATA_DISALLOW_OUT_OF_FLOW | FCDATA_IS_POPUP |
FCDATA_SKIP_ABSPOS_PUSH);
NS_NewMenuPopupFrame, FCDATA_IS_POPUP | FCDATA_SKIP_ABSPOS_PUSH);
return &data;
}
default:
@ -5383,11 +5320,6 @@ void nsCSSFrameConstructor::AddFrameConstructionItemsInternal(
(data->mBits & FCDATA_IS_POPUP) && (!aParentFrame || // Parent is inline
!aParentFrame->IsMenuFrame());
if (isPopup && !aState.mPopupList.mContainingBlock &&
!aState.mHavePendingPopupgroup) {
return;
}
const uint32_t bits = data->mBits;
// Inside colgroups, suppress everything except columns.
@ -5421,11 +5353,6 @@ void nsCSSFrameConstructor::AddFrameConstructionItemsInternal(
// This corresponds to the Release in ConstructFramesFromItem.
item->mContent->AddRef();
}
item->mIsRootPopupgroup = aContent->IsRootOfNativeAnonymousSubtree() &&
aContent->IsXULElement(nsGkAtoms::popupgroup);
if (item->mIsRootPopupgroup) {
aState.mHavePendingPopupgroup = true;
}
item->mIsPopup = isPopup;
if (canHavePageBreak && display.BreakAfter()) {
@ -5597,16 +5524,6 @@ void nsCSSFrameConstructor::ConstructFramesFromItem(
}
}
void nsCSSFrameConstructor::ReconstructDocElementHierarchy(
InsertionKind aInsertionKind) {
Element* rootElement = mDocument->GetRootElement();
if (!rootElement) {
/* nothing to do */
return;
}
RecreateFramesForContent(rootElement, aInsertionKind);
}
nsContainerFrame* nsCSSFrameConstructor::GetAbsoluteContainingBlock(
nsIFrame* aFrame, ContainingBlockType aType) {
// Starting with aFrame, look for a frame that is absolutely positioned or
@ -8364,16 +8281,6 @@ bool nsCSSFrameConstructor::MaybeRecreateContainerForFrameRemoval(
return true;
}
if (aFrame->IsPopupSetFrame()) {
nsIPopupContainer* popupContainer =
nsIPopupContainer::GetPopupContainer(mPresShell);
if (popupContainer && popupContainer->GetPopupSetFrame() == aFrame) {
TRACE("PopupSet");
ReconstructDocElementHierarchy(InsertionKind::Async);
return true;
}
}
// Reconstruct if inflowFrame is parent's only child, and parent is, or has,
// a non-fluid continuation, i.e. it was split by bidi resolution
if (!inFlowFrame->GetPrevSibling() && !inFlowFrame->GetNextSibling() &&
@ -9681,9 +9588,7 @@ void nsCSSFrameConstructor::ProcessChildren(
itemsToConstruct.SetLineBoundaryAtEnd(true);
}
// Create any anonymous frames we need here. This must happen before the
// non-anonymous children are processed to ensure that popups are never
// constructed before the popupset.
// Create any anonymous frames we need here.
AutoTArray<nsIAnonymousContentCreator::ContentInfo, 4> anonymousItems;
GetAnonymousContent(aContent, aPossiblyLeafFrame, anonymousItems);
#ifdef DEBUG
@ -10046,7 +9951,7 @@ nsFirstLetterFrame* nsCSSFrameConstructor::CreateFloatingLetterFrame(
}
aState.AddChild(letterFrame, aResult, letterContent, aParentFrame, false,
true, false, true, prevSibling);
true, true, prevSibling);
if (nextTextFrame) {
aResult.AppendFrame(nullptr, nextTextFrame);

Просмотреть файл

@ -103,8 +103,6 @@ class nsCSSFrameConstructor final : public nsFrameManager {
nsIFrame* ConstructRootFrame();
void ReconstructDocElementHierarchy(InsertionKind);
private:
enum Operation { CONTENTAPPEND, CONTENTINSERT };
@ -1117,7 +1115,6 @@ class nsCSSFrameConstructor final : public nsFrameManager {
mSuppressWhiteSpaceOptimizations(aSuppressWhiteSpaceOptimizations),
mIsText(false),
mIsGeneratedContent(false),
mIsRootPopupgroup(false),
mIsAllInline(false),
mIsBlock(false),
mIsPopup(false),
@ -1178,8 +1175,6 @@ class nsCSSFrameConstructor final : public nsFrameManager {
// Whether this is a generated content container.
// If it is, mContent is a strong pointer.
bool mIsGeneratedContent : 1;
// Whether this is an item for the root popupgroup.
bool mIsRootPopupgroup : 1;
// Whether construction from this item will create only frames that are
// IsInlineOutside() in the principal child list. This is not precise, but
// conservative: if true the frames will really be inline, whereas if false

Просмотреть файл

@ -826,21 +826,14 @@ FrameChildListID nsLayoutUtils::GetChildListNameFor(nsIFrame* aChildFrame) {
if (LayoutFrameType::MenuPopup == childType) {
nsIFrame* parent = aChildFrame->GetParent();
MOZ_ASSERT(parent, "nsMenuPopupFrame can't be the root frame");
if (parent) {
if (parent->IsPopupSetFrame()) {
id = nsIFrame::kPopupList;
} else {
nsIFrame* firstPopup =
parent->GetChildList(nsIFrame::kPopupList).FirstChild();
MOZ_ASSERT(
!firstPopup || !firstPopup->GetNextSibling(),
"We assume popupList only has one child, but it has more.");
id = firstPopup == aChildFrame ? nsIFrame::kPopupList
: nsIFrame::kPrincipalList;
}
} else {
id = nsIFrame::kPrincipalList;
}
MOZ_ASSERT(parent->IsMenuFrame(),
"nsMenuPopupFrame should be out of flow if not under a menu");
nsIFrame* firstPopup =
parent->GetChildList(nsIFrame::kPopupList).FirstChild();
MOZ_ASSERT(!firstPopup || !firstPopup->GetNextSibling(),
"We assume popupList only has one child, but it has more.");
id = firstPopup == aChildFrame ? nsIFrame::kPopupList
: nsIFrame::kPrincipalList;
} else if (LayoutFrameType::TableColGroup == childType) {
id = nsIFrame::kColGroupList;
} else if (aChildFrame->IsTableCaption()) {

Просмотреть файл

@ -72,7 +72,6 @@ FRAME_CLASSES = [
Frame("nsPageContentFrame", "PageContent", NOT_LEAF),
Frame("nsPageFrame", "Page", NOT_LEAF),
Frame("nsPlaceholderFrame", "Placeholder", LEAF),
Frame("nsPopupSetFrame", "PopupSet", NOT_LEAF),
Frame("nsProgressFrame", "Progress", LEAF),
Frame("nsRangeFrame", "Range", LEAF),
Frame("nsRubyBaseContainerFrame", "RubyBaseContainer", NOT_LEAF),

Просмотреть файл

@ -816,59 +816,65 @@ void nsAbsoluteContainingBlock::ReflowAbsoluteFrame(
ReflowOutput kidDesiredSize(kidReflowInput);
aKidFrame->Reflow(aPresContext, kidDesiredSize, kidReflowInput, aStatus);
const LogicalSize kidSize = kidDesiredSize.Size(outerWM);
// Position the child relative to our padding edge. Don't do this for popups,
// which handle their own positioning.
if (!aKidFrame->IsMenuPopupFrame()) {
const LogicalSize kidSize = kidDesiredSize.Size(outerWM);
LogicalMargin offsets = kidReflowInput.ComputedLogicalOffsets(outerWM);
LogicalMargin margin = kidReflowInput.ComputedLogicalMargin(outerWM);
LogicalMargin offsets = kidReflowInput.ComputedLogicalOffsets(outerWM);
LogicalMargin margin = kidReflowInput.ComputedLogicalMargin(outerWM);
// If we're doing CSS Box Alignment in either axis, that will apply the
// margin for us in that axis (since the thing that's aligned is the margin
// box). So, we clear out the margin here to avoid applying it twice.
if (kidReflowInput.mFlags.mIOffsetsNeedCSSAlign) {
margin.IStart(outerWM) = margin.IEnd(outerWM) = 0;
}
if (kidReflowInput.mFlags.mBOffsetsNeedCSSAlign) {
margin.BStart(outerWM) = margin.BEnd(outerWM) = 0;
}
// If we're doing CSS Box Alignment in either axis, that will apply the
// margin for us in that axis (since the thing that's aligned is the margin
// box). So, we clear out the margin here to avoid applying it twice.
if (kidReflowInput.mFlags.mIOffsetsNeedCSSAlign) {
margin.IStart(outerWM) = margin.IEnd(outerWM) = 0;
}
if (kidReflowInput.mFlags.mBOffsetsNeedCSSAlign) {
margin.BStart(outerWM) = margin.BEnd(outerWM) = 0;
}
// If we're solving for start in either inline or block direction,
// then compute it now that we know the dimensions.
ResolveSizeDependentOffsets(aPresContext, kidReflowInput, kidSize, margin,
&offsets, &logicalCBSize);
// If we're solving for start in either inline or block direction,
// then compute it now that we know the dimensions.
ResolveSizeDependentOffsets(aPresContext, kidReflowInput, kidSize, margin,
&offsets, &logicalCBSize);
if (kidReflowInput.mFrame->HasIntrinsicKeywordForBSize()) {
ResolveAutoMarginsAfterLayout(kidReflowInput, &logicalCBSize, kidSize,
margin, offsets);
}
if (kidReflowInput.mFrame->HasIntrinsicKeywordForBSize()) {
ResolveAutoMarginsAfterLayout(kidReflowInput, &logicalCBSize, kidSize,
margin, offsets);
}
// Position the child relative to our padding edge
LogicalRect rect(
outerWM,
border.IStart(outerWM) + offsets.IStart(outerWM) + margin.IStart(outerWM),
border.BStart(outerWM) + offsets.BStart(outerWM) + margin.BStart(outerWM),
kidSize.ISize(outerWM), kidSize.BSize(outerWM));
nsRect r = rect.GetPhysicalRect(
outerWM, logicalCBSize.GetPhysicalSize(wm) +
border.Size(outerWM).GetPhysicalSize(outerWM));
LogicalRect rect(outerWM,
border.IStart(outerWM) + offsets.IStart(outerWM) +
margin.IStart(outerWM),
border.BStart(outerWM) + offsets.BStart(outerWM) +
margin.BStart(outerWM),
kidSize.ISize(outerWM), kidSize.BSize(outerWM));
nsRect r = rect.GetPhysicalRect(
outerWM, logicalCBSize.GetPhysicalSize(wm) +
border.Size(outerWM).GetPhysicalSize(outerWM));
// Offset the frame rect by the given origin of the absolute containing block.
r.x += aContainingBlock.x;
r.y += aContainingBlock.y;
// Offset the frame rect by the given origin of the absolute containing
// block.
r.x += aContainingBlock.x;
r.y += aContainingBlock.y;
aKidFrame->SetRect(r);
aKidFrame->SetRect(r);
nsView* view = aKidFrame->GetView();
if (view) {
// Size and position the view and set its opacity, visibility, content
// transparency, and clip
nsContainerFrame::SyncFrameViewAfterReflow(aPresContext, aKidFrame, view,
kidDesiredSize.InkOverflow());
} else {
nsContainerFrame::PositionChildViews(aKidFrame);
nsView* view = aKidFrame->GetView();
if (view) {
// Size and position the view and set its opacity, visibility, content
// transparency, and clip
nsContainerFrame::SyncFrameViewAfterReflow(aPresContext, aKidFrame, view,
kidDesiredSize.InkOverflow());
} else {
nsContainerFrame::PositionChildViews(aKidFrame);
}
}
aKidFrame->DidReflow(aPresContext, &kidReflowInput);
const nsRect r = aKidFrame->GetRect();
#ifdef DEBUG
if (nsBlockFrame::gNoisyReflow) {
nsIFrame::IndentBy(stdout, nsBlockFrame::gNoiseIndent - 1);

Просмотреть файл

@ -15,7 +15,6 @@
#include "nsContentCreatorFunctions.h"
#include "nsCSSRendering.h"
#include "nsPresContext.h"
#include "nsPopupSetFrame.h"
#include "nsGkAtoms.h"
#include "nsIFrameInlines.h"
#include "nsDisplayList.h"
@ -158,24 +157,11 @@ nsresult nsCanvasFrame::CreateAnonymousContent(
// support context menus and tooltips.
if (XRE_IsParentProcess() && doc->NodePrincipal()->IsSystemPrincipal()) {
nsNodeInfoManager* nodeInfoManager = doc->NodeInfoManager();
RefPtr<NodeInfo> nodeInfo =
nodeInfoManager->GetNodeInfo(nsGkAtoms::popupgroup, nullptr,
kNameSpaceID_XUL, nsINode::ELEMENT_NODE);
nsresult rv = NS_NewXULElement(getter_AddRefs(mPopupgroupContent),
nodeInfo.forget(), dom::NOT_FROM_PARSER);
NS_ENSURE_SUCCESS(rv, rv);
mPopupgroupContent->SetProperty(nsGkAtoms::docLevelNativeAnonymousContent,
reinterpret_cast<void*>(true));
aElements.AppendElement(mPopupgroupContent);
nodeInfo = nodeInfoManager->GetNodeInfo(
RefPtr<NodeInfo> nodeInfo = nodeInfoManager->GetNodeInfo(
nsGkAtoms::tooltip, nullptr, kNameSpaceID_XUL, nsINode::ELEMENT_NODE);
rv = NS_NewXULElement(getter_AddRefs(mTooltipContent), nodeInfo.forget(),
dom::NOT_FROM_PARSER);
nsresult rv = NS_NewXULElement(getter_AddRefs(mTooltipContent),
nodeInfo.forget(), dom::NOT_FROM_PARSER);
NS_ENSURE_SUCCESS(rv, rv);
mTooltipContent->SetAttr(kNameSpaceID_None, nsGkAtoms::_default, u"true"_ns,
@ -208,9 +194,6 @@ void nsCanvasFrame::AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
if (mCustomContentContainer) {
aElements.AppendElement(mCustomContentContainer);
}
if (mPopupgroupContent) {
aElements.AppendElement(mPopupgroupContent);
}
if (mTooltipContent) {
aElements.AppendElement(mTooltipContent);
}
@ -225,16 +208,9 @@ void nsCanvasFrame::DestroyFrom(nsIFrame* aDestructRoot,
}
aPostDestroyData.AddAnonymousContent(mCustomContentContainer.forget());
if (mPopupgroupContent) {
aPostDestroyData.AddAnonymousContent(mPopupgroupContent.forget());
}
if (mTooltipContent) {
aPostDestroyData.AddAnonymousContent(mTooltipContent.forget());
}
MOZ_ASSERT(!mPopupSetFrame ||
nsLayoutUtils::IsProperAncestorFrame(this, mPopupSetFrame),
"Someone forgot to clear popup set frame");
nsContainerFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
}
@ -317,14 +293,6 @@ nsRect nsCanvasFrame::CanvasArea() const {
return result;
}
nsPopupSetFrame* nsCanvasFrame::GetPopupSetFrame() { return mPopupSetFrame; }
void nsCanvasFrame::SetPopupSetFrame(nsPopupSetFrame* aPopupSet) {
MOZ_ASSERT(!aPopupSet || !mPopupSetFrame,
"Popup set is already defined! Only 1 allowed.");
mPopupSetFrame = aPopupSet;
}
Element* nsCanvasFrame::GetDefaultTooltip() { return mTooltipContent; }
void nsCanvasFrame::SetDefaultTooltip(Element* aTooltip) {
@ -728,7 +696,6 @@ void nsCanvasFrame::Reflow(nsPresContext* aPresContext,
// overflow (painted by BuildPreviousPageOverflow in nsPageFrame.cpp).
// We may have additional children which are placeholders for continuations
// of fixed-pos content, see nsCSSFrameConstructor::ReplicateFixedFrames.
// We may also have a nsPopupSetFrame child (mPopupSetFrame).
const WritingMode wm = aReflowInput.GetWritingMode();
aDesiredSize.SetSize(wm, aReflowInput.ComputedSize());
if (aReflowInput.ComputedBSize() == NS_UNCONSTRAINEDSIZE) {
@ -740,11 +707,6 @@ void nsCanvasFrame::Reflow(nsPresContext* aPresContext,
nsIFrame* nextKid = nullptr;
for (auto* kidFrame = mFrames.FirstChild(); kidFrame; kidFrame = nextKid) {
nextKid = kidFrame->GetNextSibling();
if (kidFrame == mPopupSetFrame) {
// This child is handled separately after this loop.
continue;
}
ReflowOutput kidDesiredSize(aReflowInput);
bool kidDirty = kidFrame->HasAnyStateBits(NS_FRAME_IS_DIRTY);
WritingMode kidWM = kidFrame->GetWritingMode();
@ -873,23 +835,6 @@ void nsCanvasFrame::Reflow(nsPresContext* aPresContext,
ReflowChildFlags::Default, aStatus);
}
if (mPopupSetFrame) {
MOZ_ASSERT(mFrames.ContainsFrame(mPopupSetFrame),
"Only normal flow supported.");
nsReflowStatus popupStatus;
ReflowOutput popupDesiredSize(aReflowInput.GetWritingMode());
WritingMode wm = mPopupSetFrame->GetWritingMode();
LogicalSize availSize = aReflowInput.ComputedSize(wm);
availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
ReflowInput popupReflowInput(aPresContext, aReflowInput, mPopupSetFrame,
availSize);
ReflowChild(mPopupSetFrame, aPresContext, popupDesiredSize,
popupReflowInput, 0, 0, ReflowChildFlags::NoMoveFrame,
popupStatus);
FinishReflowChild(mPopupSetFrame, aPresContext, popupDesiredSize,
&popupReflowInput, 0, 0, ReflowChildFlags::NoMoveFrame);
}
FinishReflowWithAbsoluteFrames(aPresContext, aDesiredSize, aReflowInput,
aStatus);

Просмотреть файл

@ -12,14 +12,13 @@
#include "mozilla/Attributes.h"
#include "mozilla/EventForwards.h"
#include "nsContainerFrame.h"
#include "nsIScrollPositionListener.h"
#include "nsIPopupContainer.h"
#include "nsDisplayList.h"
#include "nsIAnonymousContentCreator.h"
#include "nsIPopupContainer.h"
#include "nsIScrollPositionListener.h"
class nsPresContext;
class gfxContext;
class nsPopupSetFrame;
/**
* Root frame class.
@ -40,19 +39,16 @@ class nsCanvasFrame final : public nsContainerFrame,
explicit nsCanvasFrame(ComputedStyle* aStyle, nsPresContext* aPresContext)
: nsContainerFrame(aStyle, aPresContext, kClassID),
mDoPaintFocus(false),
mAddedScrollPositionListener(false),
mPopupSetFrame(nullptr) {}
mAddedScrollPositionListener(false) {}
NS_DECL_QUERYFRAME
NS_DECL_FRAMEARENA_HELPERS(nsCanvasFrame)
nsPopupSetFrame* GetPopupSetFrame() override;
void SetPopupSetFrame(nsPopupSetFrame* aPopupSet) override;
Element* GetDefaultTooltip() override;
void SetDefaultTooltip(Element* aTooltip) override;
virtual void DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) override;
void DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) override;
void SetInitialChildList(ChildListID aListID,
nsFrameList&& aChildList) override;
@ -61,24 +57,23 @@ class nsCanvasFrame final : public nsContainerFrame,
const nsLineList::iterator* aPrevFrameLine,
nsFrameList&& aFrameList) override;
#ifdef DEBUG
virtual void RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame) override;
void RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame) override;
#endif
virtual nscoord GetMinISize(gfxContext* aRenderingContext) override;
virtual nscoord GetPrefISize(gfxContext* aRenderingContext) override;
virtual void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize,
const ReflowInput& aReflowInput,
nsReflowStatus& aStatus) override;
virtual bool IsFrameOfType(uint32_t aFlags) const override {
nscoord GetMinISize(gfxContext* aRenderingContext) override;
nscoord GetPrefISize(gfxContext* aRenderingContext) override;
void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize,
const ReflowInput& aReflowInput,
nsReflowStatus& aStatus) override;
bool IsFrameOfType(uint32_t aFlags) const override {
return nsContainerFrame::IsFrameOfType(
aFlags & ~(nsIFrame::eCanContainOverflowContainers));
}
// nsIAnonymousContentCreator
virtual nsresult CreateAnonymousContent(
nsTArray<ContentInfo>& aElements) override;
virtual void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
uint32_t aFilter) override;
nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) override;
void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
uint32_t aFilter) override;
Element* GetCustomContentContainer() const { return mCustomContentContainer; }
@ -99,20 +94,20 @@ class nsCanvasFrame final : public nsContainerFrame,
*/
NS_IMETHOD SetHasFocus(bool aHasFocus);
virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsDisplayListSet& aLists) override;
void BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsDisplayListSet& aLists) override;
void PaintFocus(mozilla::gfx::DrawTarget* aRenderingContext, nsPoint aPt);
// nsIScrollPositionListener
virtual void ScrollPositionWillChange(nscoord aX, nscoord aY) override;
virtual void ScrollPositionDidChange(nscoord aX, nscoord aY) override {}
void ScrollPositionWillChange(nscoord aX, nscoord aY) override;
void ScrollPositionDidChange(nscoord aX, nscoord aY) override {}
#ifdef DEBUG_FRAME_DUMP
virtual nsresult GetFrameName(nsAString& aResult) const override;
nsresult GetFrameName(nsAString& aResult) const override;
#endif
virtual nsresult GetContentForEvent(const mozilla::WidgetEvent* aEvent,
nsIContent** aContent) override;
nsresult GetContentForEvent(const mozilla::WidgetEvent* aEvent,
nsIContent** aContent) override;
nsRect CanvasArea() const;
@ -122,10 +117,6 @@ class nsCanvasFrame final : public nsContainerFrame,
bool mAddedScrollPositionListener;
nsCOMPtr<Element> mCustomContentContainer;
private:
nsPopupSetFrame* mPopupSetFrame;
nsCOMPtr<Element> mPopupgroupContent;
nsCOMPtr<Element> mTooltipContent;
};
@ -142,31 +133,29 @@ class nsDisplayCanvasBackgroundColor final : public nsDisplaySolidColorBase {
nsIFrame* aFrame)
: nsDisplaySolidColorBase(aBuilder, aFrame, NS_RGBA(0, 0, 0, 0)) {}
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
bool* aSnap) const override {
nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) const override {
nsCanvasFrame* frame = static_cast<nsCanvasFrame*>(mFrame);
*aSnap = true;
return frame->CanvasArea() + ToReferenceFrame();
}
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
HitTestState* aState,
nsTArray<nsIFrame*>* aOutFrames) override {
void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
HitTestState* aState, nsTArray<nsIFrame*>* aOutFrames) override {
// We need to override so we don't consider border-radius.
aOutFrames->AppendElement(mFrame);
}
virtual bool CreateWebRenderCommands(
bool CreateWebRenderCommands(
mozilla::wr::DisplayListBuilder& aBuilder,
mozilla::wr::IpcResourceUpdateQueue& aResources,
const StackingContextHelper& aSc,
mozilla::layers::RenderRootStateManager* aManager,
nsDisplayListBuilder* aDisplayListBuilder) override;
virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
void SetExtraBackgroundColor(nscolor aColor) { mColor = aColor; }
NS_DISPLAY_DECL_NAME("CanvasBackgroundColor", TYPE_CANVAS_BACKGROUND_COLOR)
virtual void WriteDebugInfo(std::stringstream& aStream) override;
void WriteDebugInfo(std::stringstream& aStream) override;
};
class nsDisplayCanvasBackgroundImage : public nsDisplayBackgroundImage {
@ -176,11 +165,11 @@ class nsDisplayCanvasBackgroundImage : public nsDisplayBackgroundImage {
const InitData& aInitData)
: nsDisplayBackgroundImage(aBuilder, aFrame, aInitData) {}
virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
// We still need to paint a background color as well as an image for this
// item, so we can't support this yet.
virtual bool SupportsOptimizingToImage() const override { return false; }
bool SupportsOptimizingToImage() const override { return false; }
bool IsSingleFixedPositionImage(nsDisplayListBuilder* aBuilder,
const nsRect& aClipRect, gfxRect* aDestRect);
@ -198,7 +187,7 @@ class nsDisplayCanvasThemedBackground : public nsDisplayThemedBackground {
nsDisplayThemedBackground::Init(aBuilder);
}
virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
NS_DISPLAY_DECL_NAME("CanvasThemedBackground", TYPE_CANVAS_THEMED_BACKGROUND)
};

Просмотреть файл

@ -1087,10 +1087,10 @@ void nsContainerFrame::PositionChildViews(nsIFrame* aFrame) {
}
// Recursively walk aFrame's child frames.
// Process the additional child lists, but skip the popup list as the
// view for popups is managed by the parent. Currently only nsMenuFrame
// and nsPopupSetFrame have a popupList and during layout will adjust the
// view manually to position the popup.
// Process the additional child lists, but skip the popup list as the view for
// popups is managed by the parent.
// Currently only nsMenuFrame has a popupList and during layout will adjust
// the view manually to position the popup.
for (const auto& [list, listID] : aFrame->ChildLists()) {
if (listID == kPopupList) {
continue;

Просмотреть файл

@ -646,7 +646,6 @@ FRAME_STATE_GROUP(Placeholder, nsPlaceholderFrame)
FRAME_STATE_BIT(Placeholder, 20, PLACEHOLDER_FOR_FLOAT)
FRAME_STATE_BIT(Placeholder, 21, PLACEHOLDER_FOR_ABSPOS)
FRAME_STATE_BIT(Placeholder, 22, PLACEHOLDER_FOR_FIXEDPOS)
FRAME_STATE_BIT(Placeholder, 23, PLACEHOLDER_FOR_POPUP)
FRAME_STATE_BIT(Placeholder, 24, PLACEHOLDER_FOR_TOPLAYER)
// This bit indicates that the out-of-flow frame's static position needs to be

Просмотреть файл

@ -12268,7 +12268,6 @@ void DR_State::InitFrameTypeTable() {
AddFrameTypeInfo(LayoutFrameType::Viewport, "VP", "viewport");
AddFrameTypeInfo(LayoutFrameType::Box, "Box", "Box");
AddFrameTypeInfo(LayoutFrameType::Slider, "Slider", "Slider");
AddFrameTypeInfo(LayoutFrameType::PopupSet, "PopupSet", "PopupSet");
AddFrameTypeInfo(LayoutFrameType::None, "unknown", "unknown");
}

Просмотреть файл

@ -120,7 +120,7 @@ void nsPlaceholderFrame::Reflow(nsPresContext* aPresContext,
// doesn't hold anyways because the default popupgroup goes before than the
// default tooltip, for example).
if (HasAnyStateBits(NS_FRAME_FIRST_REFLOW) &&
!HasAnyStateBits(PLACEHOLDER_FOR_POPUP) &&
!mOutOfFlowFrame->IsMenuPopupFrame() &&
!mOutOfFlowFrame->HasAnyStateBits(NS_FRAME_FIRST_REFLOW)) {
// Unfortunately, this can currently happen when the placeholder is in a
// later continuation or later IB-split sibling than its out-of-flow (as
@ -155,9 +155,6 @@ static nsIFrame::ChildListID ChildListIDForOutOfFlow(
if (aPlaceholderState & PLACEHOLDER_FOR_FLOAT) {
return nsIFrame::kFloatList;
}
if (aPlaceholderState & PLACEHOLDER_FOR_POPUP) {
return nsIFrame::kPopupList;
}
if (aPlaceholderState & PLACEHOLDER_FOR_FIXEDPOS) {
return nsLayoutUtils::MayBeReallyFixedPos(aChild) ? nsIFrame::kFixedList
: nsIFrame::kAbsoluteList;
@ -179,7 +176,8 @@ void nsPlaceholderFrame::DestroyFrom(nsIFrame* aDestructRoot,
// If aDestructRoot is not an ancestor of the out-of-flow frame,
// then call RemoveFrame on it here.
// Also destroy it here if it's a popup frame. (Bug 96291)
if (HasAnyStateBits(PLACEHOLDER_FOR_POPUP) ||
// FIXME(emilio): Is the popup special-case still needed?
if (oof->IsMenuPopupFrame() ||
!nsLayoutUtils::IsProperAncestorFrame(aDestructRoot, oof)) {
ChildListID listId = ChildListIDForOutOfFlow(GetStateBits(), oof);
nsFrameManager* fm = PresContext()->FrameConstructor();

Просмотреть файл

@ -50,7 +50,7 @@ nsPlaceholderFrame* NS_NewPlaceholderFrame(mozilla::PresShell* aPresShell,
#define PLACEHOLDER_TYPE_MASK \
(PLACEHOLDER_FOR_FLOAT | PLACEHOLDER_FOR_ABSPOS | PLACEHOLDER_FOR_FIXEDPOS | \
PLACEHOLDER_FOR_POPUP | PLACEHOLDER_FOR_TOPLAYER)
PLACEHOLDER_FOR_TOPLAYER)
/**
* Implementation of a frame that's used as a placeholder for a frame that
@ -78,7 +78,6 @@ class nsPlaceholderFrame final : public nsIFrame {
aTypeBits == PLACEHOLDER_FOR_FLOAT ||
aTypeBits == PLACEHOLDER_FOR_ABSPOS ||
aTypeBits == PLACEHOLDER_FOR_FIXEDPOS ||
aTypeBits == PLACEHOLDER_FOR_POPUP ||
aTypeBits == (PLACEHOLDER_FOR_TOPLAYER | PLACEHOLDER_FOR_ABSPOS) ||
aTypeBits == (PLACEHOLDER_FOR_TOPLAYER | PLACEHOLDER_FOR_FIXEDPOS),
"Unexpected type bit");

Просмотреть файл

@ -1,15 +0,0 @@
<!DOCTYPE html>
<html>
<body>
<table cellpadding="0" cellspacing="0">
<tr>
<td>First Column</td>
<td>Second Column</td>
</tr>
<tr>
<td>First Column</td>
<td>Second Column</td>
</tr>
</table>
</body>
</html>

Просмотреть файл

@ -1,24 +0,0 @@
<!DOCTYPE html>
<html>
<body>
<div style="display:table">
<div style="display: table-row">
<div style="display: table-cell">
First Column
</div>
<div style="display: table-cell">
Second Column
</div>
</div>
<div style="display: table-row">
<div style="display: table-cell">
First Column
</div>
<div style="display: -moz-popup; display: popup"></div>
<div style="display: table-cell">
Second Column
</div>
</div>
</div>
</body>
</html>

Просмотреть файл

@ -1270,7 +1270,6 @@ pref(layout.css.caption-side-non-standard.enabled,true) == 478614-7.html 478614-
== 478811-4.html 478811-4-ref.html
== 478956-1a.html 478956-1-ref.html
== 478956-1b.html 478956-1-ref.html
== chrome://reftest/content/bugs/480017-1.html chrome://reftest/content/bugs/480017-1-ref.html
== 480880-1a.html 480880-1-ref.html
== 480880-1b.html 480880-1-ref.html
== 480880-1c.html 480880-1-ref.html

Просмотреть файл

@ -29,7 +29,6 @@ UNIFIED_SOURCES += [
"nsMenuBarListener.cpp",
"nsMenuFrame.cpp",
"nsMenuPopupFrame.cpp",
"nsPopupSetFrame.cpp",
"nsRepeatService.cpp",
"nsScrollbarButtonFrame.cpp",
"nsScrollbarFrame.cpp",

Просмотреть файл

@ -8,7 +8,6 @@
#define nsIPopupContainer_h___
#include "nsQueryFrame.h"
class nsPopupSetFrame;
class nsIContent;
namespace mozilla {
@ -22,9 +21,6 @@ class nsIPopupContainer {
public:
NS_DECL_QUERYFRAME_TARGET(nsIPopupContainer)
virtual nsPopupSetFrame* GetPopupSetFrame() = 0;
virtual void SetPopupSetFrame(nsPopupSetFrame* aPopupSet) = 0;
virtual mozilla::dom::Element* GetDefaultTooltip() = 0;
virtual void SetDefaultTooltip(mozilla::dom::Element* aTooltip) = 0;

Просмотреть файл

@ -16,7 +16,6 @@
#include "nsWidgetsCID.h"
#include "nsMenuFrame.h"
#include "nsMenuBarFrame.h"
#include "nsPopupSetFrame.h"
#include "nsPIDOMWindow.h"
#include "nsFrameManager.h"
#include "mozilla/dom/Document.h"
@ -553,6 +552,27 @@ void nsMenuPopupFrame::ConstrainSizeForWayland(nsSize& aSize) const {
#endif
}
void nsMenuPopupFrame::Reflow(nsPresContext* aPresContext,
ReflowOutput& aDesiredSize,
const ReflowInput& aReflowInput,
nsReflowStatus& aStatus) {
MarkInReflow();
DO_GLOBAL_REFLOW_COUNT("nsMenuPopupFrame");
DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus);
MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
nsBoxLayoutState state(aPresContext, aReflowInput.mRenderingContext,
&aReflowInput, aReflowInput.mReflowDepth);
LayoutPopup(state, nullptr, false);
const auto wm = GetWritingMode();
LogicalSize boxSize = GetLogicalSize(wm);
aDesiredSize.SetSize(wm, boxSize);
aDesiredSize.SetBlockStartAscent(boxSize.BSize(wm));
aDesiredSize.SetOverflowAreasToDesiredBounds();
FinishAndStoreOverflow(&aDesiredSize, aReflowInput.mStyleDisplay);
}
void nsMenuPopupFrame::LayoutPopup(nsBoxLayoutState& aState,
nsIFrame* aParentMenu, bool aSizedToPopup) {
if (IsNativeMenu()) {

Просмотреть файл

@ -172,6 +172,10 @@ class nsMenuPopupFrame final : public nsBoxFrame,
*/
ConsumeOutsideClicksResult ConsumeOutsideClicks();
void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize,
const ReflowInput& aReflowInput,
nsReflowStatus& aStatus) override;
bool IsContextMenu() override { return mIsContextMenu; }
bool MenuClosed() override { return true; }

Просмотреть файл

@ -1,138 +0,0 @@
/* -*- 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 "nsPopupSetFrame.h"
#include "nsGkAtoms.h"
#include "nsCOMPtr.h"
#include "nsIContent.h"
#include "nsPresContext.h"
#include "mozilla/ComputedStyle.h"
#include "mozilla/PresShell.h"
#include "nsBoxLayoutState.h"
#include "nsIScrollableFrame.h"
#include "nsIPopupContainer.h"
#include "nsMenuPopupFrame.h"
typedef mozilla::ComputedStyle ComputedStyle;
nsIFrame* NS_NewPopupSetFrame(mozilla::PresShell* aPresShell,
ComputedStyle* aStyle) {
return new (aPresShell) nsPopupSetFrame(aStyle, aPresShell->GetPresContext());
}
NS_IMPL_FRAMEARENA_HELPERS(nsPopupSetFrame)
void nsPopupSetFrame::Init(nsIContent* aContent, nsContainerFrame* aParent,
nsIFrame* aPrevInFlow) {
nsBoxFrame::Init(aContent, aParent, aPrevInFlow);
// Normally the root box is our grandparent, but in case of wrapping
// it can be our great-grandparent.
nsIPopupContainer* popupContainer =
nsIPopupContainer::GetPopupContainer(PresShell());
if (popupContainer) {
popupContainer->SetPopupSetFrame(this);
}
}
void nsPopupSetFrame::AppendFrames(ChildListID aListID,
nsFrameList&& aFrameList) {
if (aListID == kPopupList) {
AddPopupFrameList(aFrameList);
return;
}
nsBoxFrame::AppendFrames(aListID, std::move(aFrameList));
}
void nsPopupSetFrame::RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame) {
if (aListID == kPopupList) {
RemovePopupFrame(aOldFrame);
return;
}
nsBoxFrame::RemoveFrame(aListID, aOldFrame);
}
void nsPopupSetFrame::InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame,
const nsLineList::iterator* aPrevFrameLine,
nsFrameList&& aFrameList) {
if (aListID == kPopupList) {
AddPopupFrameList(aFrameList);
return;
}
nsBoxFrame::InsertFrames(aListID, aPrevFrame, aPrevFrameLine,
std::move(aFrameList));
}
void nsPopupSetFrame::SetInitialChildList(ChildListID aListID,
nsFrameList&& aChildList) {
if (aListID == kPopupList) {
NS_ASSERTION(mPopupList.IsEmpty(),
"SetInitialChildList on non-empty child list");
AddPopupFrameList(aChildList);
return;
}
nsBoxFrame::SetInitialChildList(aListID, std::move(aChildList));
}
const nsFrameList& nsPopupSetFrame::GetChildList(ChildListID aListID) const {
if (kPopupList == aListID) {
return mPopupList;
}
return nsBoxFrame::GetChildList(aListID);
}
void nsPopupSetFrame::GetChildLists(nsTArray<ChildList>* aLists) const {
nsBoxFrame::GetChildLists(aLists);
mPopupList.AppendIfNonempty(aLists, kPopupList);
}
void nsPopupSetFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
mPopupList.DestroyFramesFrom(aDestructRoot, aPostDestroyData);
// Normally the root box is our grandparent, but in case of wrapping
// it can be our great-grandparent.
nsIPopupContainer* popupContainer =
nsIPopupContainer::GetPopupContainer(PresShell());
if (popupContainer) {
popupContainer->SetPopupSetFrame(nullptr);
}
nsBoxFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
}
NS_IMETHODIMP
nsPopupSetFrame::DoXULLayout(nsBoxLayoutState& aState) {
// lay us out
nsresult rv = nsBoxFrame::DoXULLayout(aState);
// lay out all of our currently open popups.
for (nsIFrame* f : mPopupList) {
auto* popupChild = static_cast<nsMenuPopupFrame*>(f);
popupChild->LayoutPopup(aState, nullptr, false);
}
return rv;
}
void nsPopupSetFrame::RemovePopupFrame(nsIFrame* aPopup) {
MOZ_ASSERT(aPopup->HasAnyStateBits(NS_FRAME_OUT_OF_FLOW) &&
aPopup->IsMenuPopupFrame(),
"removing wrong type of frame in popupset's ::popupList");
mPopupList.DestroyFrame(aPopup);
}
void nsPopupSetFrame::AddPopupFrameList(nsFrameList& aPopupFrameList) {
#ifdef DEBUG
for (nsIFrame* f : aPopupFrameList) {
NS_ASSERTION(
f->HasAnyStateBits(NS_FRAME_OUT_OF_FLOW) && f->IsMenuPopupFrame(),
"adding wrong type of frame in popupset's ::popupList");
}
#endif
mPopupList.InsertFrames(nullptr, nullptr, std::move(aPopupFrameList));
}

Просмотреть файл

@ -1,63 +0,0 @@
/* -*- 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 nsPopupSetFrame_h__
#define nsPopupSetFrame_h__
#include "mozilla/Attributes.h"
#include "nsAtom.h"
#include "nsBoxFrame.h"
namespace mozilla {
class PresShell;
} // namespace mozilla
nsIFrame* NS_NewPopupSetFrame(mozilla::PresShell* aPresShell,
mozilla::ComputedStyle* aStyle);
class nsPopupSetFrame final : public nsBoxFrame {
public:
NS_DECL_FRAMEARENA_HELPERS(nsPopupSetFrame)
explicit nsPopupSetFrame(ComputedStyle* aStyle, nsPresContext* aPresContext)
: nsBoxFrame(aStyle, aPresContext, kClassID) {}
~nsPopupSetFrame() = default;
virtual void Init(nsIContent* aContent, nsContainerFrame* aParent,
nsIFrame* aPrevInFlow) override;
void SetInitialChildList(ChildListID aListID,
nsFrameList&& aChildList) override;
void AppendFrames(ChildListID aListID, nsFrameList&& aFrameList) override;
virtual void RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame) override;
void InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame,
const nsLineList::iterator* aPrevFrameLine,
nsFrameList&& aFrameList) override;
virtual const nsFrameList& GetChildList(ChildListID aList) const override;
virtual void GetChildLists(nsTArray<ChildList>* aLists) const override;
NS_IMETHOD DoXULLayout(nsBoxLayoutState& aBoxLayoutState) override;
// Used to destroy our popup frames.
virtual void DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) override;
#ifdef DEBUG_FRAME_DUMP
virtual nsresult GetFrameName(nsAString& aResult) const override {
return MakeFrameName(u"PopupSet"_ns, aResult);
}
#endif
protected:
void AddPopupFrameList(nsFrameList& aPopupFrameList);
void RemovePopupFrame(nsIFrame* aPopup);
nsFrameList mPopupList;
};
#endif

Просмотреть файл

@ -271,10 +271,21 @@ menupopup,
panel,
tooltip {
display: -moz-popup;
position: absolute;
-moz-top-layer: top;
/* Popups can't have overflow */
contain: paint;
z-index: 2147483647;
text-shadow: none;
}
:is(toolbarbutton[type="menu"], button[type="menu"], menulist, menu) > :is(menupopup, panel) {
/* TODO: These could be regular abspos frames (just not in the top layer),
* once nsMenuFrame is ported to modern flex layout. */
position: static;
-moz-top-layer: none;
}
tooltip {
appearance: auto;
-moz-default-appearance: tooltip;
@ -386,6 +397,7 @@ tooltip:not([position]) {
transition-duration: 0.18s, 0.18s;
transition-timing-function:
var(--animation-easing-function), ease-out;
will-change: transform, opacity;
}
panel[type="arrow"][side="bottom"]:not([animate="false"]) {