tor-browser

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

nsDateTimeControlFrame.cpp (6896B)


      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 /**
      8 * This frame type is used for input type=date, time, month, week, and
      9 * datetime-local.
     10 */
     11 
     12 #include "nsDateTimeControlFrame.h"
     13 
     14 #include "mozilla/PresShell.h"
     15 #include "nsLayoutUtils.h"
     16 #include "nsTextControlFrame.h"
     17 
     18 using namespace mozilla;
     19 using namespace mozilla::dom;
     20 
     21 nsIFrame* NS_NewDateTimeControlFrame(PresShell* aPresShell,
     22                                     ComputedStyle* aStyle) {
     23  return new (aPresShell)
     24      nsDateTimeControlFrame(aStyle, aPresShell->GetPresContext());
     25 }
     26 
     27 NS_IMPL_FRAMEARENA_HELPERS(nsDateTimeControlFrame)
     28 
     29 NS_QUERYFRAME_HEAD(nsDateTimeControlFrame)
     30  NS_QUERYFRAME_ENTRY(nsDateTimeControlFrame)
     31 NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
     32 
     33 nsDateTimeControlFrame::nsDateTimeControlFrame(ComputedStyle* aStyle,
     34                                               nsPresContext* aPresContext)
     35    : nsContainerFrame(aStyle, aPresContext, kClassID) {}
     36 
     37 nscoord nsDateTimeControlFrame::IntrinsicISize(const IntrinsicSizeInput& aInput,
     38                                               IntrinsicISizeType aType) {
     39  return mFrames.IsEmpty() ? 0
     40                           : nsLayoutUtils::IntrinsicForContainer(
     41                                 aInput.mContext, mFrames.FirstChild(), aType);
     42 }
     43 
     44 Maybe<nscoord> nsDateTimeControlFrame::GetNaturalBaselineBOffset(
     45    WritingMode aWM, BaselineSharingGroup aBaselineGroup,
     46    BaselineExportContext) const {
     47  return nsTextControlFrame::GetSingleLineTextControlBaseline(
     48      this, mFirstBaseline, aWM, aBaselineGroup);
     49 }
     50 
     51 void nsDateTimeControlFrame::Reflow(nsPresContext* aPresContext,
     52                                    ReflowOutput& aDesiredSize,
     53                                    const ReflowInput& aReflowInput,
     54                                    nsReflowStatus& aStatus) {
     55  MarkInReflow();
     56 
     57  DO_GLOBAL_REFLOW_COUNT("nsDateTimeControlFrame");
     58  MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
     59  NS_FRAME_TRACE(
     60      NS_FRAME_TRACE_CALLS,
     61      ("enter nsDateTimeControlFrame::Reflow: availSize=%d,%d",
     62       aReflowInput.AvailableWidth(), aReflowInput.AvailableHeight()));
     63 
     64  NS_ASSERTION(mFrames.GetLength() <= 1,
     65               "There should be no more than 1 frames");
     66 
     67  const WritingMode myWM = aReflowInput.GetWritingMode();
     68 
     69  {
     70    auto baseline = nsTextControlFrame::ComputeBaseline(
     71        this, aReflowInput, /* aForSingleLineControl = */ true);
     72    mFirstBaseline = baseline.valueOr(NS_INTRINSIC_ISIZE_UNKNOWN);
     73    if (baseline) {
     74      aDesiredSize.SetBlockStartAscent(*baseline);
     75    }
     76  }
     77 
     78  // The ISize of our content box, which is the available ISize
     79  // for our anonymous content:
     80  const nscoord contentBoxISize = aReflowInput.ComputedISize();
     81  nscoord contentBoxBSize = aReflowInput.ComputedBSize();
     82 
     83  // Figure out our border-box sizes as well (by adding borderPadding to
     84  // content-box sizes):
     85  const auto borderPadding = aReflowInput.ComputedLogicalBorderPadding(myWM);
     86  const nscoord borderBoxISize =
     87      contentBoxISize + borderPadding.IStartEnd(myWM);
     88 
     89  nscoord borderBoxBSize;
     90  if (contentBoxBSize != NS_UNCONSTRAINEDSIZE) {
     91    borderBoxBSize = contentBoxBSize + borderPadding.BStartEnd(myWM);
     92  }  // else, we'll figure out borderBoxBSize after we resolve contentBoxBSize.
     93 
     94  nsIFrame* inputAreaFrame = mFrames.FirstChild();
     95  if (!inputAreaFrame) {  // display:none?
     96    if (contentBoxBSize == NS_UNCONSTRAINEDSIZE) {
     97      contentBoxBSize = 0;
     98      borderBoxBSize = borderPadding.BStartEnd(myWM);
     99    }
    100  } else {
    101    ReflowOutput childDesiredSize(aReflowInput);
    102 
    103    WritingMode wm = inputAreaFrame->GetWritingMode();
    104    LogicalSize availSize = aReflowInput.ComputedSize(wm);
    105    availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
    106 
    107    ReflowInput childReflowInput(aPresContext, aReflowInput, inputAreaFrame,
    108                                 availSize);
    109 
    110    // Convert input area margin into my own writing-mode (in case it differs):
    111    LogicalMargin childMargin = childReflowInput.ComputedLogicalMargin(myWM);
    112 
    113    // offsets of input area frame within this frame:
    114    LogicalPoint childOffset =
    115        borderPadding.StartOffset(myWM) + childMargin.StartOffset(myWM);
    116 
    117    nsReflowStatus childStatus;
    118    // We initially reflow the child with a dummy containerSize; positioning
    119    // will be fixed later.
    120    const nsSize dummyContainerSize;
    121    ReflowChild(inputAreaFrame, aPresContext, childDesiredSize,
    122                childReflowInput, myWM, childOffset, dummyContainerSize,
    123                ReflowChildFlags::Default, childStatus);
    124    MOZ_ASSERT(childStatus.IsFullyComplete(),
    125               "We gave our child unconstrained available block-size, "
    126               "so it should be complete");
    127 
    128    nscoord childMarginBoxBSize =
    129        childDesiredSize.BSize(myWM) + childMargin.BStartEnd(myWM);
    130 
    131    if (contentBoxBSize == NS_UNCONSTRAINEDSIZE) {
    132      // We are intrinsically sized -- we should shrinkwrap the input area's
    133      // block-size, or our line-height:
    134      contentBoxBSize =
    135          std::max(aReflowInput.GetLineHeight(), childMarginBoxBSize);
    136 
    137      // Make sure we obey min/max-bsize in the case when we're doing intrinsic
    138      // sizing (we get it for free when we have a non-intrinsic
    139      // aReflowInput.ComputedBSize()).  Note that we do this before
    140      // adjusting for borderpadding, since ComputedMaxBSize and
    141      // ComputedMinBSize are content heights.
    142      contentBoxBSize = aReflowInput.ApplyMinMaxBSize(contentBoxBSize);
    143 
    144      borderBoxBSize = contentBoxBSize + borderPadding.BStartEnd(myWM);
    145    }
    146 
    147    // Center child in block axis
    148    nscoord extraSpace = contentBoxBSize - childMarginBoxBSize;
    149    childOffset.B(myWM) += std::max(0, extraSpace / 2);
    150 
    151    // Needed in FinishReflowChild, for logical-to-physical conversion:
    152    nsSize borderBoxSize =
    153        LogicalSize(myWM, borderBoxISize, borderBoxBSize).GetPhysicalSize(myWM);
    154 
    155    // Place the child
    156    FinishReflowChild(inputAreaFrame, aPresContext, childDesiredSize,
    157                      &childReflowInput, myWM, childOffset, borderBoxSize,
    158                      ReflowChildFlags::Default);
    159  }
    160 
    161  LogicalSize logicalDesiredSize(myWM, borderBoxISize, borderBoxBSize);
    162  aDesiredSize.SetSize(myWM, logicalDesiredSize);
    163  aDesiredSize.SetOverflowAreasToDesiredBounds();
    164 
    165  if (inputAreaFrame) {
    166    ConsiderChildOverflow(aDesiredSize.mOverflowAreas, inputAreaFrame);
    167  }
    168 
    169  FinishAndStoreOverflow(&aDesiredSize);
    170 
    171  NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,
    172                 ("exit nsDateTimeControlFrame::Reflow: size=%d,%d",
    173                  aDesiredSize.Width(), aDesiredSize.Height()));
    174 }