layout/style/nsRuleNode.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/layout/style/nsRuleNode.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,807 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +/*
    1.10 + * a node in the lexicographic tree of rules that match an element,
    1.11 + * responsible for converting the rules' information into computed style
    1.12 + */
    1.13 +
    1.14 +#ifndef nsRuleNode_h___
    1.15 +#define nsRuleNode_h___
    1.16 +
    1.17 +#include "nsPresContext.h"
    1.18 +#include "nsStyleStruct.h"
    1.19 +
    1.20 +#include <stdint.h>
    1.21 +
    1.22 +class nsStyleContext;
    1.23 +struct nsRuleData;
    1.24 +class nsIStyleRule;
    1.25 +struct nsCSSValueList;
    1.26 +
    1.27 +class nsCSSValue;
    1.28 +struct nsCSSRect;
    1.29 +
    1.30 +class nsStyleCoord;
    1.31 +struct nsCSSValuePairList;
    1.32 +
    1.33 +template <nsStyleStructID MinIndex, nsStyleStructID Count>
    1.34 +class FixedStyleStructArray
    1.35 +{
    1.36 +private:
    1.37 +  void* mArray[Count];
    1.38 +public:
    1.39 +  void*& operator[](nsStyleStructID aIndex) {
    1.40 +    NS_ABORT_IF_FALSE(MinIndex <= aIndex && aIndex < (MinIndex + Count),
    1.41 +                      "out of range");
    1.42 +    return mArray[aIndex - MinIndex];
    1.43 +  }
    1.44 +
    1.45 +  const void* operator[](nsStyleStructID aIndex) const {
    1.46 +    NS_ABORT_IF_FALSE(MinIndex <= aIndex && aIndex < (MinIndex + Count),
    1.47 +                      "out of range");
    1.48 +    return mArray[aIndex - MinIndex];
    1.49 +  }
    1.50 +};
    1.51 +
    1.52 +struct nsInheritedStyleData
    1.53 +{
    1.54 +  FixedStyleStructArray<nsStyleStructID_Inherited_Start,
    1.55 +                        nsStyleStructID_Inherited_Count> mStyleStructs;
    1.56 +
    1.57 +  void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
    1.58 +    return aContext->AllocateFromShell(sz);
    1.59 +  }
    1.60 +
    1.61 +  void DestroyStructs(uint64_t aBits, nsPresContext* aContext) {
    1.62 +#define STYLE_STRUCT_INHERITED(name, checkdata_cb) \
    1.63 +    void *name##Data = mStyleStructs[eStyleStruct_##name]; \
    1.64 +    if (name##Data && !(aBits & NS_STYLE_INHERIT_BIT(name))) \
    1.65 +      static_cast<nsStyle##name*>(name##Data)->Destroy(aContext);
    1.66 +#define STYLE_STRUCT_RESET(name, checkdata_cb)
    1.67 +
    1.68 +#include "nsStyleStructList.h"
    1.69 +
    1.70 +#undef STYLE_STRUCT_INHERITED
    1.71 +#undef STYLE_STRUCT_RESET
    1.72 +  }
    1.73 +
    1.74 +  void Destroy(uint64_t aBits, nsPresContext* aContext) {
    1.75 +    DestroyStructs(aBits, aContext);
    1.76 +    aContext->FreeToShell(sizeof(nsInheritedStyleData), this);
    1.77 +  }
    1.78 +
    1.79 +  nsInheritedStyleData() {
    1.80 +    for (nsStyleStructID i = nsStyleStructID_Inherited_Start;
    1.81 +         i < nsStyleStructID_Inherited_Start + nsStyleStructID_Inherited_Count;
    1.82 +         i = nsStyleStructID(i + 1)) {
    1.83 +      mStyleStructs[i] = nullptr;
    1.84 +    }
    1.85 +  }
    1.86 +};
    1.87 +
    1.88 +struct nsResetStyleData
    1.89 +{
    1.90 +  FixedStyleStructArray<nsStyleStructID_Reset_Start,
    1.91 +                        nsStyleStructID_Reset_Count> mStyleStructs;
    1.92 +
    1.93 +  nsResetStyleData()
    1.94 +  {
    1.95 +    for (nsStyleStructID i = nsStyleStructID_Reset_Start;
    1.96 +         i < nsStyleStructID_Reset_Start + nsStyleStructID_Reset_Count;
    1.97 +         i = nsStyleStructID(i + 1)) {
    1.98 +      mStyleStructs[i] = nullptr;
    1.99 +    }
   1.100 +  }
   1.101 +
   1.102 +  void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
   1.103 +    return aContext->AllocateFromShell(sz);
   1.104 +  }
   1.105 +
   1.106 +  void Destroy(uint64_t aBits, nsPresContext* aContext) {
   1.107 +#define STYLE_STRUCT_RESET(name, checkdata_cb) \
   1.108 +    void *name##Data = mStyleStructs[eStyleStruct_##name]; \
   1.109 +    if (name##Data && !(aBits & NS_STYLE_INHERIT_BIT(name))) \
   1.110 +      static_cast<nsStyle##name*>(name##Data)->Destroy(aContext);
   1.111 +#define STYLE_STRUCT_INHERITED(name, checkdata_cb)
   1.112 +
   1.113 +#include "nsStyleStructList.h"
   1.114 +
   1.115 +#undef STYLE_STRUCT_RESET
   1.116 +#undef STYLE_STRUCT_INHERITED
   1.117 +
   1.118 +    aContext->FreeToShell(sizeof(nsResetStyleData), this);
   1.119 +  }
   1.120 +};
   1.121 +
   1.122 +struct nsCachedStyleData
   1.123 +{
   1.124 +  nsInheritedStyleData* mInheritedData;
   1.125 +  nsResetStyleData* mResetData;
   1.126 +
   1.127 +  static bool IsReset(const nsStyleStructID aSID) {
   1.128 +    NS_ABORT_IF_FALSE(0 <= aSID && aSID < nsStyleStructID_Length,
   1.129 +                      "must be an inherited or reset SID");
   1.130 +    return nsStyleStructID_Reset_Start <= aSID;
   1.131 +  }
   1.132 +
   1.133 +  static bool IsInherited(const nsStyleStructID aSID) {
   1.134 +    return !IsReset(aSID);
   1.135 +  }
   1.136 +
   1.137 +  static uint32_t GetBitForSID(const nsStyleStructID aSID) {
   1.138 +    return 1 << aSID;
   1.139 +  }
   1.140 +
   1.141 +  void* NS_FASTCALL GetStyleData(const nsStyleStructID aSID) {
   1.142 +    if (IsReset(aSID)) {
   1.143 +      if (mResetData) {
   1.144 +        return mResetData->mStyleStructs[aSID];
   1.145 +      }
   1.146 +    } else {
   1.147 +      if (mInheritedData) {
   1.148 +        return mInheritedData->mStyleStructs[aSID];
   1.149 +      }
   1.150 +    }
   1.151 +    return nullptr;
   1.152 +  }
   1.153 +
   1.154 +  void NS_FASTCALL SetStyleData(const nsStyleStructID aSID,
   1.155 +                                nsPresContext *aPresContext, void *aData) {
   1.156 +    if (IsReset(aSID)) {
   1.157 +      if (!mResetData) {
   1.158 +        mResetData = new (aPresContext) nsResetStyleData;
   1.159 +      }
   1.160 +      mResetData->mStyleStructs[aSID] = aData;
   1.161 +    } else {
   1.162 +      if (!mInheritedData) {
   1.163 +        mInheritedData = new (aPresContext) nsInheritedStyleData;
   1.164 +      }
   1.165 +      mInheritedData->mStyleStructs[aSID] = aData;
   1.166 +    }
   1.167 +  }
   1.168 +
   1.169 +  // Typesafe and faster versions of the above
   1.170 +  #define STYLE_STRUCT_INHERITED(name_, checkdata_cb_)                   \
   1.171 +    nsStyle##name_ * NS_FASTCALL GetStyle##name_ () {                    \
   1.172 +      return mInheritedData ? static_cast<nsStyle##name_*>(              \
   1.173 +        mInheritedData->mStyleStructs[eStyleStruct_##name_]) : nullptr;  \
   1.174 +    }
   1.175 +  #define STYLE_STRUCT_RESET(name_, checkdata_cb_)                       \
   1.176 +    nsStyle##name_ * NS_FASTCALL GetStyle##name_ () {                    \
   1.177 +      return mResetData ? static_cast<nsStyle##name_*>(                  \
   1.178 +        mResetData->mStyleStructs[eStyleStruct_##name_]) : nullptr;      \
   1.179 +    }
   1.180 +  #include "nsStyleStructList.h"
   1.181 +  #undef STYLE_STRUCT_RESET
   1.182 +  #undef STYLE_STRUCT_INHERITED
   1.183 +
   1.184 +  void Destroy(uint64_t aBits, nsPresContext* aContext) {
   1.185 +    if (mResetData)
   1.186 +      mResetData->Destroy(aBits, aContext);
   1.187 +    if (mInheritedData)
   1.188 +      mInheritedData->Destroy(aBits, aContext);
   1.189 +    mResetData = nullptr;
   1.190 +    mInheritedData = nullptr;
   1.191 +  }
   1.192 +
   1.193 +  nsCachedStyleData() :mInheritedData(nullptr), mResetData(nullptr) {}
   1.194 +  ~nsCachedStyleData() {}
   1.195 +};
   1.196 +
   1.197 +/**
   1.198 + * nsRuleNode is a node in a lexicographic tree (the "rule tree")
   1.199 + * indexed by style rules (implementations of nsIStyleRule).
   1.200 + *
   1.201 + * The rule tree is owned by the nsStyleSet and is destroyed when the
   1.202 + * presentation of the document goes away.  It is garbage-collected
   1.203 + * (using mark-and-sweep garbage collection) during the lifetime of the
   1.204 + * document (when dynamic changes cause the destruction of enough style
   1.205 + * contexts).  Rule nodes are marked if they are pointed to by a style
   1.206 + * context or one of their descendants is.
   1.207 + *
   1.208 + * An nsStyleContext, which represents the computed style data for an
   1.209 + * element, points to an nsRuleNode.  The path from the root of the rule
   1.210 + * tree to the nsStyleContext's mRuleNode gives the list of the rules
   1.211 + * matched, from least important in the cascading order to most
   1.212 + * important in the cascading order.
   1.213 + *
   1.214 + * The reason for using a lexicographic tree is that it allows for
   1.215 + * sharing of style data, which saves both memory (for storing the
   1.216 + * computed style data) and time (for computing them).  This sharing
   1.217 + * depends on the computed style data being stored in structs (nsStyle*)
   1.218 + * that contain only properties that are inherited by default
   1.219 + * ("inherited structs") or structs that contain only properties that
   1.220 + * are not inherited by default ("reset structs").  The optimization
   1.221 + * depends on the normal case being that style rules specify relatively
   1.222 + * few properties and even that elements generally have relatively few
   1.223 + * properties specified.  This allows sharing in the following ways:
   1.224 + *   1. [mainly reset structs] When a style data struct will contain the
   1.225 + *      same computed value for any elements that match the same set of
   1.226 + *      rules (common for reset structs), it can be stored on the
   1.227 + *      nsRuleNode instead of on the nsStyleContext.
   1.228 + *   2. [only? reset structs] When (1) occurs, and an nsRuleNode doesn't
   1.229 + *      have any rules that change the values in the struct, the
   1.230 + *      nsRuleNode can share that struct with its parent nsRuleNode.
   1.231 + *   3. [mainly inherited structs] When an element doesn't match any
   1.232 + *      rules that change the value of a property (or, in the edge case,
   1.233 + *      when all the values specified are 'inherit'), the nsStyleContext
   1.234 + *      can use the same nsStyle* struct as its parent nsStyleContext.
   1.235 + *
   1.236 + * Since the data represented by an nsIStyleRule are immutable, the data
   1.237 + * represented by an nsRuleNode are also immutable.
   1.238 + */
   1.239 +
   1.240 +enum nsFontSizeType {
   1.241 +  eFontSize_HTML = 1,
   1.242 +  eFontSize_CSS = 2
   1.243 +};
   1.244 +
   1.245 +class nsRuleNode {
   1.246 +public:
   1.247 +  enum RuleDetail {
   1.248 +    eRuleNone, // No props have been specified at all.
   1.249 +    eRulePartialReset, // At least one prop with a non-"inherit" value
   1.250 +                       // has been specified.  No props have been
   1.251 +                       // specified with an "inherit" value.  At least
   1.252 +                       // one prop remains unspecified.
   1.253 +    eRulePartialMixed, // At least one prop with a non-"inherit" value
   1.254 +                       // has been specified.  Some props may also have
   1.255 +                       // been specified with an "inherit" value.  At
   1.256 +                       // least one prop remains unspecified.
   1.257 +    eRulePartialInherited, // Only props with "inherit" values have
   1.258 +                           // have been specified.  At least one prop
   1.259 +                           // remains unspecified.
   1.260 +    eRuleFullReset, // All props have been specified.  None has an
   1.261 +                    // "inherit" value.
   1.262 +    eRuleFullMixed, // All props have been specified.  At least one has
   1.263 +                    // a non-"inherit" value.
   1.264 +    eRuleFullInherited  // All props have been specified with "inherit"
   1.265 +                        // values.
   1.266 +  };
   1.267 +
   1.268 +private:
   1.269 +  nsPresContext* const mPresContext; // Our pres context.
   1.270 +
   1.271 +  nsRuleNode* const mParent; // A pointer to the parent node in the tree.
   1.272 +                             // This enables us to walk backwards from the
   1.273 +                             // most specific rule matched to the least
   1.274 +                             // specific rule (which is the optimal order to
   1.275 +                             // use for lookups of style properties.
   1.276 +  nsIStyleRule* const mRule; // [STRONG] A pointer to our specific rule.
   1.277 +
   1.278 +  nsRuleNode* mNextSibling; // This value should be used only by the
   1.279 +                            // parent, since the parent may store
   1.280 +                            // children in a hash, which means this
   1.281 +                            // pointer is not meaningful.  Order of
   1.282 +                            // siblings is also not meaningful.
   1.283 +
   1.284 +  struct Key {
   1.285 +    nsIStyleRule* mRule;
   1.286 +    uint8_t mLevel;
   1.287 +    bool mIsImportantRule;
   1.288 +
   1.289 +    Key(nsIStyleRule* aRule, uint8_t aLevel, bool aIsImportantRule)
   1.290 +      : mRule(aRule), mLevel(aLevel), mIsImportantRule(aIsImportantRule)
   1.291 +    {}
   1.292 +
   1.293 +    bool operator==(const Key& aOther) const
   1.294 +    {
   1.295 +      return mRule == aOther.mRule &&
   1.296 +             mLevel == aOther.mLevel &&
   1.297 +             mIsImportantRule == aOther.mIsImportantRule;
   1.298 +    }
   1.299 +
   1.300 +    bool operator!=(const Key& aOther) const
   1.301 +    {
   1.302 +      return !(*this == aOther);
   1.303 +    }
   1.304 +  };
   1.305 +
   1.306 +  static PLDHashNumber
   1.307 +  ChildrenHashHashKey(PLDHashTable *aTable, const void *aKey);
   1.308 +
   1.309 +  static bool
   1.310 +  ChildrenHashMatchEntry(PLDHashTable *aTable,
   1.311 +                         const PLDHashEntryHdr *aHdr,
   1.312 +                         const void *aKey);
   1.313 +
   1.314 +  static const PLDHashTableOps ChildrenHashOps;
   1.315 +
   1.316 +  static PLDHashOperator
   1.317 +  EnqueueRuleNodeChildren(PLDHashTable *table, PLDHashEntryHdr *hdr,
   1.318 +                          uint32_t number, void *arg);
   1.319 +
   1.320 +  Key GetKey() const {
   1.321 +    return Key(mRule, GetLevel(), IsImportantRule());
   1.322 +  }
   1.323 +
   1.324 +  // The children of this node are stored in either a hashtable or list
   1.325 +  // that maps from rules to our nsRuleNode children.  When matching
   1.326 +  // rules, we use this mapping to transition from node to node
   1.327 +  // (constructing new nodes as needed to flesh out the tree).
   1.328 +
   1.329 +  union {
   1.330 +    void* asVoid;
   1.331 +    nsRuleNode* asList;
   1.332 +    PLDHashTable* asHash;
   1.333 +  } mChildren; // Accessed only through the methods below.
   1.334 +
   1.335 +  enum {
   1.336 +    kTypeMask = 0x1,
   1.337 +    kListType = 0x0,
   1.338 +    kHashType = 0x1
   1.339 +  };
   1.340 +  enum {
   1.341 +    // Maximum to have in a list before converting to a hashtable.
   1.342 +    // XXX Need to optimize this.
   1.343 +    kMaxChildrenInList = 32
   1.344 +  };
   1.345 +
   1.346 +  bool HaveChildren() const {
   1.347 +    return mChildren.asVoid != nullptr;
   1.348 +  }
   1.349 +  bool ChildrenAreHashed() {
   1.350 +    return (intptr_t(mChildren.asVoid) & kTypeMask) == kHashType;
   1.351 +  }
   1.352 +  nsRuleNode* ChildrenList() {
   1.353 +    return mChildren.asList;
   1.354 +  }
   1.355 +  nsRuleNode** ChildrenListPtr() {
   1.356 +    return &mChildren.asList;
   1.357 +  }
   1.358 +  PLDHashTable* ChildrenHash() {
   1.359 +    return (PLDHashTable*) (intptr_t(mChildren.asHash) & ~intptr_t(kTypeMask));
   1.360 +  }
   1.361 +  void SetChildrenList(nsRuleNode *aList) {
   1.362 +    NS_ASSERTION(!(intptr_t(aList) & kTypeMask),
   1.363 +                 "pointer not 2-byte aligned");
   1.364 +    mChildren.asList = aList;
   1.365 +  }
   1.366 +  void SetChildrenHash(PLDHashTable *aHashtable) {
   1.367 +    NS_ASSERTION(!(intptr_t(aHashtable) & kTypeMask),
   1.368 +                 "pointer not 2-byte aligned");
   1.369 +    mChildren.asHash = (PLDHashTable*)(intptr_t(aHashtable) | kHashType);
   1.370 +  }
   1.371 +  void ConvertChildrenToHash();
   1.372 +
   1.373 +  nsCachedStyleData mStyleData;   // Any data we cached on the rule node.
   1.374 +
   1.375 +  uint32_t mDependentBits; // Used to cache the fact that we can look up
   1.376 +                           // cached data under a parent rule.
   1.377 +
   1.378 +  uint32_t mNoneBits; // Used to cache the fact that the branch to this
   1.379 +                      // node specifies no non-inherited data for a
   1.380 +                      // given struct type.  (This usually implies that
   1.381 +                      // the entire branch specifies no non-inherited
   1.382 +                      // data, although not necessarily, if a
   1.383 +                      // non-inherited value is overridden by an
   1.384 +                      // explicit 'inherit' value.)  For example, if an
   1.385 +                      // entire rule branch specifies no color
   1.386 +                      // information, then a bit will be set along every
   1.387 +                      // rule node on that branch, so that you can break
   1.388 +                      // out of the rule tree early and just inherit
   1.389 +                      // from the parent style context.  The presence of
   1.390 +                      // this bit means we should just get inherited
   1.391 +                      // data from the parent style context, and it is
   1.392 +                      // never used for reset structs since their
   1.393 +                      // Compute*Data functions don't initialize from
   1.394 +                      // inherited data.
   1.395 +
   1.396 +  // Reference count.  This just counts the style contexts that reference this
   1.397 +  // rulenode.  And children the rulenode has had.  When this goes to 0 or
   1.398 +  // stops being 0, we notify the style set.
   1.399 +  // Note, in particular, that when a child is removed mRefCnt is NOT
   1.400 +  // decremented.  This is on purpose; the notifications to the style set are
   1.401 +  // only used to determine when it's worth running GC on the ruletree, and
   1.402 +  // this setup makes it so we only count unused ruletree leaves for purposes
   1.403 +  // of deciding when to GC.  We could more accurately count unused rulenodes
   1.404 +  // by releasing/addrefing our parent when our refcount transitions to or from
   1.405 +  // 0, but it doesn't seem worth it to do that.
   1.406 +  uint32_t mRefCnt;
   1.407 +
   1.408 +public:
   1.409 +  // Overloaded new operator. Initializes the memory to 0 and relies on an arena
   1.410 +  // (which comes from the presShell) to perform the allocation.
   1.411 +  void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW;
   1.412 +  void Destroy() { DestroyInternal(nullptr); }
   1.413 +
   1.414 +  // Implemented in nsStyleSet.h, since it needs to know about nsStyleSet.
   1.415 +  inline void AddRef();
   1.416 +
   1.417 +  // Implemented in nsStyleSet.h, since it needs to know about nsStyleSet.
   1.418 +  inline void Release();
   1.419 +
   1.420 +protected:
   1.421 +  void DestroyInternal(nsRuleNode ***aDestroyQueueTail);
   1.422 +  void PropagateDependentBit(nsStyleStructID aSID, nsRuleNode* aHighestNode,
   1.423 +                             void* aStruct);
   1.424 +  void PropagateNoneBit(uint32_t aBit, nsRuleNode* aHighestNode);
   1.425 +
   1.426 +  const void* SetDefaultOnRoot(const nsStyleStructID aSID,
   1.427 +                               nsStyleContext* aContext);
   1.428 +
   1.429 +  /**
   1.430 +   * Resolves any property values in aRuleData for a given style struct that
   1.431 +   * have eCSSUnit_TokenStream values, by resolving them against the computed
   1.432 +   * variable values on the style context and re-parsing the property.
   1.433 +   *
   1.434 +   * @return Whether any properties with eCSSUnit_TokenStream values were
   1.435 +   *   encountered.
   1.436 +   */
   1.437 +  static bool ResolveVariableReferences(const nsStyleStructID aSID,
   1.438 +                                        nsRuleData* aRuleData,
   1.439 +                                        nsStyleContext* aContext);
   1.440 +
   1.441 +  const void*
   1.442 +    WalkRuleTree(const nsStyleStructID aSID, nsStyleContext* aContext);
   1.443 +
   1.444 +  const void*
   1.445 +    ComputeDisplayData(void* aStartStruct,
   1.446 +                       const nsRuleData* aRuleData,
   1.447 +                       nsStyleContext* aContext, nsRuleNode* aHighestNode,
   1.448 +                       RuleDetail aRuleDetail,
   1.449 +                       const bool aCanStoreInRuleTree);
   1.450 +
   1.451 +  const void*
   1.452 +    ComputeVisibilityData(void* aStartStruct,
   1.453 +                          const nsRuleData* aRuleData,
   1.454 +                          nsStyleContext* aContext, nsRuleNode* aHighestNode,
   1.455 +                          RuleDetail aRuleDetail,
   1.456 +                          const bool aCanStoreInRuleTree);
   1.457 +
   1.458 +  const void*
   1.459 +    ComputeFontData(void* aStartStruct,
   1.460 +                    const nsRuleData* aRuleData,
   1.461 +                    nsStyleContext* aContext, nsRuleNode* aHighestNode,
   1.462 +                    RuleDetail aRuleDetail,
   1.463 +                    const bool aCanStoreInRuleTree);
   1.464 +
   1.465 +  const void*
   1.466 +    ComputeColorData(void* aStartStruct,
   1.467 +                     const nsRuleData* aRuleData,
   1.468 +                     nsStyleContext* aContext, nsRuleNode* aHighestNode,
   1.469 +                     RuleDetail aRuleDetail,
   1.470 +                     const bool aCanStoreInRuleTree);
   1.471 +
   1.472 +  const void*
   1.473 +    ComputeBackgroundData(void* aStartStruct,
   1.474 +                          const nsRuleData* aRuleData,
   1.475 +                          nsStyleContext* aContext, nsRuleNode* aHighestNode,
   1.476 +                          RuleDetail aRuleDetail,
   1.477 +                          const bool aCanStoreInRuleTree);
   1.478 +
   1.479 +  const void*
   1.480 +    ComputeMarginData(void* aStartStruct,
   1.481 +                      const nsRuleData* aRuleData,
   1.482 +                      nsStyleContext* aContext, nsRuleNode* aHighestNode,
   1.483 +                      RuleDetail aRuleDetail,
   1.484 +                      const bool aCanStoreInRuleTree);
   1.485 +
   1.486 +  const void*
   1.487 +    ComputeBorderData(void* aStartStruct,
   1.488 +                      const nsRuleData* aRuleData,
   1.489 +                      nsStyleContext* aContext, nsRuleNode* aHighestNode,
   1.490 +                      RuleDetail aRuleDetail,
   1.491 +                      const bool aCanStoreInRuleTree);
   1.492 +
   1.493 +  const void*
   1.494 +    ComputePaddingData(void* aStartStruct,
   1.495 +                       const nsRuleData* aRuleData,
   1.496 +                       nsStyleContext* aContext, nsRuleNode* aHighestNode,
   1.497 +                       RuleDetail aRuleDetail,
   1.498 +                       const bool aCanStoreInRuleTree);
   1.499 +
   1.500 +  const void*
   1.501 +    ComputeOutlineData(void* aStartStruct,
   1.502 +                       const nsRuleData* aRuleData,
   1.503 +                       nsStyleContext* aContext, nsRuleNode* aHighestNode,
   1.504 +                       RuleDetail aRuleDetail,
   1.505 +                       const bool aCanStoreInRuleTree);
   1.506 +
   1.507 +  const void*
   1.508 +    ComputeListData(void* aStartStruct,
   1.509 +                    const nsRuleData* aRuleData,
   1.510 +                    nsStyleContext* aContext, nsRuleNode* aHighestNode,
   1.511 +                    RuleDetail aRuleDetail,
   1.512 +                    const bool aCanStoreInRuleTree);
   1.513 +
   1.514 +  const void*
   1.515 +    ComputePositionData(void* aStartStruct,
   1.516 +                        const nsRuleData* aRuleData,
   1.517 +                        nsStyleContext* aContext, nsRuleNode* aHighestNode,
   1.518 +                        RuleDetail aRuleDetail,
   1.519 +                        const bool aCanStoreInRuleTree);
   1.520 +
   1.521 +  const void*
   1.522 +    ComputeTableData(void* aStartStruct,
   1.523 +                     const nsRuleData* aRuleData,
   1.524 +                     nsStyleContext* aContext, nsRuleNode* aHighestNode,
   1.525 +                     RuleDetail aRuleDetail,
   1.526 +                     const bool aCanStoreInRuleTree);
   1.527 +
   1.528 +  const void*
   1.529 +    ComputeTableBorderData(void* aStartStruct,
   1.530 +                           const nsRuleData* aRuleData,
   1.531 +                           nsStyleContext* aContext, nsRuleNode* aHighestNode,
   1.532 +                           RuleDetail aRuleDetail,
   1.533 +                           const bool aCanStoreInRuleTree);
   1.534 +
   1.535 +  const void*
   1.536 +    ComputeContentData(void* aStartStruct,
   1.537 +                       const nsRuleData* aRuleData,
   1.538 +                       nsStyleContext* aContext, nsRuleNode* aHighestNode,
   1.539 +                       RuleDetail aRuleDetail,
   1.540 +                       const bool aCanStoreInRuleTree);
   1.541 +
   1.542 +  const void*
   1.543 +    ComputeQuotesData(void* aStartStruct,
   1.544 +                      const nsRuleData* aRuleData,
   1.545 +                      nsStyleContext* aContext, nsRuleNode* aHighestNode,
   1.546 +                      RuleDetail aRuleDetail,
   1.547 +                      const bool aCanStoreInRuleTree);
   1.548 +
   1.549 +  const void*
   1.550 +    ComputeTextData(void* aStartStruct,
   1.551 +                    const nsRuleData* aRuleData,
   1.552 +                    nsStyleContext* aContext, nsRuleNode* aHighestNode,
   1.553 +                    RuleDetail aRuleDetail,
   1.554 +                    const bool aCanStoreInRuleTree);
   1.555 +
   1.556 +  const void*
   1.557 +    ComputeTextResetData(void* aStartStruct,
   1.558 +                         const nsRuleData* aRuleData,
   1.559 +                         nsStyleContext* aContext, nsRuleNode* aHighestNode,
   1.560 +                         RuleDetail aRuleDetail,
   1.561 +                         const bool aCanStoreInRuleTree);
   1.562 +
   1.563 +  const void*
   1.564 +    ComputeUserInterfaceData(void* aStartStruct,
   1.565 +                             const nsRuleData* aRuleData,
   1.566 +                             nsStyleContext* aContext,
   1.567 +                             nsRuleNode* aHighestNode,
   1.568 +                             RuleDetail aRuleDetail,
   1.569 +                             const bool aCanStoreInRuleTree);
   1.570 +
   1.571 +  const void*
   1.572 +    ComputeUIResetData(void* aStartStruct,
   1.573 +                       const nsRuleData* aRuleData,
   1.574 +                       nsStyleContext* aContext, nsRuleNode* aHighestNode,
   1.575 +                       RuleDetail aRuleDetail,
   1.576 +                       const bool aCanStoreInRuleTree);
   1.577 +
   1.578 +  const void*
   1.579 +    ComputeXULData(void* aStartStruct,
   1.580 +                   const nsRuleData* aRuleData,
   1.581 +                   nsStyleContext* aContext, nsRuleNode* aHighestNode,
   1.582 +                   RuleDetail aRuleDetail,
   1.583 +                   const bool aCanStoreInRuleTree);
   1.584 +
   1.585 +  const void*
   1.586 +    ComputeColumnData(void* aStartStruct,
   1.587 +                      const nsRuleData* aRuleData,
   1.588 +                      nsStyleContext* aContext, nsRuleNode* aHighestNode,
   1.589 +                      RuleDetail aRuleDetail,
   1.590 +                      const bool aCanStoreInRuleTree);
   1.591 +
   1.592 +  const void*
   1.593 +    ComputeSVGData(void* aStartStruct,
   1.594 +                   const nsRuleData* aRuleData,
   1.595 +                   nsStyleContext* aContext, nsRuleNode* aHighestNode,
   1.596 +                   RuleDetail aRuleDetail,
   1.597 +                   const bool aCanStoreInRuleTree);
   1.598 +
   1.599 +  const void*
   1.600 +    ComputeSVGResetData(void* aStartStruct,
   1.601 +                        const nsRuleData* aRuleData,
   1.602 +                        nsStyleContext* aContext, nsRuleNode* aHighestNode,
   1.603 +                        RuleDetail aRuleDetail,
   1.604 +                        const bool aCanStoreInRuleTree);
   1.605 +
   1.606 +  const void*
   1.607 +    ComputeVariablesData(void* aStartStruct,
   1.608 +                         const nsRuleData* aRuleData,
   1.609 +                         nsStyleContext* aContext, nsRuleNode* aHighestNode,
   1.610 +                         RuleDetail aRuleDetail,
   1.611 +                         const bool aCanStoreInRuleTree);
   1.612 +
   1.613 +  // helpers for |ComputeFontData| that need access to |mNoneBits|:
   1.614 +  static void SetFontSize(nsPresContext* aPresContext,
   1.615 +                          const nsRuleData* aRuleData,
   1.616 +                          const nsStyleFont* aFont,
   1.617 +                          const nsStyleFont* aParentFont,
   1.618 +                          nscoord* aSize,
   1.619 +                          const nsFont& aSystemFont,
   1.620 +                          nscoord aParentSize,
   1.621 +                          nscoord aScriptLevelAdjustedParentSize,
   1.622 +                          bool aUsedStartStruct,
   1.623 +                          bool aAtRoot,
   1.624 +                          bool& aCanStoreInRuleTree);
   1.625 +
   1.626 +  static void SetFont(nsPresContext* aPresContext,
   1.627 +                      nsStyleContext* aContext,
   1.628 +                      uint8_t aGenericFontID,
   1.629 +                      const nsRuleData* aRuleData,
   1.630 +                      const nsStyleFont* aParentFont,
   1.631 +                      nsStyleFont* aFont,
   1.632 +                      bool aStartStruct,
   1.633 +                      bool& aCanStoreInRuleTree);
   1.634 +
   1.635 +  static void SetGenericFont(nsPresContext* aPresContext,
   1.636 +                             nsStyleContext* aContext,
   1.637 +                             uint8_t aGenericFontID,
   1.638 +                             nsStyleFont* aFont);
   1.639 +
   1.640 +  void AdjustLogicalBoxProp(nsStyleContext* aContext,
   1.641 +                            const nsCSSValue& aLTRSource,
   1.642 +                            const nsCSSValue& aRTLSource,
   1.643 +                            const nsCSSValue& aLTRLogicalValue,
   1.644 +                            const nsCSSValue& aRTLLogicalValue,
   1.645 +                            mozilla::css::Side aSide,
   1.646 +                            nsCSSRect& aValueRect,
   1.647 +                            bool& aCanStoreInRuleTree);
   1.648 +
   1.649 +  inline RuleDetail CheckSpecifiedProperties(const nsStyleStructID aSID,
   1.650 +                                             const nsRuleData* aRuleData);
   1.651 +
   1.652 +  already_AddRefed<nsCSSShadowArray>
   1.653 +              GetShadowData(const nsCSSValueList* aList,
   1.654 +                            nsStyleContext* aContext,
   1.655 +                            bool aIsBoxShadow,
   1.656 +                            bool& aCanStoreInRuleTree);
   1.657 +  bool SetStyleFilterToCSSValue(nsStyleFilter* aStyleFilter,
   1.658 +                                const nsCSSValue& aValue,
   1.659 +                                nsStyleContext* aStyleContext,
   1.660 +                                nsPresContext* aPresContext,
   1.661 +                                bool& aCanStoreInRuleTree);
   1.662 +
   1.663 +private:
   1.664 +  nsRuleNode(nsPresContext* aPresContext, nsRuleNode* aParent,
   1.665 +             nsIStyleRule* aRule, uint8_t aLevel, bool aIsImportant);
   1.666 +  ~nsRuleNode();
   1.667 +
   1.668 +public:
   1.669 +  static nsRuleNode* CreateRootNode(nsPresContext* aPresContext);
   1.670 +
   1.671 +  static void EnsureBlockDisplay(uint8_t& display,
   1.672 +                                 bool aConvertListItem = false);
   1.673 +
   1.674 +  // Transition never returns null; on out of memory it'll just return |this|.
   1.675 +  nsRuleNode* Transition(nsIStyleRule* aRule, uint8_t aLevel,
   1.676 +                         bool aIsImportantRule);
   1.677 +  nsRuleNode* GetParent() const { return mParent; }
   1.678 +  bool IsRoot() const { return mParent == nullptr; }
   1.679 +
   1.680 +  // These uint8_ts are really nsStyleSet::sheetType values.
   1.681 +  uint8_t GetLevel() const {
   1.682 +    NS_ASSERTION(!IsRoot(), "can't call on root");
   1.683 +    return (mDependentBits & NS_RULE_NODE_LEVEL_MASK) >>
   1.684 +             NS_RULE_NODE_LEVEL_SHIFT;
   1.685 +  }
   1.686 +  bool IsImportantRule() const {
   1.687 +    NS_ASSERTION(!IsRoot(), "can't call on root");
   1.688 +    return (mDependentBits & NS_RULE_NODE_IS_IMPORTANT) != 0;
   1.689 +  }
   1.690 +
   1.691 +  /**
   1.692 +   * Has this rule node at some time in its lifetime been the mRuleNode
   1.693 +   * of some style context (as opposed to only being the ancestor of
   1.694 +   * some style context's mRuleNode)?
   1.695 +   */
   1.696 +  void SetUsedDirectly();
   1.697 +  bool IsUsedDirectly() const {
   1.698 +    return (mDependentBits & NS_RULE_NODE_USED_DIRECTLY) != 0;
   1.699 +  }
   1.700 +
   1.701 +  // NOTE:  Does not |AddRef|.  Null only for the root.
   1.702 +  nsIStyleRule* GetRule() const { return mRule; }
   1.703 +  // NOTE: Does not |AddRef|.  Never null.
   1.704 +  nsPresContext* PresContext() const { return mPresContext; }
   1.705 +
   1.706 +  const void* GetStyleData(nsStyleStructID aSID,
   1.707 +                           nsStyleContext* aContext,
   1.708 +                           bool aComputeData);
   1.709 +
   1.710 +  #define STYLE_STRUCT(name_, checkdata_cb_)                                  \
   1.711 +    const nsStyle##name_* GetStyle##name_(nsStyleContext* aContext,           \
   1.712 +                                          bool aComputeData);
   1.713 +  #include "nsStyleStructList.h"
   1.714 +  #undef STYLE_STRUCT
   1.715 +
   1.716 +  /*
   1.717 +   * Garbage collection.  Mark walks up the tree, marking any unmarked
   1.718 +   * ancestors until it reaches a marked one.  Sweep recursively sweeps
   1.719 +   * the children, destroys any that are unmarked, and clears marks,
   1.720 +   * returning true if the node on which it was called was destroyed.
   1.721 +   */
   1.722 +  void Mark();
   1.723 +  bool Sweep();
   1.724 +
   1.725 +  static bool
   1.726 +    HasAuthorSpecifiedRules(nsStyleContext* aStyleContext,
   1.727 +                            uint32_t ruleTypeMask,
   1.728 +                            bool aAuthorColorsAllowed);
   1.729 +
   1.730 +  // Expose this so media queries can use it
   1.731 +  static nscoord CalcLengthWithInitialFont(nsPresContext* aPresContext,
   1.732 +                                           const nsCSSValue& aValue);
   1.733 +  // Expose this so nsTransformFunctions can use it.
   1.734 +  static nscoord CalcLength(const nsCSSValue& aValue,
   1.735 +                            nsStyleContext* aStyleContext,
   1.736 +                            nsPresContext* aPresContext,
   1.737 +                            bool& aCanStoreInRuleTree);
   1.738 +
   1.739 +  struct ComputedCalc {
   1.740 +    nscoord mLength;
   1.741 +    float mPercent;
   1.742 +
   1.743 +    ComputedCalc(nscoord aLength, float aPercent)
   1.744 +      : mLength(aLength), mPercent(aPercent) {}
   1.745 +  };
   1.746 +  static ComputedCalc
   1.747 +  SpecifiedCalcToComputedCalc(const nsCSSValue& aValue,
   1.748 +                              nsStyleContext* aStyleContext,
   1.749 +                              nsPresContext* aPresContext,
   1.750 +                              bool& aCanStoreInRuleTree);
   1.751 +
   1.752 +  // Compute the value of an nsStyleCoord that IsCalcUnit().
   1.753 +  // (Values that don't require aPercentageBasis should be handled
   1.754 +  // inside nsRuleNode rather than through this API.)
   1.755 +  static nscoord ComputeComputedCalc(const nsStyleCoord& aCoord,
   1.756 +                                     nscoord aPercentageBasis);
   1.757 +
   1.758 +  // Compute the value of an nsStyleCoord that is either a coord, a
   1.759 +  // percent, or a calc expression.
   1.760 +  static nscoord ComputeCoordPercentCalc(const nsStyleCoord& aCoord,
   1.761 +                                         nscoord aPercentageBasis);
   1.762 +
   1.763 +  // Return whether the rule tree for which this node is the root has
   1.764 +  // cached data such that we need to do dynamic change handling for
   1.765 +  // changes that change the results of media queries or require
   1.766 +  // rebuilding all style data.
   1.767 +  bool TreeHasCachedData() const {
   1.768 +    NS_ASSERTION(IsRoot(), "should only be called on root of rule tree");
   1.769 +    return HaveChildren() || mStyleData.mInheritedData || mStyleData.mResetData;
   1.770 +  }
   1.771 +
   1.772 +  bool NodeHasCachedData(const nsStyleStructID aSID) {
   1.773 +    return !!mStyleData.GetStyleData(aSID);
   1.774 +  }
   1.775 +
   1.776 +  static void ComputeFontFeatures(const nsCSSValuePairList *aFeaturesList,
   1.777 +                                  nsTArray<gfxFontFeature>& aFeatureSettings);
   1.778 +
   1.779 +  static nscoord CalcFontPointSize(int32_t aHTMLSize, int32_t aBasePointSize, 
   1.780 +                                   nsPresContext* aPresContext,
   1.781 +                                   nsFontSizeType aFontSizeType = eFontSize_HTML);
   1.782 +
   1.783 +  static nscoord FindNextSmallerFontSize(nscoord aFontSize, int32_t aBasePointSize, 
   1.784 +                                         nsPresContext* aPresContext,
   1.785 +                                         nsFontSizeType aFontSizeType = eFontSize_HTML);
   1.786 +
   1.787 +  static nscoord FindNextLargerFontSize(nscoord aFontSize, int32_t aBasePointSize, 
   1.788 +                                        nsPresContext* aPresContext,
   1.789 +                                        nsFontSizeType aFontSizeType = eFontSize_HTML);
   1.790 +
   1.791 +  /**
   1.792 +   * @param aValue The color value, returned from nsCSSParser::ParseColorString
   1.793 +   * @param aPresContext Presentation context whose preferences are used
   1.794 +   *                     for certain enumerated colors
   1.795 +   * @param aStyleContext Style context whose color is used for 'currentColor'
   1.796 +   *
   1.797 +   * @note aPresContext and aStyleContext may be null, but in that case, fully
   1.798 +   *       opaque black will be returned for the values that rely on these
   1.799 +   *       objects to compute the color. (For example, -moz-hyperlinktext.)
   1.800 +   *
   1.801 +   * @return false if we fail to extract a color; this will not happen if both
   1.802 +   *         aPresContext and aStyleContext are non-null
   1.803 +   */
   1.804 +  static bool ComputeColor(const nsCSSValue& aValue,
   1.805 +                           nsPresContext* aPresContext,
   1.806 +                           nsStyleContext* aStyleContext,
   1.807 +                           nscolor& aResult);
   1.808 +};
   1.809 +
   1.810 +#endif

mercurial