Bug 1343078 part 3. Introduce the concept of non-inheriting anon boxes without adding any yet. r?dbaron draft
authorBoris Zbarsky <bzbarsky@mit.edu>
Wed, 08 Mar 2017 00:18:39 -0500
changeset 494999 b47530d3044990a923652ee84bb815a42985f8b1
parent 494998 788a5843ff595035779b4af51a9a57a138b97d74
child 495000 4d48dd103b654045957d89ebebe652d22dd27829
push id48199
push userbzbarsky@mozilla.com
push dateWed, 08 Mar 2017 05:19:43 +0000
reviewersdbaron
bugs1343078
milestone55.0a1
Bug 1343078 part 3. Introduce the concept of non-inheriting anon boxes without adding any yet. r?dbaron MozReview-Commit-ID: 1NZ2xI4XCWH
layout/style/nsCSSAnonBoxList.h
layout/style/nsCSSAnonBoxes.cpp
layout/style/nsCSSAnonBoxes.h
--- a/layout/style/nsCSSAnonBoxList.h
+++ b/layout/style/nsCSSAnonBoxList.h
@@ -3,26 +3,39 @@
  * 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/. */
 
 /* atom list for CSS anonymous boxes */
 
 /*
  * This file contains the list of nsIAtoms and their values for CSS
  * pseudo-element-ish things used internally for anonymous boxes.  It is
- * designed to be used as inline input to nsCSSAnonBoxes.cpp *only*
- * through the magic of C preprocessing.  All entries must be enclosed
- * in the macro CSS_ANON_BOX which will have cruel and unusual things
- * done to it.  The entries should be kept in some sort of logical
- * order.  The first argument to CSS_ANON_BOX is the C++ identifier of
- * the atom.  The second argument is the string value of the atom.
+ * designed to be used as inline input to nsCSSAnonBoxes.cpp *only* through the
+ * magic of C preprocessing.  All entries must be enclosed in the macros
+ * CSS_ANON_BOX and CSS_NON_INHERITING_ANON_BOX which will have cruel and
+ * unusual things done to it.  The entries should be kept in some sort of
+ * logical order.  The first argument to
+ * CSS_ANON_BOX/CSS_NON_INHERITING_ANON_BOX is the C++ identifier of the atom.
+ * The second argument is the string value of the atom.
+ *
+ * CSS_NON_INHERITING_ANON_BOX is used for anon boxes that never inherit style
+ * from anything.  This means all their property values are the initial values
+ * of those properties.
  */
 
 // OUTPUT_CLASS=nsCSSAnonBoxes
-// MACRO_NAME=CSS_ANON_BOX
+// MACRO_NAME=CSS_ANON_BOX/CSS_NON_INHERITING_ANON_BOX
+
+#ifndef CSS_NON_INHERITING_ANON_BOX
+#  ifdef DEFINED_CSS_NON_INHERITING_ANON_BOX
+#    error "Recursive includes of nsCSSAnonBoxList.h?"
+#  endif /* DEFINED_CSS_NON_INHERITING_ANON_BOX */
+#  define CSS_NON_INHERITING_ANON_BOX CSS_ANON_BOX
+#  define DEFINED_CSS_NON_INHERITING_ANON_BOX
+#endif /* CSS_NON_INHERITING_ANON_BOX */
 
 // ::-moz-text, ::-moz-oof-placeholder, and ::-moz-first-letter-continuation are
 // non-elements which no rule will match.
 CSS_ANON_BOX(mozText, ":-moz-text")
 // placeholder frames for out of flows.  Note that :-moz-placeholder is used for
 // the pseudo-element that represents the placeholder text in <input
 // placeholder="foo">, so we need a different string here.
 CSS_ANON_BOX(oofPlaceholder, ":-moz-oof-placeholder")
