Bug 1365159 - Part 1: Record :-moz-browser-frame and :-moz-table-border-nonzero state on snapshots. r=emilio draft
authorCameron McCormack <cam@mcc.id.au>
Mon, 05 Jun 2017 14:19:30 +0800
changeset 589332 73a78fd0285989082e2a0f13a84b612dd3380c0e
parent 589301 2c6289f56812c30254acfdddabcfec1e149c0336
child 589333 9e90151d324268523b264705998f617e959c787b
push id62331
push userbmo:cam@mcc.id.au
push dateTue, 06 Jun 2017 02:29:43 +0000
reviewersemilio
bugs1365159
milestone55.0a1
Bug 1365159 - Part 1: Record :-moz-browser-frame and :-moz-table-border-nonzero state on snapshots. r=emilio MozReview-Commit-ID: BEglHnXhpYJ
layout/base/ServoRestyleManager.cpp
layout/style/ServoElementSnapshot.cpp
layout/style/ServoElementSnapshot.h
--- a/layout/base/ServoRestyleManager.cpp
+++ b/layout/base/ServoRestyleManager.cpp
@@ -746,31 +746,46 @@ ServoRestyleManager::ContentStateChanged
   snapshot.AddState(previousState);
 
   if (Element* parent = aElement->GetFlattenedTreeParentElementForStyle()) {
     parent->NoteDirtyDescendantsForServo();
   }
   PostRestyleEvent(aElement, restyleHint, changeHint);
 }
 
