Back to index

lightning-sunbird  0.9+nobinonly
nsContainerFrame.cpp File Reference
#include "nsContainerFrame.h"
#include "nsIContent.h"
#include "nsIDocument.h"
#include "nsPresContext.h"
#include "nsIRenderingContext.h"
#include "nsStyleContext.h"
#include "nsRect.h"
#include "nsPoint.h"
#include "nsGUIEvent.h"
#include "nsStyleConsts.h"
#include "nsIView.h"
#include "nsIScrollableView.h"
#include "nsVoidArray.h"
#include "nsHTMLContainerFrame.h"
#include "nsFrameManager.h"
#include "nsIPresShell.h"
#include "nsCOMPtr.h"
#include "nsLayoutAtoms.h"
#include "nsCSSAnonBoxes.h"
#include "nsIViewManager.h"
#include "nsIWidget.h"
#include "nsGfxCIID.h"
#include "nsIServiceManager.h"
#include "nsCSSRendering.h"
#include "nsTransform2D.h"
#include "nsRegion.h"
#include "nsLayoutErrors.h"

Go to the source code of this file.


static void CleanupGeneratedContentIn (nsIContent *aRealContent, nsIFrame *aRoot)
static PRBool NonZeroStyleCoord (const nsStyleCoord &aCoord)
static PRBool HasNonZeroBorderRadius (nsStyleContext *aStyleContext)
static void SyncFrameViewGeometryDependentProperties (nsPresContext *aPresContext, nsIFrame *aFrame, nsStyleContext *aStyleContext, nsIView *aView, PRUint32 aFlags)
static void DestroyOverflowFrames (void *aFrame, nsIAtom *aPropertyName, void *aPropertyValue, void *aDtorData)

Function Documentation

static void CleanupGeneratedContentIn ( nsIContent aRealContent,
nsIFrame aRoot 
) [static]

