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:
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user