Backed out 2 changesets (bug 981248) for causing multiple failures.

CLOSED TREE

Backed out changeset 7a96708cc8b7 (bug 981248)
Backed out changeset 1eace7bd28d9 (bug 981248)
This commit is contained in:
Mihai Alexandru Michis
2020-01-14 19:28:17 +02:00
parent c7d67b115e
commit b51ee7e327
43 changed files with 1166 additions and 366 deletions

View File

@@ -108,9 +108,8 @@ class nsTextControlFrame::nsAnonDivObserver final
};
nsTextControlFrame::nsTextControlFrame(ComputedStyle* aStyle,
nsPresContext* aPresContext,
nsIFrame::ClassID aClassID)
: nsContainerFrame(aStyle, aPresContext, aClassID),
nsPresContext* aPresContext)
: nsContainerFrame(aStyle, aPresContext, kClassID),
mFirstBaseline(NS_INTRINSIC_ISIZE_UNKNOWN),
mEditorHasBeenInitialized(false),
mIsProcessing(false)
@@ -124,13 +123,6 @@ nsTextControlFrame::nsTextControlFrame(ComputedStyle* aStyle,
nsTextControlFrame::~nsTextControlFrame() {}
nsIScrollableFrame* nsTextControlFrame::GetScrollTargetFrame() {
if (!mRootNode) {
return nullptr;
}
return do_QueryFrame(mRootNode->GetPrimaryFrame());
}
void nsTextControlFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
mScrollEvent.Revoke();
@@ -151,15 +143,8 @@ void nsTextControlFrame::DestroyFrom(nsIFrame* aDestructRoot,
mMutationObserver = nullptr;
}
// If we're a subclass like nsNumberControlFrame, then it owns the root of the
// anonymous subtree where mRootNode is.
if (mClass == kClassID) {
aPostDestroyData.AddAnonymousContent(mRootNode.forget());
} else {
MOZ_ASSERT(!mRootNode || !mRootNode->IsRootOfAnonymousSubtree());
mRootNode = nullptr;
}
// FIXME(emilio, bug 1400618): Do this after the child frames are destroyed.
aPostDestroyData.AddAnonymousContent(mRootNode.forget());
aPostDestroyData.AddAnonymousContent(mPlaceholderDiv.forget());
aPostDestroyData.AddAnonymousContent(mPreviewDiv.forget());
@@ -227,7 +212,9 @@ LogicalSize nsTextControlFrame::CalcIntrinsicSize(
// Add in the size of the scrollbars for textarea
if (IsTextArea()) {
nsIScrollableFrame* scrollableFrame = GetScrollTargetFrame();
nsIFrame* first = PrincipalChildList().FirstChild();
nsIScrollableFrame* scrollableFrame = do_QueryFrame(first);
NS_ASSERTION(scrollableFrame, "Child must be scrollable");
if (scrollableFrame) {
@@ -345,6 +332,8 @@ already_AddRefed<Element> nsTextControlFrame::CreateEmptyAnonymousDiv(
RefPtr<Element> divElement = NS_NewHTMLDivElement(nodeInfo.forget());
switch (aAnonymousDivType) {
case AnonymousDivType::Root: {
divElement->SetIsNativeAnonymousRoot();
// Make our root node editable
divElement->SetFlags(NODE_IS_EDITABLE);
@@ -421,26 +410,12 @@ nsresult nsTextControlFrame::CreateAnonymousContent(
RefPtr<TextControlElement> textControlElement =
TextControlElement::FromNode(GetContent());
MOZ_ASSERT(textControlElement);
mRootNode = CreateEmptyAnonymousDiv(AnonymousDivType::Root);
if (NS_WARN_IF(!mRootNode)) {
return NS_ERROR_FAILURE;
}
nsresult rv = CreateRootNode();
NS_ENSURE_SUCCESS(rv, rv);
mMutationObserver = new nsAnonDivObserver(*this);
mRootNode->AddMutationObserver(mMutationObserver);
// Bind the frame to its text control.
//
// This can realistically fail in paginated mode, where we may replicate
// fixed-positioned elements and the replicated frame will not get the chance
// to get an editor.
nsresult rv = textControlElement->BindToFrame(this);
if (NS_WARN_IF(NS_FAILED(rv))) {
mRootNode->RemoveMutationObserver(mMutationObserver);
mMutationObserver = nullptr;
mRootNode = nullptr;
return rv;
}
// Bind the frame to its text control
rv = textControlElement->BindToFrame(this);
NS_ENSURE_SUCCESS(rv, rv);
aElements.AppendElement(mRootNode);
CreatePlaceholderIfNeeded();
@@ -502,6 +477,18 @@ void nsTextControlFrame::InitializeEagerlyIfNeeded() {
nsContentUtils::AddScriptRunner(initializer);
}
nsresult nsTextControlFrame::CreateRootNode() {
MOZ_ASSERT(!mRootNode);
mRootNode = CreateEmptyAnonymousDiv(AnonymousDivType::Root);
if (NS_WARN_IF(!mRootNode)) {
return NS_ERROR_FAILURE;
}
mMutationObserver = new nsAnonDivObserver(*this);
mRootNode->AddMutationObserver(mMutationObserver);
return NS_OK;
}
void nsTextControlFrame::CreatePlaceholderIfNeeded() {
MOZ_ASSERT(!mPlaceholderDiv);
@@ -602,30 +589,6 @@ LogicalSize nsTextControlFrame::ComputeAutoSize(
return autoSize;
}
void nsTextControlFrame::ComputeBaseline(const ReflowInput& aReflowInput,
ReflowOutput& aDesiredSize) {
// If we're layout-contained, we have no baseline.
if (aReflowInput.mStyleDisplay->IsContainLayout()) {
mFirstBaseline = NS_INTRINSIC_ISIZE_UNKNOWN;
return;
}
WritingMode wm = aReflowInput.GetWritingMode();
// Calculate the baseline and store it in mFirstBaseline.
nscoord lineHeight = aReflowInput.ComputedBSize();
float inflation = nsLayoutUtils::FontSizeInflationFor(this);
if (!IsSingleLineTextControl()) {
lineHeight = ReflowInput::CalcLineHeight(
GetContent(), Style(), PresContext(), NS_UNCONSTRAINEDSIZE, inflation);
}
RefPtr<nsFontMetrics> fontMet =
nsLayoutUtils::GetFontMetricsForFrame(this, inflation);
mFirstBaseline = nsLayoutUtils::GetCenteredFontBaseline(fontMet, lineHeight,
wm.IsLineInverted()) +
aReflowInput.ComputedLogicalBorderPadding().BStart(wm);
aDesiredSize.SetBlockStartAscent(mFirstBaseline);
}
void nsTextControlFrame::Reflow(nsPresContext* aPresContext,
ReflowOutput& aDesiredSize,
const ReflowInput& aReflowInput,
@@ -650,7 +613,22 @@ void nsTextControlFrame::Reflow(nsPresContext* aPresContext,
aReflowInput.ComputedLogicalBorderPadding().BStartEnd(wm));
aDesiredSize.SetSize(wm, finalSize);
ComputeBaseline(aReflowInput, aDesiredSize);
if (!aReflowInput.mStyleDisplay->IsContainLayout()) {
// Calculate the baseline and store it in mFirstBaseline.
nscoord lineHeight = aReflowInput.ComputedBSize();
float inflation = nsLayoutUtils::FontSizeInflationFor(this);
if (!IsSingleLineTextControl()) {
lineHeight =
ReflowInput::CalcLineHeight(GetContent(), Style(), PresContext(),
NS_UNCONSTRAINEDSIZE, inflation);
}
RefPtr<nsFontMetrics> fontMet =
nsLayoutUtils::GetFontMetricsForFrame(this, inflation);
mFirstBaseline = nsLayoutUtils::GetCenteredFontBaseline(
fontMet, lineHeight, wm.IsLineInverted()) +
aReflowInput.ComputedLogicalBorderPadding().BStart(wm);
aDesiredSize.SetBlockStartAscent(mFirstBaseline);
} // else: we're layout-contained, and so we have no baseline.
// overflow handling
aDesiredSize.SetOverflowAreasToDesiredBounds();
@@ -1204,21 +1182,6 @@ bool nsTextControlFrame::GetMaxLength(int32_t* aSize) {
// END IMPLEMENTING NS_IFORMCONTROLFRAME
// NOTE(emilio): This is needed because the root->primary frame map is not set
// up by the time this is called.
static nsIFrame* FindRootNodeFrame(const nsFrameList& aChildList,
const nsIContent* aRoot) {
for (nsIFrame* f : aChildList) {
if (f->GetContent() == aRoot) {
return f;
}
if (nsIFrame* root = FindRootNodeFrame(f->PrincipalChildList(), aRoot)) {
return root;
}
}
return nullptr;
}
void nsTextControlFrame::SetInitialChildList(ChildListID aListID,
nsFrameList& aChildList) {
nsContainerFrame::SetInitialChildList(aListID, aChildList);
@@ -1226,20 +1189,22 @@ void nsTextControlFrame::SetInitialChildList(ChildListID aListID,
return;
}
// Mark the scroll frame as being a reflow root. This will allow incremental
// reflows to be initiated at the scroll frame, rather than descending from
// the root frame of the frame hierarchy.
if (nsIFrame* frame = FindRootNodeFrame(PrincipalChildList(), mRootNode)) {
frame->AddStateBits(NS_FRAME_REFLOW_ROOT);
// Mark the scroll frame as being a reflow root. This will allow
// incremental reflows to be initiated at the scroll frame, rather
// than descending from the root frame of the frame hierarchy.
if (nsIFrame* first = PrincipalChildList().FirstChild()) {
first->AddStateBits(NS_FRAME_REFLOW_ROOT);
auto* textControlElement = TextControlElement::FromNode(GetContent());
TextControlElement* textControlElement =
TextControlElement::FromNode(GetContent());
MOZ_ASSERT(textControlElement);
textControlElement->InitializeKeyboardEventListeners();
if (nsPoint* contentScrollPos = GetProperty(ContentScrollPos())) {
nsPoint* contentScrollPos = GetProperty(ContentScrollPos());
if (contentScrollPos) {
// If we have a scroll pos stored to be passed to our anonymous
// div, do it here!
nsIStatefulFrame* statefulFrame = do_QueryFrame(frame);
nsIStatefulFrame* statefulFrame = do_QueryFrame(first);
NS_ASSERTION(statefulFrame,
"unexpected type of frame for the anonymous div");
UniquePtr<PresState> fakePresState = NewPresState();
@@ -1248,13 +1213,12 @@ void nsTextControlFrame::SetInitialChildList(ChildListID aListID,
RemoveProperty(ContentScrollPos());
delete contentScrollPos;
}
} else {
MOZ_ASSERT(!mRootNode || PrincipalChildList().IsEmpty());
}
}
void nsTextControlFrame::SetValueChanged(bool aValueChanged) {
auto* textControlElement = TextControlElement::FromNode(GetContent());
TextControlElement* textControlElement =
TextControlElement::FromNode(GetContent());
MOZ_ASSERT(textControlElement);
if (mPlaceholderDiv) {
@@ -1319,7 +1283,8 @@ nsresult nsTextControlFrame::UpdateValueDisplay(bool aNotify,
}
if (aBeforeEditorInit && value.IsEmpty()) {
if (nsIContent* node = mRootNode->GetFirstChild()) {
nsIContent* node = mRootNode->GetFirstChild();
if (node) {
mRootNode->RemoveChildNode(node, true);
}
return NS_OK;
@@ -1344,15 +1309,20 @@ nsTextControlFrame::GetOwnedSelectionController(
}
nsFrameSelection* nsTextControlFrame::GetOwnedFrameSelection() {
auto* textControlElement = TextControlElement::FromNode(GetContent());
TextControlElement* textControlElement =
TextControlElement::FromNode(GetContent());
MOZ_ASSERT(textControlElement);
return textControlElement->GetConstFrameSelection();
}
UniquePtr<PresState> nsTextControlFrame::SaveState() {
if (nsIStatefulFrame* scrollStateFrame =
do_QueryFrame(GetScrollTargetFrame())) {
return scrollStateFrame->SaveState();
if (mRootNode) {
// Query the nsIStatefulFrame from the HTMLScrollFrame
nsIStatefulFrame* scrollStateFrame =
do_QueryFrame(mRootNode->GetPrimaryFrame());
if (scrollStateFrame) {
return scrollStateFrame->SaveState();
}
}
return nullptr;
@@ -1362,10 +1332,13 @@ NS_IMETHODIMP
nsTextControlFrame::RestoreState(PresState* aState) {
NS_ENSURE_ARG_POINTER(aState);
// Query the nsIStatefulFrame from the HTMLScrollFrame
if (nsIStatefulFrame* scrollStateFrame =
do_QueryFrame(GetScrollTargetFrame())) {
return scrollStateFrame->RestoreState(aState);
if (mRootNode) {
// Query the nsIStatefulFrame from the HTMLScrollFrame
nsIStatefulFrame* scrollStateFrame =
do_QueryFrame(mRootNode->GetPrimaryFrame());
if (scrollStateFrame) {
return scrollStateFrame->RestoreState(aState);
}
}
// Most likely, we don't have our anonymous content constructed yet, which
@@ -1389,42 +1362,29 @@ void nsTextControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
*/
DO_GLOBAL_REFLOW_COUNT_DSP("nsTextControlFrame");
auto* control = TextControlElement::FromNode(GetContent());
MOZ_ASSERT(control);
TextControlElement* textControlElement =
TextControlElement::FromNode(GetContent());
MOZ_ASSERT(textControlElement);
DisplayBorderBackgroundOutline(aBuilder, aLists);
nsIFrame* kid = mFrames.FirstChild();
// Redirect all lists to the Content list so that nothing can escape, ie
// opacity creating stacking contexts that then get sorted with stacking
// contexts external to us.
nsDisplayList* content = aLists.Content();
nsDisplayListSet set(content, content, content, content, content, content);
for (nsIFrame* kid = mFrames.FirstChild(); kid; kid = kid->GetNextSibling()) {
nsIContent* kidContent = kid->GetContent();
Maybe<DisplayListClipState::AutoSaveRestore> overlayTextClip;
if (kidContent == mPlaceholderDiv && !control->GetPlaceholderVisibility()) {
continue;
while (kid) {
// If the frame is the placeholder or preview frame, we should only show
// it if it has to be visible.
if (!((kid->GetContent() == mPlaceholderDiv &&
!textControlElement->GetPlaceholderVisibility()) ||
(kid->GetContent() == mPreviewDiv &&
!textControlElement->GetPreviewVisibility()))) {
BuildDisplayListForChild(aBuilder, kid, set, 0);
}
if (kidContent == mPreviewDiv && !control->GetPreviewVisibility()) {
continue;
}
// Clip the preview text to the root box, so that it doesn't, e.g., overlay
// with our <input type="number"> spin buttons.
//
// For other input types, this will be a noop since we size the root via
// ReflowTextControlChild, which sets the same available space for all
// children.
if (kidContent == mPlaceholderDiv || kidContent == mPreviewDiv) {
if (mRootNode) {
if (auto* root = mRootNode->GetPrimaryFrame()) {
overlayTextClip.emplace(aBuilder);
nsRect rootBox(aBuilder->ToReferenceFrame(root), root->GetSize());
overlayTextClip->ClipContentDescendants(rootBox);
}
}
}
BuildDisplayListForChild(aBuilder, kid, set, 0);
kid = kid->GetNextSibling();
}
}