+static inline bool
+AttributeInfluencesOtherPseudoClassState(Element* aElement, nsIAtom* aAttribute)
+{
+  // We must record some state for :-moz-browser-frame and
+  // :-moz-table-border-nonzero.
+  return (aAttribute == nsGkAtoms::mozbrowser &&
+          aElement->IsAnyOfHTMLElements(nsGkAtoms::iframe, nsGkAtoms::frame)) ||
+         (aAttribute == nsGkAtoms::border &&
+          aElement->IsHTMLElement(nsGkAtoms::table));
+}
+
 void
 ServoRestyleManager::AttributeWillChange(Element* aElement,
                                          int32_t aNameSpaceID,
                                          nsIAtom* aAttribute, int32_t aModType,
                                          const nsAttrValue* aNewValue)
 {
   MOZ_ASSERT(!mInStyleRefresh);
 
   if (!aElement->HasServoData()) {
     return;
   }
 
   ServoElementSnapshot& snapshot = SnapshotFor(aElement);
   snapshot.AddAttrs(aElement);
 
+  if (AttributeInfluencesOtherPseudoClassState(aElement, aAttribute)) {
+    snapshot.AddOtherPseudoClassState(aElement);
+  }
+
   if (Element* parent = aElement->GetFlattenedTreeParentElementForStyle()) {
     parent->NoteDirtyDescendantsForServo();
   }
 }
 
 void
 ServoRestyleManager::AttributeChanged(Element* aElement, int32_t aNameSpaceID,
                                       nsIAtom* aAttribute, int32_t aModType,
--- a/layout/style/ServoElementSnapshot.cpp
+++ b/layout/style/ServoElementSnapshot.cpp
@@ -9,16 +9,18 @@
 #include "nsIContentInlines.h"
 #include "nsContentUtils.h"
 
 namespace mozilla {
 
 ServoElementSnapshot::ServoElementSnapshot(const Element* aElement)
   : mState(0)
   , mContains(Flags(0))
+  , mIsTableBorderNonzero(false)
+  , mIsMozBrowserFrame(false)
 {
   MOZ_COUNT_CTOR(ServoElementSnapshot);
   mIsHTMLElementInHTMLDocument =
     aElement->IsHTMLElement() && aElement->IsInHTMLDocument();
   mIsInChromeDocument =
     nsContentUtils::IsChromeDoc(aElement->OwnerDoc());
 }
 
@@ -48,9 +50,28 @@ ServoElementSnapshot::AddAttrs(Element* 
   if (aElement->HasID()) {
     mContains |= Flags::Id;
   }
   if (aElement->MayHaveClass()) {
     mContains |= Flags::MaybeClass;
   }
 }
 
+void
+ServoElementSnapshot::AddOtherPseudoClassState(Element* aElement)
+{
+  MOZ_ASSERT(aElement);
+
+  if (HasOtherPseudoClassState()) {
+    return;
+  }
+
+  mIsTableBorderNonzero =
+    *nsCSSPseudoClasses::MatchesElement(CSSPseudoClassType::mozTableBorderNonzero,
+                                        aElement);
+  mIsMozBrowserFrame =
+    *nsCSSPseudoClasses::MatchesElement(CSSPseudoClassType::mozBrowserFrame,
+                                        aElement);
+
+  mContains |= Flags::OtherPseudoClassState;
+}
+
 } // namespace mozilla
--- a/layout/style/ServoElementSnapshot.h
+++ b/layout/style/ServoElementSnapshot.h
@@ -43,16 +43,17 @@ struct ServoAttrSnapshot
  * contains.
  */
 enum class ServoElementSnapshotFlags : uint8_t
 {
   State = 1 << 0,
   Attributes = 1 << 1,
   Id = 1 << 2,
   MaybeClass = 1 << 3,
+  OtherPseudoClassState = 1 << 4,
 };
 
 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(ServoElementSnapshotFlags)
 
 /**
  * This class holds all non-tree-structural state of an element that might be
  * used for selector matching eventually.
  *
@@ -70,16 +71,21 @@ public:
 
   explicit ServoElementSnapshot(const Element* aElement);
   ~ServoElementSnapshot();
 
   bool HasAttrs() const { return HasAny(Flags::Attributes); }
 
   bool HasState() const { return HasAny(Flags::State); }
 
+  bool HasOtherPseudoClassState() const
+  {
+    return HasAny(Flags::OtherPseudoClassState);
+  }
+
   /**
    * Captures the given state (if not previously captured).
    */
   void AddState(EventStates aState)
   {
     if (!HasAny(Flags::State)) {
       mState = aState.ServoValue();
       mContains |= Flags::State;
@@ -87,16 +93,22 @@ public:
   }
 
   /**
    * Captures the given element attributes (if not previously captured).
    */
   void AddAttrs(Element* aElement);
 
   /**
+   * Captures some other pseudo-class matching state not included in
+   * EventStates.
+   */
+  void AddOtherPseudoClassState(Element* aElement);
+
+  /**
    * Needed methods for attribute matching.
    */
   BorrowedAttrInfo GetAttrInfoAt(uint32_t aIndex) const
   {
     MOZ_ASSERT(HasAttrs());
     if (aIndex >= mAttrs.Length()) {
       return BorrowedAttrInfo(nullptr, nullptr);
     }
@@ -135,23 +147,37 @@ public:
 
   bool IsInChromeDocument() const
   {
     return mIsInChromeDocument;
   }
 
   bool HasAny(Flags aFlags) const { return bool(mContains & aFlags); }
 
+  bool IsTableBorderNonzero() const
+  {
+    MOZ_ASSERT(HasOtherPseudoClassState());
+    return mIsTableBorderNonzero;
+  }
+
+  bool IsMozBrowserFrame() const
+  {
+    MOZ_ASSERT(HasOtherPseudoClassState());
+    return mIsMozBrowserFrame;
+  }
+
 private:
   // TODO: Profile, a 1 or 2 element AutoTArray could be worth it, given we know
   // we're dealing with attribute changes when we take snapshots of attributes,
   // though it can be wasted space if we deal with a lot of state-only
   // snapshots.
   nsTArray<ServoAttrSnapshot> mAttrs;
   ServoStateType mState;
   Flags mContains;
-  bool mIsHTMLElementInHTMLDocument;
-  bool mIsInChromeDocument;
+  bool mIsHTMLElementInHTMLDocument : 1;
+  bool mIsInChromeDocument : 1;
+  bool mIsTableBorderNonzero : 1;
+  bool mIsMozBrowserFrame : 1;
 };
 
 } // namespace mozilla
 
 #endif