Bug 1309109 part 2 - Move immutable and container from css::Declaration to a new base class. r?heycam draft
authorXidorn Quan <me@upsuper.org>
Tue, 11 Oct 2016 19:32:40 +1100
changeset 426165 03c7ec24733666b5ad42b7c1b9a6b32e6dba8cac
parent 426164 c8dce2a87e6139f7e68b551ee66802de3dfde28f
child 426166 1d32b4281488945d2839c4b2009a83b1892491e9
push id32640
push userxquan@mozilla.com
push dateTue, 18 Oct 2016 00:25:47 +0000
reviewersheycam
bugs1309109
milestone52.0a1
Bug 1309109 part 2 - Move immutable and container from css::Declaration to a new base class. r?heycam MozReview-Commit-ID: 9gCrBrK70Z3
layout/style/Declaration.cpp
layout/style/Declaration.h
layout/style/DeclarationBlock.h
layout/style/moz.build
--- a/layout/style/Declaration.cpp
+++ b/layout/style/Declaration.cpp
@@ -53,37 +53,30 @@ ImportantStyleData::List(FILE* out, int3
     str.AppendLiteral("  ");
   }
 
   str.AppendLiteral("! important rule\n");
   fprintf_stderr(out, "%s", str.get());
 }
 #endif
 
-Declaration::Declaration()
-  : mImmutable(false)
-{
-  mContainer.mRaw = uintptr_t(0);
-}
-
 Declaration::Declaration(const Declaration& aCopy)
-  : mOrder(aCopy.mOrder),
+  : DeclarationBlock(aCopy),
+    mOrder(aCopy.mOrder),
     mVariableOrder(aCopy.mVariableOrder),
     mData(aCopy.mData ? aCopy.mData->Clone() : nullptr),
     mImportantData(aCopy.mImportantData ?
                      aCopy.mImportantData->Clone() : nullptr),
     mVariables(aCopy.mVariables ?
         new CSSVariableDeclarations(*aCopy.mVariables) :
         nullptr),
     mImportantVariables(aCopy.mImportantVariables ?
         new CSSVariableDeclarations(*aCopy.mImportantVariables) :
-        nullptr),
-    mImmutable(false)
+        nullptr)
 {
-  mContainer.mRaw = uintptr_t(0);
 }
 
 Declaration::~Declaration()
 {
 }
 
 NS_INTERFACE_MAP_BEGIN(Declaration)
   if (aIID.Equals(NS_GET_IID(mozilla::css::Declaration))) {
--- a/layout/style/Declaration.h
+++ b/layout/style/Declaration.h
@@ -13,16 +13,17 @@
 
 // This header is in EXPORTS because it's used in several places in content/,
 // but it's not really a public interface.
 #ifndef MOZILLA_INTERNAL_API
 #error "This file should only be included within libxul"
 #endif
 
 #include "mozilla/Attributes.h"
+#include "mozilla/DeclarationBlock.h"
 #include "mozilla/MemoryReporting.h"
 #include "CSSVariableDeclarations.h"
 #include "nsCSSDataBlock.h"
 #include "nsCSSPropertyID.h"
 #include "nsCSSProps.h"
 #include "nsIStyleRule.h"
 #include "nsStringFwd.h"
 #include "nsTArray.h"
@@ -77,24 +78,26 @@ private:
 // begins life in an invalid state which ends when InitializeEmpty or
 // CompressFrom is called upon it.  After that, it can be attached to
 // exactly one style rule, and will be destroyed when that style rule
 // is destroyed.  A declaration becomes immutable (via a SetImmutable
 // call) when it is matched (put in the rule tree); after that, it must
 // be copied before it can be modified, which is taken care of by
 // |EnsureMutable|.
 
-class Declaration final : public nsIStyleRule {
+class Declaration final : public DeclarationBlock
+                        , public nsIStyleRule
+{
 public:
   /**
    * Construct an |Declaration| that is in an invalid state (null
    * |mData|) and cannot be used until its |CompressFrom| method or
    * |InitializeEmpty| method is called.
    */
-  Declaration();
+  Declaration() : DeclarationBlock(StyleBackendType::Gecko) {}
 
   Declaration(const Declaration& aCopy);
 
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_CSS_DECLARATION_IMPL_CID)
 
   NS_DECL_ISUPPORTS
 
 private:
@@ -272,85 +275,34 @@ public:
   }
 
   bool HasNonImportantValueFor(nsCSSPropertyID aProperty) const {
     MOZ_ASSERT(!nsCSSProps::IsShorthand(aProperty), "must be longhand");
     return !!mData->ValueFor(aProperty);
   }
 
   /**
-   * Return whether |this| may be modified.
-   */
-  bool IsMutable() const {
-    return !mImmutable;
-  }
-
-  /**
    * Copy |this|, if necessary to ensure that it can be modified.
    */
   already_AddRefed<Declaration> EnsureMutable();
 
   /**
-   * Crash if |this| cannot be modified.
-   */
-  void AssertMutable() const {
-    MOZ_ASSERT(IsMutable(), "someone forgot to call EnsureMutable");
-  }
-
-  /**
-   * Mark this declaration as unmodifiable.  It's 'const' so it can
-   * be called from ToString.
-   */
-  void SetImmutable() const { mImmutable = true; }
-
-  /**
    * Clear the data, in preparation for its replacement with entirely
    * new data by a call to |CompressFrom|.
    */
   void ClearData() {
     AssertMutable();
     mData = nullptr;
     mImportantData = nullptr;
     mVariables = nullptr;
     mImportantVariables = nullptr;
     mOrder.Clear();
     mVariableOrder.Clear();
   }
 
-  void SetOwningRule(Rule* aRule) {
-    MOZ_ASSERT(!mContainer.mOwningRule || !aRule,
-               "should never overwrite one rule with another");
-    mContainer.mOwningRule = aRule;
-  }
-
-  Rule* GetOwningRule() const {
-    if (mContainer.mRaw & 0x1) {
-      return nullptr;
-    }
-    return mContainer.mOwningRule;
-  }
-
-  void SetHTMLCSSStyleSheet(nsHTMLCSSStyleSheet* aHTMLCSSStyleSheet) {
-    MOZ_ASSERT(!mContainer.mHTMLCSSStyleSheet || !aHTMLCSSStyleSheet,
-               "should never overwrite one sheet with another");
-    mContainer.mHTMLCSSStyleSheet = aHTMLCSSStyleSheet;
-    if (aHTMLCSSStyleSheet) {
-      mContainer.mRaw |= uintptr_t(1);
-    }
-  }
-
-  nsHTMLCSSStyleSheet* GetHTMLCSSStyleSheet() const {
-    if (!(mContainer.mRaw & 0x1)) {
-      return nullptr;
-    }
-    auto c = mContainer;
-    c.mRaw &= ~uintptr_t(1);
-    return c.mHTMLCSSStyleSheet;
-  }
-
   ImportantStyleData* GetImportantStyleData() {
     if (HasImportantData()) {
       return &mImportantStyleData;
     }
     return nullptr;
   }
 
 private:
@@ -433,39 +385,18 @@ private:
   nsAutoPtr<nsCSSCompressedDataBlock> mImportantData;
 
   // may be null
   nsAutoPtr<CSSVariableDeclarations> mVariables;
 
   // may be null
   nsAutoPtr<CSSVariableDeclarations> mImportantVariables;
 
-  union {
-    // We only ever have one of these since we have an
-    // nsHTMLCSSStyleSheet only for style attributes, and style
-    // attributes never have an owning rule.
-
-    // It's an nsHTMLCSSStyleSheet if the low bit is set.
-
-    uintptr_t mRaw;
-
-    // The style rule that owns this declaration.  May be null.
-    Rule* mOwningRule;
-
-    // The nsHTMLCSSStyleSheet that is responsible for this declaration.
-    // Only non-null for style attributes.
-    nsHTMLCSSStyleSheet* mHTMLCSSStyleSheet;
-  } mContainer;
-
   friend class ImportantStyleData;
   ImportantStyleData mImportantStyleData;
-
-  // set when declaration put in the rule tree;
-  // also by ToString (hence the 'mutable').
-  mutable bool mImmutable;
 };
 
 inline ::mozilla::css::Declaration*
 ImportantStyleData::Declaration()
 {
   union {
     char* ch; /* for pointer arithmetic */
     ::mozilla::css::Declaration* declaration;
new file mode 100644
--- /dev/null
+++ b/layout/style/DeclarationBlock.h
@@ -0,0 +1,113 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ * representation of a declaration block in a CSS stylesheet, or of
+ * a style attribute
+ */
+
+#ifndef mozilla_DeclarationBlock_h
+#define mozilla_DeclarationBlock_h
+
+#include "mozilla/StyleBackendType.h"
+
+class nsHTMLCSSStyleSheet;
+
+namespace mozilla {
+
+namespace css {
+class Rule;
+} // namespace css
+
+class DeclarationBlock
+{
+protected:
+  DeclarationBlock(StyleBackendType aType)
+    : mImmutable(false), mType(aType) { mContainer.mRaw = 0; }
+
+  DeclarationBlock(const DeclarationBlock& aCopy)
+    : DeclarationBlock(aCopy.mType) {}
+
+public:
+  /**
+   * Return whether |this| may be modified.
+   */
+  bool IsMutable() const {
+    return !mImmutable;
+  }
+
+  /**
+   * Crash if |this| cannot be modified.
+   */
+  void AssertMutable() const {
+    MOZ_ASSERT(IsMutable(), "someone forgot to call EnsureMutable");
+  }
+
+  /**
+   * Mark this declaration as unmodifiable.  It's 'const' so it can
+   * be called from ToString.
+   */
+  void SetImmutable() const { mImmutable = true; }
+
+  void SetOwningRule(css::Rule* aRule) {
+    MOZ_ASSERT(!mContainer.mOwningRule || !aRule,
+               "should never overwrite one rule with another");
+    mContainer.mOwningRule = aRule;
+  }
+
+  css::Rule* GetOwningRule() const {
+    if (mContainer.mRaw & 0x1) {
+      return nullptr;
+    }
+    return mContainer.mOwningRule;
+  }
+
+  void SetHTMLCSSStyleSheet(nsHTMLCSSStyleSheet* aHTMLCSSStyleSheet) {
+    MOZ_ASSERT(!mContainer.mHTMLCSSStyleSheet || !aHTMLCSSStyleSheet,
+               "should never overwrite one sheet with another");
+    mContainer.mHTMLCSSStyleSheet = aHTMLCSSStyleSheet;
+    if (aHTMLCSSStyleSheet) {
+      mContainer.mRaw |= uintptr_t(1);
+    }
+  }
+
+  nsHTMLCSSStyleSheet* GetHTMLCSSStyleSheet() const {
+    if (!(mContainer.mRaw & 0x1)) {
+      return nullptr;
+    }
+    auto c = mContainer;
+    c.mRaw &= ~uintptr_t(1);
+    return c.mHTMLCSSStyleSheet;
+  }
+
+private:
+  union {
+    // We only ever have one of these since we have an
+    // nsHTMLCSSStyleSheet only for style attributes, and style
+    // attributes never have an owning rule.
+
+    // It's an nsHTMLCSSStyleSheet if the low bit is set.
+
+    uintptr_t mRaw;
+
+    // The style rule that owns this declaration.  May be null.
+    css::Rule* mOwningRule;
+
+    // The nsHTMLCSSStyleSheet that is responsible for this declaration.
+    // Only non-null for style attributes.
+    nsHTMLCSSStyleSheet* mHTMLCSSStyleSheet;
+  } mContainer;
+
+  // set when declaration put in the rule tree;
+  // also by ToString (hence the 'mutable').
+  mutable bool mImmutable;
+
+  const StyleBackendType mType;
+};
+
+} // namespace mozilla
+
+#endif // mozilla_DeclarationBlock_h
--- a/layout/style/moz.build
+++ b/layout/style/moz.build
@@ -81,16 +81,17 @@ EXPORTS += [
 
 EXPORTS.mozilla += [
     'AnimationCollection.h',
     'CSSEnabledState.h',
     'CSSStyleSheet.h',
     'CSSVariableDeclarations.h',
     'CSSVariableResolver.h',
     'CSSVariableValues.h',
+    'DeclarationBlock.h',
     'HandleRefPtr.h',
     'IncrementalClearCOMRuleArray.h',
     'LayerAnimationInfo.h',
     'RuleNodeCacheConditions.h',
     'RuleProcessorCache.h',
     'ServoBindingHelpers.h',
     'ServoBindingList.h',
     'ServoBindings.h',