fune/layout/forms/nsSearchControlFrame.cpp
Emilio Cobos Álvarez 9cec29125b Bug 1698043 - Simplify <input type=number/search> layout to fix this bug and make ::-moz-complex-control-wrapper unnecessary. r=dholbert
This should be a simpler setup. We keep every element being a direct
anon child of the text control, and special case the reflow of the
spinners / clear button, to subtract that size from the other elements.

This fixes the bug by ensuring that the editor and placeholder are sized
and positioned in exactly the same way.

Differential Revision: https://phabricator.services.mozilla.com/D108305
2021-03-14 07:53:13 +00:00

100 lines
3.2 KiB
C++

/* -*- 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 "nsSearchControlFrame.h"
#include "HTMLInputElement.h"
#include "mozilla/PresShell.h"
#include "nsGkAtoms.h"
#include "nsNameSpaceManager.h"
#include "nsStyleConsts.h"
#include "nsContentUtils.h"
#include "nsContentCreatorFunctions.h"
#include "nsCSSPseudoElements.h"
#include "nsICSSDeclaration.h"
#ifdef ACCESSIBILITY
# include "mozilla/a11y/AccTypes.h"
#endif
using namespace mozilla;
using namespace mozilla::dom;
nsIFrame* NS_NewSearchControlFrame(PresShell* aPresShell,
ComputedStyle* aStyle) {
return new (aPresShell)
nsSearchControlFrame(aStyle, aPresShell->GetPresContext());
}
NS_IMPL_FRAMEARENA_HELPERS(nsSearchControlFrame)
NS_QUERYFRAME_HEAD(nsSearchControlFrame)
NS_QUERYFRAME_ENTRY(nsSearchControlFrame)
NS_QUERYFRAME_TAIL_INHERITING(nsTextControlFrame)
nsSearchControlFrame::nsSearchControlFrame(ComputedStyle* aStyle,
nsPresContext* aPresContext)
: nsTextControlFrame(aStyle, aPresContext, kClassID) {}
void nsSearchControlFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
aPostDestroyData.AddAnonymousContent(mClearButton.forget());
nsTextControlFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
}
nsresult nsSearchControlFrame::CreateAnonymousContent(
nsTArray<ContentInfo>& aElements) {
// We create an anonymous tree for our input element that is structured as
// follows:
//
// input
// button - clear button
// div - editor root
// div - placeholder
// div - preview div
//
// If you change this, be careful to change the destruction order in
// nsSearchControlFrame::DestroyFrom.
// Create the ::-moz-search-clear-button pseudo-element:
mClearButton = MakeAnonElement(PseudoStyleType::mozSearchClearButton, nullptr,
nsGkAtoms::button);
aElements.AppendElement(mClearButton);
nsTextControlFrame::CreateAnonymousContent(aElements);
// Update clear button visibility based on value
UpdateClearButtonState();
return NS_OK;
}
void nsSearchControlFrame::AppendAnonymousContentTo(
nsTArray<nsIContent*>& aElements, uint32_t aFilter) {
if (mClearButton) {
aElements.AppendElement(mClearButton);
}
nsTextControlFrame::AppendAnonymousContentTo(aElements, aFilter);
}
void nsSearchControlFrame::UpdateClearButtonState() {
if (!mClearButton) {
return;
}
auto* content = HTMLInputElement::FromNode(mContent);
nsGenericHTMLElement* element = nsGenericHTMLElement::FromNode(mClearButton);
nsCOMPtr<nsICSSDeclaration> declaration = element->Style();
if (content->IsValueEmpty()) {
declaration->SetProperty("visibility"_ns, "hidden"_ns, ""_ns,
IgnoreErrors());
} else {
nsAutoCString dummy;
declaration->RemoveProperty("visibility"_ns, dummy, IgnoreErrors());
}
}