layout/generic/nsPlaceholderFrame.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/layout/generic/nsPlaceholderFrame.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,168 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +/*
    1.10 + * rendering object for the point that anchors out-of-flow rendering
    1.11 + * objects such as floats and absolutely positioned elements
    1.12 + */
    1.13 +
    1.14 +/*
    1.15 + * Destruction of a placeholder and its out-of-flow must observe the
    1.16 + * following constraints:
    1.17 + *
    1.18 + * - The mapping from the out-of-flow to the placeholder must be
    1.19 + *   removed from the frame manager before the placeholder is destroyed.
    1.20 + * - The mapping from the out-of-flow to the placeholder must be
    1.21 + *   removed from the frame manager before the out-of-flow is destroyed.
    1.22 + * - The placeholder must be removed from the frame tree, or have the
    1.23 + *   mapping from it to its out-of-flow cleared, before the out-of-flow
    1.24 + *   is destroyed (so that the placeholder will not point to a destroyed
    1.25 + *   frame while it's in the frame tree).
    1.26 + *
    1.27 + * Furthermore, some code assumes that placeholders point to something
    1.28 + * useful, so placeholders without an associated out-of-flow should not
    1.29 + * remain in the tree.
    1.30 + *
    1.31 + * The placeholder's Destroy() implementation handles the destruction of
    1.32 + * the placeholder and its out-of-flow. To avoid crashes, frame removal
    1.33 + * and destruction code that works with placeholders must not assume
    1.34 + * that the placeholder points to its out-of-flow.
    1.35 + */
    1.36 +
    1.37 +#ifndef nsPlaceholderFrame_h___
    1.38 +#define nsPlaceholderFrame_h___
    1.39 +
    1.40 +#include "mozilla/Attributes.h"
    1.41 +#include "nsFrame.h"
    1.42 +#include "nsGkAtoms.h"
    1.43 +
    1.44 +nsIFrame* NS_NewPlaceholderFrame(nsIPresShell* aPresShell,
    1.45 +                                 nsStyleContext* aContext,
    1.46 +                                 nsFrameState aTypeBit);
    1.47 +
    1.48 +#define PLACEHOLDER_TYPE_MASK    (PLACEHOLDER_FOR_FLOAT | \
    1.49 +                                  PLACEHOLDER_FOR_ABSPOS | \
    1.50 +                                  PLACEHOLDER_FOR_FIXEDPOS | \
    1.51 +                                  PLACEHOLDER_FOR_POPUP)
    1.52 +
    1.53 +/**
    1.54 + * Implementation of a frame that's used as a placeholder for a frame that
    1.55 + * has been moved out of the flow.
    1.56 + */
    1.57 +class nsPlaceholderFrame MOZ_FINAL : public nsFrame {
    1.58 +public:
    1.59 +  NS_DECL_FRAMEARENA_HELPERS
    1.60 +#ifdef DEBUG
    1.61 +  NS_DECL_QUERYFRAME_TARGET(nsPlaceholderFrame)
    1.62 +  NS_DECL_QUERYFRAME
    1.63 +#endif
    1.64 +
    1.65 +  /**
    1.66 +   * Create a new placeholder frame.  aTypeBit must be one of the
    1.67 +   * PLACEHOLDER_FOR_* constants above.
    1.68 +   */
    1.69 +  friend nsIFrame* NS_NewPlaceholderFrame(nsIPresShell* aPresShell,
    1.70 +                                          nsStyleContext* aContext,
    1.71 +                                          nsFrameState aTypeBit);
    1.72 +  nsPlaceholderFrame(nsStyleContext* aContext, nsFrameState aTypeBit)
    1.73 +    : nsFrame(aContext)
    1.74 +  {
    1.75 +    NS_PRECONDITION(aTypeBit == PLACEHOLDER_FOR_FLOAT ||
    1.76 +                    aTypeBit == PLACEHOLDER_FOR_ABSPOS ||
    1.77 +                    aTypeBit == PLACEHOLDER_FOR_FIXEDPOS ||
    1.78 +                    aTypeBit == PLACEHOLDER_FOR_POPUP,
    1.79 +                    "Unexpected type bit");
    1.80 +    AddStateBits(aTypeBit);
    1.81 +  }
    1.82 +
    1.83 +  // Get/Set the associated out of flow frame
    1.84 +  nsIFrame*  GetOutOfFlowFrame() const { return mOutOfFlowFrame; }
    1.85 +  void       SetOutOfFlowFrame(nsIFrame* aFrame) {
    1.86 +               NS_ASSERTION(!aFrame || !aFrame->GetPrevContinuation(),
    1.87 +                            "OOF must be first continuation");
    1.88 +               mOutOfFlowFrame = aFrame;
    1.89 +             }
    1.90 +
    1.91 +  // nsIFrame overrides
    1.92 +  // We need to override GetMinSize and GetPrefSize because XUL uses
    1.93 +  // placeholders not within lines.
    1.94 +  virtual void AddInlineMinWidth(nsRenderingContext* aRenderingContext,
    1.95 +                                 InlineMinWidthData* aData) MOZ_OVERRIDE;
    1.96 +  virtual void AddInlinePrefWidth(nsRenderingContext* aRenderingContext,
    1.97 +                                  InlinePrefWidthData* aData) MOZ_OVERRIDE;
    1.98 +  virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
    1.99 +  virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
   1.100 +  virtual nsSize GetMaxSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
   1.101 +
   1.102 +  virtual nsresult Reflow(nsPresContext* aPresContext,
   1.103 +                          nsHTMLReflowMetrics& aDesiredSize,
   1.104 +                          const nsHTMLReflowState& aReflowState,
   1.105 +                          nsReflowStatus& aStatus) MOZ_OVERRIDE;
   1.106 +
   1.107 +  virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
   1.108 +
   1.109 +#if defined(DEBUG) || (defined(MOZ_REFLOW_PERF_DSP) && defined(MOZ_REFLOW_PERF))
   1.110 +  virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
   1.111 +                                const nsRect&           aDirtyRect,
   1.112 +                                const nsDisplayListSet& aLists) MOZ_OVERRIDE;
   1.113 +#endif // DEBUG || (MOZ_REFLOW_PERF_DSP && MOZ_REFLOW_PERF)
   1.114 +  
   1.115 +#ifdef DEBUG_FRAME_DUMP
   1.116 +  void List(FILE* out = stderr, const char* aPrefix = "", uint32_t aFlags = 0) const MOZ_OVERRIDE;
   1.117 +  virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
   1.118 +#endif // DEBUG
   1.119 +
   1.120 +  /**
   1.121 +   * Get the "type" of the frame
   1.122 +   *
   1.123 +   * @see nsGkAtoms::placeholderFrame
   1.124 +   */
   1.125 +  virtual nsIAtom* GetType() const MOZ_OVERRIDE;
   1.126 +
   1.127 +  virtual bool IsEmpty() MOZ_OVERRIDE { return true; }
   1.128 +  virtual bool IsSelfEmpty() MOZ_OVERRIDE { return true; }
   1.129 +
   1.130 +  virtual bool CanContinueTextRun() const MOZ_OVERRIDE;
   1.131 +
   1.132 +#ifdef ACCESSIBILITY
   1.133 +  virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE
   1.134 +  {
   1.135 +    nsIFrame* realFrame = GetRealFrameForPlaceholder(this);
   1.136 +    return realFrame ? realFrame->AccessibleType() :
   1.137 +                       nsFrame::AccessibleType();
   1.138 +  }
   1.139 +#endif
   1.140 +
   1.141 +  virtual nsIFrame* GetParentStyleContextFrame() const MOZ_OVERRIDE;
   1.142 +
   1.143 +  /**
   1.144 +   * @return the out-of-flow for aFrame if aFrame is a placeholder; otherwise
   1.145 +   * aFrame
   1.146 +   */
   1.147 +  static nsIFrame* GetRealFrameFor(nsIFrame* aFrame) {
   1.148 +    NS_PRECONDITION(aFrame, "Must have a frame to work with");
   1.149 +    if (aFrame->GetType() == nsGkAtoms::placeholderFrame) {
   1.150 +      return GetRealFrameForPlaceholder(aFrame);
   1.151 +    }
   1.152 +    return aFrame;
   1.153 +  }
   1.154 +
   1.155 +  /**
   1.156 +   * @return the out-of-flow for aFrame, which is known to be a placeholder
   1.157 +   */
   1.158 +  static nsIFrame* GetRealFrameForPlaceholder(nsIFrame* aFrame) {
   1.159 +    NS_PRECONDITION(aFrame->GetType() == nsGkAtoms::placeholderFrame,
   1.160 +                    "Must have placeholder frame as input");
   1.161 +    nsIFrame* outOfFlow =
   1.162 +      static_cast<nsPlaceholderFrame*>(aFrame)->GetOutOfFlowFrame();
   1.163 +    NS_ASSERTION(outOfFlow, "Null out-of-flow for placeholder?");
   1.164 +    return outOfFlow;
   1.165 +  }
   1.166 +
   1.167 +protected:
   1.168 +  nsIFrame* mOutOfFlowFrame;
   1.169 +};
   1.170 +
   1.171 +#endif /* nsPlaceholderFrame_h___ */

mercurial