зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset e41bfdf79fb8 (bug 1665476) for causing windows mochitest failures in test_windowminmaxsize.xhtml
CLOSED TREE
This commit is contained in:
Родитель
bbca45e817
Коммит
326297bd47
|
@ -32,6 +32,7 @@
|
|||
#include "nsCSSPropertyIDSet.h"
|
||||
#include "nsCSSProps.h" // For nsCSSProps::PropHasFlags
|
||||
#include "nsCSSPseudoElements.h" // For PseudoStyleType
|
||||
#include "nsCSSRendering.h" // For IsCanvasFrame
|
||||
#include "nsDOMMutationObserver.h" // For nsAutoAnimationMutationBatch
|
||||
#include "nsIFrame.h"
|
||||
#include "nsIFrameInlines.h"
|
||||
|
@ -2051,7 +2052,7 @@ KeyframeEffect::MatchForCompositor KeyframeEffect::IsMatchForCompositor(
|
|||
// We don't yet support off-main-thread background-color animations on
|
||||
// canvas frame or on <body> which genarate nsDisplayCanvasBackgroundColor
|
||||
// or nsDisplaySolidColor display item.
|
||||
if (aFrame->IsCanvasFrame() ||
|
||||
if (nsCSSRendering::IsCanvasFrame(aFrame) ||
|
||||
(aFrame->GetContent() &&
|
||||
aFrame->GetContent()->IsHTMLElement(nsGkAtoms::body))) {
|
||||
return KeyframeEffect::MatchForCompositor::No;
|
||||
|
|
|
@ -466,6 +466,8 @@ void APZCCallbackHelper::InitializeRootDisplayport(PresShell* aPresShell) {
|
|||
DisplayPortUtils::SetDisplayPortBaseIfNotSet(content, *baseRect);
|
||||
}
|
||||
|
||||
// Note that we also set the base rect that goes with these margins in
|
||||
// nsRootBoxFrame::BuildDisplayList.
|
||||
DisplayPortUtils::SetDisplayPortMargins(
|
||||
content, aPresShell, DisplayPortMargins::Empty(content),
|
||||
DisplayPortUtils::ClearMinimalDisplayPortProperty::Yes, 0);
|
||||
|
|
|
@ -5216,7 +5216,7 @@ void PresShell::AddCanvasBackgroundColorItem(
|
|||
// cases (it will usually be a viewport frame when we have a canvas frame in
|
||||
// the (sub)tree).
|
||||
if (!(aFlags & AddCanvasBackgroundColorFlags::ForceDraw) &&
|
||||
!aFrame->IsViewportFrame() && !aFrame->IsPageContentFrame()) {
|
||||
!nsCSSRendering::IsCanvasFrame(aFrame)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -214,6 +214,9 @@ static FrameCtorDebugFlags gFlags[] = {
|
|||
|
||||
//------------------------------------------------------------------
|
||||
|
||||
nsContainerFrame* NS_NewRootBoxFrame(PresShell* aPresShell,
|
||||
ComputedStyle* aStyle);
|
||||
|
||||
nsContainerFrame* NS_NewDocElementBoxFrame(PresShell* aPresShell,
|
||||
ComputedStyle* aStyle);
|
||||
|
||||
|
@ -2592,7 +2595,7 @@ void nsCSSFrameConstructor::SetUpDocElementContainingBlock(
|
|||
Galley presentation, XUL
|
||||
|
||||
ViewportFrame [fixed-cb]
|
||||
nsCanvasFrame [abs-cb]
|
||||
nsRootBoxFrame
|
||||
root element frame (nsDocElementBoxFrame)
|
||||
|
||||
Print presentation, non-XUL
|
||||
|
@ -2629,7 +2632,7 @@ void nsCSSFrameConstructor::SetUpDocElementContainingBlock(
|
|||
mRootElementFrame is "root element frame". This is the primary frame for
|
||||
the root element.
|
||||
mDocElementContainingBlock is the parent of mRootElementFrame
|
||||
(i.e. nsCanvasFrame)
|
||||
(i.e. nsCanvasFrame or nsRootBoxFrame)
|
||||
mPageSequenceFrame is the nsPageSequenceFrame, or null if there isn't
|
||||
one
|
||||
*/
|
||||
|
@ -2672,10 +2675,21 @@ void nsCSSFrameConstructor::SetUpDocElementContainingBlock(
|
|||
static_cast<nsContainerFrame*>(GetRootFrame());
|
||||
ComputedStyle* viewportPseudoStyle = viewportFrame->Style();
|
||||
|
||||
nsContainerFrame* rootFrame =
|
||||
NS_NewCanvasFrame(mPresShell, viewportPseudoStyle);
|
||||
nsContainerFrame* rootFrame = nullptr;
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
if (aDocElement->IsXULElement()) {
|
||||
// pass a temporary stylecontext, the correct one will be set later
|
||||
rootFrame = NS_NewRootBoxFrame(mPresShell, viewportPseudoStyle);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
// pass a temporary stylecontext, the correct one will be set later
|
||||
rootFrame = NS_NewCanvasFrame(mPresShell, viewportPseudoStyle);
|
||||
mHasRootAbsPosContainingBlock = true;
|
||||
}
|
||||
|
||||
PseudoStyleType rootPseudo = PseudoStyleType::canvas;
|
||||
mHasRootAbsPosContainingBlock = true;
|
||||
mDocElementContainingBlock = rootFrame;
|
||||
|
||||
// --------- IF SCROLLABLE WRAP IN SCROLLFRAME --------
|
||||
|
|
|
@ -203,7 +203,9 @@ bool nsFrameIterator::IsDone() { return mOffEdge != 0; }
|
|||
|
||||
void nsFrameIterator::First() { mCurrent = mStart; }
|
||||
|
||||
static bool IsRootFrame(nsIFrame* aFrame) { return aFrame->IsCanvasFrame(); }
|
||||
static bool IsRootFrame(nsIFrame* aFrame) {
|
||||
return aFrame->IsCanvasFrame() || aFrame->IsXULRootFrame();
|
||||
}
|
||||
|
||||
void nsFrameIterator::Last() {
|
||||
nsIFrame* result;
|
||||
|
|
|
@ -6089,7 +6089,7 @@ nsIFrame* nsLayoutUtils::GetClosestLayer(nsIFrame* aFrame) {
|
|||
SamplingFilter nsLayoutUtils::GetSamplingFilterForFrame(nsIFrame* aForFrame) {
|
||||
SamplingFilter defaultFilter = SamplingFilter::GOOD;
|
||||
ComputedStyle* sc;
|
||||
if (aForFrame->IsCanvasFrame()) {
|
||||
if (nsCSSRendering::IsCanvasFrame(aForFrame)) {
|
||||
nsCSSRendering::FindBackground(aForFrame, &sc);
|
||||
} else {
|
||||
sc = aForFrame->Style();
|
||||
|
|
|
@ -79,6 +79,7 @@ FRAME_CLASSES = [
|
|||
Frame("nsProgressFrame", "Progress", LEAF),
|
||||
Frame("nsRangeFrame", "Range", LEAF),
|
||||
Frame("nsResizerFrame", "Box", NOT_LEAF),
|
||||
Frame("nsRootBoxFrame", "XULRoot", NOT_LEAF),
|
||||
Frame("nsRubyBaseContainerFrame", "RubyBaseContainer", NOT_LEAF),
|
||||
Frame("nsRubyBaseFrame", "RubyBase", NOT_LEAF),
|
||||
Frame("nsRubyFrame", "Ruby", NOT_LEAF),
|
||||
|
|
|
@ -49,10 +49,6 @@ nsCanvasFrame* NS_NewCanvasFrame(PresShell* aPresShell, ComputedStyle* aStyle) {
|
|||
return new (aPresShell) nsCanvasFrame(aStyle, aPresShell->GetPresContext());
|
||||
}
|
||||
|
||||
nsIPopupContainer* nsIPopupContainer::GetPopupContainer(PresShell* aPresShell) {
|
||||
return aPresShell ? aPresShell->GetCanvasFrame() : nullptr;
|
||||
}
|
||||
|
||||
NS_IMPL_FRAMEARENA_HELPERS(nsCanvasFrame)
|
||||
|
||||
NS_QUERYFRAME_HEAD(nsCanvasFrame)
|
||||
|
|
|
@ -730,9 +730,8 @@ void nsContainerFrame::SyncWindowProperties(nsPresContext* aPresContext,
|
|||
nsIFrame* aFrame, nsView* aView,
|
||||
gfxContext* aRC, uint32_t aFlags) {
|
||||
#ifdef MOZ_XUL
|
||||
if (!aView || aFrame->GetParent() || !aView->HasWidget()) {
|
||||
if (!aView || !nsCSSRendering::IsCanvasFrame(aFrame) || !aView->HasWidget())
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIWidget> windowWidget =
|
||||
GetPresContextContainerWidget(aPresContext);
|
||||
|
|
|
@ -2535,7 +2535,8 @@ auto nsIFrame::ComputeShouldPaintBackground() const -> ShouldPaintBackground {
|
|||
}
|
||||
|
||||
bool nsIFrame::DisplayBackgroundUnconditional(nsDisplayListBuilder* aBuilder,
|
||||
const nsDisplayListSet& aLists) {
|
||||
const nsDisplayListSet& aLists,
|
||||
bool aForceBackground) {
|
||||
const bool hitTesting = aBuilder->IsForEventDelivery();
|
||||
if (hitTesting && !aBuilder->HitTestIsForVisibility()) {
|
||||
// For hit-testing, we generally just need a light-weight data structure
|
||||
|
@ -2548,9 +2549,11 @@ bool nsIFrame::DisplayBackgroundUnconditional(nsDisplayListBuilder* aBuilder,
|
|||
}
|
||||
|
||||
AppendedBackgroundType result = AppendedBackgroundType::None;
|
||||
// Here we don't try to detect background propagation, canvas frame does its
|
||||
// own thing.
|
||||
if (hitTesting ||
|
||||
|
||||
// Here we don't try to detect background propagation. Frames that might
|
||||
// receive a propagated background should just set aForceBackground to
|
||||
// true.
|
||||
if (hitTesting || aForceBackground ||
|
||||
!StyleBackground()->IsTransparent(this) ||
|
||||
StyleDisplay()->HasAppearance() ||
|
||||
// We do forcibly create a display item for background color animations
|
||||
|
@ -2573,7 +2576,8 @@ bool nsIFrame::DisplayBackgroundUnconditional(nsDisplayListBuilder* aBuilder,
|
|||
}
|
||||
|
||||
void nsIFrame::DisplayBorderBackgroundOutline(nsDisplayListBuilder* aBuilder,
|
||||
const nsDisplayListSet& aLists) {
|
||||
const nsDisplayListSet& aLists,
|
||||
bool aForceBackground) {
|
||||
// The visibility check belongs here since child elements have the
|
||||
// opportunity to override the visibility property and display even if
|
||||
// their parent is hidden.
|
||||
|
@ -2583,7 +2587,9 @@ void nsIFrame::DisplayBorderBackgroundOutline(nsDisplayListBuilder* aBuilder,
|
|||
|
||||
DisplayOutsetBoxShadowUnconditional(aBuilder, aLists.BorderBackground());
|
||||
|
||||
bool bgIsThemed = DisplayBackgroundUnconditional(aBuilder, aLists);
|
||||
bool bgIsThemed =
|
||||
DisplayBackgroundUnconditional(aBuilder, aLists, aForceBackground);
|
||||
|
||||
DisplayInsetBoxShadowUnconditional(aBuilder, aLists.BorderBackground());
|
||||
|
||||
// If there's a themed background, we should not create a border item.
|
||||
|
@ -12119,6 +12125,7 @@ void DR_State::InitFrameTypeTable() {
|
|||
AddFrameTypeInfo(LayoutFrameType::Page, "page", "page");
|
||||
AddFrameTypeInfo(LayoutFrameType::Placeholder, "place", "placeholder");
|
||||
AddFrameTypeInfo(LayoutFrameType::Canvas, "canvas", "canvas");
|
||||
AddFrameTypeInfo(LayoutFrameType::XULRoot, "xulroot", "xulroot");
|
||||
AddFrameTypeInfo(LayoutFrameType::Scroll, "scroll", "scroll");
|
||||
AddFrameTypeInfo(LayoutFrameType::TableCell, "cell", "tableCell");
|
||||
AddFrameTypeInfo(LayoutFrameType::TableCol, "col", "tableCol");
|
||||
|
|
|
@ -4902,17 +4902,27 @@ class nsIFrame : public nsQueryFrame {
|
|||
/**
|
||||
* Adds display items for standard CSS background if necessary.
|
||||
* Does not check IsVisibleForPainting.
|
||||
* @param aForceBackground draw the background even if the frame
|
||||
* background style appears to have no background --- this is useful
|
||||
* for frames that might receive a propagated background via
|
||||
* nsCSSRendering::FindBackground
|
||||
* @return whether a themed background item was created.
|
||||
*/
|
||||
bool DisplayBackgroundUnconditional(nsDisplayListBuilder* aBuilder,
|
||||
const nsDisplayListSet& aLists);
|
||||
const nsDisplayListSet& aLists,
|
||||
bool aForceBackground);
|
||||
/**
|
||||
* Adds display items for standard CSS borders, background and outline for
|
||||
* for this frame, as necessary. Checks IsVisibleForPainting and won't
|
||||
* display anything if the frame is not visible.
|
||||
* @param aForceBackground draw the background even if the frame
|
||||
* background style appears to have no background --- this is useful
|
||||
* for frames that might receive a propagated background via
|
||||
* nsCSSRendering::FindBackground
|
||||
*/
|
||||
void DisplayBorderBackgroundOutline(nsDisplayListBuilder* aBuilder,
|
||||
const nsDisplayListSet& aLists);
|
||||
const nsDisplayListSet& aLists,
|
||||
bool aForceBackground = false);
|
||||
/**
|
||||
* Add a display item for the CSS outline. Does not check visibility.
|
||||
*/
|
||||
|
|
|
@ -1134,7 +1134,7 @@ auto nsCSSRendering::FindNonTransparentBackgroundFrame(nsIFrame* aFrame,
|
|||
return {frame, true, false};
|
||||
}
|
||||
|
||||
if (frame->IsCanvasFrame()) {
|
||||
if (IsCanvasFrame(frame)) {
|
||||
nsIFrame* bgFrame = nullptr;
|
||||
if (FindBackgroundFrame(frame, &bgFrame) &&
|
||||
NS_GET_A(bgFrame->StyleBackground()->BackgroundColor(bgFrame))) {
|
||||
|
@ -1146,6 +1146,18 @@ auto nsCSSRendering::FindNonTransparentBackgroundFrame(nsIFrame* aFrame,
|
|||
return {};
|
||||
}
|
||||
|
||||
// Returns true if aFrame is a canvas frame.
|
||||
// We need to treat the viewport as canvas because, even though
|
||||
// it does not actually paint a background, we need to get the right
|
||||
// background style so we correctly detect transparent documents.
|
||||
bool nsCSSRendering::IsCanvasFrame(const nsIFrame* aFrame) {
|
||||
LayoutFrameType frameType = aFrame->Type();
|
||||
return frameType == LayoutFrameType::Canvas ||
|
||||
frameType == LayoutFrameType::XULRoot ||
|
||||
frameType == LayoutFrameType::PageContent ||
|
||||
frameType == LayoutFrameType::Viewport;
|
||||
}
|
||||
|
||||
nsIFrame* nsCSSRendering::FindBackgroundStyleFrame(nsIFrame* aForFrame) {
|
||||
const nsStyleBackground* result = aForFrame->StyleBackground();
|
||||
|
||||
|
@ -1203,7 +1215,8 @@ nsIFrame* nsCSSRendering::FindBackgroundStyleFrame(nsIFrame* aForFrame) {
|
|||
* resulting value is 'transparent', the rendering is undefined.
|
||||
*
|
||||
* Thus, in our implementation, it is responsible for ensuring that:
|
||||
* + we paint the correct background on the |nsCanvasFrame| or |nsPageFrame|,
|
||||
* + we paint the correct background on the |nsCanvasFrame|,
|
||||
* |nsRootBoxFrame|, or |nsPageFrame|,
|
||||
* + we don't paint the background on the root element, and
|
||||
* + we don't paint the background on the BODY element in *some* cases,
|
||||
* and for SGML-based HTML documents only.
|
||||
|
@ -1258,7 +1271,7 @@ bool nsCSSRendering::FindBackgroundFrame(const nsIFrame* aForFrame,
|
|||
nsIFrame** aBackgroundFrame) {
|
||||
nsIFrame* rootElementFrame =
|
||||
aForFrame->PresShell()->FrameConstructor()->GetRootElementStyleFrame();
|
||||
if (aForFrame->IsCanvasFrame()) {
|
||||
if (IsCanvasFrame(aForFrame)) {
|
||||
*aBackgroundFrame = FindCanvasBackgroundFrame(aForFrame, rootElementFrame);
|
||||
return true;
|
||||
}
|
||||
|
@ -2397,7 +2410,7 @@ ImgDrawResult nsCSSRendering::PaintStyleImageLayerWithSC(
|
|||
// PresShell::AddCanvasBackgroundColorItem(), and painted by
|
||||
// nsDisplayCanvasBackground directly.) Either way we don't need to
|
||||
// paint the background color here.
|
||||
bool isCanvasFrame = aParams.frame->IsCanvasFrame();
|
||||
bool isCanvasFrame = IsCanvasFrame(aParams.frame);
|
||||
const bool paintMask = aParams.paintFlags & PAINTBG_MASK_IMAGE;
|
||||
|
||||
// Determine whether we are drawing background images and/or
|
||||
|
|
|
@ -277,6 +277,11 @@ struct nsCSSRendering {
|
|||
*/
|
||||
static nsIFrame* FindBackgroundStyleFrame(nsIFrame* aForFrame);
|
||||
|
||||
/**
|
||||
* @return true if |aFrame| is a canvas frame, in the CSS sense.
|
||||
*/
|
||||
static bool IsCanvasFrame(const nsIFrame* aFrame);
|
||||
|
||||
/**
|
||||
* Fill in an aBackgroundSC to be used to paint the background
|
||||
* for an element. This applies the rules for propagating
|
||||
|
@ -300,7 +305,7 @@ struct nsCSSRendering {
|
|||
*
|
||||
* @param aForFrame
|
||||
* the frame used to represent the canvas, in the CSS sense (i.e.
|
||||
* aForFrame->IsCanvasFrame() must be true)
|
||||
* nsCSSRendering::IsCanvasFrame(aForFrame) must be true)
|
||||
* @param aRootElementFrame
|
||||
* the frame representing the root element of the document
|
||||
* @param aBackground
|
||||
|
@ -309,7 +314,7 @@ struct nsCSSRendering {
|
|||
|
||||
static nsIFrame* FindCanvasBackgroundFrame(const nsIFrame* aForFrame,
|
||||
nsIFrame* aRootElementFrame) {
|
||||
MOZ_ASSERT(aForFrame->IsCanvasFrame(), "not a canvas frame");
|
||||
MOZ_ASSERT(IsCanvasFrame(aForFrame), "not a canvas frame");
|
||||
if (aRootElementFrame) {
|
||||
return FindBackgroundStyleFrame(aRootElementFrame);
|
||||
}
|
||||
|
|
|
@ -3626,9 +3626,13 @@ AppendedBackgroundType nsDisplayBackgroundImage::AppendBackgroundItemsToTop(
|
|||
}
|
||||
|
||||
bool drawBackgroundColor = false;
|
||||
bool drawBackgroundImage = false;
|
||||
// XUL root frames need special handling for now even though they return true
|
||||
// from nsCSSRendering::IsCanvasFrame they rely on us painting the background
|
||||
// image from here, see bug 1665476.
|
||||
bool drawBackgroundImage =
|
||||
aFrame->IsXULRootFrame() && aFrame->ComputeShouldPaintBackground().mImage;
|
||||
nscolor color = NS_RGBA(0, 0, 0, 0);
|
||||
if (bg && !(aFrame->IsCanvasFrame() || aFrame->IsViewportFrame())) {
|
||||
if (!nsCSSRendering::IsCanvasFrame(aFrame) && bg) {
|
||||
color = nsCSSRendering::DetermineBackgroundColor(
|
||||
presContext, bgSC, aFrame, drawBackgroundImage, drawBackgroundColor);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
.wide { background: red; width: 800px; height: 30px; display: inline-block;}
|
||||
|
||||
#container {
|
||||
background-color: yellow;
|
||||
}
|
||||
|
||||
#rightBox {
|
||||
margin-left: 1000px;
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0"?> <!-- -*- Mode: HTML -*- -->
|
||||
|
||||
<?xml-stylesheet type="text/css" href="1150021-1-ref.css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
title="gsg"
|
||||
>
|
||||
|
||||
<vbox id="container">
|
||||
<vbox id="rightBox">
|
||||
<html:span>
|
||||
<html:div class="wide"></html:div><html:div class="wide"></html:div>
|
||||
</html:span>
|
||||
</vbox>
|
||||
</vbox>
|
||||
|
||||
|
||||
|
||||
</window>
|
|
@ -0,0 +1,10 @@
|
|||
window { direction: rtl; }
|
||||
.wide { background: red; width: 800px; height: 30px; display: inline-block;}
|
||||
|
||||
#container {
|
||||
background-color: yellow;
|
||||
}
|
||||
|
||||
#rightBox {
|
||||
margin-left: 1000px;
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0"?> <!-- -*- Mode: HTML -*- -->
|
||||
|
||||
<?xml-stylesheet type="text/css" href="1150021-1.css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
title="gsg"
|
||||
>
|
||||
|
||||
<vbox id="container">
|
||||
<vbox id="rightBox">
|
||||
<html:span>
|
||||
<html:div class="wide"></html:div><html:div class="wide"></html:div>
|
||||
</html:span>
|
||||
</vbox>
|
||||
</vbox>
|
||||
|
||||
|
||||
|
||||
</window>
|
|
@ -1898,6 +1898,7 @@ pref(apz.allow_zooming,true) skip-if(!Android) fuzzy-if(Android,0-54,0-6) == 113
|
|||
pref(apz.allow_zooming,true) skip-if(!Android) fuzzy-if(Android,0-54,0-8) == 1133905-6-vh-rtl.html 1133905-ref-vh-rtl.html
|
||||
pref(apz.allow_zooming,true) skip-if(!Android) != 1133905-ref-vh-rtl.html about:blank # make sure it doesn't render blank
|
||||
== 1149304-1-transform-change.html 1149304-1-transform-change-ref.html
|
||||
== chrome://reftest/content/bugs/1150021-1.xhtml chrome://reftest/content/bugs/1150021-1-ref.xhtml
|
||||
fuzzy-if(webrender,0-128,0-22) == 1151145-1.html 1151145-1-ref.html # bug 1646527 for WR fuzz
|
||||
== 1151306-1.html 1151306-1-ref.html
|
||||
== 1153845-1.html 1153845-1-ref.html
|
||||
|
|
|
@ -28,6 +28,7 @@ UNIFIED_SOURCES += [
|
|||
"nsBoxLayoutState.cpp",
|
||||
"nsButtonBoxFrame.cpp",
|
||||
"nsRepeatService.cpp",
|
||||
"nsRootBoxFrame.cpp",
|
||||
"nsScrollbarButtonFrame.cpp",
|
||||
"nsScrollbarFrame.cpp",
|
||||
"nsSliderFrame.cpp",
|
||||
|
|
|
@ -16,14 +16,19 @@
|
|||
#include "nsGkAtoms.h"
|
||||
#include "nsBoxFrame.h"
|
||||
#include "nsStackLayout.h"
|
||||
#include "nsIAnonymousContentCreator.h"
|
||||
#include "nsNodeInfoManager.h"
|
||||
#include "nsContentCreatorFunctions.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
class nsDocElementBoxFrame final : public nsBoxFrame {
|
||||
class nsDocElementBoxFrame final : public nsBoxFrame,
|
||||
public nsIAnonymousContentCreator {
|
||||
public:
|
||||
virtual void DestroyFrom(nsIFrame* aDestructRoot,
|
||||
PostDestroyData& aPostDestroyData) override;
|
||||
|
||||
friend nsIFrame* NS_NewBoxFrame(mozilla::PresShell* aPresShell,
|
||||
ComputedStyle* aStyle);
|
||||
|
||||
|
@ -31,9 +36,16 @@ class nsDocElementBoxFrame final : public nsBoxFrame {
|
|||
nsPresContext* aPresContext)
|
||||
: nsBoxFrame(aStyle, aPresContext, kClassID, true) {}
|
||||
|
||||
NS_DECL_QUERYFRAME
|
||||
NS_DECL_FRAMEARENA_HELPERS(nsDocElementBoxFrame)
|
||||
|
||||
bool IsFrameOfType(uint32_t aFlags) const override {
|
||||
// nsIAnonymousContentCreator
|
||||
virtual nsresult CreateAnonymousContent(
|
||||
nsTArray<ContentInfo>& aElements) override;
|
||||
virtual void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
|
||||
uint32_t aFilter) override;
|
||||
|
||||
virtual bool IsFrameOfType(uint32_t aFlags) const override {
|
||||
// Override nsBoxFrame.
|
||||
if (aFlags & (nsIFrame::eReplacedContainsBlock | nsIFrame::eReplaced))
|
||||
return false;
|
||||
|
@ -41,8 +53,11 @@ class nsDocElementBoxFrame final : public nsBoxFrame {
|
|||
}
|
||||
|
||||
#ifdef DEBUG_FRAME_DUMP
|
||||
nsresult GetFrameName(nsAString& aResult) const override;
|
||||
virtual nsresult GetFrameName(nsAString& aResult) const override;
|
||||
#endif
|
||||
private:
|
||||
nsCOMPtr<Element> mPopupgroupContent;
|
||||
nsCOMPtr<Element> mTooltipContent;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -55,6 +70,70 @@ nsContainerFrame* NS_NewDocElementBoxFrame(PresShell* aPresShell,
|
|||
|
||||
NS_IMPL_FRAMEARENA_HELPERS(nsDocElementBoxFrame)
|
||||
|
||||
void nsDocElementBoxFrame::DestroyFrom(nsIFrame* aDestructRoot,
|
||||
PostDestroyData& aPostDestroyData) {
|
||||
aPostDestroyData.AddAnonymousContent(mPopupgroupContent.forget());
|
||||
aPostDestroyData.AddAnonymousContent(mTooltipContent.forget());
|
||||
nsBoxFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
|
||||
}
|
||||
|
||||
nsresult nsDocElementBoxFrame::CreateAnonymousContent(
|
||||
nsTArray<ContentInfo>& aElements) {
|
||||
Document* doc = mContent->GetComposedDoc();
|
||||
if (!doc) {
|
||||
// The page is currently being torn down. Why bother.
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsNodeInfoManager* nodeInfoManager = doc->NodeInfoManager();
|
||||
|
||||
// create the top-secret popupgroup node. shhhhh!
|
||||
RefPtr<NodeInfo> nodeInfo;
|
||||
nodeInfo = nodeInfoManager->GetNodeInfo(
|
||||
nsGkAtoms::popupgroup, nullptr, kNameSpaceID_XUL, nsINode::ELEMENT_NODE);
|
||||
NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsresult rv = NS_NewXULElement(getter_AddRefs(mPopupgroupContent),
|
||||
nodeInfo.forget(), dom::NOT_FROM_PARSER);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// XXX(Bug 1631371) Check if this should use a fallible operation as it
|
||||
// pretended earlier.
|
||||
aElements.AppendElement(mPopupgroupContent);
|
||||
|
||||
// create the top-secret default tooltip node. shhhhh!
|
||||
nodeInfo = nodeInfoManager->GetNodeInfo(
|
||||
nsGkAtoms::tooltip, nullptr, kNameSpaceID_XUL, nsINode::ELEMENT_NODE);
|
||||
NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
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,
|
||||
false);
|
||||
|
||||
// XXX(Bug 1631371) Check if this should use a fallible operation as it
|
||||
// pretended earlier.
|
||||
aElements.AppendElement(mTooltipContent);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsDocElementBoxFrame::AppendAnonymousContentTo(
|
||||
nsTArray<nsIContent*>& aElements, uint32_t aFilter) {
|
||||
if (mPopupgroupContent) {
|
||||
aElements.AppendElement(mPopupgroupContent);
|
||||
}
|
||||
|
||||
if (mTooltipContent) {
|
||||
aElements.AppendElement(mTooltipContent);
|
||||
}
|
||||
}
|
||||
|
||||
NS_QUERYFRAME_HEAD(nsDocElementBoxFrame)
|
||||
NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator)
|
||||
NS_QUERYFRAME_TAIL_INHERITING(nsBoxFrame)
|
||||
|
||||
#ifdef DEBUG_FRAME_DUMP
|
||||
nsresult nsDocElementBoxFrame::GetFrameName(nsAString& aResult) const {
|
||||
return MakeFrameName(u"DocElementBox"_ns, aResult);
|
||||
|
|
|
@ -192,7 +192,7 @@ void nsMenuPopupFrame::Init(nsIContent* aContent, nsContainerFrame* aParent,
|
|||
aContent->AsElement()->AttrValueIs(kNameSpaceID_None, nsGkAtoms::_default,
|
||||
nsGkAtoms::_true, eIgnoreCase)) {
|
||||
nsIPopupContainer* popupContainer =
|
||||
nsIPopupContainer::GetPopupContainer(PresShell());
|
||||
nsIPopupContainer::GetPopupContainer(PresContext()->GetPresShell());
|
||||
if (popupContainer) {
|
||||
popupContainer->SetDefaultTooltip(aContent->AsElement());
|
||||
}
|
||||
|
@ -2369,7 +2369,7 @@ void nsMenuPopupFrame::DestroyFrom(nsIFrame* aDestructRoot,
|
|||
if (pm) pm->PopupDestroyed(this);
|
||||
|
||||
nsIPopupContainer* popupContainer =
|
||||
nsIPopupContainer::GetPopupContainer(PresShell());
|
||||
nsIPopupContainer::GetPopupContainer(PresContext()->GetPresShell());
|
||||
if (popupContainer && popupContainer->GetDefaultTooltip() == mContent) {
|
||||
popupContainer->SetDefaultTooltip(nullptr);
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ void nsPopupSetFrame::Init(nsIContent* aContent, nsContainerFrame* aParent,
|
|||
// Normally the root box is our grandparent, but in case of wrapping
|
||||
// it can be our great-grandparent.
|
||||
nsIPopupContainer* popupContainer =
|
||||
nsIPopupContainer::GetPopupContainer(PresShell());
|
||||
nsIPopupContainer::GetPopupContainer(PresContext()->GetPresShell());
|
||||
if (popupContainer) {
|
||||
popupContainer->SetPopupSetFrame(this);
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ void nsPopupSetFrame::DestroyFrom(nsIFrame* aDestructRoot,
|
|||
// Normally the root box is our grandparent, but in case of wrapping
|
||||
// it can be our great-grandparent.
|
||||
nsIPopupContainer* popupContainer =
|
||||
nsIPopupContainer::GetPopupContainer(PresShell());
|
||||
nsIPopupContainer::GetPopupContainer(PresContext()->GetPresShell());
|
||||
if (popupContainer) {
|
||||
popupContainer->SetPopupSetFrame(nullptr);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,219 @@
|
|||
/* -*- 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 "nsHTMLParts.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsBoxFrame.h"
|
||||
#include "nsDisplayList.h"
|
||||
#include "nsStackLayout.h"
|
||||
#include "nsIPopupContainer.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsFrameManager.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "mozilla/BasicEvents.h"
|
||||
#include "mozilla/DisplayPortUtils.h"
|
||||
#include "mozilla/PresShell.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
// Interface IDs
|
||||
|
||||
// static
|
||||
nsIPopupContainer* nsIPopupContainer::GetPopupContainer(PresShell* aPresShell) {
|
||||
if (!aPresShell) {
|
||||
return nullptr;
|
||||
}
|
||||
nsIFrame* rootFrame = aPresShell->GetRootFrame();
|
||||
if (!rootFrame) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (rootFrame) {
|
||||
rootFrame = rootFrame->PrincipalChildList().FirstChild();
|
||||
}
|
||||
|
||||
nsIPopupContainer* rootBox = do_QueryFrame(rootFrame);
|
||||
|
||||
// If the rootBox was not found yet this may be a top level non-XUL document.
|
||||
if (rootFrame && !rootBox) {
|
||||
// In a non-XUL document the rootFrame here will be a nsHTMLScrollFrame,
|
||||
// get the nsCanvasFrame (which is the popup container) from it.
|
||||
rootFrame = rootFrame->GetContentInsertionFrame();
|
||||
rootBox = do_QueryFrame(rootFrame);
|
||||
}
|
||||
|
||||
return rootBox;
|
||||
}
|
||||
|
||||
class nsRootBoxFrame final : public nsBoxFrame, public nsIPopupContainer {
|
||||
public:
|
||||
friend nsIFrame* NS_NewBoxFrame(mozilla::PresShell* aPresShell,
|
||||
ComputedStyle* aStyle);
|
||||
|
||||
explicit nsRootBoxFrame(ComputedStyle* aStyle, nsPresContext* aPresContext);
|
||||
|
||||
NS_DECL_QUERYFRAME
|
||||
NS_DECL_FRAMEARENA_HELPERS(nsRootBoxFrame)
|
||||
|
||||
virtual nsPopupSetFrame* GetPopupSetFrame() override;
|
||||
virtual void SetPopupSetFrame(nsPopupSetFrame* aPopupSet) override;
|
||||
virtual dom::Element* GetDefaultTooltip() override;
|
||||
virtual void SetDefaultTooltip(dom::Element* aTooltip) override;
|
||||
|
||||
virtual void AppendFrames(ChildListID aListID,
|
||||
nsFrameList& aFrameList) override;
|
||||
virtual void InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame,
|
||||
const nsLineList::iterator* aPrevFrameLine,
|
||||
nsFrameList& aFrameList) override;
|
||||
virtual void RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame) override;
|
||||
|
||||
virtual void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize,
|
||||
const ReflowInput& aReflowInput,
|
||||
nsReflowStatus& aStatus) override;
|
||||
virtual nsresult HandleEvent(nsPresContext* aPresContext,
|
||||
WidgetGUIEvent* aEvent,
|
||||
nsEventStatus* aEventStatus) override;
|
||||
|
||||
virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
const nsDisplayListSet& aLists) override;
|
||||
|
||||
virtual bool IsFrameOfType(uint32_t aFlags) const override {
|
||||
// Override bogus IsFrameOfType in nsBoxFrame.
|
||||
if (aFlags & (nsIFrame::eReplacedContainsBlock | nsIFrame::eReplaced))
|
||||
return false;
|
||||
return nsBoxFrame::IsFrameOfType(aFlags);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_FRAME_DUMP
|
||||
virtual nsresult GetFrameName(nsAString& aResult) const override;
|
||||
#endif
|
||||
|
||||
nsPopupSetFrame* mPopupSetFrame;
|
||||
|
||||
protected:
|
||||
dom::Element* mDefaultTooltip;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
nsContainerFrame* NS_NewRootBoxFrame(PresShell* aPresShell,
|
||||
ComputedStyle* aStyle) {
|
||||
return new (aPresShell) nsRootBoxFrame(aStyle, aPresShell->GetPresContext());
|
||||
}
|
||||
|
||||
NS_IMPL_FRAMEARENA_HELPERS(nsRootBoxFrame)
|
||||
|
||||
nsRootBoxFrame::nsRootBoxFrame(ComputedStyle* aStyle,
|
||||
nsPresContext* aPresContext)
|
||||
: nsBoxFrame(aStyle, aPresContext, kClassID, true),
|
||||
mPopupSetFrame(nullptr),
|
||||
mDefaultTooltip(nullptr) {
|
||||
nsCOMPtr<nsBoxLayout> layout;
|
||||
NS_NewStackLayout(layout);
|
||||
SetXULLayoutManager(layout);
|
||||
}
|
||||
|
||||
void nsRootBoxFrame::AppendFrames(ChildListID aListID,
|
||||
nsFrameList& aFrameList) {
|
||||
MOZ_ASSERT(aListID == kPrincipalList, "unexpected child list ID");
|
||||
MOZ_ASSERT(mFrames.IsEmpty(), "already have a child frame");
|
||||
nsBoxFrame::AppendFrames(aListID, aFrameList);
|
||||
}
|
||||
|
||||
void nsRootBoxFrame::InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame,
|
||||
const nsLineList::iterator* aPrevFrameLine,
|
||||
nsFrameList& aFrameList) {
|
||||
// Because we only support a single child frame inserting is the same
|
||||
// as appending.
|
||||
MOZ_ASSERT(!aPrevFrame, "unexpected previous sibling frame");
|
||||
AppendFrames(aListID, aFrameList);
|
||||
}
|
||||
|
||||
void nsRootBoxFrame::RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame) {
|
||||
NS_ASSERTION(aListID == kPrincipalList, "unexpected child list ID");
|
||||
if (aOldFrame == mFrames.FirstChild()) {
|
||||
nsBoxFrame::RemoveFrame(aListID, aOldFrame);
|
||||
} else {
|
||||
MOZ_CRASH("unknown aOldFrame");
|
||||
}
|
||||
}
|
||||
|
||||
void nsRootBoxFrame::Reflow(nsPresContext* aPresContext,
|
||||
ReflowOutput& aDesiredSize,
|
||||
const ReflowInput& aReflowInput,
|
||||
nsReflowStatus& aStatus) {
|
||||
DO_GLOBAL_REFLOW_COUNT("nsRootBoxFrame");
|
||||
MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
|
||||
|
||||
return nsBoxFrame::Reflow(aPresContext, aDesiredSize, aReflowInput, aStatus);
|
||||
}
|
||||
|
||||
void nsRootBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
const nsDisplayListSet& aLists) {
|
||||
if (mContent && mContent->GetProperty(nsGkAtoms::DisplayPortMargins)) {
|
||||
// The XUL document's root element may have displayport margins set in
|
||||
// ChromeProcessController::InitializeRoot, and we should to supply the
|
||||
// base rect.
|
||||
nsRect displayPortBase =
|
||||
aBuilder->GetVisibleRect().Intersect(nsRect(nsPoint(0, 0), GetSize()));
|
||||
DisplayPortUtils::SetDisplayPortBase(mContent, displayPortBase);
|
||||
}
|
||||
|
||||
// root boxes don't need a debug border/outline or a selection overlay...
|
||||
// They *may* have a background propagated to them, so force creation
|
||||
// of a background display list element.
|
||||
DisplayBorderBackgroundOutline(aBuilder, aLists, true);
|
||||
|
||||
BuildDisplayListForChildren(aBuilder, aLists);
|
||||
}
|
||||
|
||||
nsresult nsRootBoxFrame::HandleEvent(nsPresContext* aPresContext,
|
||||
WidgetGUIEvent* aEvent,
|
||||
nsEventStatus* aEventStatus) {
|
||||
NS_ENSURE_ARG_POINTER(aEventStatus);
|
||||
if (nsEventStatus_eConsumeNoDefault == *aEventStatus) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (aEvent->mMessage == eMouseUp) {
|
||||
nsIFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsPopupSetFrame* nsRootBoxFrame::GetPopupSetFrame() { return mPopupSetFrame; }
|
||||
|
||||
void nsRootBoxFrame::SetPopupSetFrame(nsPopupSetFrame* aPopupSet) {
|
||||
// Under normal conditions this should only be called once. However,
|
||||
// if something triggers ReconstructDocElementHierarchy, we will
|
||||
// destroy this frame's child (the nsDocElementBoxFrame), but not this
|
||||
// frame. This will cause the popupset to remove itself by calling
|
||||
// |SetPopupSetFrame(nullptr)|, and then we'll be able to accept a new
|
||||
// popupset. Since the anonymous content is associated with the
|
||||
// nsDocElementBoxFrame, we'll get a new popupset when the new doc
|
||||
// element box frame is created.
|
||||
MOZ_ASSERT(!aPopupSet || !mPopupSetFrame,
|
||||
"Popup set is already defined! Only 1 allowed.");
|
||||
mPopupSetFrame = aPopupSet;
|
||||
}
|
||||
|
||||
dom::Element* nsRootBoxFrame::GetDefaultTooltip() { return mDefaultTooltip; }
|
||||
|
||||
void nsRootBoxFrame::SetDefaultTooltip(dom::Element* aTooltip) {
|
||||
mDefaultTooltip = aTooltip;
|
||||
}
|
||||
|
||||
NS_QUERYFRAME_HEAD(nsRootBoxFrame)
|
||||
NS_QUERYFRAME_ENTRY(nsIPopupContainer)
|
||||
NS_QUERYFRAME_TAIL_INHERITING(nsBoxFrame)
|
||||
|
||||
#ifdef DEBUG_FRAME_DUMP
|
||||
nsresult nsRootBoxFrame::GetFrameName(nsAString& aResult) const {
|
||||
return MakeFrameName(u"RootBox"_ns, aResult);
|
||||
}
|
||||
#endif
|
|
@ -25,7 +25,6 @@ function do_test() {
|
|||
setTimeout(doe, 200);
|
||||
}
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.expectAssertions(1);
|
||||
addLoadEvent(do_test);
|
||||
]]>
|
||||
</script>
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
:root {
|
||||
text-rendering: optimizeLegibility;
|
||||
-moz-control-character-visibility: visible;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
:root:-moz-locale-dir(rtl) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче