Bug 1347411 part 5. Change stylo to correctly recompute style on the anonymous boxes that hang off comboboxes. r?heycam draft
authorBoris Zbarsky <bzbarsky@mit.edu>
Wed, 15 Mar 2017 11:48:29 -0400
changeset 499350 3488a0d4a37980d245bcb38683cb27eb6a42627d
parent 499349 56d6685a2c636a75926155945a7d99ceffb636db
child 499351 54ad84d037fb7c05db84d072fcf5292e80f95f1c
push id49371
push userbzbarsky@mozilla.com
push dateWed, 15 Mar 2017 16:46:41 +0000
reviewersheycam
bugs1347411
milestone55.0a1
Bug 1347411 part 5. Change stylo to correctly recompute style on the anonymous boxes that hang off comboboxes. r?heycam I did manual testing for ::-moz-dropdown-list. Unfortunately, the only way I know to test it is to have a combobox in a non-e10s window and dynamically change its background color, then drop down the dropdown and see whether it picked up the changed background color. MozReview-Commit-ID: B2RkW4otv4s
layout/base/nsCSSFrameConstructor.cpp
layout/forms/nsComboboxControlFrame.cpp
layout/forms/nsComboboxControlFrame.h
layout/reftests/forms/select/dynamic-text-indent-1-ref.html
layout/reftests/forms/select/dynamic-text-indent-1.html
layout/reftests/forms/select/dynamic-text-overflow-1-ref.html
layout/reftests/forms/select/dynamic-text-overflow-1.html
layout/reftests/forms/select/reftest-stylo.list
layout/reftests/forms/select/reftest.list
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -3107,16 +3107,18 @@ nsCSSFrameConstructor::ConstructSelectFr
     // since the complete tree is required before we restore.
     nsILayoutHistoryState *historyState = aState.mFrameState;
     aState.mFrameState = nullptr;
     // Initialize the combobox frame
     InitAndRestoreFrame(aState, content,
                         aState.GetGeometricParent(aStyleDisplay, aParentFrame),
                         comboboxFrame);
 
+    comboboxFrame->AddStateBits(NS_FRAME_OWNS_ANON_BOXES);
+
     aState.AddChild(comboboxFrame, aFrameItems, content, styleContext,
                     aParentFrame);
 
     // Resolve pseudo element style for the dropdown list
     RefPtr<nsStyleContext> listStyle;
     listStyle = mPresShell->StyleSet()->
       ResolveInheritingAnonymousBoxStyle(nsCSSAnonBoxes::dropDownList,
                                          styleContext);
--- a/layout/forms/nsComboboxControlFrame.cpp
+++ b/layout/forms/nsComboboxControlFrame.cpp
@@ -1181,16 +1181,28 @@ nsComboboxControlFrame::SetFormProperty(
   return fcFrame->SetFormProperty(aName, aValue);
 }
 
 nsContainerFrame*
 nsComboboxControlFrame::GetContentInsertionFrame() {
   return mInRedisplayText ? mDisplayFrame : mDropdownFrame->GetContentInsertionFrame();
 }
 
+void
+nsComboboxControlFrame::DoUpdateStyleOfOwnedAnonBoxes(
+  ServoStyleSet& aStyleSet,
+  nsStyleChangeList& aChangeList,
+  nsChangeHint aHintForThisFrame)
+{
+  UpdateStyleOfChildAnonBox(mDropdownFrame, aStyleSet, aChangeList,
+                            aHintForThisFrame);
+  UpdateStyleOfChildAnonBox(mDisplayFrame, aStyleSet, aChangeList,
+                            aHintForThisFrame);
+}
+
 nsresult
 nsComboboxControlFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
 {
   // The frames used to display the combo box and the button used to popup the dropdown list
   // are created through anonymous content. The dropdown list is not created through anonymous
   // content because its frame is initialized specifically for the drop-down case and it is placed
   // a special list referenced through NS_COMBO_FRAME_POPUP_LIST_INDEX to keep separate from the
   // layout of the display and button.
--- a/layout/forms/nsComboboxControlFrame.h
+++ b/layout/forms/nsComboboxControlFrame.h
@@ -118,16 +118,21 @@ public:
   virtual void DestroyFrom(nsIFrame* aDestructRoot) override;
   virtual void SetInitialChildList(ChildListID     aListID,
                                    nsFrameList&    aChildList) override;
   virtual const nsFrameList& GetChildList(ChildListID aListID) const override;
   virtual void GetChildLists(nsTArray<ChildList>* aLists) const override;
 
   virtual nsContainerFrame* GetContentInsertionFrame() override;
 
+  // Update the style on the block wrappers around our kids.
+  void DoUpdateStyleOfOwnedAnonBoxes(mozilla::ServoStyleSet& aStyleSet,
+                                     nsStyleChangeList& aChangeList,
+                                     nsChangeHint aHintForThisFrame) override;
+
   // nsIFormControlFrame
   virtual nsresult SetFormProperty(nsIAtom* aName, const nsAString& aValue) override;
   /**
    * Inform the control that it got (or lost) focus.
    * If it lost focus, the dropdown menu will be rolled up if needed,
    * and FireOnChange() will be called.
    * @param aOn true if got focus, false if lost focus.
    * @param aRepaint if true then force repaint (NOTE: we always force repaint currently)
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/select/dynamic-text-indent-1-ref.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<select style="text-indent: 15px">
+  <option selected>Text<option>
+</select>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/select/dynamic-text-indent-1.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+  <select>
+    <option selected>Text<option>
+  </select>
+  <script>
+    onload = function() {
+      var s = document.querySelector("select");
+      window.w = s.offsetWidth;
+      s.style.textIndent = "15px";
+      document.documentElement.className = "";
+    }
+  </script>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/select/dynamic-text-overflow-1-ref.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<select style="width: 100px; overflow: hidden; text-overflow: ellipsis;">
+  <option selected>Text that is long enough that it totally overflows<option>
+</select>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/select/dynamic-text-overflow-1.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+  <select style="width: 100px; overflow: hidden;">
+    <option selected>Text that is long enough that it totally overflows<option>
+  </select>
+  <script>
+    onload = function() {
+      var s = document.querySelector("select");
+      window.w = s.offsetWidth;
+      s.style.textOverflow = "ellipsis";
+      document.documentElement.className = "";
+    }
+  </script>
+</html>
--- a/layout/reftests/forms/select/reftest-stylo.list
+++ b/layout/reftests/forms/select/reftest-stylo.list
@@ -5,8 +5,10 @@ fails == boguskids.html boguskids.html
 fails == dynamic-boguskids.html dynamic-boguskids.html
 fails == option-children.html option-children.html
 fuzzy(1,4) == padding-button-placement.html padding-button-placement.html
 fails HTTP(../..) == vertical-centering.html vertical-centering.html # Bug 1290237
 fails == 997709-2.html 997709-2.html
 fails needs-focus == focusring-1.html focusring-1.html
 fails needs-focus == focusring-2.html focusring-2.html
 fails needs-focus == focusring-3.html focusring-3.html
+fails == dynamic-text-indent-1.html dynamic-text-indent-1.html
+fails == dynamic-text-overflow-1.html dynamic-text-overflow-1.html
--- a/layout/reftests/forms/select/reftest.list
+++ b/layout/reftests/forms/select/reftest.list
@@ -4,8 +4,10 @@ fuzzy-if(Android,4,11) == out-of-bounds-
 == dynamic-boguskids.html boguskids-ref.html
 == option-children.html option-children-ref.html
 fuzzy(1,4) == padding-button-placement.html padding-button-placement-ref.html
 HTTP(../..) == vertical-centering.html vertical-centering-ref.html
 == 997709-2.html 997709-2-ref.html
 needs-focus == focusring-1.html focusring-1-ref.html
 needs-focus == focusring-2.html focusring-2-ref.html
 needs-focus == focusring-3.html focusring-3-ref.html
+== dynamic-text-indent-1.html dynamic-text-indent-1-ref.html
+== dynamic-text-overflow-1.html dynamic-text-overflow-1-ref.html