@@ -97,8 +110,13 @@ CSS_ANON_BOX(moztreecheckbox, ":-moz-tre
 CSS_ANON_BOX(moztreeprogressmeter, ":-moz-tree-progressmeter")
 CSS_ANON_BOX(moztreedropfeedback, ":-moz-tree-drop-feedback")
 #endif
 
 CSS_ANON_BOX(mozSVGMarkerAnonChild, ":-moz-svg-marker-anon-child")
 CSS_ANON_BOX(mozSVGOuterSVGAnonChild, ":-moz-svg-outer-svg-anon-child")
 CSS_ANON_BOX(mozSVGForeignContent, ":-moz-svg-foreign-content")
 CSS_ANON_BOX(mozSVGText, ":-moz-svg-text")
+
+#ifdef DEFINED_CSS_NON_INHERITING_ANON_BOX
+#  undef DEFINED_CSS_NON_INHERITING_ANON_BOX
+#  undef CSS_NON_INHERITING_ANON_BOX
+#endif /* DEFINED_CSS_NON_INHERITING_ANON_BOX */
--- a/layout/style/nsCSSAnonBoxes.cpp
+++ b/layout/style/nsCSSAnonBoxes.cpp
@@ -20,19 +20,29 @@ using namespace mozilla;
 #undef CSS_ANON_BOX
 
 #define CSS_ANON_BOX(name_, value_) \
   NS_STATIC_ATOM_BUFFER(name_##_buffer, value_)
 #include "nsCSSAnonBoxList.h"
 #undef CSS_ANON_BOX
 
 static const nsStaticAtom CSSAnonBoxes_info[] = {
-#define CSS_ANON_BOX(name_, value_) \
+  // Put the non-inheriting anon boxes first, so we can index into them easily.
+#define CSS_ANON_BOX(name_, value_) /* nothing */
+#define CSS_NON_INHERITING_ANON_BOX(name_, value_) \
   NS_STATIC_ATOM(name_##_buffer, (nsIAtom**)&nsCSSAnonBoxes::name_),
 #include "nsCSSAnonBoxList.h"
+#undef CSS_NON_INHERITING_ANON_BOX
+#undef CSS_ANON_BOX
+
+#define CSS_ANON_BOX(name_, value_)                                   \
+  NS_STATIC_ATOM(name_##_buffer, (nsIAtom**)&nsCSSAnonBoxes::name_),
+#define CSS_NON_INHERITING_ANON_BOX(name_, value_) /* nothing */
+#include "nsCSSAnonBoxList.h"
+#undef CSS_NON_INHERITING_ANON_BOX
 #undef CSS_ANON_BOX
 };
 
 void nsCSSAnonBoxes::AddRefAtoms()
 {
   NS_RegisterStaticAtoms(CSSAnonBoxes_info);
 }
 
@@ -45,8 +55,15 @@ bool nsCSSAnonBoxes::IsAnonBox(nsIAtom *
 #ifdef MOZ_XUL
 /* static */ bool
 nsCSSAnonBoxes::IsTreePseudoElement(nsIAtom* aPseudo)
 {
   return StringBeginsWith(nsDependentAtomString(aPseudo),
                           NS_LITERAL_STRING(":-moz-tree-"));
 }
 #endif
+
+/* static */ nsIAtom*
+nsCSSAnonBoxes::GetNonInheritingPseudoAtom(NonInheriting aBoxType)
+{
+  MOZ_ASSERT(aBoxType < NonInheriting::_Count);
+  return *CSSAnonBoxes_info[static_cast<NonInheritingBase>(aBoxType)].mAtom;
+}
--- a/layout/style/nsCSSAnonBoxes.h
+++ b/layout/style/nsCSSAnonBoxes.h
@@ -27,11 +27,41 @@ public:
   {
     return aPseudo == mozText || aPseudo == oofPlaceholder ||
            aPseudo == firstLetterContinuation;
   }
 
 #define CSS_ANON_BOX(_name, _value) static nsICSSAnonBoxPseudo* _name;
 #include "nsCSSAnonBoxList.h"
 #undef CSS_ANON_BOX
+
+  typedef uint8_t NonInheritingBase;
+  enum class NonInheriting : NonInheritingBase {
+#define CSS_ANON_BOX(_name, _value) /* nothing */
+#define CSS_NON_INHERITING_ANON_BOX(_name, _value) _name,
+#include "nsCSSAnonBoxList.h"
+#undef CSS_NON_INHERITING_ANON_BOX
+#undef CSS_ANON_BOX
+    _Count
+  };
+
+  // Be careful using this: if we have a lot of non-inheriting anon box types it
+  // might not be very fast.  We may want to think of ways to handle that
+  // (e.g. by moving to an enum instead of an atom, like we did for
+  // pseudo-elements, or by adding a new value of the pseudo-element enum for
+  // non-inheriting anon boxes or something).
+  static bool IsNonInheritingAnonBox(nsIAtom* aPseudo)
+  {
+    return
+#define CSS_ANON_BOX(_name, _value) /* nothing */
+#define CSS_NON_INHERITING_ANON_BOX(_name, _value) _name == aPseudo ||
+#include "nsCSSAnonBoxList.h"
+#undef CSS_NON_INHERITING_ANON_BOX
+#undef CSS_ANON_BOX
+      0;
+  }
+
+  // Get the atom for a given non-inheriting anon box type.  aBoxType must be <
+  // NonInheriting::_Count.
+  static nsIAtom* GetNonInheritingPseudoAtom(NonInheriting aBoxType);
 };
 
 #endif /* nsCSSAnonBoxes_h___ */