Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/layout/generic/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 8 kB image not shown  

Quelle  nsPlaceholderFrame.cpp   Sprache: 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/. */


/*
 * rendering object for the point that anchors out-of-flow rendering
 * objects such as floats and absolutely positioned elements
 */


#include "nsPlaceholderFrame.h"

#include "gfxContext.h"
#include "gfxUtils.h"
#include "mozilla/dom/ElementInlines.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/PresShell.h"
#include "mozilla/PresShellInlines.h"
#include "mozilla/ServoStyleSetInlines.h"
#include "nsCSSFrameConstructor.h"
#include "nsDisplayList.h"
#include "nsLayoutUtils.h"
#include "nsPresContext.h"
#include "nsPresContextInlines.h"
#include "nsIFrameInlines.h"
#include "nsIContentInlines.h"

using namespace mozilla;
using namespace mozilla::dom;
using namespace mozilla::gfx;

nsPlaceholderFrame* NS_NewPlaceholderFrame(PresShell* aPresShell,
                                           ComputedStyle* aStyle,
                                           nsFrameState aTypeBits) {
  return new (aPresShell)
      nsPlaceholderFrame(aStyle, aPresShell->GetPresContext(), aTypeBits);
}

NS_IMPL_FRAMEARENA_HELPERS(nsPlaceholderFrame)

#ifdef DEBUG
NS_QUERYFRAME_HEAD(nsPlaceholderFrame)
  NS_QUERYFRAME_ENTRY(nsPlaceholderFrame)
NS_QUERYFRAME_TAIL_INHERITING(nsIFrame)
#endif

/* virtual */
void nsPlaceholderFrame::AddInlineMinISize(const IntrinsicSizeInput& aInput,
                                           InlineMinISizeData* aData) {
  // Override AddInlineMinISize so that *nothing* happens. In
  // particular, we don't want to zero out |aData->mTrailingWhitespace|,
  // since nsLineLayout skips placeholders when trimming trailing
  // whitespace, and we don't want to set aData->mSkipWhitespace to
  // false.

  // ...but push floats onto aData's list.
  AddFloatToIntrinsicISizeData(aInput, IntrinsicISizeType::MinISize, aData);
}

/* virtual */
void nsPlaceholderFrame::AddInlinePrefISize(const IntrinsicSizeInput& aInput,
                                            InlinePrefISizeData* aData) {
  // Override AddInlinePrefISize so that *nothing* happens. In
  // particular, we don't want to zero out |aData->mTrailingWhitespace|,
  // since nsLineLayout skips placeholders when trimming trailing
  // whitespace, and we don't want to set aData->mSkipWhitespace to
  // false.

  // ...but push floats onto aData's list.
  AddFloatToIntrinsicISizeData(aInput, IntrinsicISizeType::PrefISize, aData);
}

void nsPlaceholderFrame::AddFloatToIntrinsicISizeData(
    const IntrinsicSizeInput& aInput, IntrinsicISizeType aType,
    InlineIntrinsicISizeData* aData) const {
  if (mOutOfFlowFrame->IsFloating()) {
    const IntrinsicSizeInput floatInput(
        aInput, mOutOfFlowFrame->GetWritingMode(), GetWritingMode());
    const nscoord floatISize = nsLayoutUtils::IntrinsicForContainer(
        floatInput.mContext, mOutOfFlowFrame, aType,
        floatInput.mPercentageBasisForChildren);
    aData->mFloats.EmplaceBack(mOutOfFlowFrame, floatISize);
  }
}

void nsPlaceholderFrame::Reflow(nsPresContext* aPresContext,
                                ReflowOutput& aDesiredSize,
                                const ReflowInput& aReflowInput,
                                nsReflowStatus& aStatus) {
  // NOTE that the ReflowInput passed to this method is not fully initialized,
  // on the grounds that reflowing a placeholder is a rather trivial operation.
  // (See bug 1367711.)

#ifdef DEBUG
  // We should be getting reflowed before our out-of-flow. If this is our first
  // reflow, and our out-of-flow has already received its first reflow (before
  // us), complain.
  //
  // Popups are an exception though, because their position doesn't depend on
  // the placeholder, so they don't have this requirement (and this condition
  // doesn't hold anyways because the default popupgroup goes before than the
  // default tooltip, for example).
  if (HasAnyStateBits(NS_FRAME_FIRST_REFLOW) &&
      !mOutOfFlowFrame->IsMenuPopupFrame() &&
      !mOutOfFlowFrame->HasAnyStateBits(NS_FRAME_FIRST_REFLOW)) {
    // Unfortunately, this can currently happen when the placeholder is in a
    // later continuation or later IB-split sibling than its out-of-flow (as
    // is the case in some of our existing unit tests). So for now, in that
    // case, we'll warn instead of asserting.
    bool isInContinuationOrIBSplit = false;
    nsIFrame* ancestor = this;
    while ((ancestor = ancestor->GetParent())) {
      if (nsLayoutUtils::GetPrevContinuationOrIBSplitSibling(ancestor)) {
        isInContinuationOrIBSplit = true;
        break;
      }
    }

    if (isInContinuationOrIBSplit) {
      NS_WARNING("Out-of-flow frame got reflowed before its placeholder");
    } else {
      NS_ERROR("Out-of-flow frame got reflowed before its placeholder");
    }
  }
#endif

  MarkInReflow();
  DO_GLOBAL_REFLOW_COUNT("nsPlaceholderFrame");
  MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
  aDesiredSize.ClearSize();
}

