Bug 1824667 - Remove nsTextBoxFrame. r=jwatt

Use a MiddleCroppingBlockFrame subclass that looks at the value attribute
instead. We don't need accesskey etc for these so we can just reuse it as is.

Differential Revision: https://phabricator.services.mozilla.com/D173669
This commit is contained in:
Emilio Cobos Álvarez
2023-03-27 23:46:51 +00:00
parent 052276b751
commit 3cb807aa01
10 changed files with 230 additions and 1215 deletions

View File

@@ -23,7 +23,6 @@
#include "nsNameSpaceManager.h"
#include "nsNetUtil.h"
#include "nsString.h"
#include "nsTextBoxFrame.h"
#include "nsXULElement.h"
using namespace mozilla::a11y;
@@ -36,21 +35,6 @@ XULLabelAccessible::XULLabelAccessible(nsIContent* aContent,
DocAccessible* aDoc)
: HyperTextAccessibleWrap(aContent, aDoc) {
mType = eXULLabelType;
// If @value attribute is given then it's rendered instead text content. In
// this case we need to create a text leaf accessible to make @value attribute
// accessible.
// XXX: text interface doesn't let you get the text by words.
nsTextBoxFrame* textBoxFrame = do_QueryFrame(mContent->GetPrimaryFrame());
if (textBoxFrame) {
mValueTextLeaf = new XULLabelTextLeafAccessible(mContent, mDoc);
mDoc->BindToDocument(mValueTextLeaf, nullptr);
nsAutoString text;
textBoxFrame->GetCroppedTitle(text);
mValueTextLeaf->SetText(text);
AppendChild(mValueTextLeaf);
}
}
void XULLabelAccessible::Shutdown() {

View File

@@ -66,7 +66,6 @@
#include "nsIFormControl.h"
#include "nsCSSAnonBoxes.h"
#include "nsTextFragment.h"
#include "nsTextBoxFrame.h"
#include "nsIAnonymousContentCreator.h"
#include "nsContentUtils.h"
#include "nsIScriptError.h"
@@ -172,6 +171,7 @@ nsIFrame* NS_NewSVGFEImageFrame(PresShell* aPresShell, ComputedStyle* aStyle);
nsIFrame* NS_NewSVGFEUnstyledLeafFrame(PresShell* aPresShell,
ComputedStyle* aStyle);
nsIFrame* NS_NewFileControlLabelFrame(PresShell*, ComputedStyle*);
nsIFrame* NS_NewMiddleCroppingLabelFrame(PresShell*, ComputedStyle*);
#include "mozilla/dom/NodeInfo.h"
#include "prenv.h"
@@ -502,6 +502,33 @@ static bool ParentIsWrapperAnonBox(nsIFrame* aParent) {
return maybeAnonBox->Style()->IsWrapperAnonBox();
}
static bool InsertSeparatorBeforeAccessKey() {
static bool sInitialized = false;
static bool sValue = false;
if (!sInitialized) {
sInitialized = true;
const char* prefName = "intl.menuitems.insertseparatorbeforeaccesskeys";
nsAutoString val;
Preferences::GetLocalizedString(prefName, val);
sValue = val.EqualsLiteral("true");
}
return sValue;
}
static bool AlwaysAppendAccessKey() {
static bool sInitialized = false;
static bool sValue = false;
if (!sInitialized) {
sInitialized = true;
const char* prefName = "intl.menuitems.alwaysappendaccesskeys";
nsAutoString val;
Preferences::GetLocalizedString(prefName, val);
sValue = val.EqualsLiteral("true");
}
return sValue;
}
//----------------------------------------------------------------------
// Block/inline frame construction logic. We maintain a few invariants here:
@@ -1612,14 +1639,14 @@ void nsCSSFrameConstructor::CreateGeneratedContent(
ToUpperCase(accesskey);
nsAutoString accessKeyLabel = u"("_ns + accesskey + u")"_ns;
if (!StringEndsWith(value, accessKeyLabel)) {
if (nsTextBoxFrame::InsertSeparatorBeforeAccessKey() &&
!value.IsEmpty() && !NS_IS_SPACE(value.Last())) {
if (InsertSeparatorBeforeAccessKey() && !value.IsEmpty() &&
!NS_IS_SPACE(value.Last())) {
value.Append(' ');
}
value.Append(accessKeyLabel);
}
};
if (nsTextBoxFrame::AlwaysAppendAccessKey()) {
if (AlwaysAppendAccessKey()) {
AppendAccessKeyLabel();
RefPtr c = CreateGenConTextNode(aState, value, nullptr);
aAddChild(c);
@@ -4167,9 +4194,9 @@ nsCSSFrameConstructor::FindXULLabelOrDescriptionData(const Element& aElement,
return nullptr;
}
static constexpr FrameConstructionData sXULTextBoxData =
SIMPLE_XUL_FCDATA(NS_NewTextBoxFrame);
return &sXULTextBoxData;
static constexpr FrameConstructionData sMiddleCroppingData =
SIMPLE_XUL_FCDATA(NS_NewMiddleCroppingLabelFrame);
return &sMiddleCroppingData;
}
#ifdef XP_MACOSX

View File

@@ -115,6 +115,7 @@ FRAME_CLASSES = [
# Not a leaf, though it always has a ShadowRoot, so in practice light DOM
# children never render.
Frame("SVGUseFrame", "SVGUse", NOT_LEAF),
Frame("MiddleCroppingLabelFrame", "MiddleCroppingLabel", LEAF),
Frame("SVGViewFrame", "SVGView", LEAF),
Frame("nsTableCellFrame", "TableCell", NOT_LEAF),
Frame("nsTableColFrame", "TableCol", LEAF),
@@ -123,7 +124,6 @@ FRAME_CLASSES = [
Frame("nsTableWrapperFrame", "TableWrapper", NOT_LEAF),
Frame("nsTableRowFrame", "TableRow", NOT_LEAF),
Frame("nsTableRowGroupFrame", "TableRowGroup", NOT_LEAF),
Frame("nsTextBoxFrame", "LeafBox", LEAF),
Frame("nsTextControlFrame", "TextInput", LEAF),
Frame("nsTextFrame", "Text", LEAF),
Frame("nsTreeBodyFrame", "LeafBox", LEAF),

View File

@@ -9,8 +9,8 @@
#include "nsLayoutUtils.h"
#include "nsTextNode.h"
#include "nsLineLayout.h"
#include "mozilla/dom/Document.h"
#include "gfxContext.h"
#include "mozilla/dom/Document.h"
#include "mozilla/intl/Segmenter.h"
#include "mozilla/ReflowInput.h"
#include "mozilla/ReflowOutput.h"

View File

@@ -0,0 +1,38 @@
/* -*- 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 "MiddleCroppingLabelFrame.h"
#include "MiddleCroppingBlockFrame.h"
#include "mozilla/dom/Element.h"
#include "mozilla/PresShell.h"
nsIFrame* NS_NewMiddleCroppingLabelFrame(mozilla::PresShell* aPresShell,
mozilla::ComputedStyle* aStyle) {
return new (aPresShell)
mozilla::MiddleCroppingLabelFrame(aStyle, aPresShell->GetPresContext());
}
namespace mozilla {
void MiddleCroppingLabelFrame::GetUncroppedValue(nsAString& aValue) {
mContent->AsElement()->GetAttr(nsGkAtoms::value, aValue);
}
nsresult MiddleCroppingLabelFrame::AttributeChanged(int32_t aNameSpaceID,
nsAtom* aAttribute,
int32_t aModType) {
if (aNameSpaceID == kNameSpaceID_None && aAttribute == nsGkAtoms::value) {
UpdateDisplayedValueToUncroppedValue(true);
}
return NS_OK;
}
NS_QUERYFRAME_HEAD(MiddleCroppingLabelFrame)
NS_QUERYFRAME_ENTRY(MiddleCroppingLabelFrame)
NS_QUERYFRAME_TAIL_INHERITING(MiddleCroppingBlockFrame)
NS_IMPL_FRAMEARENA_HELPERS(MiddleCroppingLabelFrame)
} // namespace mozilla

View File

@@ -0,0 +1,29 @@
/* -*- 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 mozilla_MiddleCroppingLabelFrame_h
#define mozilla_MiddleCroppingLabelFrame_h
#include "MiddleCroppingBlockFrame.h"
namespace mozilla {
// A frame for a <xul:label> or <xul:description> with crop="center"
class MiddleCroppingLabelFrame final : public MiddleCroppingBlockFrame {
public:
NS_DECL_QUERYFRAME
NS_DECL_FRAMEARENA_HELPERS(MiddleCroppingLabelFrame)
MiddleCroppingLabelFrame(ComputedStyle* aStyle, nsPresContext* aPresContext)
: MiddleCroppingBlockFrame(aStyle, aPresContext, kClassID) {}
void GetUncroppedValue(nsAString& aValue) override;
nsresult AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute,
int32_t aModType) override;
};
} // namespace mozilla
#endif

View File

@@ -19,6 +19,7 @@ EXPORTS += [
]
UNIFIED_SOURCES += [
"MiddleCroppingLabelFrame.cpp",
"nsBox.cpp",
"nsBoxLayoutState.cpp",
"nsLeafBoxFrame.cpp",
@@ -28,7 +29,6 @@ UNIFIED_SOURCES += [
"nsScrollbarFrame.cpp",
"nsSliderFrame.cpp",
"nsSplitterFrame.cpp",
"nsTextBoxFrame.cpp",
"nsXULPopupManager.cpp",
"nsXULTooltipListener.cpp",
"SimpleXULLeafFrame.cpp",

File diff suppressed because it is too large Load Diff

View File

@@ -1,128 +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 nsTextBoxFrame_h___
#define nsTextBoxFrame_h___
#include "mozilla/Attributes.h"
#include "nsLeafBoxFrame.h"
class nsAccessKeyInfo;
class nsAsyncAccesskeyUpdate;
class nsFontMetrics;
namespace mozilla {
class nsDisplayXULTextBox;
class PresShell;
} // namespace mozilla
class nsTextBoxFrame final : public nsLeafBoxFrame {
public:
NS_DECL_QUERYFRAME
NS_DECL_FRAMEARENA_HELPERS(nsTextBoxFrame)
virtual nsSize GetXULPrefSize(nsBoxLayoutState& aBoxLayoutState) override;
virtual nsSize GetXULMinSize(nsBoxLayoutState& aBoxLayoutState) override;
virtual nscoord GetXULBoxAscent(nsBoxLayoutState& aBoxLayoutState) override;
NS_IMETHOD DoXULLayout(nsBoxLayoutState& aBoxLayoutState) override;
virtual void MarkIntrinsicISizesDirty() override;
enum CroppingStyle { CropNone, CropLeft, CropRight, CropCenter, CropAuto };
friend nsIFrame* NS_NewTextBoxFrame(mozilla::PresShell* aPresShell,
ComputedStyle* aStyle);
virtual void Init(nsIContent* aContent, nsContainerFrame* aParent,
nsIFrame* asPrevInFlow) override;
virtual nsresult AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute,
int32_t aModType) override;
#ifdef DEBUG_FRAME_DUMP
virtual nsresult GetFrameName(nsAString& aResult) const override;
#endif
void UpdateAttributes(nsAtom* aAttribute, bool& aResize, bool& aRedraw);
virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsDisplayListSet& aLists) override;
virtual ~nsTextBoxFrame();
void PaintTitle(gfxContext& aRenderingContext, const nsRect& aDirtyRect,
nsPoint aPt, const nscolor* aOverrideColor);
nsRect GetComponentAlphaBounds() const;
virtual bool XULComputesOwnOverflowArea() override;
void GetCroppedTitle(nsString& aTitle) const { aTitle = mCroppedTitle; }
virtual void DidSetComputedStyle(ComputedStyle* aOldComputedStyle) override;
// Helper for GetCroppedTitle, factored out so that we can also use it from
// nsTreeBodyFrame::AdjustForCellText.
static void CropStringForWidth(nsAString& aText,
gfxContext& aRenderingContext,
nsFontMetrics& aFontMetrics, nscoord aWidth,
CroppingStyle aCropType);
static bool AlwaysAppendAccessKey();
static bool InsertSeparatorBeforeAccessKey();
protected:
friend class nsAsyncAccesskeyUpdate;
friend class mozilla::nsDisplayXULTextBox;
// Should be called only by nsAsyncAccesskeyUpdate.
// Returns true if accesskey was updated.
bool UpdateAccesskey(WeakFrame& aWeakThis);
void UpdateAccessTitle();
void UpdateAccessIndex();
// Recompute our title, ignoring the access key but taking into
// account text-transform.
void RecomputeTitle();
// REVIEW: SORRY! Couldn't resist devirtualizing these
void LayoutTitle(nsPresContext* aPresContext, gfxContext& aRenderingContext,
const nsRect& aRect);
void CalculateUnderline(DrawTarget* aDrawTarget, nsFontMetrics& aFontMetrics);
void CalcTextSize(nsBoxLayoutState& aBoxLayoutState);
void CalcDrawRect(gfxContext& aRenderingContext);
explicit nsTextBoxFrame(ComputedStyle* aStyle, nsPresContext* aPresContext);
nscoord CalculateTitleForWidth(gfxContext& aRenderingContext, nscoord aWidth);
void GetTextSize(gfxContext& aRenderingContext, const nsString& aString,
nsSize& aSize, nscoord& aAscent);
private:
void DrawText(gfxContext& aRenderingContext, const nsRect& aDirtyRect,
const nsRect& aTextRect, const nscolor* aOverrideColor);
nsString mTitle;
nsString mCroppedTitle;
nsString mAccessKey;
nsSize mTextSize;
nsRect mTextDrawRect;
nsAccessKeyInfo* mAccessKeyInfo;
CroppingStyle mCropType;
nscoord mAscent;
bool mNeedsRecalc;
bool mNeedsReflowCallback;
static bool gAlwaysAppendAccessKey;
static bool gAccessKeyPrefInitialized;
static bool gInsertSeparatorBeforeAccessKey;
static bool gInsertSeparatorPrefInitialized;
}; // class nsTextBoxFrame
#endif /* nsTextBoxFrame_h___ */

View File

@@ -39,6 +39,7 @@
#include "mozilla/ComputedStyle.h"
#include "mozilla/dom/Document.h"
#include "mozilla/dom/ReferrerInfo.h"
#include "mozilla/intl/Segmenter.h"
#include "nsCSSRendering.h"
#include "nsString.h"
#include "nsContainerFrame.h"
@@ -48,7 +49,6 @@
#include "nsWidgetsCID.h"
#include "nsIFrameInlines.h"
#include "nsBoxLayoutState.h"
#include "nsTextBoxFrame.h"
#include "nsTreeContentView.h"
#include "nsTreeUtils.h"
#include "nsStyleConsts.h"
@@ -80,6 +80,129 @@ using namespace mozilla::gfx;
using namespace mozilla::image;
using namespace mozilla::layout;
enum CroppingStyle { CropNone, CropLeft, CropRight, CropCenter, CropAuto };
// FIXME: Maybe unify with MiddleCroppingBlockFrame?
static void CropStringForWidth(nsAString& aText, gfxContext& aRenderingContext,
nsFontMetrics& aFontMetrics, nscoord aWidth,
CroppingStyle aCropType) {
DrawTarget* drawTarget = aRenderingContext.GetDrawTarget();
// See if the width is even smaller than the ellipsis
// If so, clear the text completely.
const nsDependentString& kEllipsis = nsContentUtils::GetLocalizedEllipsis();
aFontMetrics.SetTextRunRTL(false);
nscoord ellipsisWidth =
nsLayoutUtils::AppUnitWidthOfString(kEllipsis, aFontMetrics, drawTarget);
if (ellipsisWidth > aWidth) {
aText.Truncate(0);
return;
}
if (ellipsisWidth == aWidth) {
aText.Assign(kEllipsis);
return;
}
// We will be drawing an ellipsis, thank you very much.
// Subtract out the required width of the ellipsis.
// This is the total remaining width we have to play with.
aWidth -= ellipsisWidth;
using mozilla::intl::GraphemeClusterBreakIteratorUtf16;
using mozilla::intl::GraphemeClusterBreakReverseIteratorUtf16;
// Now we crop. This is quite basic: it will not be really accurate in the
// presence of complex scripts with contextual shaping, etc., as it measures
// each grapheme cluster in isolation, not in its proper context.
switch (aCropType) {
case CropAuto:
case CropNone:
case CropRight: {
const Span text(aText);
GraphemeClusterBreakIteratorUtf16 iter(text);
uint32_t pos = 0;
nscoord totalWidth = 0;
while (Maybe<uint32_t> nextPos = iter.Next()) {
const nscoord charWidth = nsLayoutUtils::AppUnitWidthOfString(
text.FromTo(pos, *nextPos), aFontMetrics, drawTarget);
if (totalWidth + charWidth > aWidth) {
break;
}
pos = *nextPos;
totalWidth += charWidth;
}
if (pos < aText.Length()) {
aText.Replace(pos, aText.Length() - pos, kEllipsis);
}
} break;
case CropLeft: {
const Span text(aText);
GraphemeClusterBreakReverseIteratorUtf16 iter(text);
uint32_t pos = text.Length();
nscoord totalWidth = 0;
// nextPos is decreasing since we use a reverse iterator.
while (Maybe<uint32_t> nextPos = iter.Next()) {
const nscoord charWidth = nsLayoutUtils::AppUnitWidthOfString(
text.FromTo(*nextPos, pos), aFontMetrics, drawTarget);
if (totalWidth + charWidth > aWidth) {
break;
}
pos = *nextPos;
totalWidth += charWidth;
}
if (pos > 0) {
aText.Replace(0, pos, kEllipsis);
}
} break;
case CropCenter: {
const Span text(aText);
nscoord totalWidth = 0;
GraphemeClusterBreakIteratorUtf16 leftIter(text);
GraphemeClusterBreakReverseIteratorUtf16 rightIter(text);
uint32_t leftPos = 0;
uint32_t rightPos = text.Length();
while (leftPos < rightPos) {
Maybe<uint32_t> nextPos = leftIter.Next();
nscoord charWidth = nsLayoutUtils::AppUnitWidthOfString(
text.FromTo(leftPos, *nextPos), aFontMetrics, drawTarget);
if (totalWidth + charWidth > aWidth) {
break;
}
leftPos = *nextPos;
totalWidth += charWidth;
if (leftPos >= rightPos) {
break;
}
nextPos = rightIter.Next();
charWidth = nsLayoutUtils::AppUnitWidthOfString(
text.FromTo(*nextPos, rightPos), aFontMetrics, drawTarget);
if (totalWidth + charWidth > aWidth) {
break;
}
rightPos = *nextPos;
totalWidth += charWidth;
}
if (leftPos < rightPos) {
aText.Replace(leftPos, rightPos - leftPos, kEllipsis);
}
} break;
}
}
// Function that cancels all the image requests in our cache.
void nsTreeBodyFrame::CancelImageRequests() {
for (nsTreeImageCacheEntry entry : mImageCache.Values()) {
@@ -1194,15 +1317,14 @@ void nsTreeBodyFrame::AdjustForCellText(nsAutoString& aText, int32_t aRowIndex,
}
}
using CroppingStyle = nsTextBoxFrame::CroppingStyle;
CroppingStyle cropType = CroppingStyle::CropRight;
if (aColumn->GetCropStyle() == 1) {
cropType = CroppingStyle::CropCenter;
} else if (aColumn->GetCropStyle() == 2) {
cropType = CroppingStyle::CropLeft;
}
nsTextBoxFrame::CropStringForWidth(aText, aRenderingContext, aFontMetrics,
maxWidth, cropType);
CropStringForWidth(aText, aRenderingContext, aFontMetrics, maxWidth,
cropType);
nscoord width = nsLayoutUtils::AppUnitWidthOfStringBidi(
aText, this, aFontMetrics, aRenderingContext);