Back to index

lightning-sunbird  0.9+nobinonly
Public Types | Public Member Functions | Static Public Member Functions | Public Attributes | Protected Member Functions | Static Protected Member Functions | Protected Attributes | Private Types | Private Member Functions | Private Attributes | Friends
nsRuleNode Class Reference

nsRuleNode is a node in a lexicographic tree (the "rule tree") indexed by style rules (implementations of nsIStyleRule). More...

#include <nsRuleNode.h>

Collaboration diagram for nsRuleNode:
Collaboration graph
[legend]

List of all members.

Public Types

enum  RuleDetail {
  eRuleNone, eRulePartialReset, eRulePartialMixed, eRulePartialInherited,
  eRuleFullReset, eRuleFullMixed, eRuleFullInherited, eRuleUnknown
}

Public Member Functions

 NS_HIDDEN_ (void *) operator new(size_t sz
 NS_HIDDEN_ (void) Destroy()
 nsRuleNode (nsPresContext *aPresContext, nsIStyleRule *aRule, nsRuleNode *aParent) NS_HIDDEN
virtual ~nsRuleNode () NS_HIDDEN
 NS_HIDDEN_ (nsresult) Transition(nsIStyleRule *aRule
nsRuleNodeGetParent () const
PRBool IsRoot () const
nsIStyleRuleGetRule () const
nsPresContextGetPresContext () const
 NS_HIDDEN_ (nsresult) ClearStyleData()
 NS_HIDDEN_ (const nsStyleStruct *) GetStyleData(nsStyleStructID aSID
 NS_HIDDEN_ (void) Mark()
 NS_HIDDEN_ (PRBool) Sweep()

Static Public Member Functions

static NS_HIDDEN_ (nsILanguageAtomService *) gLangService
static NS_HIDDEN_ (nsRuleNode *) CreateRootNode(nsPresContext *aPresContext)

Public Attributes

nsPresContext *aContext CPP_THROW_NEW
nsRuleNode ** aResult
nsStyleContext PRBool aComputeData

Protected Member Functions

 NS_HIDDEN_ (void) PropagateDependentBit(PRUint32 aBit
 NS_HIDDEN_ (void) PropagateNoneBit(PRUint32 aBit
 NS_HIDDEN_ (const nsStyleStruct *) SetDefaultOnRoot(const nsStyleStructID aSID
 WalkRuleTree (const nsStyleStructID aSID, nsStyleContext *aContext, nsRuleData *aRuleData, nsRuleDataStruct *aSpecificData)
 ComputeDisplayData (nsStyleStruct *aStartDisplay, const nsRuleDataStruct &aDisplayData, nsStyleContext *aContext, nsRuleNode *aHighestNode, const RuleDetail &aRuleDetail, PRBool aInherited)
 ComputeVisibilityData (nsStyleStruct *aStartVisibility, const nsRuleDataStruct &aDisplayData, nsStyleContext *aContext, nsRuleNode *aHighestNode, const RuleDetail &aRuleDetail, PRBool aInherited)
 ComputeFontData (nsStyleStruct *aStartFont, const nsRuleDataStruct &aFontData, nsStyleContext *aContext, nsRuleNode *aHighestNode, const RuleDetail &aRuleDetail, PRBool aInherited)
 ComputeColorData (nsStyleStruct *aStartColor, const nsRuleDataStruct &aColorData, nsStyleContext *aContext, nsRuleNode *aHighestNode, const RuleDetail &aRuleDetail, PRBool aInherited)
 ComputeBackgroundData (nsStyleStruct *aStartBackground, const nsRuleDataStruct &aColorData, nsStyleContext *aContext, nsRuleNode *aHighestNode, const RuleDetail &aRuleDetail, PRBool aInherited)
 ComputeMarginData (nsStyleStruct *aStartMargin, const nsRuleDataStruct &aMarginData, nsStyleContext *aContext, nsRuleNode *aHighestNode, const RuleDetail &aRuleDetail, PRBool aInherited)
 ComputeBorderData (nsStyleStruct *aStartBorder, const nsRuleDataStruct &aMarginData, nsStyleContext *aContext, nsRuleNode *aHighestNode, const RuleDetail &aRuleDetail, PRBool aInherited)
 ComputePaddingData (nsStyleStruct *aStartPadding, const nsRuleDataStruct &aMarginData, nsStyleContext *aContext, nsRuleNode *aHighestNode, const RuleDetail &aRuleDetail, PRBool aInherited)
 ComputeOutlineData (nsStyleStruct *aStartOutline, const nsRuleDataStruct &aMarginData, nsStyleContext *aContext, nsRuleNode *aHighestNode, const RuleDetail &aRuleDetail, PRBool aInherited)
 ComputeListData (nsStyleStruct *aStartList, const nsRuleDataStruct &aListData, nsStyleContext *aContext, nsRuleNode *aHighestNode, const RuleDetail &aRuleDetail, PRBool aInherited)
 ComputePositionData (nsStyleStruct *aStartPosition, const nsRuleDataStruct &aPositionData, nsStyleContext *aContext, nsRuleNode *aHighestNode, const RuleDetail &aRuleDetail, PRBool aInherited)
 ComputeTableData (nsStyleStruct *aStartTable, const nsRuleDataStruct &aTableData, nsStyleContext *aContext, nsRuleNode *aHighestNode, const RuleDetail &aRuleDetail, PRBool aInherited)
 ComputeTableBorderData (nsStyleStruct *aStartTable, const nsRuleDataStruct &aTableData, nsStyleContext *aContext, nsRuleNode *aHighestNode, const RuleDetail &aRuleDetail, PRBool aInherited)
 ComputeContentData (nsStyleStruct *aStartContent, const nsRuleDataStruct &aData, nsStyleContext *aContext, nsRuleNode *aHighestNode, const RuleDetail &aRuleDetail, PRBool aInherited)
 ComputeQuotesData (nsStyleStruct *aStartQuotes, const nsRuleDataStruct &aData, nsStyleContext *aContext, nsRuleNode *aHighestNode, const RuleDetail &aRuleDetail, PRBool aInherited)
 ComputeTextData (nsStyleStruct *aStartData, const nsRuleDataStruct &aData, nsStyleContext *aContext, nsRuleNode *aHighestNode, const RuleDetail &aRuleDetail, PRBool aInherited)
 ComputeTextResetData (nsStyleStruct *aStartData, const nsRuleDataStruct &aData, nsStyleContext *aContext, nsRuleNode *aHighestNode, const RuleDetail &aRuleDetail, PRBool aInherited)
 ComputeUserInterfaceData (nsStyleStruct *aStartData, const nsRuleDataStruct &aData, nsStyleContext *aContext, nsRuleNode *aHighestNode, const RuleDetail &aRuleDetail, PRBool aInherited)
 ComputeUIResetData (nsStyleStruct *aStartData, const nsRuleDataStruct &aData, nsStyleContext *aContext, nsRuleNode *aHighestNode, const RuleDetail &aRuleDetail, PRBool aInherited)
 ComputeXULData (nsStyleStruct *aStartXUL, const nsRuleDataStruct &aXULData, nsStyleContext *aContext, nsRuleNode *aHighestNode, const RuleDetail &aRuleDetail, PRBool aInherited)
 ComputeColumnData (nsStyleStruct *aStartColumn, const nsRuleDataStruct &aColumnData, nsStyleContext *aContext, nsRuleNode *aHighestNode, const RuleDetail &aRuleDetail, PRBool aInherited)
 NS_HIDDEN_ (void) AdjustLogicalBoxProp(nsStyleContext *aContext
RuleDetail CheckSpecifiedProperties (const nsStyleStructID aSID, const nsRuleDataStruct &aRuleDataStruct)
 NS_HIDDEN_ (const nsStyleStruct *) GetParentData(const nsStyleStructID aSID)
 NS_HIDDEN_ (const nsStyleStruct *) GetDisplayData(nsStyleContext *aContext)
 NS_HIDDEN_ (const nsStyleStruct *) GetVisibilityData(nsStyleContext *aContext)
 NS_HIDDEN_ (const nsStyleStruct *) GetFontData(nsStyleContext *aContext)
 NS_HIDDEN_ (const nsStyleStruct *) GetColorData(nsStyleContext *aContext)
 NS_HIDDEN_ (const nsStyleStruct *) GetBackgroundData(nsStyleContext *aContext)
 NS_HIDDEN_ (const nsStyleStruct *) GetMarginData(nsStyleContext *aContext)
 NS_HIDDEN_ (const nsStyleStruct *) GetBorderData(nsStyleContext *aContext)
 NS_HIDDEN_ (const nsStyleStruct *) GetPaddingData(nsStyleContext *aContext)
 NS_HIDDEN_ (const nsStyleStruct *) GetOutlineData(nsStyleContext *aContext)
 NS_HIDDEN_ (const nsStyleStruct *) GetListData(nsStyleContext *aContext)
 NS_HIDDEN_ (const nsStyleStruct *) GetPositionData(nsStyleContext *aContext)
 NS_HIDDEN_ (const nsStyleStruct *) GetTableData(nsStyleContext *aContext)
 GetTableBorderData (nsStyleContext *aContext)
 NS_HIDDEN_ (const nsStyleStruct *) GetContentData(nsStyleContext *aContext)
 NS_HIDDEN_ (const nsStyleStruct *) GetQuotesData(nsStyleContext *aContext)
 NS_HIDDEN_ (const nsStyleStruct *) GetTextData(nsStyleContext *aContext)
 NS_HIDDEN_ (const nsStyleStruct *) GetTextResetData(nsStyleContext *aContext)
 GetUserInterfaceData (nsStyleContext *aContext)
 NS_HIDDEN_ (const nsStyleStruct *) GetUIResetData(nsStyleContext *aContext)
 NS_HIDDEN_ (const nsStyleStruct *) GetXULData(nsStyleContext *aContext)
 NS_HIDDEN_ (const nsStyleStruct *) GetColumnData(nsStyleContext *aContext)

Static Protected Member Functions

static NS_HIDDEN_ (void) SetFont(nsPresContext *aPresContext
static NS_HIDDEN_ (void) SetGenericFont(nsPresContext *aPresContext

Protected Attributes

nsRuleNodeaHighestNode
nsStyleContextaContext
static nsStyleContextaContext
static nsStyleContext nscoord aMinFontSize
static nsStyleContext nscoord
PRBool 
aUseDocumentFonts
static nsStyleContext nscoord
PRBool PRBool 
aIsGeneric
static nsStyleContext nscoord
PRBool PRBool const
nsRuleDataFont
aFontData
static nsStyleContext nscoord
PRBool PRBool const
nsRuleDataFont const nsFont
aDefaultFont
static nsStyleContext nscoord
PRBool PRBool const
nsRuleDataFont const nsFont
const nsStyleFont
aParentFont
static nsStyleContext nscoord
PRBool PRBool const
nsRuleDataFont const nsFont
const nsStyleFont nsStyleFont
aFont
static nsStyleContext nscoord
PRBool PRBool const
nsRuleDataFont const nsFont
const nsStyleFont nsStyleFont
PRBool
aInherited
static nsStyleContext const
nsRuleDataFont
aFontData
static nsStyleContext const
nsRuleDataFont PRUint8 
aGenericFontID
static nsStyleContext const
nsRuleDataFont PRUint8 nscoord 
aMinFontSize
static nsStyleContext const
nsRuleDataFont PRUint8 nscoord
PRBool 
aUseDocumentFonts
static nsStyleContext const
nsRuleDataFont PRUint8 nscoord
PRBool nsStyleFont
aFont
const nsCSSValueaLTRSource
const nsCSSValue const nsCSSValueaRTLSource
const nsCSSValue const
nsCSSValue const nsCSSValue
aLTRLogicalValue
const nsCSSValue const
nsCSSValue const nsCSSValue
const nsCSSValue
aRTLLogicalValue
const nsCSSValue const
nsCSSValue const nsCSSValue
const nsCSSValue const
nsStyleSides
aParentRect
const nsCSSValue const
nsCSSValue const nsCSSValue
const nsCSSValue const
nsStyleSides nsStyleSides
aRect
const nsCSSValue const
nsCSSValue const nsCSSValue
const nsCSSValue const
nsStyleSides nsStyleSides
PRUint8 
aSide
const nsCSSValue const
nsCSSValue const nsCSSValue
const nsCSSValue const
nsStyleSides nsStyleSides
PRUint8 PRInt32 
aMask
const nsCSSValue const
nsCSSValue const nsCSSValue
const nsCSSValue const
nsStyleSides nsStyleSides
PRUint8 PRInt32 PRBool
aInherited

Private Types

enum  { kTypeMask = 0x1, kListType = 0x0, kHashType = 0x1 }
enum  { kMaxChildrenInList = 32 }

Private Member Functions

PRBool HaveChildren ()
PRBool ChildrenAreHashed ()
nsRuleListChildrenList ()
nsRuleList ** ChildrenListPtr ()
PLDHashTableChildrenHash ()
void SetChildrenList (nsRuleList *aList)
void SetChildrenHash (PLDHashTable *aHashtable)
void ConvertChildrenToHash ()

Private Attributes

nsPresContextmPresContext
nsRuleNodemParent
nsIStyleRulemRule
voidmChildrenTaggedPtr
nsCachedStyleData mStyleData
PRUint32 mDependentBits
PRUint32 mNoneBits

Friends

struct nsRuleList

Detailed Description

nsRuleNode is a node in a lexicographic tree (the "rule tree") indexed by style rules (implementations of nsIStyleRule).

The rule tree is owned by the nsStyleSet and is destroyed when the presentation of the document goes away. It is garbage-collected (using mark-and-sweep garbage collection) during the lifetime of the document (when dynamic changes cause the destruction of enough style contexts). Rule nodes are marked if they are pointed to by a style context or one of their descendants is.

An nsStyleContext, which represents the computed style data for an element, points to an nsRuleNode. The path from the root of the rule tree to the nsStyleContext's mRuleNode gives the list of the rules matched, from least important in the cascading order to most important in the cascading order.

The reason for using a lexicographic tree is that it allows for sharing of style data, which saves both memory (for storing the computed style data) and time (for computing them). This sharing depends on the computed style data being stored in structs (nsStyle*) that contain only properties that are inherited by default ("inherited structs") or structs that contain only properties that are not inherited by default ("reset structs"). The optimization depends on the normal case being that style rules specify relatively few properties and even that elements generally have relatively few properties specified. This allows sharing in the following ways:

  1. [mainly reset structs] When a style data struct will contain the same computed value for any elements that match the same set of rules (common for reset structs), it can be stored on the nsRuleNode instead of on the nsStyleContext.
  2. [only? reset structs] When (1) occurs, and an nsRuleNode doesn't have any rules that change the values in the struct, the nsRuleNode can share that struct with its parent nsRuleNode.
  3. [mainly inherited structs] When an element doesn't match any rules that change the value of a property (or, in the edge case, when all the values specified are 'inherit'), the nsStyleContext can use the same nsStyle* struct as its parent nsStyleContext.

Since the data represented by an nsIStyleRule are immutable, the data represented by an nsRuleNode are also immutable (with a few exceptions, like system color changes).

Definition at line 286 of file nsRuleNode.h.


Member Enumeration Documentation

anonymous enum [private]
Enumerator:
kTypeMask 
kListType 
kHashType 

Definition at line 335 of file nsRuleNode.h.

       {
    kTypeMask = 0x1,
    kListType = 0x0,
    kHashType = 0x1
  };
anonymous enum [private]
Enumerator:
kMaxChildrenInList 

Definition at line 340 of file nsRuleNode.h.

       {
    // Maximum to have in a list before converting to a hashtable.
    // XXX Need to optimize this.
    kMaxChildrenInList = 32
  };
Enumerator:
eRuleNone 
eRulePartialReset 
eRulePartialMixed 
eRulePartialInherited 
eRuleFullReset 
eRuleFullMixed 
eRuleFullInherited 
eRuleUnknown 

Definition at line 295 of file nsRuleNode.h.

                  {
    eRuleNone, // No props have been specified at all.
    eRulePartialReset, // At least one prop with a non-inherited value
                       // has been specified.  No props have been
                       // specified with an inherited value.  At least
                       // one prop remains unspecified.
    eRulePartialMixed, // At least one prop with a non-inherited value
                       // has been specified.  Some props may also have
                       // been specified with an inherited value.  At
                       // least one prop remains unspecified.
    eRulePartialInherited, // Only props with inherited values have
                           // have been specified.  At least one prop
                           // remains unspecified.
    eRuleFullReset, // All props have been specified.  None has an
                    // inherited value.
    eRuleFullMixed, // All props have been specified.  At least one has
                    // a non-inherited value.
    eRuleFullInherited, // All props have been specified with inherited
                        // values.
    eRuleUnknown // Information unknown (used as a result from a check
                 // callback to trigger the normal checking codepath)
  };

Constructor & Destructor Documentation

nsRuleNode::nsRuleNode ( nsPresContext aPresContext,
nsIStyleRule aRule,
nsRuleNode aParent 
)
nsRuleNode::~nsRuleNode ( ) [virtual]

Definition at line 425 of file nsRuleNode.cpp.

Here is the call graph for this function:


Member Function Documentation

Definition at line 903 of file nsRuleNode.cpp.

{
  const StructCheckData *structData = gCheckProperties + aSID;
  if (structData->callback) {
    nsRuleNode::RuleDetail res = (*structData->callback)(aRuleDataStruct);
    if (res != eRuleUnknown)
      return res;
  }

  // Build a count of the:
  PRUint32 total = 0,      // total number of props in the struct
           specified = 0,  // number that were specified for this node
           inherited = 0;  // number that were 'inherit' (and not
                           //   eCSSUnit_Inherit) for this node
  PRBool canHaveExplicitInherit = PR_FALSE;

  for (const PropertyCheckData *prop = structData->props,
                           *prop_end = prop + structData->nprops;
       prop != prop_end;
       ++prop)
    switch (prop->type) {

      case eCSSType_Value:
        ++total;
        ExamineCSSValue(ValueAtOffset(aRuleDataStruct, prop->offset),
                        specified, inherited);
        break;

      case eCSSType_Rect:
        total += 4;
        ExamineCSSRect(RectAtOffset(aRuleDataStruct, prop->offset),
                       specified, inherited);
        break;

      case eCSSType_ValuePair:
        total += 2;
        ExamineCSSValuePair(ValuePairAtOffset(aRuleDataStruct, prop->offset),
                            specified, inherited);
        break;
        
      case eCSSType_ValueList:
        {
          ++total;
          const nsCSSValueList* valueList =
              ValueListAtOffset(aRuleDataStruct, prop->offset);
          if (valueList) {
            ++specified;
            if (eCSSUnit_Inherit == valueList->mValue.GetUnit()) {
              ++inherited;
            }
          }
        }
        break;

      case eCSSType_CounterData:
        {
          ++total;
          const nsCSSCounterData* counterData =
              CounterDataAtOffset(aRuleDataStruct, prop->offset);
          if (counterData) {
            ++specified;
            if (eCSSUnit_Inherit == counterData->mCounter.GetUnit()) {
              ++inherited;
            }
          }
        }
        break;

      case eCSSType_Quotes:
        {
          ++total;
          const nsCSSQuotes* quotes =
              QuotesAtOffset(aRuleDataStruct, prop->offset);
          if (quotes) {
            ++specified;
            if (eCSSUnit_Inherit == quotes->mOpen.GetUnit()) {
              ++inherited;
            }
          }
        }
        break;

      case eCSSType_Shadow:
        NS_NOTYETIMPLEMENTED("nsCSSShadow not yet transferred to structs");
        break;

      default:
        NS_NOTREACHED("unknown type");
        break;

    }

#if 0
  printf("CheckSpecifiedProperties: SID=%d total=%d spec=%d inh=%d chei=%s.\n",
    aSID, total, specified, inherited, canHaveExplicitInherit?"true":"false");
#endif

  if (canHaveExplicitInherit) {
    if (specified == total)
      return eRuleFullMixed;
    return eRulePartialMixed;
  }
  if (inherited == total)
    return eRuleFullInherited;
  if (specified == total) {
    if (inherited == 0)
      return eRuleFullReset;
    return eRuleFullMixed;
  }
  if (specified == 0)
    return eRuleNone;
  if (specified == inherited)
    return eRulePartialInherited;
  if (inherited == 0)
    return eRulePartialReset;
  return eRulePartialMixed;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool nsRuleNode::ChildrenAreHashed ( ) [inline, private]

Definition at line 349 of file nsRuleNode.h.

Here is the caller graph for this function:

PLDHashTable* nsRuleNode::ChildrenHash ( ) [inline, private]

Definition at line 358 of file nsRuleNode.h.

Here is the caller graph for this function:

nsRuleList* nsRuleNode::ChildrenList ( ) [inline, private]

Definition at line 352 of file nsRuleNode.h.

Here is the caller graph for this function:

nsRuleList** nsRuleNode::ChildrenListPtr ( ) [inline, private]

Definition at line 355 of file nsRuleNode.h.

const nsStyleStruct * nsRuleNode::ComputeBackgroundData ( nsStyleStruct aStartBackground,
const nsRuleDataStruct aColorData,
nsStyleContext aContext,
nsRuleNode aHighestNode,
const RuleDetail aRuleDetail,
PRBool  aInherited 
) [protected]

Definition at line 3120 of file nsRuleNode.cpp.

{
  nsStyleContext* parentContext = aContext->GetParent();

  const nsRuleDataColor& colorData = NS_STATIC_CAST(const nsRuleDataColor&, aData);
  nsStyleBackground* bg;
  if (aStartStruct)
    // We only need to compute the delta between this computed data and our
    // computed data.
    bg = new (mPresContext) nsStyleBackground(*NS_STATIC_CAST(nsStyleBackground*, aStartStruct));
  else
    bg = new (mPresContext) nsStyleBackground(mPresContext);

  if (NS_UNLIKELY(!bg))
    return nsnull;  // Out Of Memory

  const nsStyleBackground* parentBG = bg;
  if (parentContext && 
      aRuleDetail != eRuleFullReset &&
      aRuleDetail != eRulePartialReset &&
      aRuleDetail != eRuleNone)
    parentBG = parentContext->GetStyleBackground();
  PRBool inherited = aInherited;
  // save parentFlags in case bg == parentBG and we clobber them later
  PRUint8 parentFlags = parentBG->mBackgroundFlags;

  // background-color: color, string, enum (flags), inherit
  if (eCSSUnit_Inherit == colorData.mBackColor.GetUnit()) { // do inherit first, so SetColor doesn't do it
    bg->mBackgroundColor = parentBG->mBackgroundColor;
    bg->mBackgroundFlags &= ~NS_STYLE_BG_COLOR_TRANSPARENT;
    bg->mBackgroundFlags |= (parentFlags & NS_STYLE_BG_COLOR_TRANSPARENT);
    inherited = PR_TRUE;
  }
  else if (SetColor(colorData.mBackColor, parentBG->mBackgroundColor, 
                    mPresContext, aContext, bg->mBackgroundColor, inherited)) {
    bg->mBackgroundFlags &= ~NS_STYLE_BG_COLOR_TRANSPARENT;
  }
  else if (eCSSUnit_Enumerated == colorData.mBackColor.GetUnit()) {
    //bg->mBackgroundColor = parentBG->mBackgroundColor; XXXwdh crap crap crap!
    bg->mBackgroundFlags |= NS_STYLE_BG_COLOR_TRANSPARENT;
  }

  // background-image: url (stored as image), none, inherit
  if (eCSSUnit_Image == colorData.mBackImage.GetUnit()) {
    bg->mBackgroundImage = colorData.mBackImage.GetImageValue();
    bg->mBackgroundFlags &= ~NS_STYLE_BG_IMAGE_NONE;
  }
  else if (eCSSUnit_None == colorData.mBackImage.GetUnit()) {
    bg->mBackgroundImage = nsnull;
    bg->mBackgroundFlags |= NS_STYLE_BG_IMAGE_NONE;
  }
  else if (eCSSUnit_Inherit == colorData.mBackImage.GetUnit()) {
    inherited = PR_TRUE;
    bg->mBackgroundImage = parentBG->mBackgroundImage;
    bg->mBackgroundFlags &= ~NS_STYLE_BG_IMAGE_NONE;
    bg->mBackgroundFlags |= (parentFlags & NS_STYLE_BG_IMAGE_NONE);
  }

  // background-repeat: enum, inherit
  if (eCSSUnit_Enumerated == colorData.mBackRepeat.GetUnit()) {
    bg->mBackgroundRepeat = colorData.mBackRepeat.GetIntValue();
  }
  else if (eCSSUnit_Inherit == colorData.mBackRepeat.GetUnit()) {
    inherited = PR_TRUE;
    bg->mBackgroundRepeat = parentBG->mBackgroundRepeat;
  }

  // background-attachment: enum, inherit
  if (eCSSUnit_Enumerated == colorData.mBackAttachment.GetUnit()) {
    bg->mBackgroundAttachment = colorData.mBackAttachment.GetIntValue();
  }
  else if (eCSSUnit_Inherit == colorData.mBackAttachment.GetUnit()) {
    inherited = PR_TRUE;
    bg->mBackgroundAttachment = parentBG->mBackgroundAttachment;
  }

  // background-clip: enum, inherit, initial
  if (eCSSUnit_Enumerated == colorData.mBackClip.GetUnit()) {
    bg->mBackgroundClip = colorData.mBackClip.GetIntValue();
  }
  else if (eCSSUnit_Inherit == colorData.mBackClip.GetUnit()) {
    bg->mBackgroundClip = parentBG->mBackgroundClip;
  }
  else if (eCSSUnit_Initial == colorData.mBackClip.GetUnit()) {
    bg->mBackgroundClip = NS_STYLE_BG_CLIP_BORDER;
  }

  // background-inline-policy: enum, inherit, initial
  if (eCSSUnit_Enumerated == colorData.mBackInlinePolicy.GetUnit()) {
    bg->mBackgroundInlinePolicy = colorData.mBackInlinePolicy.GetIntValue();
  }
  else if (eCSSUnit_Inherit == colorData.mBackInlinePolicy.GetUnit()) {
    bg->mBackgroundInlinePolicy = parentBG->mBackgroundInlinePolicy;
  }
  else if (eCSSUnit_Initial == colorData.mBackInlinePolicy.GetUnit()) {
    bg->mBackgroundInlinePolicy = NS_STYLE_BG_INLINE_POLICY_CONTINUOUS;
  }

  // background-origin: enum, inherit, initial
  if (eCSSUnit_Enumerated == colorData.mBackOrigin.GetUnit()) {
    bg->mBackgroundOrigin = colorData.mBackOrigin.GetIntValue();
  }
  else if (eCSSUnit_Inherit == colorData.mBackOrigin.GetUnit()) {
    bg->mBackgroundOrigin = parentBG->mBackgroundOrigin;
  }
  else if (eCSSUnit_Initial == colorData.mBackOrigin.GetUnit()) {
    bg->mBackgroundOrigin = NS_STYLE_BG_ORIGIN_PADDING;
  }

  // background-position: enum, length, percent (flags), inherit
  if (eCSSUnit_Percent == colorData.mBackPositionX.GetUnit()) {
    bg->mBackgroundXPosition.mFloat = colorData.mBackPositionX.GetPercentValue();
    bg->mBackgroundFlags |= NS_STYLE_BG_X_POSITION_PERCENT;
    bg->mBackgroundFlags &= ~NS_STYLE_BG_X_POSITION_LENGTH;
  }
  else if (colorData.mBackPositionX.IsLengthUnit()) {
    bg->mBackgroundXPosition.mCoord = CalcLength(colorData.mBackPositionX, nsnull, 
                                                 aContext, mPresContext, inherited);
    bg->mBackgroundFlags |= NS_STYLE_BG_X_POSITION_LENGTH;
    bg->mBackgroundFlags &= ~NS_STYLE_BG_X_POSITION_PERCENT;
  }
  else if (eCSSUnit_Enumerated == colorData.mBackPositionX.GetUnit()) {
    bg->mBackgroundXPosition.mFloat = (float)colorData.mBackPositionX.GetIntValue() / 100.0f;
    bg->mBackgroundFlags |= NS_STYLE_BG_X_POSITION_PERCENT;
    bg->mBackgroundFlags &= ~NS_STYLE_BG_X_POSITION_LENGTH;
  }
  else if (eCSSUnit_Inherit == colorData.mBackPositionX.GetUnit()) {
    inherited = PR_TRUE;
    bg->mBackgroundXPosition = parentBG->mBackgroundXPosition;
    bg->mBackgroundFlags &= ~(NS_STYLE_BG_X_POSITION_LENGTH | NS_STYLE_BG_X_POSITION_PERCENT);
    bg->mBackgroundFlags |= (parentFlags & (NS_STYLE_BG_X_POSITION_LENGTH | NS_STYLE_BG_X_POSITION_PERCENT));
  }

  if (eCSSUnit_Percent == colorData.mBackPositionY.GetUnit()) {
    bg->mBackgroundYPosition.mFloat = colorData.mBackPositionY.GetPercentValue();
    bg->mBackgroundFlags |= NS_STYLE_BG_Y_POSITION_PERCENT;
    bg->mBackgroundFlags &= ~NS_STYLE_BG_Y_POSITION_LENGTH;
  }
  else if (colorData.mBackPositionY.IsLengthUnit()) {
    bg->mBackgroundYPosition.mCoord = CalcLength(colorData.mBackPositionY, nsnull,
                                                 aContext, mPresContext, inherited);
    bg->mBackgroundFlags |= NS_STYLE_BG_Y_POSITION_LENGTH;
    bg->mBackgroundFlags &= ~NS_STYLE_BG_Y_POSITION_PERCENT;
  }
  else if (eCSSUnit_Enumerated == colorData.mBackPositionY.GetUnit()) {
    bg->mBackgroundYPosition.mFloat = (float)colorData.mBackPositionY.GetIntValue() / 100.0f;
    bg->mBackgroundFlags |= NS_STYLE_BG_Y_POSITION_PERCENT;
    bg->mBackgroundFlags &= ~NS_STYLE_BG_Y_POSITION_LENGTH;
  }
  else if (eCSSUnit_Inherit == colorData.mBackPositionY.GetUnit()) {
    inherited = PR_TRUE;
    bg->mBackgroundYPosition = parentBG->mBackgroundYPosition;
    bg->mBackgroundFlags &= ~(NS_STYLE_BG_Y_POSITION_LENGTH | NS_STYLE_BG_Y_POSITION_PERCENT);
    bg->mBackgroundFlags |= (parentFlags & (NS_STYLE_BG_Y_POSITION_LENGTH | NS_STYLE_BG_Y_POSITION_PERCENT));
  }

  if (inherited)
    // We inherited, and therefore can't be cached in the rule node.  We have to be put right on the
    // style context.
    aContext->SetStyle(eStyleStruct_Background, bg);
  else {
    // We were fully specified and can therefore be cached right on the rule node.
    if (!aHighestNode->mStyleData.mResetData) {
      aHighestNode->mStyleData.mResetData = new (mPresContext) nsResetStyleData;
      if (NS_UNLIKELY(!aHighestNode->mStyleData.mResetData)) {
        bg->Destroy(mPresContext);
        return nsnull;
      }
    }
    aHighestNode->mStyleData.mResetData->mBackgroundData = bg;
    // Propagate the bit down.
    PropagateDependentBit(NS_STYLE_INHERIT_BIT(Background), aHighestNode);
  }

  return bg;
}

Here is the call graph for this function:

const nsStyleStruct * nsRuleNode::ComputeBorderData ( nsStyleStruct aStartBorder,
const nsRuleDataStruct aMarginData,
nsStyleContext aContext,
nsRuleNode aHighestNode,
const RuleDetail aRuleDetail,
PRBool  aInherited 
) [protected]

Definition at line 3378 of file nsRuleNode.cpp.

{
  nsStyleContext* parentContext = aContext->GetParent();

  const nsRuleDataMargin& marginData = NS_STATIC_CAST(const nsRuleDataMargin&, aData);
  nsStyleBorder* border;
  if (aStartStruct)
    // We only need to compute the delta between this computed data and our
    // computed data.
    border = new (mPresContext) nsStyleBorder(*NS_STATIC_CAST(nsStyleBorder*, aStartStruct));
  else
    border = new (mPresContext) nsStyleBorder(mPresContext);
  
  if (NS_UNLIKELY(!border))
    return nsnull;  // Out Of Memory

  const nsStyleBorder* parentBorder = border;
  if (parentContext && 
      aRuleDetail != eRuleFullReset &&
      aRuleDetail != eRulePartialReset &&
      aRuleDetail != eRuleNone)
    parentBorder = parentContext->GetStyleBorder();
  PRBool inherited = aInherited;

  // border-size: length, enum, inherit
  nsStyleCoord  coord;
  nsStyleCoord  parentCoord;
  { // scope for compilers with broken |for| loop scoping
    NS_FOR_CSS_SIDES(side) {
      const nsCSSValue &value = marginData.mBorderWidth.*(nsCSSRect::sides[side]);
      NS_ASSERTION(eCSSUnit_Percent != value.GetUnit(),
                   "Percentage borders not implemented yet "
                   "If implementing, make sure to fix all consumers of "
                   "nsStyleBorder, the IsPercentageAwareChild method, "
                   "the nsAbsoluteContainingBlock::FrameDependsOnContainer "
                   "method, the "
                   "nsLineLayout::IsPercentageAwareReplacedElement method "
                   "and probably some other places");
      if (eCSSUnit_Enumerated == value.GetUnit()) {
        NS_ASSERTION(value.GetIntValue() == NS_STYLE_BORDER_WIDTH_THIN ||
                     value.GetIntValue() == NS_STYLE_BORDER_WIDTH_MEDIUM ||
                     value.GetIntValue() == NS_STYLE_BORDER_WIDTH_THICK,
                     "Unexpected enum value");
        border->SetBorderWidth(side,
                               (mPresContext->GetBorderWidthTable())[value.GetIntValue()]);
      }
      else if (SetCoord(value, coord, parentCoord, SETCOORD_LENGTH, aContext,
                        mPresContext, inherited)) {
        if (coord.GetUnit() == eStyleUnit_Coord) {
          border->SetBorderWidth(side, coord.GetCoordValue());
        }
#ifdef DEBUG
        else {
          NS_ASSERTION(coord.GetUnit() == eStyleUnit_Chars, "unexpected unit");
          NS_WARNING("Border set in chars; we don't handle that");
        }
#endif        
      }
      else if (eCSSUnit_Inherit == value.GetUnit()) {
        inherited = PR_TRUE;
        border->SetBorderWidth(side, parentBorder->GetBorderWidth(side));
      }
      else if (eCSSUnit_Initial == value.GetUnit()) {
        border->SetBorderWidth(side,
          (mPresContext->GetBorderWidthTable())[NS_STYLE_BORDER_WIDTH_MEDIUM]);
      }
    }
  }

  // border-style: enum, none, inhert
  const nsCSSRect& ourStyle = marginData.mBorderStyle;
  { // scope for compilers with broken |for| loop scoping
    NS_FOR_CSS_SIDES(side) {
      const nsCSSValue &value = ourStyle.*(nsCSSRect::sides[side]);
      nsCSSUnit unit = value.GetUnit();
      if (eCSSUnit_Enumerated == unit) {
        border->SetBorderStyle(side, value.GetIntValue());
      }
      else if (eCSSUnit_None == unit || eCSSUnit_Initial == unit) {
        border->SetBorderStyle(side, NS_STYLE_BORDER_STYLE_NONE);
      }
      else if (eCSSUnit_Inherit == unit) {
        inherited = PR_TRUE;
        border->SetBorderStyle(side, parentBorder->GetBorderStyle(side));
      }
    }
  }

  // border-colors: color, string, enum
  nscolor borderColor;
  nscolor unused = NS_RGB(0,0,0);
  
  { // scope for compilers with broken |for| loop scoping
    NS_FOR_CSS_SIDES(side) {
      nsCSSValueList* list =
          marginData.mBorderColors.*(nsCSSValueListRect::sides[side]);
      if (list) {
        // Some composite border color information has been specified for this
        // border side.
        border->EnsureBorderColors();
        border->ClearBorderColors(side);
        while (list) {
          if (SetColor(list->mValue, unused, mPresContext, aContext, borderColor, inherited))
            border->AppendBorderColor(side, borderColor, PR_FALSE);
          else if (eCSSUnit_Enumerated == list->mValue.GetUnit() &&
                   NS_STYLE_COLOR_TRANSPARENT == list->mValue.GetIntValue())
            border->AppendBorderColor(side, nsnull, PR_TRUE);
          list = list->mNext;
        }
      }
    }
  }

  // border-color: color, string, enum, inherit
  const nsCSSRect& ourBorderColor = marginData.mBorderColor;
  PRBool transparent;
  PRBool foreground;

  { // scope for compilers with broken |for| loop scoping
    NS_FOR_CSS_SIDES(side) {
      const nsCSSValue &value = ourBorderColor.*(nsCSSRect::sides[side]);
      if (eCSSUnit_Inherit == value.GetUnit()) {
        if (parentContext) {
          inherited = PR_TRUE;
          parentBorder->GetBorderColor(side, borderColor,
                                       transparent, foreground);
          if (transparent)
            border->SetBorderTransparent(side);
          else if (foreground) {
            // We want to inherit the color from the parent, not use the
            // color on the element where this chunk of style data will be
            // used.  We can ensure that the data for the parent are fully
            // computed (unlike for the element where this will be used, for
            // which the color could be specified on a more specific rule).
            border->SetBorderColor(side, parentContext->GetStyleColor()->mColor);
          } else
            border->SetBorderColor(side, borderColor);
        } else {
          // We're the root
          border->SetBorderToForeground(side);
        }
      }
      else if (SetColor(value, unused, mPresContext, aContext, borderColor, inherited)) {
        border->SetBorderColor(side, borderColor);
      }
      else if (eCSSUnit_Enumerated == value.GetUnit()) {
        switch (value.GetIntValue()) {
          case NS_STYLE_COLOR_TRANSPARENT:
            border->SetBorderTransparent(side);
            break;
          case NS_STYLE_COLOR_MOZ_USE_TEXT_COLOR:
            border->SetBorderToForeground(side);
            break;
        }
      }
    }
  }

  // -moz-border-radius: length, percent, inherit
  { // scope for compilers with broken |for| loop scoping
    NS_FOR_CSS_SIDES(side) {
      parentBorder->mBorderRadius.Get(side, parentCoord);
      if (SetCoord(marginData.mBorderRadius.*(nsCSSRect::sides[side]), coord,
                   parentCoord, SETCOORD_LPH, aContext, mPresContext,
                   inherited))
        border->mBorderRadius.Set(side, coord);
    }
  }

  // float-edge: enum, inherit
  if (eCSSUnit_Enumerated == marginData.mFloatEdge.GetUnit())
    border->mFloatEdge = marginData.mFloatEdge.GetIntValue();
  else if (eCSSUnit_Inherit == marginData.mFloatEdge.GetUnit()) {
    inherited = PR_TRUE;
    border->mFloatEdge = parentBorder->mFloatEdge;
  }

  if (inherited)
    // We inherited, and therefore can't be cached in the rule node.  We have to be put right on the
    // style context.
    aContext->SetStyle(eStyleStruct_Border, border);
  else {
    // We were fully specified and can therefore be cached right on the rule node.
    if (!aHighestNode->mStyleData.mResetData) {
      aHighestNode->mStyleData.mResetData = new (mPresContext) nsResetStyleData;
      if (NS_UNLIKELY(!aHighestNode->mStyleData.mResetData)) {
        border->Destroy(mPresContext);
        return nsnull;
      }
    }
    aHighestNode->mStyleData.mResetData->mBorderData = border;
    // Propagate the bit down.
    PropagateDependentBit(NS_STYLE_INHERIT_BIT(Border), aHighestNode);
  }

  return border;
}

Here is the call graph for this function:

const nsStyleStruct * nsRuleNode::ComputeColorData ( nsStyleStruct aStartColor,
const nsRuleDataStruct aColorData,
nsStyleContext aContext,
nsRuleNode aHighestNode,
const RuleDetail aRuleDetail,
PRBool  aInherited 
) [protected]

Definition at line 3047 of file nsRuleNode.cpp.

{
  nsStyleContext* parentContext = aContext->GetParent();

  const nsRuleDataColor& colorData = NS_STATIC_CAST(const nsRuleDataColor&, aData);
  nsStyleColor* color = nsnull;
  const nsStyleColor* parentColor = nsnull;
  PRBool inherited = aInherited;

  if (parentContext && aRuleDetail != eRuleFullReset)
    parentColor = parentContext->GetStyleColor();
  if (aStartStruct)
    // We only need to compute the delta between this computed data and our
    // computed data.
    color = new (mPresContext) nsStyleColor(*NS_STATIC_CAST(nsStyleColor*, aStartStruct));
  else {
    // XXXldb What about eRuleFullInherited?  Which path is faster?
    if (aRuleDetail != eRuleFullMixed && aRuleDetail != eRuleFullReset) {
      // No question. We will have to inherit. Go ahead and init
      // with inherited vals from parent.
      inherited = PR_TRUE;
      if (parentColor)
        color = new (mPresContext) nsStyleColor(*parentColor);
      else
        color = new (mPresContext) nsStyleColor(mPresContext);
    }
    else
      color = new (mPresContext) nsStyleColor(mPresContext);
  }

  if (NS_UNLIKELY(!color))
    return nsnull;  // Out Of Memory
  if (!parentColor)
    parentColor = color;

  // color: color, string, inherit
  // Special case for currentColor.  According to CSS3, setting color to 'currentColor'
  // should behave as if it is inherited
  if (colorData.mColor.GetUnit() == eCSSUnit_Integer && 
      colorData.mColor.GetIntValue() == NS_COLOR_CURRENTCOLOR) {
    color->mColor = parentColor->mColor;
    inherited = PR_TRUE;
  } else {
    SetColor(colorData.mColor, parentColor->mColor, mPresContext, aContext, color->mColor, 
             inherited);
  }

  if (inherited)
    // We inherited, and therefore can't be cached in the rule node.  We have to be put right on the
    // style context.
    aContext->SetStyle(eStyleStruct_Color, color);
  else {
    // We were fully specified and can therefore be cached right on the rule node.
    if (!aHighestNode->mStyleData.mInheritedData) {
      aHighestNode->mStyleData.mInheritedData = new (mPresContext) nsInheritedStyleData;
      if (NS_UNLIKELY(!aHighestNode->mStyleData.mInheritedData)) {
        color->Destroy(mPresContext);
        return nsnull;
      }
    }
    aHighestNode->mStyleData.mInheritedData->mColorData = color;
    // Propagate the bit down.
    PropagateDependentBit(NS_STYLE_INHERIT_BIT(Color), aHighestNode);
  }

  return color;
}

Here is the call graph for this function:

const nsStyleStruct * nsRuleNode::ComputeColumnData ( nsStyleStruct aStartColumn,
const nsRuleDataStruct aColumnData,
nsStyleContext aContext,
nsRuleNode aHighestNode,
const RuleDetail aRuleDetail,
PRBool  aInherited 
) [protected]

Definition at line 4584 of file nsRuleNode.cpp.

{
  nsStyleContext* parentContext = aContext->GetParent();

  const nsRuleDataColumn& columnData = NS_STATIC_CAST(const nsRuleDataColumn&, aData);
  nsStyleColumn* column = nsnull;
  
  if (aStartStruct)
    // We only need to compute the delta between this computed data and our
    // computed data.
    column = new (mPresContext) nsStyleColumn(*NS_STATIC_CAST(nsStyleColumn*, aStartStruct));
  else
    column = new (mPresContext) nsStyleColumn();

  if (NS_UNLIKELY(!column))
    return nsnull;  // Out Of Memory

  const nsStyleColumn* parent = column;
  if (parentContext && 
      aRuleDetail != eRuleFullReset &&
      aRuleDetail != eRulePartialReset &&
      aRuleDetail != eRuleNone)
    parent = parentContext->GetStyleColumn();

  PRBool inherited = aInherited;

  // column-width: length, auto, inherit
  SetCoord(columnData.mColumnWidth,
           column->mColumnWidth, parent->mColumnWidth, SETCOORD_LAH,
           aContext, mPresContext, inherited);

  // column-gap: length, percentage, inherit
  SetCoord(columnData.mColumnGap,
           column->mColumnGap, parent->mColumnGap, SETCOORD_LPH,
           aContext, mPresContext, inherited);

  // column-count: auto, integer, inherit
  if (eCSSUnit_Auto == columnData.mColumnCount.GetUnit()) {
    column->mColumnCount = NS_STYLE_COLUMN_COUNT_AUTO;
  } else if (eCSSUnit_Integer == columnData.mColumnCount.GetUnit()) {
    column->mColumnCount = columnData.mColumnCount.GetIntValue();
    // Max 1000 columns - wallpaper for bug 345583.
    column->mColumnCount = PR_MIN(column->mColumnCount, 1000);
  } else if (eCSSUnit_Inherit == columnData.mColumnCount.GetUnit()) {
    inherited = PR_TRUE;
    column->mColumnCount = parent->mColumnCount;
  }

  if (inherited)
    // We inherited, and therefore can't be cached in the rule node.  We have to be put right on the
    // style context.
    aContext->SetStyle(eStyleStruct_Column, column);
  else {
    // We were fully specified and can therefore be cached right on the rule node.
    if (!aHighestNode->mStyleData.mResetData) {
      aHighestNode->mStyleData.mResetData = new (mPresContext) nsResetStyleData;
      if (NS_UNLIKELY(!aHighestNode->mStyleData.mResetData)) {
        column->Destroy(mPresContext);
        return nsnull;
      }
    }
    aHighestNode->mStyleData.mResetData->mColumnData = column;
    // Propagate the bit down.
    PropagateDependentBit(NS_STYLE_INHERIT_BIT(Column), aHighestNode);
  }

  return column;
}

Here is the call graph for this function:

const nsStyleStruct * nsRuleNode::ComputeContentData ( nsStyleStruct aStartContent,
const nsRuleDataStruct aData,
nsStyleContext aContext,
nsRuleNode aHighestNode,
const RuleDetail aRuleDetail,
PRBool  aInherited 
) [protected]

Definition at line 4161 of file nsRuleNode.cpp.

{
  nsStyleContext* parentContext = aContext->GetParent();

  const nsRuleDataContent& contentData = NS_STATIC_CAST(const nsRuleDataContent&, aData);
  nsStyleContent* content;
  if (aStartStruct)
    // We only need to compute the delta between this computed data and our
    // computed data.
    content = new (mPresContext) nsStyleContent(*NS_STATIC_CAST(nsStyleContent*, aStartStruct));
  else
    content = new (mPresContext) nsStyleContent();
  
  if (NS_UNLIKELY(!content))
    return nsnull;  // Out Of Memory

  const nsStyleContent* parentContent = content;
  if (parentContext && 
      aRuleDetail != eRuleFullReset &&
      aRuleDetail != eRulePartialReset &&
      aRuleDetail != eRuleNone)
    parentContent = parentContext->GetStyleContent();
  PRBool inherited = aInherited;

  // content: [string, url, counter, attr, enum]+, normal, inherit
  PRUint32 count;
  nsAutoString  buffer;
  nsCSSValueList* contentValue = contentData.mContent;
  if (contentValue) {
    if (eCSSUnit_Normal == contentValue->mValue.GetUnit() ||
        eCSSUnit_Initial == contentValue->mValue.GetUnit()) {
      // "normal" and "initial" both mean no content
      content->AllocateContents(0);
    }
    else if (eCSSUnit_Inherit == contentValue->mValue.GetUnit()) {
      inherited = PR_TRUE;
      count = parentContent->ContentCount();
      if (NS_SUCCEEDED(content->AllocateContents(count))) {
        while (0 < count--) {
          content->ContentAt(count) = parentContent->ContentAt(count);
        }
      }
    }
    else {
      count = 0;
      while (contentValue) {
        count++;
        contentValue = contentValue->mNext;
      }
      if (NS_SUCCEEDED(content->AllocateContents(count))) {
        const nsAutoString  nullStr;
        count = 0;
        contentValue = contentData.mContent;
        while (contentValue) {
          const nsCSSValue& value = contentValue->mValue;
          nsCSSUnit unit = value.GetUnit();
          nsStyleContentType type;
          nsStyleContentData &data = content->ContentAt(count++);
          switch (unit) {
            case eCSSUnit_String:   type = eStyleContentType_String;    break;
            case eCSSUnit_Image:    type = eStyleContentType_Image;       break;
            case eCSSUnit_Attr:     type = eStyleContentType_Attr;      break;
            case eCSSUnit_Counter:  type = eStyleContentType_Counter;   break;
            case eCSSUnit_Counters: type = eStyleContentType_Counters;  break;
            case eCSSUnit_Enumerated:
              switch (value.GetIntValue()) {
                case NS_STYLE_CONTENT_OPEN_QUOTE:     
                  type = eStyleContentType_OpenQuote;     break;
                case NS_STYLE_CONTENT_CLOSE_QUOTE:
                  type = eStyleContentType_CloseQuote;    break;
                case NS_STYLE_CONTENT_NO_OPEN_QUOTE:
                  type = eStyleContentType_NoOpenQuote;   break;
                case NS_STYLE_CONTENT_NO_CLOSE_QUOTE:
                  type = eStyleContentType_NoCloseQuote;  break;
                default:
                  NS_ERROR("bad content value");
              }
              break;
            default:
              NS_ERROR("bad content type");
          }
          data.mType = type;
          if (type == eStyleContentType_Image) {
            data.mContent.mImage = value.GetImageValue();
            NS_IF_ADDREF(data.mContent.mImage);
          }
          else if (type <= eStyleContentType_Attr) {
            value.GetStringValue(buffer);
            Unquote(buffer);
            data.mContent.mString = nsCRT::strdup(buffer.get());
          }
          else if (type <= eStyleContentType_Counters) {
            data.mContent.mCounters = value.GetArrayValue();
            data.mContent.mCounters->AddRef();
          }
          else {
            data.mContent.mString = nsnull;
          }
          contentValue = contentValue->mNext;
        }
      } 
    }
  }

  // counter-increment: [string [int]]+, none, inherit
  nsCSSCounterData* ourIncrement = contentData.mCounterIncrement;
  if (ourIncrement) {
    if (eCSSUnit_None == ourIncrement->mCounter.GetUnit() ||
        eCSSUnit_Initial == ourIncrement->mCounter.GetUnit()) {
      content->AllocateCounterIncrements(0);
    }
    else if (eCSSUnit_Inherit == ourIncrement->mCounter.GetUnit()) {
      inherited = PR_TRUE;
      count = parentContent->CounterIncrementCount();
      if (NS_SUCCEEDED(content->AllocateCounterIncrements(count))) {
        while (0 < count--) {
          const nsStyleCounterData *data =
            parentContent->GetCounterIncrementAt(count);
          content->SetCounterIncrementAt(count, data->mCounter, data->mValue);
        }
      }
    }
    else if (eCSSUnit_String == ourIncrement->mCounter.GetUnit()) {
      count = 0;
      while (ourIncrement) {
        count++;
        ourIncrement = ourIncrement->mNext;
      }
      if (NS_SUCCEEDED(content->AllocateCounterIncrements(count))) {
        count = 0;
        ourIncrement = contentData.mCounterIncrement;
        while (ourIncrement) {
          PRInt32 increment;
          if (eCSSUnit_Integer == ourIncrement->mValue.GetUnit()) {
            increment = ourIncrement->mValue.GetIntValue();
          }
          else {
            increment = 1;
          }
          ourIncrement->mCounter.GetStringValue(buffer);
          content->SetCounterIncrementAt(count++, buffer, increment);
          ourIncrement = ourIncrement->mNext;
        }
      }
    }
  }

  // counter-reset: [string [int]]+, none, inherit
  nsCSSCounterData* ourReset = contentData.mCounterReset;
  if (ourReset) {
    if (eCSSUnit_None == ourReset->mCounter.GetUnit() ||
        eCSSUnit_Initial == ourReset->mCounter.GetUnit()) {
      content->AllocateCounterResets(0);
    }
    else if (eCSSUnit_Inherit == ourReset->mCounter.GetUnit()) {
      inherited = PR_TRUE;
      count = parentContent->CounterResetCount();
      if (NS_SUCCEEDED(content->AllocateCounterResets(count))) {
        while (0 < count--) {
          const nsStyleCounterData *data =
            parentContent->GetCounterResetAt(count);
          content->SetCounterResetAt(count, data->mCounter, data->mValue);
        }
      }
    }
    else if (eCSSUnit_String == ourReset->mCounter.GetUnit()) {
      count = 0;
      while (ourReset) {
        count++;
        ourReset = ourReset->mNext;
      }
      if (NS_SUCCEEDED(content->AllocateCounterResets(count))) {
        count = 0;
        ourReset = contentData.mCounterReset;
        while (ourReset) {
          PRInt32 reset;
          if (eCSSUnit_Integer == ourReset->mValue.GetUnit()) {
            reset = ourReset->mValue.GetIntValue();
          }
          else {
            reset = 0;
          }
          ourReset->mCounter.GetStringValue(buffer);
          content->SetCounterResetAt(count++, buffer, reset);
          ourReset = ourReset->mNext;
        }
      }
    }
  }

  // marker-offset: length, auto, inherit
  SetCoord(contentData.mMarkerOffset, content->mMarkerOffset, parentContent->mMarkerOffset,
           SETCOORD_LH | SETCOORD_AUTO, aContext, mPresContext, inherited);
    
  if (inherited)
    // We inherited, and therefore can't be cached in the rule node.  We have to be put right on the
    // style context.
    aContext->SetStyle(eStyleStruct_Content, content);
  else {
    // We were fully specified and can therefore be cached right on the rule node.
    if (!aHighestNode->mStyleData.mResetData) {
      aHighestNode->mStyleData.mResetData = new (mPresContext) nsResetStyleData;
      if (NS_UNLIKELY(!aHighestNode->mStyleData.mResetData)) {
        content->Destroy(mPresContext);
        return nsnull;
      }
    }
    aHighestNode->mStyleData.mResetData->mContentData = content;
    // Propagate the bit down.
    PropagateDependentBit(NS_STYLE_INHERIT_BIT(Content), aHighestNode);
  }

  return content;
}

Here is the call graph for this function:

const nsStyleStruct * nsRuleNode::ComputeDisplayData ( nsStyleStruct aStartDisplay,
const nsRuleDataStruct aDisplayData,
nsStyleContext aContext,
nsRuleNode aHighestNode,
const RuleDetail aRuleDetail,
PRBool  aInherited 
) [protected]

Definition at line 2618 of file nsRuleNode.cpp.

{
  nsStyleContext* parentContext = aContext->GetParent();

  const nsRuleDataDisplay& displayData = NS_STATIC_CAST(const nsRuleDataDisplay&, aData);
  nsStyleDisplay* display;
  if (aStartStruct)
    // We only need to compute the delta between this computed data and our
    // computed data.
    display = new (mPresContext) nsStyleDisplay(*NS_STATIC_CAST(nsStyleDisplay*, aStartStruct));
  else
    display = new (mPresContext) nsStyleDisplay();

  if (NS_UNLIKELY(!display))
    return nsnull;  // Out Of Memory

  const nsStyleDisplay* parentDisplay = display;
  nsIAtom* pseudoTag = aContext->GetPseudoType();
  PRBool generatedContent = (pseudoTag == nsCSSPseudoElements::before || 
                             pseudoTag == nsCSSPseudoElements::after);

  if (parentContext && 
      ((aRuleDetail != eRuleFullReset &&
        aRuleDetail != eRulePartialReset &&
        aRuleDetail != eRuleNone) ||
       generatedContent))
    parentDisplay = parentContext->GetStyleDisplay();
  PRBool inherited = aInherited;

  // opacity: factor, inherit
  if (eCSSUnit_Number == displayData.mOpacity.GetUnit()) {
    display->mOpacity = displayData.mOpacity.GetFloatValue();
    if (display->mOpacity > 1.0f)
      display->mOpacity = 1.0f;
    if (display->mOpacity < 0.0f)
      display->mOpacity = 0.0f;
  }
  else if (eCSSUnit_Inherit == displayData.mOpacity.GetUnit()) {
    inherited = PR_TRUE;
    display->mOpacity = parentDisplay->mOpacity;
  }

  // display: enum, none, inherit
  if (eCSSUnit_Enumerated == displayData.mDisplay.GetUnit()) {
    display->mDisplay = displayData.mDisplay.GetIntValue();
  }
  else if (eCSSUnit_None == displayData.mDisplay.GetUnit()) {
    display->mDisplay = NS_STYLE_DISPLAY_NONE;
  }
  else if (eCSSUnit_Inherit == displayData.mDisplay.GetUnit()) {
    inherited = PR_TRUE;
    display->mDisplay = parentDisplay->mDisplay;
  }

  // appearance: enum, none, inherit
  if (eCSSUnit_Enumerated == displayData.mAppearance.GetUnit()) {
    display->mAppearance = displayData.mAppearance.GetIntValue();
  }
  else if (eCSSUnit_None == displayData.mAppearance.GetUnit()) {
    display->mAppearance = NS_THEME_NONE;
  }
  else if (eCSSUnit_Inherit == displayData.mAppearance.GetUnit()) {
    inherited = PR_TRUE;
    display->mAppearance = parentDisplay->mAppearance;
  }

  // binding: url, none, inherit
  if (eCSSUnit_URL == displayData.mBinding.GetUnit()) {
    display->mBinding = displayData.mBinding.GetURLValue();
  }
  else if (eCSSUnit_None == displayData.mBinding.GetUnit()) {
    display->mBinding = nsnull;
  }
  else if (eCSSUnit_Inherit == displayData.mBinding.GetUnit()) {
    inherited = PR_TRUE;
    display->mBinding = parentDisplay->mBinding;
  }

  // position: enum, inherit
  if (eCSSUnit_Enumerated == displayData.mPosition.GetUnit()) {
    display->mPosition = displayData.mPosition.GetIntValue();
  }
  else if (eCSSUnit_Inherit == displayData.mPosition.GetUnit()) {
    inherited = PR_TRUE;
    display->mPosition = parentDisplay->mPosition;
  }

  // clear: enum, none, inherit
  if (eCSSUnit_Enumerated == displayData.mClear.GetUnit()) {
    display->mBreakType = displayData.mClear.GetIntValue();
  }
  else if (eCSSUnit_None == displayData.mClear.GetUnit()) {
    display->mBreakType = NS_STYLE_CLEAR_NONE;
  }
  else if (eCSSUnit_Inherit == displayData.mClear.GetUnit()) {
    inherited = PR_TRUE;
    display->mBreakType = parentDisplay->mBreakType;
  }

  // temp fix for bug 24000
  if (eCSSUnit_Enumerated == displayData.mBreakBefore.GetUnit()) {
    display->mBreakBefore = (NS_STYLE_PAGE_BREAK_ALWAYS == displayData.mBreakBefore.GetIntValue());
  }
  if (eCSSUnit_Enumerated == displayData.mBreakAfter.GetUnit()) {
    display->mBreakAfter = (NS_STYLE_PAGE_BREAK_ALWAYS == displayData.mBreakAfter.GetIntValue());
  }
  // end temp fix

  // float: enum, none, inherit
  if (eCSSUnit_Enumerated == displayData.mFloat.GetUnit()) {
    display->mFloats = displayData.mFloat.GetIntValue();
  }
  else if (eCSSUnit_None == displayData.mFloat.GetUnit()) {
    display->mFloats = NS_STYLE_FLOAT_NONE;
  }
  else if (eCSSUnit_Inherit == displayData.mFloat.GetUnit()) {
    inherited = PR_TRUE;
    display->mFloats = parentDisplay->mFloats;
  }

  // overflow-x: enum, auto, inherit
  if (eCSSUnit_Enumerated == displayData.mOverflowX.GetUnit()) {
    display->mOverflowX = displayData.mOverflowX.GetIntValue();
  }
  else if (eCSSUnit_Auto == displayData.mOverflowX.GetUnit()) {
    display->mOverflowX = NS_STYLE_OVERFLOW_AUTO;
  }
  else if (eCSSUnit_Inherit == displayData.mOverflowX.GetUnit()) {
    inherited = PR_TRUE;
    display->mOverflowX = parentDisplay->mOverflowX;
  }

  // overflow-y: enum, auto, inherit
  if (eCSSUnit_Enumerated == displayData.mOverflowY.GetUnit()) {
    display->mOverflowY = displayData.mOverflowY.GetIntValue();
  }
  else if (eCSSUnit_Auto == displayData.mOverflowY.GetUnit()) {
    display->mOverflowY = NS_STYLE_OVERFLOW_AUTO;
  }
  else if (eCSSUnit_Inherit == displayData.mOverflowY.GetUnit()) {
    inherited = PR_TRUE;
    display->mOverflowY = parentDisplay->mOverflowY;
  }

  // CSS3 overflow-x and overflow-y require some fixup as well in some
  // cases.  NS_STYLE_OVERFLOW_VISIBLE and NS_STYLE_OVERFLOW_CLIP are
  // meaningful only when used in both dimensions.
  if (display->mOverflowX != display->mOverflowY &&
      (display->mOverflowX == NS_STYLE_OVERFLOW_VISIBLE ||
       display->mOverflowX == NS_STYLE_OVERFLOW_CLIP ||
       display->mOverflowY == NS_STYLE_OVERFLOW_VISIBLE ||
       display->mOverflowY == NS_STYLE_OVERFLOW_CLIP)) {
    // We can't store in the rule tree since a more specific rule might
    // change these conditions.
    inherited = PR_TRUE;

    // NS_STYLE_OVERFLOW_CLIP is a deprecated value, so if it's specified
    // in only one dimension, convert it to NS_STYLE_OVERFLOW_HIDDEN.
    if (display->mOverflowX == NS_STYLE_OVERFLOW_CLIP)
      display->mOverflowX = NS_STYLE_OVERFLOW_HIDDEN;
    if (display->mOverflowY == NS_STYLE_OVERFLOW_CLIP)
      display->mOverflowY = NS_STYLE_OVERFLOW_HIDDEN;

    // If 'visible' is specified but doesn't match the other dimension, it
    // turns into 'auto'.
    if (display->mOverflowX == NS_STYLE_OVERFLOW_VISIBLE)
      display->mOverflowX = NS_STYLE_OVERFLOW_AUTO;
    if (display->mOverflowY == NS_STYLE_OVERFLOW_VISIBLE)
      display->mOverflowY = NS_STYLE_OVERFLOW_AUTO;
  }

  // clip property: length, auto, inherit
  if (eCSSUnit_Inherit == displayData.mClip.mTop.GetUnit()) { // if one is inherit, they all are
    inherited = PR_TRUE;
    display->mClipFlags = parentDisplay->mClipFlags;
    display->mClip = parentDisplay->mClip;
  }
  else {
    PRBool  fullAuto = PR_TRUE;

    display->mClipFlags = 0; // clear it

    if (eCSSUnit_Auto == displayData.mClip.mTop.GetUnit()) {
      display->mClip.y = 0;
      display->mClipFlags |= NS_STYLE_CLIP_TOP_AUTO;
    } 
    else if (displayData.mClip.mTop.IsLengthUnit()) {
      display->mClip.y = CalcLength(displayData.mClip.mTop, nsnull, aContext, mPresContext, inherited);
      fullAuto = PR_FALSE;
    }
    if (eCSSUnit_Auto == displayData.mClip.mBottom.GetUnit()) {
      // Setting to NS_MAXSIZE for the 'auto' case ensures that
      // the clip rect is nonempty. It is important that mClip be
      // nonempty if the actual clip rect could be nonempty.
      display->mClip.height = NS_MAXSIZE;
      display->mClipFlags |= NS_STYLE_CLIP_BOTTOM_AUTO;
    } 
    else if (displayData.mClip.mBottom.IsLengthUnit()) {
      display->mClip.height = CalcLength(displayData.mClip.mBottom, nsnull, aContext, mPresContext, inherited) -
                              display->mClip.y;
      fullAuto = PR_FALSE;
    }
    if (eCSSUnit_Auto == displayData.mClip.mLeft.GetUnit()) {
      display->mClip.x = 0;
      display->mClipFlags |= NS_STYLE_CLIP_LEFT_AUTO;
    } 
    else if (displayData.mClip.mLeft.IsLengthUnit()) {
      display->mClip.x = CalcLength(displayData.mClip.mLeft, nsnull, aContext, mPresContext, inherited);
      fullAuto = PR_FALSE;
    }
    if (eCSSUnit_Auto == displayData.mClip.mRight.GetUnit()) {
      // Setting to NS_MAXSIZE for the 'auto' case ensures that
      // the clip rect is nonempty. It is important that mClip be
      // nonempty if the actual clip rect could be nonempty.
      display->mClip.width = NS_MAXSIZE;
      display->mClipFlags |= NS_STYLE_CLIP_RIGHT_AUTO;
    } 
    else if (displayData.mClip.mRight.IsLengthUnit()) {
      display->mClip.width = CalcLength(displayData.mClip.mRight, nsnull, aContext, mPresContext, inherited) -
                             display->mClip.x;
      fullAuto = PR_FALSE;
    }
    display->mClipFlags &= ~NS_STYLE_CLIP_TYPE_MASK;
    if (fullAuto) {
      display->mClipFlags |= NS_STYLE_CLIP_AUTO;
    }
    else {
      display->mClipFlags |= NS_STYLE_CLIP_RECT;
    }
  }

  // CSS2 specified fixups:
  if (generatedContent) {
    // According to CSS2 section 12.1, :before and :after
    // pseudo-elements must not be positioned or floated (CSS2 12.1) and
    // must be limited to certain display types (depending on the
    // display type of the element to which they are attached).

    if (display->mPosition != NS_STYLE_POSITION_STATIC)
      display->mPosition = NS_STYLE_POSITION_STATIC;
    if (display->mFloats != NS_STYLE_FLOAT_NONE)
      display->mFloats = NS_STYLE_FLOAT_NONE;

    PRUint8 displayValue = display->mDisplay;
    if (displayValue != NS_STYLE_DISPLAY_NONE &&
        displayValue != NS_STYLE_DISPLAY_INLINE) {
      inherited = PR_TRUE;
      if (parentDisplay->IsBlockLevel() ||
          parentDisplay->mDisplay == NS_STYLE_DISPLAY_TABLE_CELL ||
          parentDisplay->mDisplay == NS_STYLE_DISPLAY_TABLE_CAPTION) {
        // If the subject of the selector is a block-level element,
        // allowed values are 'none', 'inline', 'block', and 'marker'.
        // If the value of the 'display' has any other value, the
        // pseudo-element will behave as if the value were 'block'.
        if (displayValue != NS_STYLE_DISPLAY_BLOCK &&
            displayValue != NS_STYLE_DISPLAY_MARKER)
          display->mDisplay = NS_STYLE_DISPLAY_BLOCK;
      } else {
        // If the subject of the selector is an inline-level element,
        // allowed values are 'none' and 'inline'. If the value of the
        // 'display' has any other value, the pseudo-element will behave
        // as if the value were 'inline'.
        display->mDisplay = NS_STYLE_DISPLAY_INLINE;
      }
    }
  }
  else if (display->mDisplay != NS_STYLE_DISPLAY_NONE) {
    // CSS2 9.7 specifies display type corrections dealing with 'float'
    // and 'position'.  Since generated content can't be floated or
    // positioned, we can deal with it here.

    // 1) if float is not none, and display is not none, then we must
    // set a block-level 'display' type per CSS2.1 section 9.7.
    if (display->mFloats != NS_STYLE_FLOAT_NONE) {
      EnsureBlockDisplay(display->mDisplay);
      
      // We can't cache the data in the rule tree since if a more specific
      // rule has 'float: none' we'll end up with the wrong 'display'
      // property.
      inherited = PR_TRUE;
    } else if (nsCSSPseudoElements::firstLetter == pseudoTag) {
      // a non-floating first-letter must be inline
      // XXX this fix can go away once bug 103189 is fixed correctly
      display->mDisplay = NS_STYLE_DISPLAY_INLINE;
      
      // We can't cache the data in the rule tree since if a more specific
      // rule has 'float: left' we'll end up with the wrong 'display'
      // property.
      inherited = PR_TRUE;
    }
    
    // 2) if position is 'absolute' or 'fixed' then display must be
    // block-level and float must be 'none'
    if (display->IsAbsolutelyPositioned()) {
      // Backup original display value for calculation of a hypothetical
      // box (CSS2 10.6.4/10.6.5).
      // See nsHTMLReflowState::CalculateHypotheticalBox
      display->mOriginalDisplay = display->mDisplay;
      EnsureBlockDisplay(display->mDisplay);
      display->mFloats = NS_STYLE_FLOAT_NONE;
      
      // We can't cache the data in the rule tree since if a more specific
      // rule has 'position: static' we'll end up with problems with the
      // 'display' and 'float' properties.
      inherited = PR_TRUE;
    }
  }

  if (inherited)
    // We inherited, and therefore can't be cached in the rule node.  We have to be put right on the
    // style context.
    aContext->SetStyle(eStyleStruct_Display, display);
  else {
    // We were fully specified and can therefore be cached right on the rule node.
    if (!aHighestNode->mStyleData.mResetData) {
      aHighestNode->mStyleData.mResetData = new (mPresContext) nsResetStyleData;
      if (NS_UNLIKELY(!aHighestNode->mStyleData.mResetData)) {
        display->Destroy(mPresContext);
        return nsnull;
      }
    }
    aHighestNode->mStyleData.mResetData->mDisplayData = display;
    // Propagate the bit down.
    PropagateDependentBit(NS_STYLE_INHERIT_BIT(Display), aHighestNode);
  }

  return display;
}

Here is the call graph for this function:

const nsStyleStruct * nsRuleNode::ComputeFontData ( nsStyleStruct aStartFont,
const nsRuleDataStruct aFontData,
nsStyleContext aContext,
nsRuleNode aHighestNode,
const RuleDetail aRuleDetail,
PRBool  aInherited 
) [protected]

Definition at line 2036 of file nsRuleNode.cpp.

{
  nsStyleContext* parentContext = aContext->GetParent();

  const nsRuleDataFont& fontData = NS_STATIC_CAST(const nsRuleDataFont&, aData);
  nsStyleFont* font = nsnull;
  const nsStyleFont* parentFont = nsnull;
  PRBool inherited = aInherited;

  // This optimization is a little weaker here since 'em', etc., for
  // 'font-size' require inheritance.
  if (parentContext &&
      (aRuleDetail != eRuleFullReset ||
       (fontData.mSize.IsRelativeLengthUnit() &&
        fontData.mSize.GetUnit() != eCSSUnit_Pixel) ||
       fontData.mSize.GetUnit() == eCSSUnit_Percent))
    parentFont = parentContext->GetStyleFont();
  if (aStartStruct)
    // We only need to compute the delta between this computed data and our
    // computed data.
    font = new (mPresContext) nsStyleFont(*NS_STATIC_CAST(nsStyleFont*, aStartStruct));
  else {
    // XXXldb What about eRuleFullInherited?  Which path is faster?
    if (aRuleDetail != eRuleFullMixed && aRuleDetail != eRuleFullReset) {
      // No question. We will have to inherit. Go ahead and init
      // with inherited vals from parent.
      inherited = PR_TRUE;
      if (parentFont)
        font = new (mPresContext) nsStyleFont(*parentFont);
      else
        font = new (mPresContext) nsStyleFont(mPresContext);
    }
    else
      font = new (mPresContext) nsStyleFont(mPresContext);
  }

  if (NS_UNLIKELY(!font))
    return nsnull; // Out Of Memory
  if (!parentFont)
    parentFont = font;

  // See if there is a minimum font-size constraint to honor
  nscoord minimumFontSize = 
    mPresContext->GetCachedIntPref(kPresContext_MinimumFontSize);

  if (minimumFontSize < 0)
    minimumFontSize = 0;

  PRBool useDocumentFonts = PR_TRUE;

  // Figure out if we are a generic font
  PRUint8 generic = kGenericFont_NONE;
  if (eCSSUnit_String == fontData.mFamily.GetUnit()) {
    fontData.mFamily.GetStringValue(font->mFont.name);
    nsFont::GetGenericID(font->mFont.name, &generic);

    // MJA: bug 31816
    // if we are not using document fonts, but this is a XUL document,
    // then we use the document fonts anyway
    useDocumentFonts =
      mPresContext->GetCachedBoolPref(kPresContext_UseDocumentFonts);
  }

  // See if we are in the chrome
  // We only need to know this to determine if we have to use the
  // document fonts (overriding the useDocumentFonts flag), or to
  // determine if we have to override the minimum font-size constraint.
  if ((!useDocumentFonts || minimumFontSize > 0) && IsChrome(mPresContext)) {
    useDocumentFonts = PR_TRUE;
    minimumFontSize = 0;
  }

  // If we don't have to use document fonts, then we are only entitled
  // to use the user's default variable-width font and fixed-width font
  if (!useDocumentFonts) {
    if (generic != kGenericFont_moz_fixed)
      generic = kGenericFont_NONE;
  }

  // Now compute our font struct
  if (generic == kGenericFont_NONE) {
    // continue the normal processing
    // our default font is the most recent generic font
    const nsFont* defaultFont =
      mPresContext->GetDefaultFont(parentFont->mFlags & NS_STYLE_FONT_FACE_MASK);

    nsRuleNode::SetFont(mPresContext, aContext, minimumFontSize,
                        useDocumentFonts, PR_FALSE,
                        fontData, *defaultFont, parentFont, font, inherited);
  }
  else {
    // re-calculate the font as a generic font
    inherited = PR_TRUE;
    nsRuleNode::SetGenericFont(mPresContext, aContext, fontData, generic,
                               minimumFontSize, useDocumentFonts, font);
  }
  // Set our generic font's bit to inform our descendants
  font->mFlags &= ~NS_STYLE_FONT_FACE_MASK;
  font->mFlags |= generic;

  if (inherited)
    // We inherited, and therefore can't be cached in the rule node.  We have to be put right on the
    // style context.
    aContext->SetStyle(eStyleStruct_Font, font);
  else {
    // We were fully specified and can therefore be cached right on the rule node.
    if (!aHighestNode->mStyleData.mInheritedData) {
      aHighestNode->mStyleData.mInheritedData = new (mPresContext) nsInheritedStyleData;
      if (NS_UNLIKELY(!aHighestNode->mStyleData.mInheritedData)) {
        font->Destroy(mPresContext);
        return nsnull;
      }
    }
    aHighestNode->mStyleData.mInheritedData->mFontData = font;
    // Propagate the bit down.
    PropagateDependentBit(NS_STYLE_INHERIT_BIT(Font), aHighestNode);
  }

  return font;
}

Here is the call graph for this function:

const nsStyleStruct * nsRuleNode::ComputeListData ( nsStyleStruct aStartList,
const nsRuleDataStruct aListData,
nsStyleContext aContext,
nsRuleNode aHighestNode,
const RuleDetail aRuleDetail,
PRBool  aInherited 
) [protected]

Definition at line 3757 of file nsRuleNode.cpp.

{
  nsStyleContext* parentContext = aContext->GetParent();

  const nsRuleDataList& listData = NS_STATIC_CAST(const nsRuleDataList&, aData);
  nsStyleList* list = nsnull;
  const nsStyleList* parentList = nsnull;
  PRBool inherited = aInherited;

  if (parentContext && aRuleDetail != eRuleFullReset)
    parentList = parentContext->GetStyleList();
  if (aStartStruct)
    // We only need to compute the delta between this computed data and our
    // computed data.
    list = new (mPresContext) nsStyleList(*NS_STATIC_CAST(nsStyleList*, aStartStruct));
  else {
    // XXXldb What about eRuleFullInherited?  Which path is faster?
    if (aRuleDetail != eRuleFullMixed && aRuleDetail != eRuleFullReset) {
      // No question. We will have to inherit. Go ahead and init
      // with inherited vals from parent.
      inherited = PR_TRUE;
      if (parentList)
        list = new (mPresContext) nsStyleList(*parentList);
      else
        list = new (mPresContext) nsStyleList();
    }
    else
      list = new (mPresContext) nsStyleList();
  }

  if (NS_UNLIKELY(!list))
    return nsnull;  // Out Of Memory
  if (!parentList)
    parentList = list;

  // list-style-type: enum, none, inherit
  if (eCSSUnit_Enumerated == listData.mType.GetUnit()) {
    list->mListStyleType = listData.mType.GetIntValue();
  }
  else if (eCSSUnit_None == listData.mType.GetUnit()) {
    list->mListStyleType = NS_STYLE_LIST_STYLE_NONE;
  }
  else if (eCSSUnit_Inherit == listData.mType.GetUnit()) {
    inherited = PR_TRUE;
    list->mListStyleType = parentList->mListStyleType;
  }

  // list-style-image: url, none, inherit
  if (eCSSUnit_Image == listData.mImage.GetUnit()) {
    list->mListStyleImage = listData.mImage.GetImageValue();
  }
  else if (eCSSUnit_None == listData.mImage.GetUnit()) {
    list->mListStyleImage = nsnull;
  }
  else if (eCSSUnit_Inherit == listData.mImage.GetUnit()) {
    inherited = PR_TRUE;
    list->mListStyleImage = parentList->mListStyleImage;
  }

  // list-style-position: enum, inherit
  if (eCSSUnit_Enumerated == listData.mPosition.GetUnit()) {
    list->mListStylePosition = listData.mPosition.GetIntValue();
  }
  else if (eCSSUnit_Inherit == listData.mPosition.GetUnit()) {
    inherited = PR_TRUE;
    list->mListStylePosition = parentList->mListStylePosition;
  }

  // image region property: length, auto, inherit
  if (eCSSUnit_Inherit == listData.mImageRegion.mTop.GetUnit()) { // if one is inherit, they all are
    inherited = PR_TRUE;
    list->mImageRegion = parentList->mImageRegion;
  }
  else {
    if (eCSSUnit_Auto == listData.mImageRegion.mTop.GetUnit())
      list->mImageRegion.y = 0;
    else if (listData.mImageRegion.mTop.IsLengthUnit())
      list->mImageRegion.y = CalcLength(listData.mImageRegion.mTop, nsnull, aContext, mPresContext, inherited);
      
    if (eCSSUnit_Auto == listData.mImageRegion.mBottom.GetUnit())
      list->mImageRegion.height = 0;
    else if (listData.mImageRegion.mBottom.IsLengthUnit())
      list->mImageRegion.height = CalcLength(listData.mImageRegion.mBottom, nsnull, aContext, 
                                            mPresContext, inherited) - list->mImageRegion.y;
  
    if (eCSSUnit_Auto == listData.mImageRegion.mLeft.GetUnit())
      list->mImageRegion.x = 0;
    else if (listData.mImageRegion.mLeft.IsLengthUnit())
      list->mImageRegion.x = CalcLength(listData.mImageRegion.mLeft, nsnull, aContext, mPresContext, inherited);
      
    if (eCSSUnit_Auto == listData.mImageRegion.mRight.GetUnit())
      list->mImageRegion.width = 0;
    else if (listData.mImageRegion.mRight.IsLengthUnit())
      list->mImageRegion.width = CalcLength(listData.mImageRegion.mRight, nsnull, aContext, mPresContext, inherited) -
                                list->mImageRegion.x;
  }

  if (inherited)
    // We inherited, and therefore can't be cached in the rule node.  We have to be put right on the
    // style context.
    aContext->SetStyle(eStyleStruct_List, list);
  else {
    // We were fully specified and can therefore be cached right on the rule node.
    if (!aHighestNode->mStyleData.mInheritedData) {
      aHighestNode->mStyleData.mInheritedData = new (mPresContext) nsInheritedStyleData;
      if (NS_UNLIKELY(!aHighestNode->mStyleData.mInheritedData)) {
        list->Destroy(mPresContext);
        return nsnull;
      }
    }
    aHighestNode->mStyleData.mInheritedData->mListData = list;
    // Propagate the bit down.
    PropagateDependentBit(NS_STYLE_INHERIT_BIT(List), aHighestNode);
  }

  return list;
}

Here is the call graph for this function:

const nsStyleStruct * nsRuleNode::ComputeMarginData ( nsStyleStruct aStartMargin,
const nsRuleDataStruct aMarginData,
nsStyleContext aContext,
nsRuleNode aHighestNode,
const RuleDetail aRuleDetail,
PRBool  aInherited 
) [protected]

Definition at line 3302 of file nsRuleNode.cpp.

{
  nsStyleContext* parentContext = aContext->GetParent();

  const nsRuleDataMargin& marginData = NS_STATIC_CAST(const nsRuleDataMargin&, aData);
  nsStyleMargin* margin;
  if (aStartStruct)
    // We only need to compute the delta between this computed data and our
    // computed data.
    margin = new (mPresContext) nsStyleMargin(*NS_STATIC_CAST(nsStyleMargin*, aStartStruct));
  else
    margin = new (mPresContext) nsStyleMargin();

  if (NS_UNLIKELY(!margin))
    return nsnull;  // Out Of Memory

  const nsStyleMargin* parentMargin = margin;
  if (parentContext && 
      aRuleDetail != eRuleFullReset &&
      aRuleDetail != eRulePartialReset &&
      aRuleDetail != eRuleNone)
    parentMargin = parentContext->GetStyleMargin();
  PRBool inherited = aInherited;

  // margin: length, percent, auto, inherit
  nsStyleCoord  coord;
  nsStyleCoord  parentCoord;
  NS_FOR_CSS_SIDES(side) {
    parentMargin->mMargin.Get(side, parentCoord);
    if (SetCoord(marginData.mMargin.*(nsCSSRect::sides[side]),
                 coord, parentCoord, SETCOORD_LPAH,
                 aContext, mPresContext, inherited)) {
      margin->mMargin.Set(side, coord);
    }
  }

  AdjustLogicalBoxProp(aContext,
                       marginData.mMarginLeftLTRSource,
                       marginData.mMarginLeftRTLSource,
                       marginData.mMarginStart, marginData.mMarginEnd,
                       parentMargin->mMargin, margin->mMargin,
                       NS_SIDE_LEFT, SETCOORD_LPAH, inherited);
  AdjustLogicalBoxProp(aContext,
                       marginData.mMarginRightLTRSource,
                       marginData.mMarginRightRTLSource,
                       marginData.mMarginEnd, marginData.mMarginStart,
                       parentMargin->mMargin, margin->mMargin,
                       NS_SIDE_RIGHT, SETCOORD_LPAH, inherited);

  if (inherited)
    // We inherited, and therefore can't be cached in the rule node.  We have to be put right on the
    // style context.
    aContext->SetStyle(eStyleStruct_Margin, margin);
  else {
    // We were fully specified and can therefore be cached right on the rule node.
    if (!aHighestNode->mStyleData.mResetData) {
      aHighestNode->mStyleData.mResetData = new (mPresContext) nsResetStyleData;
      if (NS_UNLIKELY(!aHighestNode->mStyleData.mResetData)) {
        margin->Destroy(mPresContext);
        return nsnull;
      }
    }
    aHighestNode->mStyleData.mResetData->mMarginData = margin;
    // Propagate the bit down.
    PropagateDependentBit(NS_STYLE_INHERIT_BIT(Margin), aHighestNode);
  }

  margin->RecalcData();
  return margin;
}

Here is the call graph for this function:

const nsStyleStruct * nsRuleNode::ComputeOutlineData ( nsStyleStruct aStartOutline,
const nsRuleDataStruct aMarginData,
nsStyleContext aContext,
nsRuleNode aHighestNode,
const RuleDetail aRuleDetail,
PRBool  aInherited 
) [protected]

Definition at line 3657 of file nsRuleNode.cpp.

{
  nsStyleContext* parentContext = aContext->GetParent();

  const nsRuleDataMargin& marginData = NS_STATIC_CAST(const nsRuleDataMargin&, aData);
  nsStyleOutline* outline;
  if (aStartStruct)
    // We only need to compute the delta between this computed data and our
    // computed data.
    outline = new (mPresContext) nsStyleOutline(*NS_STATIC_CAST(nsStyleOutline*, aStartStruct));
  else
    outline = new (mPresContext) nsStyleOutline(mPresContext);
  
  if (NS_UNLIKELY(!outline))
    return nsnull;  // Out Of Memory

  const nsStyleOutline* parentOutline = outline;
  if (parentContext && 
      aRuleDetail != eRuleFullReset &&
      aRuleDetail != eRulePartialReset &&
      aRuleDetail != eRuleNone)
    parentOutline = parentContext->GetStyleOutline();
  PRBool inherited = aInherited;

  // outline-width: length, enum, inherit
  SetCoord(marginData.mOutlineWidth, outline->mOutlineWidth, parentOutline->mOutlineWidth,
           SETCOORD_LEH, aContext, mPresContext, inherited);

  // outline-offset: length, inherit
  SetCoord(marginData.mOutlineOffset, outline->mOutlineOffset, parentOutline->mOutlineOffset,
           SETCOORD_LH, aContext, mPresContext, inherited);
  

  // outline-color: color, string, enum, inherit
  nscolor outlineColor;
  nscolor unused = NS_RGB(0,0,0);
  if (eCSSUnit_Inherit == marginData.mOutlineColor.GetUnit()) {
    inherited = PR_TRUE;
    if (parentOutline->GetOutlineColor(outlineColor))
      outline->SetOutlineColor(outlineColor);
    else
      outline->SetOutlineInvert();
  }
  else if (SetColor(marginData.mOutlineColor, unused, mPresContext, aContext, outlineColor, inherited))
    outline->SetOutlineColor(outlineColor);
  else if (eCSSUnit_Enumerated == marginData.mOutlineColor.GetUnit())
    outline->SetOutlineInvert();

// -moz-outline-radius: length, percent, inherit
  nsStyleCoord  coord;
  nsStyleCoord  parentCoord;
  { // scope for compilers with broken |for| loop scoping
    NS_FOR_CSS_SIDES(side) {
      parentOutline->mOutlineRadius.Get(side, parentCoord);
      if (SetCoord(marginData.mOutlineRadius.*(nsCSSRect::sides[side]), coord,
                   parentCoord, SETCOORD_LPH, aContext, mPresContext,
                   inherited))
        outline->mOutlineRadius.Set(side, coord);
    }
  }

  // outline-style: auto, enum, none, inherit
  if (eCSSUnit_Enumerated == marginData.mOutlineStyle.GetUnit())
    outline->SetOutlineStyle(marginData.mOutlineStyle.GetIntValue());
  else if (eCSSUnit_None == marginData.mOutlineStyle.GetUnit())
    outline->SetOutlineStyle(NS_STYLE_BORDER_STYLE_NONE);
  else if (eCSSUnit_Auto == marginData.mOutlineStyle.GetUnit()) {
    outline->SetOutlineStyle(NS_STYLE_BORDER_STYLE_AUTO);
  } else if (eCSSUnit_Inherit == marginData.mOutlineStyle.GetUnit()) {
    inherited = PR_TRUE;
    outline->SetOutlineStyle(parentOutline->GetOutlineStyle());
  }

  if (inherited)
    // We inherited, and therefore can't be cached in the rule node.  We have to be put right on the
    // style context.
    aContext->SetStyle(eStyleStruct_Outline, outline);
  else {
    // We were fully specified and can therefore be cached right on the rule node.
    if (!aHighestNode->mStyleData.mResetData) {
      aHighestNode->mStyleData.mResetData = new (mPresContext) nsResetStyleData;
      if (NS_UNLIKELY(!aHighestNode->mStyleData.mResetData)) {
        outline->Destroy(mPresContext);
        return nsnull;
      }
    }
    aHighestNode->mStyleData.mResetData->mOutlineData = outline;
    // Propagate the bit down.
    PropagateDependentBit(NS_STYLE_INHERIT_BIT(Outline), aHighestNode);
  }

  outline->RecalcData(mPresContext);
  return outline;
}

Here is the call graph for this function:

const nsStyleStruct * nsRuleNode::ComputePaddingData ( nsStyleStruct aStartPadding,
const nsRuleDataStruct aMarginData,
nsStyleContext aContext,
nsRuleNode aHighestNode,
const RuleDetail aRuleDetail,
PRBool  aInherited 
) [protected]

Definition at line 3581 of file nsRuleNode.cpp.

{
  nsStyleContext* parentContext = aContext->GetParent();

  const nsRuleDataMargin& marginData = NS_STATIC_CAST(const nsRuleDataMargin&, aData);
  nsStylePadding* padding;
  if (aStartStruct)
    // We only need to compute the delta between this computed data and our
    // computed data.
    padding = new (mPresContext) nsStylePadding(*NS_STATIC_CAST(nsStylePadding*, aStartStruct));
  else
    padding = new (mPresContext) nsStylePadding();
  
  if (NS_UNLIKELY(!padding))
    return nsnull;  // Out Of Memory

  const nsStylePadding* parentPadding = padding;
  if (parentContext && 
      aRuleDetail != eRuleFullReset &&
      aRuleDetail != eRulePartialReset &&
      aRuleDetail != eRuleNone)
    parentPadding = parentContext->GetStylePadding();
  PRBool inherited = aInherited;

  // padding: length, percent, inherit
  nsStyleCoord  coord;
  nsStyleCoord  parentCoord;
  NS_FOR_CSS_SIDES(side) {
    parentPadding->mPadding.Get(side, parentCoord);
    if (SetCoord(marginData.mPadding.*(nsCSSRect::sides[side]),
                 coord, parentCoord, SETCOORD_LPH,
                 aContext, mPresContext, inherited)) {
      padding->mPadding.Set(side, coord);
    }
  }

  AdjustLogicalBoxProp(aContext,
                       marginData.mPaddingLeftLTRSource,
                       marginData.mPaddingLeftRTLSource,
                       marginData.mPaddingStart, marginData.mPaddingEnd,
                       parentPadding->mPadding, padding->mPadding,
                       NS_SIDE_LEFT, SETCOORD_LPH, inherited);
  AdjustLogicalBoxProp(aContext,
                       marginData.mPaddingRightLTRSource,
                       marginData.mPaddingRightRTLSource,
                       marginData.mPaddingEnd, marginData.mPaddingStart,
                       parentPadding->mPadding, padding->mPadding,
                       NS_SIDE_RIGHT, SETCOORD_LPH, inherited);

  if (inherited)
    // We inherited, and therefore can't be cached in the rule node.  We have to be put right on the
    // style context.
    aContext->SetStyle(eStyleStruct_Padding, padding);
  else {
    // We were fully specified and can therefore be cached right on the rule node.
    if (!aHighestNode->mStyleData.mResetData) {
      aHighestNode->mStyleData.mResetData = new (mPresContext) nsResetStyleData;
      if (!aHighestNode->mStyleData.mResetData) {
        delete padding;
        return nsnull;
      }
    }
    aHighestNode->mStyleData.mResetData->mPaddingData = padding;
    // Propagate the bit down.
    PropagateDependentBit(NS_STYLE_INHERIT_BIT(Padding), aHighestNode);
  }

  padding->RecalcData();
  return padding;
}

Here is the call graph for this function:

const nsStyleStruct * nsRuleNode::ComputePositionData ( nsStyleStruct aStartPosition,
const nsRuleDataStruct aPositionData,
nsStyleContext aContext,
nsRuleNode aHighestNode,
const RuleDetail aRuleDetail,
PRBool  aInherited 
) [protected]

Definition at line 3880 of file nsRuleNode.cpp.

{
  nsStyleContext* parentContext = aContext->GetParent();

  const nsRuleDataPosition& posData = NS_STATIC_CAST(const nsRuleDataPosition&, aData);
  nsStylePosition* pos;
  if (aStartStruct)
    // We only need to compute the delta between this computed data and our
    // computed data.
    pos = new (mPresContext) nsStylePosition(*NS_STATIC_CAST(nsStylePosition*, aStartStruct));
  else
    pos = new (mPresContext) nsStylePosition();
  
  if (NS_UNLIKELY(!pos))
    return nsnull;  // Out Of Memory

  const nsStylePosition* parentPos = pos;
  if (parentContext && 
      aRuleDetail != eRuleFullReset &&
      aRuleDetail != eRulePartialReset &&
      aRuleDetail != eRuleNone)
    parentPos = parentContext->GetStylePosition();
  PRBool inherited = aInherited;

  // box offsets: length, percent, auto, inherit
  nsStyleCoord  coord;
  nsStyleCoord  parentCoord;
  NS_FOR_CSS_SIDES(side) {
    parentPos->mOffset.Get(side, parentCoord);
    if (SetCoord(posData.mOffset.*(nsCSSRect::sides[side]),
                 coord, parentCoord, SETCOORD_LPAH,
                 aContext, mPresContext, inherited)) {
      pos->mOffset.Set(side, coord);
    }
  }

  if (posData.mWidth.GetUnit() == eCSSUnit_Proportional)
    pos->mWidth.SetIntValue((PRInt32)(posData.mWidth.GetFloatValue()), eStyleUnit_Proportional);
  else 
    SetCoord(posData.mWidth, pos->mWidth, parentPos->mWidth,
             SETCOORD_LPAH, aContext, mPresContext, inherited);
  SetCoord(posData.mMinWidth, pos->mMinWidth, parentPos->mMinWidth,
           SETCOORD_LPH, aContext, mPresContext, inherited);
  if (! SetCoord(posData.mMaxWidth, pos->mMaxWidth, parentPos->mMaxWidth,
                 SETCOORD_LPH, aContext, mPresContext, inherited)) {
    if (eCSSUnit_None == posData.mMaxWidth.GetUnit()) {
      pos->mMaxWidth.Reset();
    }
  }

  SetCoord(posData.mHeight, pos->mHeight, parentPos->mHeight,
           SETCOORD_LPAH, aContext, mPresContext, inherited);
  SetCoord(posData.mMinHeight, pos->mMinHeight, parentPos->mMinHeight,
           SETCOORD_LPH, aContext, mPresContext, inherited);
  if (! SetCoord(posData.mMaxHeight, pos->mMaxHeight, parentPos->mMaxHeight,
                 SETCOORD_LPH, aContext, mPresContext, inherited)) {
    if (eCSSUnit_None == posData.mMaxHeight.GetUnit()) {
      pos->mMaxHeight.Reset();
    }
  }

  // box-sizing: enum, inherit
  if (eCSSUnit_Enumerated == posData.mBoxSizing.GetUnit()) {
    pos->mBoxSizing = posData.mBoxSizing.GetIntValue();
  }
  else if (eCSSUnit_Inherit == posData.mBoxSizing.GetUnit()) {
    inherited = PR_TRUE;
    pos->mBoxSizing = parentPos->mBoxSizing;
  }

  // z-index
  if (! SetCoord(posData.mZIndex, pos->mZIndex, parentPos->mZIndex,
                 SETCOORD_IA, aContext, nsnull, inherited)) {
    if (eCSSUnit_Inherit == posData.mZIndex.GetUnit()) {
      // handle inherit, because it's ok to inherit 'auto' here
      inherited = PR_TRUE;
      pos->mZIndex = parentPos->mZIndex;
    }
  }

  if (inherited)
    // We inherited, and therefore can't be cached in the rule node.  We have to be put right on the
    // style context.
    aContext->SetStyle(eStyleStruct_Position, pos);
  else {
    // We were fully specified and can therefore be cached right on the rule node.
    if (!aHighestNode->mStyleData.mResetData) {
      aHighestNode->mStyleData.mResetData = new (mPresContext) nsResetStyleData;
      if (NS_UNLIKELY(!aHighestNode->mStyleData.mResetData)) {
        pos->Destroy(mPresContext);
        return nsnull;
      }
    }
    aHighestNode->mStyleData.mResetData->mPositionData = pos;
    // Propagate the bit down.
    PropagateDependentBit(NS_STYLE_INHERIT_BIT(Position), aHighestNode);
  }

  return pos;
}

Here is the call graph for this function:

const nsStyleStruct * nsRuleNode::ComputeQuotesData ( nsStyleStruct aStartQuotes,
const nsRuleDataStruct aData,
nsStyleContext aContext,
nsRuleNode aHighestNode,
const RuleDetail aRuleDetail,
PRBool  aInherited 
) [protected]

Definition at line 4381 of file nsRuleNode.cpp.

{
  nsStyleContext* parentContext = aContext->GetParent();

  const nsRuleDataContent& contentData = NS_STATIC_CAST(const nsRuleDataContent&, aData);
  nsStyleQuotes* quotes = nsnull;
  const nsStyleQuotes* parentQuotes = nsnull;
  PRBool inherited = aInherited;

  if (parentContext && aRuleDetail != eRuleFullReset)
    parentQuotes = parentContext->GetStyleQuotes();
  if (aStartStruct)
    // We only need to compute the delta between this computed data and our
    // computed data.
    quotes = new (mPresContext) nsStyleQuotes(*NS_STATIC_CAST(nsStyleQuotes*, aStartStruct));
  else {
    // XXXldb What about eRuleFullInherited?  Which path is faster?
    if (aRuleDetail != eRuleFullMixed && aRuleDetail != eRuleFullReset) {
      // No question. We will have to inherit. Go ahead and init
      // with inherited vals from parent.
      inherited = PR_TRUE;
      if (parentQuotes)
        quotes = new (mPresContext) nsStyleQuotes(*parentQuotes);
      else
        quotes = new (mPresContext) nsStyleQuotes();
    }
    else
      quotes = new (mPresContext) nsStyleQuotes();
  }

  if (NS_UNLIKELY(!quotes))
    return nsnull;  // Out Of Memory
  if (!parentQuotes)
    parentQuotes = quotes;

  // quotes: [string string]+, none, inherit
  PRUint32 count;
  nsAutoString  buffer;
  nsCSSQuotes* ourQuotes = contentData.mQuotes;
  if (ourQuotes) {
    nsAutoString  closeBuffer;
    if (eCSSUnit_Inherit == ourQuotes->mOpen.GetUnit()) {
      inherited = PR_TRUE;
      count = parentQuotes->QuotesCount();
      if (NS_SUCCEEDED(quotes->AllocateQuotes(count))) {
        while (0 < count--) {
          parentQuotes->GetQuotesAt(count, buffer, closeBuffer);
          quotes->SetQuotesAt(count, buffer, closeBuffer);
        }
      }
    }
    else if (eCSSUnit_None == ourQuotes->mOpen.GetUnit()) {
      quotes->AllocateQuotes(0);
    }
    else if (eCSSUnit_String == ourQuotes->mOpen.GetUnit()) {
      count = 0;
      while (ourQuotes) {
        count++;
        ourQuotes = ourQuotes->mNext;
      }
      if (NS_SUCCEEDED(quotes->AllocateQuotes(count))) {
        count = 0;
        ourQuotes = contentData.mQuotes;
        while (ourQuotes) {
          ourQuotes->mOpen.GetStringValue(buffer);
          ourQuotes->mClose.GetStringValue(closeBuffer);
          Unquote(buffer);
          Unquote(closeBuffer);
          quotes->SetQuotesAt(count++, buffer, closeBuffer);
          ourQuotes = ourQuotes->mNext;
        }
      }
    }
  }

  if (inherited)
    // We inherited, and therefore can't be cached in the rule node.  We have to be put right on the
    // style context.
    aContext->SetStyle(eStyleStruct_Quotes, quotes);
  else {
    // We were fully specified and can therefore be cached right on the rule node.
    if (!aHighestNode->mStyleData.mInheritedData) {
      aHighestNode->mStyleData.mInheritedData = new (mPresContext) nsInheritedStyleData;
      if (NS_UNLIKELY(!aHighestNode->mStyleData.mInheritedData)) {
        quotes->Destroy(mPresContext);
        return nsnull;
      }
    }
    aHighestNode->mStyleData.mInheritedData->mQuotesData = quotes;
    // Propagate the bit down.
    PropagateDependentBit(NS_STYLE_INHERIT_BIT(Quotes), aHighestNode);
  }

  return quotes;
}

Here is the call graph for this function:

const nsStyleStruct * nsRuleNode::ComputeTableBorderData ( nsStyleStruct aStartTable,
const nsRuleDataStruct aTableData,
nsStyleContext aContext,
nsRuleNode aHighestNode,
const RuleDetail aRuleDetail,
PRBool  aInherited 
) [protected]

Definition at line 4064 of file nsRuleNode.cpp.

{
  nsStyleContext* parentContext = aContext->GetParent();

  const nsRuleDataTable& tableData = NS_STATIC_CAST(const nsRuleDataTable&, aData);
  nsStyleTableBorder* table = nsnull;
  const nsStyleTableBorder* parentTable = nsnull;
  PRBool inherited = aInherited;

  if (parentContext && aRuleDetail != eRuleFullReset)
    parentTable = parentContext->GetStyleTableBorder();
  if (aStartStruct)
    // We only need to compute the delta between this computed data and our
    // computed data.
    table = new (mPresContext) nsStyleTableBorder(*NS_STATIC_CAST(nsStyleTableBorder*, aStartStruct));
  else {
    // XXXldb What about eRuleFullInherited?  Which path is faster?
    if (aRuleDetail != eRuleFullMixed && aRuleDetail != eRuleFullReset) {
      // No question. We will have to inherit. Go ahead and init
      // with inherited vals from parent.
      inherited = PR_TRUE;
      if (parentTable)
        table = new (mPresContext) nsStyleTableBorder(*parentTable);
      else
        table = new (mPresContext) nsStyleTableBorder(mPresContext);
    }
    else
      table = new (mPresContext) nsStyleTableBorder(mPresContext);
  }

  if (NS_UNLIKELY(!table))
    return nsnull;  // Out Of Memory
  if (!parentTable)
    parentTable = table;

  // border-collapse: enum, inherit
  if (eCSSUnit_Enumerated == tableData.mBorderCollapse.GetUnit()) {
    table->mBorderCollapse = tableData.mBorderCollapse.GetIntValue();
  }
  else if (eCSSUnit_Inherit == tableData.mBorderCollapse.GetUnit()) {
    inherited = PR_TRUE;
    table->mBorderCollapse = parentTable->mBorderCollapse;
  }

  // border-spacing-x: length, inherit
  SetCoord(tableData.mBorderSpacing.mXValue, table->mBorderSpacingX,
           parentTable->mBorderSpacingX, SETCOORD_LH,
           aContext, mPresContext, inherited);
  // border-spacing-y: length, inherit
  SetCoord(tableData.mBorderSpacing.mYValue, table->mBorderSpacingY,
           parentTable->mBorderSpacingY, SETCOORD_LH,
           aContext, mPresContext, inherited);

  // caption-side: enum, inherit
  if (eCSSUnit_Enumerated == tableData.mCaptionSide.GetUnit()) {
    table->mCaptionSide = tableData.mCaptionSide.GetIntValue();
  }
  else if (eCSSUnit_Inherit == tableData.mCaptionSide.GetUnit()) {
    inherited = PR_TRUE;
    table->mCaptionSide = parentTable->mCaptionSide;
  }

  // empty-cells: enum, inherit
  if (eCSSUnit_Enumerated == tableData.mEmptyCells.GetUnit()) {
    table->mEmptyCells = tableData.mEmptyCells.GetIntValue();
  }
  else if (eCSSUnit_Inherit == tableData.mEmptyCells.GetUnit()) {
    inherited = PR_TRUE;
    table->mEmptyCells = parentTable->mEmptyCells;
  }

  if (inherited)
    // We inherited, and therefore can't be cached in the rule node.  We have to be put right on the
    // style context.
    aContext->SetStyle(eStyleStruct_TableBorder, table);
  else {
    // We were fully specified and can therefore be cached right on the rule node.
    if (!aHighestNode->mStyleData.mInheritedData) {
      aHighestNode->mStyleData.mInheritedData = new (mPresContext) nsInheritedStyleData;
      if (NS_UNLIKELY(!aHighestNode->mStyleData.mInheritedData)) {
        table->Destroy(mPresContext);
        return nsnull;
      }
    }
    aHighestNode->mStyleData.mInheritedData->mTableBorderData = table;
    // Propagate the bit down.
    PropagateDependentBit(NS_STYLE_INHERIT_BIT(TableBorder), aHighestNode);
  }

  return table;
}

Here is the call graph for this function:

const nsStyleStruct * nsRuleNode::ComputeTableData ( nsStyleStruct aStartTable,
const nsRuleDataStruct aTableData,
nsStyleContext aContext,
nsRuleNode aHighestNode,
const RuleDetail aRuleDetail,
PRBool  aInherited 
) [protected]

Definition at line 3986 of file nsRuleNode.cpp.

{
  nsStyleContext* parentContext = aContext->GetParent();

  const nsRuleDataTable& tableData = NS_STATIC_CAST(const nsRuleDataTable&, aData);
  nsStyleTable* table;
  if (aStartStruct)
    // We only need to compute the delta between this computed data and our
    // computed data.
    table = new (mPresContext) nsStyleTable(*NS_STATIC_CAST(nsStyleTable*, aStartStruct));
  else
    table = new (mPresContext) nsStyleTable();
  
  if (!table)
    return nsnull;  // Out Of Memory

  const nsStyleTable* parentTable = table;
  if (parentContext && 
      aRuleDetail != eRuleFullReset &&
      aRuleDetail != eRulePartialReset &&
      aRuleDetail != eRuleNone)
    parentTable = parentContext->GetStyleTable();
  PRBool inherited = aInherited;

  // table-layout: auto, enum, inherit
  if (eCSSUnit_Enumerated == tableData.mLayout.GetUnit())
    table->mLayoutStrategy = tableData.mLayout.GetIntValue();
  else if (eCSSUnit_Auto == tableData.mLayout.GetUnit())
    table->mLayoutStrategy = NS_STYLE_TABLE_LAYOUT_AUTO;
  else if (eCSSUnit_Inherit == tableData.mLayout.GetUnit()) {
    inherited = PR_TRUE;
    table->mLayoutStrategy = parentTable->mLayoutStrategy;
  }

  // rules: enum (not a real CSS prop)
  if (eCSSUnit_Enumerated == tableData.mRules.GetUnit())
    table->mRules = tableData.mRules.GetIntValue();

  // frame: enum (not a real CSS prop)
  if (eCSSUnit_Enumerated == tableData.mFrame.GetUnit())
    table->mFrame = tableData.mFrame.GetIntValue();

  // cols: enum, int (not a real CSS prop)
  if (eCSSUnit_Enumerated == tableData.mCols.GetUnit() ||
      eCSSUnit_Integer == tableData.mCols.GetUnit())
    table->mCols = tableData.mCols.GetIntValue();

  // span: pixels (not a real CSS prop)
  if (eCSSUnit_Enumerated == tableData.mSpan.GetUnit() ||
      eCSSUnit_Integer == tableData.mSpan.GetUnit())
    table->mSpan = tableData.mSpan.GetIntValue();
    
  if (inherited)
    // We inherited, and therefore can't be cached in the rule node.  We have to be put right on the
    // style context.
    aContext->SetStyle(eStyleStruct_Table, table);
  else {
    // We were fully specified and can therefore be cached right on the rule node.
    if (!aHighestNode->mStyleData.mResetData) {
      aHighestNode->mStyleData.mResetData = new (mPresContext) nsResetStyleData;
      if (NS_UNLIKELY(!aHighestNode->mStyleData.mResetData)) {
        table->Destroy(mPresContext);
        return nsnull;
      }
    }
    aHighestNode->mStyleData.mResetData->mTableData = table;
    // Propagate the bit down.
    PropagateDependentBit(NS_STYLE_INHERIT_BIT(Table), aHighestNode);
  }

  return table;
}

Here is the call graph for this function:

const nsStyleStruct * nsRuleNode::ComputeTextData ( nsStyleStruct aStartData,
const nsRuleDataStruct aData,
nsStyleContext aContext,
nsRuleNode aHighestNode,
const RuleDetail aRuleDetail,
PRBool  aInherited 
) [protected]

Definition at line 2162 of file nsRuleNode.cpp.

{
  nsStyleContext* parentContext = aContext->GetParent();

  const nsRuleDataText& textData = NS_STATIC_CAST(const nsRuleDataText&, aData);
  nsStyleText* text = nsnull;
  const nsStyleText* parentText = nsnull;
  PRBool inherited = aInherited;

  if (parentContext && aRuleDetail != eRuleFullReset)
    parentText = parentContext->GetStyleText();
  if (aStartStruct)
    // We only need to compute the delta between this computed data and our
    // computed data.
    text = new (mPresContext) nsStyleText(*NS_STATIC_CAST(nsStyleText*, aStartStruct));
  else {
    // XXXldb What about eRuleFullInherited?  Which path is faster?
    if (aRuleDetail != eRuleFullMixed && aRuleDetail != eRuleFullReset) {
      // No question. We will have to inherit. Go ahead and init
      // with inherited vals from parent.
      inherited = PR_TRUE;
      if (parentText)
        text = new (mPresContext) nsStyleText(*parentText);
      else
        text = new (mPresContext) nsStyleText();
    }
    else
      text = new (mPresContext) nsStyleText();
  }

  if (NS_UNLIKELY(!text))
    return nsnull;  // Out Of Memory
  if (!parentText)
    parentText = text;

    // letter-spacing: normal, length, inherit
  SetCoord(textData.mLetterSpacing, text->mLetterSpacing, parentText->mLetterSpacing,
           SETCOORD_LH | SETCOORD_NORMAL, aContext, mPresContext, inherited);

  // line-height: normal, number, length, percent, inherit
  if (eCSSUnit_Percent == textData.mLineHeight.GetUnit()) {
    inherited = PR_TRUE;
    // Use |mFont.size| to pick up minimum font size.
    text->mLineHeight.SetCoordValue(
        nscoord(float(aContext->GetStyleFont()->mFont.size) *
                textData.mLineHeight.GetPercentValue()));
  } else {
    SetCoord(textData.mLineHeight, text->mLineHeight, parentText->mLineHeight,
             SETCOORD_LH | SETCOORD_FACTOR | SETCOORD_NORMAL,
             aContext, mPresContext, inherited);
    if (textData.mLineHeight.IsFixedLengthUnit() ||
        textData.mLineHeight.GetUnit() == eCSSUnit_Pixel) {
      nscoord lh = nsStyleFont::ZoomText(mPresContext,
                                         text->mLineHeight.GetCoordValue());
      nscoord minimumFontSize =
        mPresContext->GetCachedIntPref(kPresContext_MinimumFontSize);

      if (minimumFontSize > 0 && !IsChrome(mPresContext)) {
        // If we applied a minimum font size, scale the line height by
        // the same ratio.  (If we *might* have applied a minimum font
        // size, we can't cache in the rule tree.)
        inherited = PR_TRUE;
        const nsStyleFont *font = aContext->GetStyleFont();
        if (font->mSize != 0) {
          lh = nscoord(float(lh) * float(font->mFont.size) / float(font->mSize));
        } else {
          lh = minimumFontSize;
        }
      }
      text->mLineHeight.SetCoordValue(lh);
    }
  }


  // text-align: enum, string, inherit
  if (eCSSUnit_Enumerated == textData.mTextAlign.GetUnit()) {
    text->mTextAlign = textData.mTextAlign.GetIntValue();
  }
  else if (eCSSUnit_String == textData.mTextAlign.GetUnit()) {
    NS_NOTYETIMPLEMENTED("align string");
  }
  else if (eCSSUnit_Inherit == textData.mTextAlign.GetUnit()) {
    inherited = PR_TRUE;
    text->mTextAlign = parentText->mTextAlign;
  }
  else if (eCSSUnit_Initial == textData.mTextAlign.GetUnit())
    text->mTextAlign = NS_STYLE_TEXT_ALIGN_DEFAULT;

  // text-indent: length, percent, inherit
  SetCoord(textData.mTextIndent, text->mTextIndent, parentText->mTextIndent,
           SETCOORD_LPH, aContext, mPresContext, inherited);

  // text-transform: enum, none, inherit
  if (eCSSUnit_Enumerated == textData.mTextTransform.GetUnit()) {
    text->mTextTransform = textData.mTextTransform.GetIntValue();
  }
  else if (eCSSUnit_None == textData.mTextTransform.GetUnit()) {
    text->mTextTransform = NS_STYLE_TEXT_TRANSFORM_NONE;
  }
  else if (eCSSUnit_Inherit == textData.mTextTransform.GetUnit()) {
    inherited = PR_TRUE;
    text->mTextTransform = parentText->mTextTransform;
  }

  // white-space: enum, normal, inherit
  if (eCSSUnit_Enumerated == textData.mWhiteSpace.GetUnit()) {
    text->mWhiteSpace = textData.mWhiteSpace.GetIntValue();
  }
  else if (eCSSUnit_Normal == textData.mWhiteSpace.GetUnit()) {
    text->mWhiteSpace = NS_STYLE_WHITESPACE_NORMAL;
  }
  else if (eCSSUnit_Inherit == textData.mWhiteSpace.GetUnit()) {
    inherited = PR_TRUE;
    text->mWhiteSpace = parentText->mWhiteSpace;
  }

  // word-spacing: normal, length, inherit
  SetCoord(textData.mWordSpacing, text->mWordSpacing, parentText->mWordSpacing,
           SETCOORD_LH | SETCOORD_NORMAL, aContext, mPresContext, inherited);

  if (inherited)
    // We inherited, and therefore can't be cached in the rule node.  We have to be put right on the
    // style context.
    aContext->SetStyle(eStyleStruct_Text, text);
  else {
    // We were fully specified and can therefore be cached right on the rule node.
    if (!aHighestNode->mStyleData.mInheritedData) {
      aHighestNode->mStyleData.mInheritedData = new (mPresContext) nsInheritedStyleData;
      if (NS_UNLIKELY(!aHighestNode->mStyleData.mInheritedData)) {
        text->Destroy(mPresContext);
        return nsnull;
      }
    }
    aHighestNode->mStyleData.mInheritedData->mTextData = text;
    // Propagate the bit down.
    PropagateDependentBit(NS_STYLE_INHERIT_BIT(Text), aHighestNode);
  }

  return text;
}

Here is the call graph for this function:

const nsStyleStruct * nsRuleNode::ComputeTextResetData ( nsStyleStruct aStartData,
const nsRuleDataStruct aData,
nsStyleContext aContext,
nsRuleNode aHighestNode,
const RuleDetail aRuleDetail,
PRBool  aInherited 
) [protected]

Definition at line 2308 of file nsRuleNode.cpp.

{
  nsStyleContext* parentContext = aContext->GetParent();

  const nsRuleDataText& textData = NS_STATIC_CAST(const nsRuleDataText&, aData);
  nsStyleTextReset* text;
  if (aStartData)
    // We only need to compute the delta between this computed data and our
    // computed data.
    text = new (mPresContext) nsStyleTextReset(*NS_STATIC_CAST(nsStyleTextReset*, aStartData));
  else
    text = new (mPresContext) nsStyleTextReset();

  if (NS_UNLIKELY(!text))
    return nsnull;  // Out Of Memory

  const nsStyleTextReset* parentText = text;
  if (parentContext && 
      aRuleDetail != eRuleFullReset &&
      aRuleDetail != eRulePartialReset &&
      aRuleDetail != eRuleNone)
    parentText = parentContext->GetStyleTextReset();
  PRBool inherited = aInherited;
  
  // vertical-align: enum, length, percent, inherit
  SetCoord(textData.mVerticalAlign, text->mVerticalAlign, parentText->mVerticalAlign,
           SETCOORD_LPH | SETCOORD_ENUMERATED, aContext, mPresContext, inherited);

  // text-decoration: none, enum (bit field), inherit
  if (eCSSUnit_Enumerated == textData.mDecoration.GetUnit()) {
    PRInt32 td = textData.mDecoration.GetIntValue();
    text->mTextDecoration = td;
    if (td & NS_STYLE_TEXT_DECORATION_PREF_ANCHORS) {
      PRBool underlineLinks =
        mPresContext->GetCachedBoolPref(kPresContext_UnderlineLinks);
      if (underlineLinks) {
        text->mTextDecoration |= NS_STYLE_TEXT_DECORATION_UNDERLINE;
      }
      else {
        text->mTextDecoration &= ~NS_STYLE_TEXT_DECORATION_UNDERLINE;
      }
    }
  }
  else if (eCSSUnit_None == textData.mDecoration.GetUnit()) {
    text->mTextDecoration = NS_STYLE_TEXT_DECORATION_NONE;
  }
  else if (eCSSUnit_Inherit == textData.mDecoration.GetUnit()) {
    inherited = PR_TRUE;
    text->mTextDecoration = parentText->mTextDecoration;
  }

  // unicode-bidi: enum, normal, inherit
  if (eCSSUnit_Normal == textData.mUnicodeBidi.GetUnit() ) {
    text->mUnicodeBidi = NS_STYLE_UNICODE_BIDI_NORMAL;
  }
  else if (eCSSUnit_Enumerated == textData.mUnicodeBidi.GetUnit() ) {
    text->mUnicodeBidi = textData.mUnicodeBidi.GetIntValue();
  }
  else if (eCSSUnit_Inherit == textData.mUnicodeBidi.GetUnit() ) {
    inherited = PR_TRUE;
    text->mUnicodeBidi = parentText->mUnicodeBidi;
  }

  if (inherited)
    // We inherited, and therefore can't be cached in the rule node.  We have to be put right on the
    // style context.
    aContext->SetStyle(eStyleStruct_TextReset, text);
  else {
    // We were fully specified and can therefore be cached right on the rule node.
    if (!aHighestNode->mStyleData.mResetData) {
      aHighestNode->mStyleData.mResetData = new (mPresContext) nsResetStyleData;
      if (NS_UNLIKELY(!aHighestNode->mStyleData.mResetData)) {
        text->Destroy(mPresContext);
        return nsnull;
      }
    }
    aHighestNode->mStyleData.mResetData->mTextResetData = text;
    // Propagate the bit down.
    PropagateDependentBit(NS_STYLE_INHERIT_BIT(TextReset), aHighestNode);
  }

  return text;
}

Here is the call graph for this function:

const nsStyleStruct * nsRuleNode::ComputeUIResetData ( nsStyleStruct aStartData,
const nsRuleDataStruct aData,
nsStyleContext aContext,
nsRuleNode aHighestNode,
const RuleDetail aRuleDetail,
PRBool  aInherited 
) [protected]

Definition at line 2551 of file nsRuleNode.cpp.

{
  nsStyleContext* parentContext = aContext->GetParent();

  const nsRuleDataUserInterface& uiData = NS_STATIC_CAST(const nsRuleDataUserInterface&, aData);
  nsStyleUIReset* ui;
  if (aStartData)
    // We only need to compute the delta between this computed data and our
    // computed data.
    ui = new (mPresContext) nsStyleUIReset(*NS_STATIC_CAST(nsStyleUIReset*, aStartData));
  else
    ui = new (mPresContext) nsStyleUIReset();

  if (NS_UNLIKELY(!ui))
    return nsnull;  // Out Of Memory

  const nsStyleUIReset* parentUI = ui;
  if (parentContext && 
      aRuleDetail != eRuleFullReset &&
      aRuleDetail != eRulePartialReset &&
      aRuleDetail != eRuleNone)
    parentUI = parentContext->GetStyleUIReset();
  PRBool inherited = aInherited;
  
  // user-select: none, enum, inherit
  if (eCSSUnit_Enumerated == uiData.mUserSelect.GetUnit()) {
    ui->mUserSelect = uiData.mUserSelect.GetIntValue();
  }
  else if (eCSSUnit_None == uiData.mUserSelect.GetUnit()) {
    ui->mUserSelect = NS_STYLE_USER_SELECT_NONE;
  }
  else if (eCSSUnit_Inherit == uiData.mUserSelect.GetUnit()) {
    inherited = PR_TRUE;
    ui->mUserSelect = parentUI->mUserSelect;
  }

  // force-broken-image-icons: integer
  if (eCSSUnit_Integer == uiData.mForceBrokenImageIcon.GetUnit()) {
    ui->mForceBrokenImageIcon = uiData.mForceBrokenImageIcon.GetIntValue();
  }
  
  if (inherited)
    // We inherited, and therefore can't be cached in the rule node.  We have to be put right on the
    // style context.
    aContext->SetStyle(eStyleStruct_UIReset, ui);
  else {
    // We were fully specified and can therefore be cached right on the rule node.
    if (!aHighestNode->mStyleData.mResetData) {
      aHighestNode->mStyleData.mResetData = new (mPresContext) nsResetStyleData;
      if (NS_UNLIKELY(!aHighestNode->mStyleData.mResetData)) {
        ui->Destroy(mPresContext);
        return nsnull;
      }
    }
    aHighestNode->mStyleData.mResetData->mUIResetData = ui;
    // Propagate the bit down.
    PropagateDependentBit(NS_STYLE_INHERIT_BIT(UIReset), aHighestNode);
  }

  return ui;
}

Here is the call graph for this function:

const nsStyleStruct * nsRuleNode::ComputeUserInterfaceData ( nsStyleStruct aStartData,
const nsRuleDataStruct aData,
nsStyleContext aContext,
nsRuleNode aHighestNode,
const RuleDetail aRuleDetail,
PRBool  aInherited 
) [protected]

Definition at line 2397 of file nsRuleNode.cpp.

{
  nsStyleContext* parentContext = aContext->GetParent();

  const nsRuleDataUserInterface& uiData = NS_STATIC_CAST(const nsRuleDataUserInterface&, aData);
  nsStyleUserInterface* ui = nsnull;
  const nsStyleUserInterface* parentUI = nsnull;
  PRBool inherited = aInherited;

  if (parentContext && aRuleDetail != eRuleFullReset)
    parentUI = parentContext->GetStyleUserInterface();
  if (aStartData)
    // We only need to compute the delta between this computed data and our
    // computed data.
    ui = new (mPresContext) nsStyleUserInterface(*NS_STATIC_CAST(nsStyleUserInterface*, aStartData));
  else {
    // XXXldb What about eRuleFullInherited?  Which path is faster?
    if (aRuleDetail != eRuleFullMixed && aRuleDetail != eRuleFullReset) {
      // No question. We will have to inherit. Go ahead and init
      // with inherited vals from parent.
      inherited = PR_TRUE;
      if (parentUI)
        ui = new (mPresContext) nsStyleUserInterface(*parentUI);
      else
        ui = new (mPresContext) nsStyleUserInterface();
    }
    else
      ui = new (mPresContext) nsStyleUserInterface();
  }

  if (NS_UNLIKELY(!ui))
    return nsnull;  // Out Of Memory
  if (!parentUI)
    parentUI = ui;

  // cursor: enum, auto, url, inherit
  nsCSSValueList*  list = uiData.mCursor;
  if (nsnull != list) {
    delete [] ui->mCursorArray;
    ui->mCursorArray = nsnull;
    ui->mCursorArrayLength = 0;

    if (eCSSUnit_Inherit == list->mValue.GetUnit()) {
      inherited = PR_TRUE;
      ui->mCursor = parentUI->mCursor;
      ui->CopyCursorArrayFrom(*parentUI);
    }
    else {
      // The parser will never create a list that is *all* URL values --
      // that's invalid.
      PRUint32 arrayLength = 0;
      for (nsCSSValueList *list2 = list;
           list2->mValue.GetUnit() == eCSSUnit_Array; list2 = list2->mNext)
        if (list2->mValue.GetArrayValue()->Item(0).GetImageValue())
          ++arrayLength;

      if (arrayLength != 0) {
        ui->mCursorArray = new nsCursorImage[arrayLength];
        if (ui->mCursorArray) {
          ui->mCursorArrayLength = arrayLength;

          for (nsCursorImage *item = ui->mCursorArray;
               list->mValue.GetUnit() == eCSSUnit_Array;
               list = list->mNext) {
            nsCSSValue::Array *arr = list->mValue.GetArrayValue();
            imgIRequest *req = arr->Item(0).GetImageValue();
            if (req) {
              item->mImage = req;
              if (arr->Item(1).GetUnit() != eCSSUnit_Null) {
                item->mHaveHotspot = PR_TRUE;
                item->mHotspotX = arr->Item(1).GetFloatValue(),
                item->mHotspotY = arr->Item(2).GetFloatValue();
              }
              ++item;
            }
          }
        }
      }

      if (eCSSUnit_Enumerated == list->mValue.GetUnit()) {
        ui->mCursor = list->mValue.GetIntValue();
      }
      else if (eCSSUnit_Auto == list->mValue.GetUnit()) {
        ui->mCursor = NS_STYLE_CURSOR_AUTO;
      }
    }
  }

  // user-input: auto, none, enum, inherit
  if (eCSSUnit_Enumerated == uiData.mUserInput.GetUnit()) {
    ui->mUserInput = uiData.mUserInput.GetIntValue();
  }
  else if (eCSSUnit_Auto == uiData.mUserInput.GetUnit()) {
    ui->mUserInput = NS_STYLE_USER_INPUT_AUTO;
  }
  else if (eCSSUnit_None == uiData.mUserInput.GetUnit()) {
    ui->mUserInput = NS_STYLE_USER_INPUT_NONE;
  }
  else if (eCSSUnit_Inherit == uiData.mUserInput.GetUnit()) {
    inherited = PR_TRUE;
    ui->mUserInput = parentUI->mUserInput;
  }

  // user-modify: enum, inherit
  if (eCSSUnit_Enumerated == uiData.mUserModify.GetUnit()) {
    ui->mUserModify = uiData.mUserModify.GetIntValue();
  }
  else if (eCSSUnit_Inherit == uiData.mUserModify.GetUnit()) {
    inherited = PR_TRUE;
    ui->mUserModify = parentUI->mUserModify;
  }

  // user-focus: none, normal, enum, inherit
  if (eCSSUnit_Enumerated == uiData.mUserFocus.GetUnit()) {
    ui->mUserFocus = uiData.mUserFocus.GetIntValue();
  }
  else if (eCSSUnit_None == uiData.mUserFocus.GetUnit()) {
    ui->mUserFocus = NS_STYLE_USER_FOCUS_NONE;
  }
  else if (eCSSUnit_Normal == uiData.mUserFocus.GetUnit()) {
    ui->mUserFocus = NS_STYLE_USER_FOCUS_NORMAL;
  }
  else if (eCSSUnit_Inherit == uiData.mUserFocus.GetUnit()) {
    inherited = PR_TRUE;
    ui->mUserFocus = parentUI->mUserFocus;
  }

  if (inherited)
    // We inherited, and therefore can't be cached in the rule node.  We have to be put right on the
    // style context.
    aContext->SetStyle(eStyleStruct_UserInterface, ui);
  else {
    // We were fully specified and can therefore be cached right on the rule node.
    if (!aHighestNode->mStyleData.mInheritedData) {
      aHighestNode->mStyleData.mInheritedData = new (mPresContext) nsInheritedStyleData;
      if (NS_UNLIKELY(!aHighestNode->mStyleData.mInheritedData)) {
        ui->Destroy(mPresContext);
        return nsnull;
      }
    }    
    aHighestNode->mStyleData.mInheritedData->mUserInterfaceData = ui;
    // Propagate the bit down.
    PropagateDependentBit(NS_STYLE_INHERIT_BIT(UserInterface), aHighestNode);
  }

  return ui;
}

Here is the call graph for this function:

const nsStyleStruct * nsRuleNode::ComputeVisibilityData ( nsStyleStruct aStartVisibility,
const nsRuleDataStruct aDisplayData,
nsStyleContext aContext,
nsRuleNode aHighestNode,
const RuleDetail aRuleDetail,
PRBool  aInherited 
) [protected]

Definition at line 2952 of file nsRuleNode.cpp.

{
  nsStyleContext* parentContext = aContext->GetParent();

  const nsRuleDataDisplay& displayData = NS_STATIC_CAST(const nsRuleDataDisplay&, aData);
  nsStyleVisibility* visibility = nsnull;
  const nsStyleVisibility* parentVisibility = nsnull;
  PRBool inherited = aInherited;

  if (parentContext && aRuleDetail != eRuleFullReset)
    parentVisibility = parentContext->GetStyleVisibility();
  if (aStartStruct)
    // We only need to compute the delta between this computed data and our
    // computed data.
    visibility = new (mPresContext) nsStyleVisibility(*NS_STATIC_CAST(nsStyleVisibility*, aStartStruct));
  else {
    // XXXldb What about eRuleFullInherited?  Which path is faster?
    if (aRuleDetail != eRuleFullMixed && aRuleDetail != eRuleFullReset) {
      // No question. We will have to inherit. Go ahead and init
      // with inherited vals from parent.
      inherited = PR_TRUE;
      if (parentVisibility)
        visibility = new (mPresContext) nsStyleVisibility(*parentVisibility);
      else
        visibility = new (mPresContext) nsStyleVisibility(mPresContext);
    }
    else
      visibility = new (mPresContext) nsStyleVisibility(mPresContext);
  }

  if (NS_UNLIKELY(!visibility))
    return nsnull;  // Out Of Memory
  if (!parentVisibility)
    parentVisibility = visibility;

  // direction: enum, inherit
  if (eCSSUnit_Enumerated == displayData.mDirection.GetUnit()) {
    visibility->mDirection = displayData.mDirection.GetIntValue();
    if (NS_STYLE_DIRECTION_RTL == visibility->mDirection)
      mPresContext->SetBidiEnabled(PR_TRUE);
  }
  else if (eCSSUnit_Inherit == displayData.mDirection.GetUnit()) {
    inherited = PR_TRUE;
    visibility->mDirection = parentVisibility->mDirection;
  }

  // visibility: enum, inherit
  if (eCSSUnit_Enumerated == displayData.mVisibility.GetUnit()) {
    visibility->mVisible = displayData.mVisibility.GetIntValue();
  }
  else if (eCSSUnit_Inherit == displayData.mVisibility.GetUnit()) {
    inherited = PR_TRUE;
    visibility->mVisible = parentVisibility->mVisible;
  }

  // lang: string, inherit
  // this is not a real CSS property, it is a html attribute mapped to CSS struture
  if (eCSSUnit_String == displayData.mLang.GetUnit()) {
    if (!gLangService) {
      CallGetService(NS_LANGUAGEATOMSERVICE_CONTRACTID, &gLangService);
    }

    if (gLangService) {
      nsAutoString lang;
      displayData.mLang.GetStringValue(lang);
      visibility->mLangGroup = gLangService->LookupLanguage(lang);
    }
  } 

  if (inherited)
    // We inherited, and therefore can't be cached in the rule node.  We have to be put right on the
    // style context.
    aContext->SetStyle(eStyleStruct_Visibility, visibility);
  else {
    // We were fully specified and can therefore be cached right on the rule node.
    if (!aHighestNode->mStyleData.mInheritedData) {
      aHighestNode->mStyleData.mInheritedData = new (mPresContext) nsInheritedStyleData;
      if (NS_UNLIKELY(!aHighestNode->mStyleData.mInheritedData)) {
        visibility->Destroy(mPresContext);
        return nsnull;
      }
    }
    aHighestNode->mStyleData.mInheritedData->mVisibilityData = visibility;
    // Propagate the bit down.
    PropagateDependentBit(NS_STYLE_INHERIT_BIT(Visibility), aHighestNode);
  }

  return visibility;
}

Here is the call graph for this function:

const nsStyleStruct * nsRuleNode::ComputeXULData ( nsStyleStruct aStartXUL,
const nsRuleDataStruct aXULData,
nsStyleContext aContext,
nsRuleNode aHighestNode,
const RuleDetail aRuleDetail,
PRBool  aInherited 
) [protected]

Definition at line 4482 of file nsRuleNode.cpp.

{
  nsStyleContext* parentContext = aContext->GetParent();

  const nsRuleDataXUL& xulData = NS_STATIC_CAST(const nsRuleDataXUL&, aData);
  nsStyleXUL* xul = nsnull;
  
  if (aStartStruct)
    // We only need to compute the delta between this computed data and our
    // computed data.
    xul = new (mPresContext) nsStyleXUL(*NS_STATIC_CAST(nsStyleXUL*, aStartStruct));
  else
    xul = new (mPresContext) nsStyleXUL();

  if (NS_UNLIKELY(!xul))
    return nsnull;  // Out Of Memory

  const nsStyleXUL* parentXUL = xul;
  if (parentContext && 
      aRuleDetail != eRuleFullReset &&
      aRuleDetail != eRulePartialReset &&
      aRuleDetail != eRuleNone)
    parentXUL = parentContext->GetStyleXUL();

  PRBool inherited = aInherited;

  // box-align: enum, inherit
  if (eCSSUnit_Enumerated == xulData.mBoxAlign.GetUnit()) {
    xul->mBoxAlign = xulData.mBoxAlign.GetIntValue();
  }
  else if (eCSSUnit_Inherit == xulData.mBoxAlign.GetUnit()) {
    inherited = PR_TRUE;
    xul->mBoxAlign = parentXUL->mBoxAlign;
  }

  // box-direction: enum, inherit
  if (eCSSUnit_Enumerated == xulData.mBoxDirection.GetUnit()) {
    xul->mBoxDirection = xulData.mBoxDirection.GetIntValue();
  }
  else if (eCSSUnit_Inherit == xulData.mBoxDirection.GetUnit()) {
    inherited = PR_TRUE;
    xul->mBoxDirection = parentXUL->mBoxDirection;
  }

  // box-flex: factor, inherit
  if (eCSSUnit_Number == xulData.mBoxFlex.GetUnit()) {
    xul->mBoxFlex = xulData.mBoxFlex.GetFloatValue();
  }
  else if (eCSSUnit_Inherit == xulData.mBoxOrient.GetUnit()) {
    inherited = PR_TRUE;
    xul->mBoxFlex = parentXUL->mBoxFlex;
  }

  // box-orient: enum, inherit
  if (eCSSUnit_Enumerated == xulData.mBoxOrient.GetUnit()) {
    xul->mBoxOrient = xulData.mBoxOrient.GetIntValue();
  }
  else if (eCSSUnit_Inherit == xulData.mBoxOrient.GetUnit()) {
    inherited = PR_TRUE;
    xul->mBoxOrient = parentXUL->mBoxOrient;
  }

  // box-pack: enum, inherit
  if (eCSSUnit_Enumerated == xulData.mBoxPack.GetUnit()) {
    xul->mBoxPack = xulData.mBoxPack.GetIntValue();
  }
  else if (eCSSUnit_Inherit == xulData.mBoxPack.GetUnit()) {
    inherited = PR_TRUE;
    xul->mBoxPack = parentXUL->mBoxPack;
  }

  // box-ordinal-group: integer
  if (eCSSUnit_Integer == xulData.mBoxOrdinal.GetUnit()) {
    xul->mBoxOrdinal = xulData.mBoxOrdinal.GetIntValue();
  }

  if (inherited)
    // We inherited, and therefore can't be cached in the rule node.  We have to be put right on the
    // style context.
    aContext->SetStyle(eStyleStruct_XUL, xul);
  else {
    // We were fully specified and can therefore be cached right on the rule node.
    if (!aHighestNode->mStyleData.mResetData) {
      aHighestNode->mStyleData.mResetData = new (mPresContext) nsResetStyleData;
      if (NS_UNLIKELY(!aHighestNode->mStyleData.mResetData)) {
        xul->Destroy(mPresContext);
        return nsnull;
      }
    }
    aHighestNode->mStyleData.mResetData->mXULData = xul;
    // Propagate the bit down.
    PropagateDependentBit(NS_STYLE_INHERIT_BIT(XUL), aHighestNode);
  }

  return xul;
}

Here is the call graph for this function:

Definition at line 492 of file nsRuleNode.cpp.

{
  NS_ASSERTION(!ChildrenAreHashed() && HaveChildren(),
               "must have a non-empty list of children");
  PLDHashTable *hash = PL_NewDHashTable(&ChildrenHashOps, nsnull,
                                        sizeof(ChildrenHashEntry),
                                        kMaxChildrenInList * 4);
  if (!hash)
    return;
  for (nsRuleList* curr = ChildrenList(); curr;
       curr = curr->DestroySelf(mPresContext)) {
    // This will never fail because of the initial size we gave the table.
    ChildrenHashEntry *entry = NS_STATIC_CAST(ChildrenHashEntry*,
        PL_DHashTableOperate(hash, curr->mRuleNode->mRule, PL_DHASH_ADD));
    NS_ASSERTION(!entry->mRuleNode, "duplicate entries in list");
    entry->mRuleNode = curr->mRuleNode;
  }
  SetChildrenHash(hash);
}

Here is the call graph for this function:

nsRuleNode* nsRuleNode::GetParent ( ) const [inline]

Definition at line 625 of file nsRuleNode.h.

{ return mParent; }

Here is the caller graph for this function:

Definition at line 631 of file nsRuleNode.h.

{ return mPresContext; }

Here is the caller graph for this function:

nsIStyleRule* nsRuleNode::GetRule ( ) const [inline]

Definition at line 629 of file nsRuleNode.h.

{ return mRule; }

Here is the caller graph for this function:

Definition at line 1186 of file nsRuleNode.cpp.

{
  nsRuleDataTable tableData; // Declare a struct with null CSS values.
  nsRuleData ruleData(eStyleStruct_TableBorder, mPresContext, aContext);
  ruleData.mTableData = &tableData;

  return WalkRuleTree(eStyleStruct_TableBorder, aContext, &ruleData, &tableData);
}

Here is the call graph for this function:

Definition at line 1063 of file nsRuleNode.cpp.

{
  nsRuleDataUserInterface uiData; // Declare a struct with null CSS values.
  nsRuleData ruleData(eStyleStruct_UserInterface, mPresContext, aContext);
  ruleData.mUserInterfaceData = &uiData;

  const nsStyleStruct* res = WalkRuleTree(eStyleStruct_UserInterface, aContext, &ruleData, &uiData);
  uiData.mCursor = nsnull;
  return res;
}

Here is the call graph for this function:

PRBool nsRuleNode::HaveChildren ( ) [inline, private]

Definition at line 346 of file nsRuleNode.h.

                        {
    return mChildrenTaggedPtr != nsnull;
  }

Here is the caller graph for this function:

PRBool nsRuleNode::IsRoot ( ) const [inline]

Definition at line 626 of file nsRuleNode.h.

{ return mParent == nsnull; }

Here is the caller graph for this function:

nsRuleNode::NS_HIDDEN_ ( void  ) [protected]
nsRuleNode::NS_HIDDEN_ ( void  ) [protected]
nsRuleNode::NS_HIDDEN_ ( const nsStyleStruct ) const [protected]
static nsRuleNode::NS_HIDDEN_ ( void  ) [static, protected]
static nsRuleNode::NS_HIDDEN_ ( void  ) [static, protected]
nsRuleNode::NS_HIDDEN_ ( void  ) [protected]
nsRuleNode::NS_HIDDEN_ ( const nsStyleStruct ) const [protected]
static nsRuleNode::NS_HIDDEN_ ( nsRuleNode ) [static]
void nsRuleNode::SetChildrenHash ( PLDHashTable aHashtable) [inline, private]

Definition at line 366 of file nsRuleNode.h.

                                                 {
    NS_ASSERTION(!(PRWord(aHashtable) & kTypeMask),
                 "pointer not 2-byte aligned");
    mChildrenTaggedPtr = (void*)(PRWord(aHashtable) | kHashType);
  }

Here is the caller graph for this function:

void nsRuleNode::SetChildrenList ( nsRuleList aList) [inline, private]

Definition at line 361 of file nsRuleNode.h.

                                          {
    NS_ASSERTION(!(PRWord(aList) & kTypeMask),
                 "pointer not 2-byte aligned");
    mChildrenTaggedPtr = aList;
  }
const nsStyleStruct * nsRuleNode::WalkRuleTree ( const nsStyleStructID  aSID,
nsStyleContext aContext,
nsRuleData aRuleData,
nsRuleDataStruct aSpecificData 
) [protected]

Definition at line 1265 of file nsRuleNode.cpp.

{
  // We start at the most specific rule in the tree.  
  nsStyleStruct* startStruct = nsnull;
  
  nsRuleNode* ruleNode = this;
  nsRuleNode* highestNode = nsnull; // The highest node in the rule tree
                                    // that has the same properties
                                    // specified for struct |aSID| as
                                    // |this| does.
  nsRuleNode* rootNode = this; // After the loop below, this will be the
                               // highest node that we've walked without
                               // finding cached data on the rule tree.
                               // If we don't find any cached data, it
                               // will be the root.  (XXX misnamed)
  RuleDetail detail = eRuleNone;
  PRUint32 bit = nsCachedStyleData::GetBitForSID(aSID);

  while (ruleNode) {
    // See if this rule node has cached the fact that the remaining
    // nodes along this path specify no data whatsoever.
    if (ruleNode->mNoneBits & bit)
      break;

    // If the dependent bit is set on a rule node for this struct, that
    // means its rule won't have any information to add, so skip it.
    // XXXldb I don't understand why we need to check |detail| here, but
    // we do.
    if (detail == eRuleNone)
      while (ruleNode->mDependentBits & bit) {
        NS_ASSERTION(ruleNode->mStyleData.GetStyleData(aSID) == nsnull,
                     "dependent bit with cached data makes no sense");
        // Climb up to the next rule in the tree (a less specific rule).
        rootNode = ruleNode;
        ruleNode = ruleNode->mParent;
        NS_ASSERTION(!(ruleNode->mNoneBits & bit), "can't have both bits set");
      }

    // Check for cached data after the inner loop above -- otherwise
    // we'll miss it.
    startStruct = ruleNode->mStyleData.GetStyleData(aSID);
    if (startStruct)
      break; // We found a rule with fully specified data.  We don't
             // need to go up the tree any further, since the remainder
             // of this branch has already been computed.

    // Ask the rule to fill in the properties that it specifies.
    nsIStyleRule *rule = ruleNode->mRule;
    if (rule)
      rule->MapRuleInfoInto(aRuleData);

    // Now we check to see how many properties have been specified by
    // the rules we've examined so far.
    RuleDetail oldDetail = detail;
    detail = CheckSpecifiedProperties(aSID, *aSpecificData);
  
    if (oldDetail == eRuleNone && detail != eRuleNone)
      highestNode = ruleNode;

    if (detail == eRuleFullReset ||
        detail == eRuleFullMixed ||
        detail == eRuleFullInherited)
      break; // We don't need to examine any more rules.  All properties
             // have been fully specified.

    // Climb up to the next rule in the tree (a less specific rule).
    rootNode = ruleNode;
    ruleNode = ruleNode->mParent;
  }

  PRBool isReset = nsCachedStyleData::IsReset(aSID);
  if (!highestNode)
    highestNode = rootNode;

  if (!aRuleData->mCanStoreInRuleTree)
    detail = eRulePartialMixed; // Treat as though some data is specified to avoid
                                // the optimizations and force data computation.

  if (detail == eRuleNone && startStruct && !aRuleData->mPostResolveCallback) {
    // We specified absolutely no rule information, but a parent rule in the tree
    // specified all the rule information.  We set a bit along the branch from our
    // node in the tree to the node that specified the data that tells nodes on that
    // branch that they never need to examine their rules for this particular struct type
    // ever again.
    PropagateDependentBit(bit, ruleNode);
    return startStruct;
  }
  else if (!startStruct && ((!isReset && (detail == eRuleNone || detail == eRulePartialInherited)) 
                             || detail == eRuleFullInherited)) {
    // We specified no non-inherited information and neither did any of
    // our parent rules.

    // We set a bit along the branch from the highest node (ruleNode)
    // down to our node (this) indicating that no non-inherited data was
    // specified.  This bit is guaranteed to be set already on the path
    // from the highest node to the root node in the case where
    // (detail == eRuleNone), which is the most common case here.
    // We must check |!isReset| because the Compute*Data functions for
    // reset structs wouldn't handle none bits correctly.
    if (highestNode != this && !isReset)
      PropagateNoneBit(bit, highestNode);
    
    // All information must necessarily be inherited from our parent style context.
    // In the absence of any computed data in the rule tree and with
    // no rules specified that didn't have values of 'inherit', we should check our parent.
    nsStyleContext* parentContext = aContext->GetParent();
    if (parentContext) {
      // We have a parent, and so we should just inherit from the parent.
      // Set the inherit bits on our context.  These bits tell the style context that
      // it never has to go back to the rule tree for data.  Instead the style context tree
      // should be walked to find the data.
      const nsStyleStruct* parentStruct = parentContext->GetStyleData(aSID);
      aContext->AddStyleBit(bit); // makes const_cast OK.
      aContext->SetStyle(aSID, NS_CONST_CAST(nsStyleStruct*, parentStruct));
      return parentStruct;
    }
    else
      // We are the root.  In the case of fonts, the default values just
      // come from the pres context.
      return SetDefaultOnRoot(aSID, aContext);
  }

  // We need to compute the data from the information that the rules specified.
  const nsStyleStruct* res;
#define STYLE_STRUCT_TEST aSID
#define STYLE_STRUCT(name, checkdata_cb, ctor_args)                           \
  res = Compute##name##Data(startStruct, *aSpecificData, aContext,            \
                      highestNode, detail, !aRuleData->mCanStoreInRuleTree);
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
#undef STYLE_STRUCT_TEST

  // If we have a post-resolve callback, handle that now.
  if (aRuleData->mPostResolveCallback && (NS_LIKELY(res != nsnull)))
    (*aRuleData->mPostResolveCallback)((nsStyleStruct*)res, aRuleData);

  // Now return the result.
  return res;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Friends And Related Function Documentation

friend struct nsRuleList [friend]

Definition at line 396 of file nsRuleNode.h.


Member Data Documentation

Definition at line 635 of file nsRuleNode.h.

Definition at line 411 of file nsRuleNode.h.

Definition at line 556 of file nsRuleNode.h.

Definition at line 556 of file nsRuleNode.h.

Definition at line 556 of file nsRuleNode.h.

Definition at line 566 of file nsRuleNode.h.

Definition at line 556 of file nsRuleNode.h.

Definition at line 566 of file nsRuleNode.h.

Definition at line 566 of file nsRuleNode.h.

Definition at line 407 of file nsRuleNode.h.

Definition at line 556 of file nsRuleNode.h.

Definition at line 574 of file nsRuleNode.h.

Definition at line 556 of file nsRuleNode.h.

Definition at line 574 of file nsRuleNode.h.

Definition at line 574 of file nsRuleNode.h.

Definition at line 574 of file nsRuleNode.h.

Definition at line 556 of file nsRuleNode.h.

Definition at line 566 of file nsRuleNode.h.

Definition at line 556 of file nsRuleNode.h.

Definition at line 574 of file nsRuleNode.h.

Definition at line 574 of file nsRuleNode.h.

Definition at line 624 of file nsRuleNode.h.

Definition at line 574 of file nsRuleNode.h.

Definition at line 574 of file nsRuleNode.h.

Definition at line 574 of file nsRuleNode.h.

Definition at line 556 of file nsRuleNode.h.

Definition at line 566 of file nsRuleNode.h.

Definition at line 401 of file nsRuleNode.h.

Definition at line 333 of file nsRuleNode.h.

Definition at line 375 of file nsRuleNode.h.

Definition at line 378 of file nsRuleNode.h.

Definition at line 321 of file nsRuleNode.h.

Definition at line 319 of file nsRuleNode.h.

Definition at line 326 of file nsRuleNode.h.

Definition at line 373 of file nsRuleNode.h.


The documentation for this class was generated from the following files: