Bug 1365159 - Part 1: Record :-moz-browser-frame and :-moz-table-border-nonzero state on snapshots. r=emilio
authorCameron McCormack <cam@mcc.id.au>
Mon, 05 Jun 2017 14:19:30 +0800
changeset 410595 ce1f1e2027ef040d0ae0f7540392d453f6515f95
parent 410594 71fbf74857a39bdf2565ce466b5d254bd8199c8e
child 410596 5c9f9457ae2ad0c8d417efbb4f8c53157920a3ed
push id7391
push usermtabara@mozilla.com
push dateMon, 12 Jun 2017 13:08:53 +0000
treeherdermozilla-beta@2191d7f87e2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio
bugs1365159
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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