Definition at line 125 of file nsContainerFrame.cpp.

  nsIAtom* frameList = nsnull;
  PRInt32 listIndex = 0;
  do {
    nsIFrame* child = aRoot->GetFirstChild(frameList);
    while (child) {
      nsIContent* content = child->GetContent();
      if (content && content != aRealContent) {
      ::CleanupGeneratedContentIn(aRealContent, child);
      child = child->GetNextSibling();
    frameList = aRoot->GetAdditionalChildListName(listIndex++);
  } while (frameList);

Here is the call graph for this function:

Here is the caller graph for this function:

static void DestroyOverflowFrames ( void aFrame,
nsIAtom aPropertyName,
void aPropertyValue,
void aDtorData 
) [static]

Definition at line 1111 of file nsContainerFrame.cpp.

  if (aPropertyValue) {
    nsFrameList frames((nsIFrame*)aPropertyValue);

    frames.DestroyFrames(NS_STATIC_CAST(nsPresContext*, aDtorData));

Here is the call graph for this function:

Here is the caller graph for this function:

static PRBool HasNonZeroBorderRadius ( nsStyleContext aStyleContext) [static]

Definition at line 458 of file nsContainerFrame.cpp.

  const nsStyleBorder* border = aStyleContext->GetStyleBorder();

  nsStyleCoord coord;
  if (NonZeroStyleCoord(coord)) return PR_TRUE;    
  if (NonZeroStyleCoord(coord)) return PR_TRUE;    
  if (NonZeroStyleCoord(coord)) return PR_TRUE;    
  if (NonZeroStyleCoord(coord)) return PR_TRUE;    

  return PR_FALSE;

Here is the call graph for this function:

Here is the caller graph for this function:

static PRBool NonZeroStyleCoord ( const nsStyleCoord aCoord) [static]

Definition at line 444 of file nsContainerFrame.cpp.

  switch (aCoord.GetUnit()) {
  case eStyleUnit_Percent:
    return aCoord.GetPercentValue() > 0;
  case eStyleUnit_Coord:
    return aCoord.GetCoordValue() > 0;
  case eStyleUnit_Null:
    return PR_FALSE;
    return PR_TRUE;

Here is the call graph for this function:

Here is the caller graph for this function:

static void SyncFrameViewGeometryDependentProperties ( nsPresContext aPresContext,
nsIFrame aFrame,
nsStyleContext aStyleContext,
nsIView aView,
PRUint32  aFlags 
) [static]

Definition at line 475 of file nsContainerFrame.cpp.

  nsIViewManager* vm = aView->GetViewManager();

  PRBool isCanvas;
  const nsStyleBackground* bg;
  PRBool hasBG =
    nsCSSRendering::FindBackground(aPresContext, aFrame, &bg, &isCanvas);

  // background-attachment: fixed is not really geometry dependent, but
  // we set it here because it's cheap to do so
  PRBool fixedBackground = hasBG && bg->HasFixedBackground();
  // If the frame has a fixed background attachment, then indicate that the
  // view's contents should be repainted and not bitblt'd
  vm->SetViewBitBltEnabled(aView, !fixedBackground);

  const nsStyleDisplay* display = aStyleContext->GetStyleDisplay();
  // If the frame has a solid background color, 'background-clip:border',
  // and it's a kind of frame that paints its background, and rounded borders aren't
  // clipping the background, then it's opaque.
  // If the frame has a native theme appearance then its background
  // color is actually not relevant.
  PRBool  viewHasTransparentContent =
    !(hasBG && !(bg->mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT) &&
      !display->mAppearance && bg->mBackgroundClip == NS_STYLE_BG_CLIP_BORDER &&
      aFrame->CanPaintBackground() &&

  PRBool drawnOnUniformField = PR_FALSE;
  if (aStyleContext->GetPseudoType() == nsCSSAnonBoxes::scrolledContent) {
    // If the nsGfxScrollFrame draws a solid unclipped background
    // color, and nothing else, then tell the view system that we're
    // drawn on a uniform field. Note that it's OK if the background
    // is clipped to the padding area, since the scrollport is within
    // the borders.
    nsIFrame* scrollFrame = aFrame->GetParent();
    while (scrollFrame->GetStyleContext()->GetPseudoType()
           == nsCSSAnonBoxes::scrolledContent) {
      scrollFrame = scrollFrame->GetParent();
    PRBool scrollFrameIsCanvas;
    const nsStyleBackground* scrollFrameBG;
    PRBool scrollFrameHasBG =
      nsCSSRendering::FindBackground(aPresContext, scrollFrame, &scrollFrameBG,
    const nsStyleDisplay* bgDisplay = scrollFrame->GetStyleDisplay();
    drawnOnUniformField = scrollFrameHasBG &&
      !(scrollFrameBG->mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT) &&
      (scrollFrameBG->mBackgroundFlags & NS_STYLE_BG_IMAGE_NONE) &&
      !HasNonZeroBorderRadius(scrollFrame->GetStyleContext()) &&
        && (bgDisplay->mClipFlags & NS_STYLE_CLIP_RECT));

  if (isCanvas) {
    nsIView* rootView;
    nsIView* rootParent = rootView->GetParent();
    if (!rootParent) {
      // We're the root of a view manager hierarchy. We will have to
      // paint something. NOTE: this can be overridden below.
      viewHasTransparentContent = PR_FALSE;

    nsIDocument *doc = aPresContext->PresShell()->GetDocument();
    if (doc) {
      nsIContent *rootElem = doc->GetRootContent();
      if (!doc->GetParentDocument() &&
          (nsCOMPtr<nsISupports>(doc->GetContainer())) &&
          rootElem && rootElem->IsContentOfType(nsIContent::eXUL)) {
        // we're XUL at the root of the document hierarchy. Try to make our
        // window translucent.
        // don't proceed unless this is the root view
        // (sometimes the non-root-view is a canvas)
        if (aView->HasWidget() && aView == rootView) {
          viewHasTransparentContent = hasBG && (bg->mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT);
  // XXX we should also set widget transparency for XUL popups

  nsFrameState kidState = aFrame->GetStateBits();
  PRBool isBlockLevel =
    display->IsBlockLevel() || (kidState & NS_FRAME_OUT_OF_FLOW);
  if (!viewHasTransparentContent) {
    const nsStyleVisibility* vis = aStyleContext->GetStyleVisibility();
    if (// If we're showing the view but the frame is hidden, then the
        // view is transparent
        (nsViewVisibility_kShow == aView->GetVisibility() &&
         NS_STYLE_VISIBILITY_HIDDEN == vis->mVisible)) {
      viewHasTransparentContent = PR_TRUE;
    } else {
      PRBool isScrolledContent = aView->GetParent() &&
      // If we have overflowing kids and we're not clipped by a parent
      // scrolling view, then the view must be transparent.
      if (!isScrolledContent && (kidState & NS_FRAME_OUTSIDE_CHILDREN)) {
        viewHasTransparentContent = PR_TRUE;

  // If the frame has visible content that overflows the content area, then we
  // need the view marked as having transparent content

  // There are two types of clipping:
  // - 'clip' which only applies to absolutely positioned elements, and is
  //    relative to the element's border edge. 'clip' applies to the entire
  //    element
  // - 'overflow:-moz-hidden-unscrollable' which only applies to
  //    block-level elements and replaced elements. Note
  //    that out-of-flow frames like floated or absolutely positioned
  //    frames are block-level, but we can't rely on the 'display' value
  //    being set correctly in the style context...
  PRBool hasClip = display->IsAbsolutelyPositioned() && (display->mClipFlags & NS_STYLE_CLIP_RECT);
  PRBool hasOverflowClip = isBlockLevel && (display->mOverflowX == NS_STYLE_OVERFLOW_CLIP);
  if (hasClip || hasOverflowClip) {
    nsSize frameSize = aFrame->GetSize();
    nsRect  clipRect;

    if (hasClip) {
      // Start with the 'auto' values and then factor in user specified values
      clipRect.SetRect(0, 0, frameSize.width, frameSize.height);

      if (display->mClipFlags & NS_STYLE_CLIP_RECT) {
        if (0 == (NS_STYLE_CLIP_TOP_AUTO & display->mClipFlags)) {
          clipRect.y = display->mClip.y;
        if (0 == (NS_STYLE_CLIP_LEFT_AUTO & display->mClipFlags)) {
          clipRect.x = display->mClip.x;
        if (0 == (NS_STYLE_CLIP_RIGHT_AUTO & display->mClipFlags)) {
          clipRect.width = display->mClip.width;
        if (0 == (NS_STYLE_CLIP_BOTTOM_AUTO & display->mClipFlags)) {
          clipRect.height = display->mClip.height;

    if (hasOverflowClip) {
      const nsStyleBorder* borderStyle = aStyleContext->GetStyleBorder();
      const nsStylePadding* paddingStyle = aStyleContext->GetStylePadding();

      nsMargin padding;
      nsRect overflowClipRect(0, 0, frameSize.width, frameSize.height);
      // XXX We need to handle percentage padding
      if (paddingStyle->GetPadding(padding)) {
#ifdef DEBUG
      else {
        NS_WARNING("Percentage padding and CLIP overflow don't mix");

      if (hasClip) {
        // If both 'clip' and 'overflow-clip' apply then use the intersection
        // of the two
        clipRect.IntersectRect(clipRect, overflowClipRect);
      } else {
        clipRect = overflowClipRect;
    nsRect newSize = aView->GetBounds();
    newSize -= aView->GetPosition();

    // If part of the view is being clipped out, then mark it transparent
    if (clipRect.y > newSize.y
        || clipRect.x > newSize.x
        || clipRect.XMost() < newSize.XMost()
        || clipRect.YMost() < newSize.YMost()) {
      viewHasTransparentContent = PR_TRUE;

    // Set clipping of child views.
    nsRegion region(clipRect);
    vm->SetViewChildClipRegion(aView, &region);
  } else {
    // Remove clipping of child views.
    vm->SetViewChildClipRegion(aView, nsnull);

  vm->SetViewContentTransparency(aView, viewHasTransparentContent);

Here is the call graph for this function:

Here is the caller graph for this function: