tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nsCheckboxRadioFrame.cpp (5531B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "nsCheckboxRadioFrame.h"
      8 
      9 #include "mozilla/PresShell.h"
     10 #include "nsIContent.h"
     11 #include "nsLayoutUtils.h"
     12 
     13 using namespace mozilla;
     14 
     15 nsCheckboxRadioFrame* NS_NewCheckboxRadioFrame(PresShell* aPresShell,
     16                                               ComputedStyle* aStyle) {
     17  return new (aPresShell)
     18      nsCheckboxRadioFrame(aStyle, aPresShell->GetPresContext());
     19 }
     20 
     21 nsCheckboxRadioFrame::nsCheckboxRadioFrame(ComputedStyle* aStyle,
     22                                           nsPresContext* aPresContext)
     23    : nsAtomicContainerFrame(aStyle, aPresContext, kClassID) {}
     24 
     25 nsCheckboxRadioFrame::~nsCheckboxRadioFrame() = default;
     26 
     27 NS_IMPL_FRAMEARENA_HELPERS(nsCheckboxRadioFrame)
     28 
     29 NS_QUERYFRAME_HEAD(nsCheckboxRadioFrame)
     30 NS_QUERYFRAME_TAIL_INHERITING(nsAtomicContainerFrame)
     31 
     32 nscoord nsCheckboxRadioFrame::DefaultSize() {
     33  const CSSCoord size = StyleDisplay()->HasAppearance()
     34                            ? PresContext()->Theme()->GetCheckboxRadioPrefSize()
     35                            : CSSCoord(13.0f);
     36  return CSSPixel::ToAppUnits(Style()->EffectiveZoom().Zoom(size));
     37 }
     38 
     39 /* virtual */
     40 void nsCheckboxRadioFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
     41                                            const nsDisplayListSet& aLists) {
     42  DO_GLOBAL_REFLOW_COUNT_DSP("nsCheckboxRadioFrame");
     43  DisplayBorderBackgroundOutline(aBuilder, aLists);
     44 }
     45 
     46 nscoord nsCheckboxRadioFrame::IntrinsicISize(const IntrinsicSizeInput& aInput,
     47                                             IntrinsicISizeType aType) {
     48  return StyleDisplay()->HasAppearance() ? DefaultSize() : 0;
     49 }
     50 
     51 /* virtual */
     52 LogicalSize nsCheckboxRadioFrame::ComputeAutoSize(
     53    const SizeComputationInput& aSizingInput, WritingMode aWM,
     54    const LogicalSize& aCBSize, nscoord aAvailableISize,
     55    const LogicalSize& aMargin, const LogicalSize& aBorderPadding,
     56    const StyleSizeOverrides& aSizeOverrides, ComputeSizeFlags aFlags) {
     57  LogicalSize size(aWM, 0, 0);
     58  if (!StyleDisplay()->HasAppearance()) {
     59    return size;
     60  }
     61  return nsAtomicContainerFrame::ComputeAutoSize(
     62      aSizingInput, aWM, aCBSize, aAvailableISize, aMargin, aBorderPadding,
     63      aSizeOverrides, aFlags);
     64 }
     65 
     66 Maybe<nscoord> nsCheckboxRadioFrame::GetNaturalBaselineBOffset(
     67    WritingMode aWM, BaselineSharingGroup aBaselineGroup,
     68    BaselineExportContext) const {
     69  NS_ASSERTION(!IsSubtreeDirty(), "frame must not be dirty");
     70 
     71  if (aBaselineGroup == BaselineSharingGroup::Last) {
     72    return Nothing{};
     73  }
     74 
     75  if (StyleDisplay()->IsBlockOutsideStyle()) {
     76    return Nothing{};
     77  }
     78 
     79  // For appearance:none we use a standard CSS baseline, i.e. synthesized from
     80  // our margin-box.
     81  if (!StyleDisplay()->HasAppearance()) {
     82    return Nothing{};
     83  }
     84 
     85  if (aWM.IsCentralBaseline()) {
     86    return Some(BSize(aWM) / 2);
     87  }
     88 
     89  // This is for compatibility with Chrome, Safari and Edge (Dec 2016).
     90  // Treat radio buttons and checkboxes as having an intrinsic baseline
     91  // at the block-end of the control (use the block-end content edge rather
     92  // than the margin edge).
     93  // For "inverted" lines (typically in writing-mode:vertical-lr), use the
     94  // block-start end instead.
     95  // See kCheckboxRadioBorderWidth in Theme.cpp
     96  CSSCoord border = PresContext()->Theme()->GetCheckboxRadioBorderWidth();
     97  auto bp = CSSPixel::ToAppUnits(Style()->EffectiveZoom().Zoom(border));
     98  return Some(aWM.IsLineInverted() ? std::min(bp, BSize(aWM))
     99                                   : std::max(0, BSize(aWM) - bp));
    100 }
    101 
    102 void nsCheckboxRadioFrame::Reflow(nsPresContext* aPresContext,
    103                                  ReflowOutput& aDesiredSize,
    104                                  const ReflowInput& aReflowInput,
    105                                  nsReflowStatus& aStatus) {
    106  MarkInReflow();
    107  DO_GLOBAL_REFLOW_COUNT("nsCheckboxRadioFrame");
    108  MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
    109  NS_FRAME_TRACE(
    110      NS_FRAME_TRACE_CALLS,
    111      ("enter nsCheckboxRadioFrame::Reflow: aMaxSize=%d,%d",
    112       aReflowInput.AvailableWidth(), aReflowInput.AvailableHeight()));
    113 
    114  const auto wm = aReflowInput.GetWritingMode();
    115  MOZ_ASSERT(aReflowInput.ComputedLogicalBorderPadding(wm).IsAllZero());
    116 
    117  const auto contentBoxSize =
    118      aReflowInput.ComputedSizeWithBSizeFallback([&] { return DefaultSize(); });
    119  aDesiredSize.SetSize(wm, contentBoxSize);
    120  if (nsLayoutUtils::FontSizeInflationEnabled(aPresContext)) {
    121    const float inflation = nsLayoutUtils::FontSizeInflationFor(this);
    122    aDesiredSize.Width() *= inflation;
    123    aDesiredSize.Height() *= inflation;
    124  }
    125 
    126  NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,
    127                 ("exit nsCheckboxRadioFrame::Reflow: size=%d,%d",
    128                  aDesiredSize.Width(), aDesiredSize.Height()));
    129 
    130  aDesiredSize.SetOverflowAreasToDesiredBounds();
    131  FinishAndStoreOverflow(&aDesiredSize);
    132 }
    133 
    134 nsresult nsCheckboxRadioFrame::HandleEvent(nsPresContext* aPresContext,
    135                                           WidgetGUIEvent* aEvent,
    136                                           nsEventStatus* aEventStatus) {
    137  // Check for disabled content so that selection works properly (?).
    138  if (IsContentDisabled()) {
    139    return nsIFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
    140  }
    141  return NS_OK;
    142 }