static FrameChildListID ChildListIDForOutOfFlow(nsFrameState aPlaceholderState,
                                                const nsIFrame* aChild) {
  if (aPlaceholderState & PLACEHOLDER_FOR_FLOAT) {
    return FrameChildListID::Float;
  }
  if (aPlaceholderState & PLACEHOLDER_FOR_FIXEDPOS) {
    return nsLayoutUtils::MayBeReallyFixedPos(aChild)
               ? FrameChildListID::Fixed
               : FrameChildListID::Absolute;
  }
  if (aPlaceholderState & PLACEHOLDER_FOR_ABSPOS) {
    return FrameChildListID::Absolute;
  }
  MOZ_DIAGNOSTIC_CRASH("unknown list");
  return FrameChildListID::Float;
}

void nsPlaceholderFrame::Destroy(DestroyContext& aContext) {
  if (nsIFrame* oof = mOutOfFlowFrame) {
    mOutOfFlowFrame = nullptr;
    oof->RemoveProperty(nsIFrame::PlaceholderFrameProperty());

    // Destroy the out of flow now.
    ChildListID listId = ChildListIDForOutOfFlow(GetStateBits(), oof);
    nsFrameManager* fm = PresContext()->FrameConstructor();
    fm->RemoveFrame(aContext, listId, oof);
  }

  nsIFrame::Destroy(aContext);
}

/* virtual */
bool nsPlaceholderFrame::CanContinueTextRun() const {
  if (!mOutOfFlowFrame) {
    return false;
  }
  // first-letter frames can continue text runs, and placeholders for floated
  // first-letter frames can too
  return mOutOfFlowFrame->CanContinueTextRun();
}

ComputedStyle* nsPlaceholderFrame::GetParentComputedStyleForOutOfFlow(
    nsIFrame** aProviderFrame) const {
  MOZ_ASSERT(GetParent(), "How can we not have a parent here?");

  Element* parentElement =
      mContent ? mContent->GetFlattenedTreeParentElement() : nullptr;
  // See the similar code in nsIFrame::DoGetParentComputedStyle.
  if (parentElement && MOZ_LIKELY(parentElement->HasServoData()) &&
      Servo_Element_IsDisplayContents(parentElement)) {
    RefPtr<ComputedStyle> style =
        ServoStyleSet::ResolveServoStyle(*parentElement);
    *aProviderFrame = nullptr;
    // See the comment in GetParentComputedStyle to see why returning this as a
    // weak ref is fine.
    return style;
  }

  return GetLayoutParentStyleForOutOfFlow(aProviderFrame);
}

ComputedStyle* nsPlaceholderFrame::GetLayoutParentStyleForOutOfFlow(
    nsIFrame** aProviderFrame) const {
  // Lie about our pseudo so we can step out of all anon boxes and
  // pseudo-elements.  The other option would be to reimplement the
  // {ib} split gunk here.
  //
  // See the hack in CorrectStyleParentFrame for why we pass `MAX`.
  *aProviderFrame = CorrectStyleParentFrame(GetParent(), PseudoStyleType::MAX);
  return *aProviderFrame ? (*aProviderFrame)->Style() : nullptr;
}

#if defined(DEBUG) || (defined(MOZ_REFLOW_PERF_DSP) && defined(MOZ_REFLOW_PERF))

void nsPlaceholderFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
                                          const nsDisplayListSet& aLists) {
  DO_GLOBAL_REFLOW_COUNT_DSP("nsPlaceholderFrame");
}
#endif  // DEBUG || (MOZ_REFLOW_PERF_DSP && MOZ_REFLOW_PERF)

#ifdef DEBUG_FRAME_DUMP
nsresult nsPlaceholderFrame::GetFrameName(nsAString& aResult) const {
  return MakeFrameName(u"Placeholder"_ns, aResult);
}

void nsPlaceholderFrame::List(FILE* out, const char* aPrefix,
                              ListFlags aFlags) const {
  nsCString str;
  ListGeneric(str, aPrefix, aFlags);

  if (mOutOfFlowFrame) {
    str += " outOfFlowFrame=";
    str += mOutOfFlowFrame->ListTag();
  }
  fprintf_stderr(out, "%s\n", str.get());
}
#endif

Messung V0.5
C=93 H=100 G=96

¤ Dauer der Verarbeitung: 0.1 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.