Bug 1428297 - (Part 1) Add an nsLayoutUtils function to check whether content-select is enabled draft
authorKuoE0 <kuoe0.tw@gmail.com>
Thu, 11 Jan 2018 10:37:41 +0800
changeset 718893 e409cd861e26270f5688bce5af24910c0ddc39d1
parent 718845 4db166f0442dddc5b9011c722d7499501fedf283
child 718894 091f78895f4945a77d6746e99b5a171fe1721e9d
push id95083
push userbmo:kuoe0@mozilla.com
push dateThu, 11 Jan 2018 03:14:32 +0000
bugs1428297
milestone59.0a1
Bug 1428297 - (Part 1) Add an nsLayoutUtils function to check whether content-select is enabled MozReview-Commit-ID: KVQ25Dhl9xl
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsLayoutUtils.cpp
layout/base/nsLayoutUtils.h
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -102,17 +102,16 @@
 #include "nsPageFrame.h"
 #include "nsSimplePageSequenceFrame.h"
 #include "nsTableWrapperFrame.h"
 #include "nsIScrollableFrame.h"
 #include "nsBackdropFrame.h"
 #include "nsTransitionManager.h"
 #include "DetailsFrame.h"
 #include "nsThemeConstants.h"
-#include "mozilla/Preferences.h"
 
 #ifdef MOZ_XUL
 #include "nsIRootBox.h"
 #endif
 #ifdef ACCESSIBILITY
 #include "nsAccessibilityService.h"
 #endif
 
@@ -130,17 +129,16 @@
 #include "ActiveLayerTracker.h"
 #include "nsIPresShellInlines.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 // An alias for convenience.
 static const nsIFrame::ChildListID kPrincipalList = nsIFrame::kPrincipalList;
-static const char* kPrefSelectPopupInContent = "dom.select_popup_in_content.enabled";
 
 nsIFrame*
 NS_NewHTMLCanvasFrame (nsIPresShell* aPresShell, nsStyleContext* aContext);
 
 nsIFrame*
 NS_NewHTMLVideoFrame (nsIPresShell* aPresShell, nsStyleContext* aContext);
 
 nsContainerFrame*
@@ -3231,17 +3229,17 @@ nsCSSFrameConstructor::ConstructSelectFr
     // Notify the listbox that it is being used as a dropdown list.
     nsIListControlFrame * listControlFrame = do_QueryFrame(listFrame);
     if (listControlFrame) {
       listControlFrame->SetComboboxFrame(comboboxFrame);
     }
     // Notify combobox that it should use the listbox as it's popup
     comboboxFrame->SetDropDown(listFrame);
 
-    if (!Preferences::GetBool(kPrefSelectPopupInContent)) {
+    if (!nsLayoutUtils::IsContentSelectEnabled()) {
       // TODO(kuoe0) Remove this assertion when content-select is shipped.
       NS_ASSERTION(!listFrame->IsAbsPosContainingBlock(),
                    "Ended up with positioned dropdown list somehow.");
     }
     NS_ASSERTION(!listFrame->IsFloating(),
                  "Ended up with floating dropdown list somehow.");
 
     // child frames of combobox frame
@@ -3283,17 +3281,17 @@ nsCSSFrameConstructor::ConstructSelectFr
     AddFCItemsForAnonymousContent(aState, comboboxFrame, newAnonymousItems,
                                   fcItems);
     ConstructFramesFromItemList(aState, fcItems, comboboxFrame,
                                 /* aParentIsWrapperAnonBox = */ false,
                                 childItems);
 
     comboboxFrame->SetInitialChildList(kPrincipalList, childItems);
 
-    if (!Preferences::GetBool(kPrefSelectPopupInContent)) {
+    if (!nsLayoutUtils::IsContentSelectEnabled()) {
       // Initialize the additional popup child list which contains the
       // dropdown list frame.
       nsFrameItems popupItems;
       popupItems.AddChild(listFrame);
       comboboxFrame->SetInitialChildList(nsIFrame::kSelectPopupList,
                                          popupItems);
     }
 
@@ -3342,17 +3340,17 @@ nsCSSFrameConstructor::InitializeSelectF
     aState.GetGeometricParent(aStyleContext->StyleDisplay(), aParentFrame);
 
   // We don't call InitAndRestoreFrame for scrollFrame because we can only
   // restore the frame state after its parts have been created (in particular,
   // the scrollable view). So we have to split Init and Restore.
 
   scrollFrame->Init(aContent, geometricParent, nullptr);
 
-  if (!aBuildCombobox || Preferences::GetBool(kPrefSelectPopupInContent)) {
+  if (!aBuildCombobox || nsLayoutUtils::IsContentSelectEnabled()) {
     aState.AddChild(scrollFrame, aFrameItems, aContent, aParentFrame);
   }
 
   BuildScrollFrame(aState, aContent, aStyleContext, scrolledFrame,
                    geometricParent, scrollFrame);
 
   if (aState.mFrameState) {
     // Restore frame state for the scroll frame
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -159,16 +159,17 @@ using namespace mozilla::image;
 using namespace mozilla::layers;
 using namespace mozilla::layout;
 using namespace mozilla::gfx;
 
 #define WEBKIT_PREFIXES_ENABLED_PREF_NAME "layout.css.prefixes.webkit"
 #define TEXT_ALIGN_UNSAFE_ENABLED_PREF_NAME "layout.css.text-align-unsafe-value.enabled"
 #define FLOAT_LOGICAL_VALUES_ENABLED_PREF_NAME "layout.css.float-logical-values.enabled"
 #define INTERCHARACTER_RUBY_ENABLED_PREF_NAME "layout.css.ruby.intercharacter.enabled"
+#define CONTENT_SELECT_ENABLED_PREF_NAME "dom.select_popup_in_content.enabled"
 
 // The time in number of frames that we estimate for a refresh driver
 // to be quiescent
 #define DEFAULT_QUIESCENT_FRAMES 2
 // The time (milliseconds) we estimate is needed between the end of an
 // idle time and the next Tick.
 #define DEFAULT_IDLE_PERIOD_TIME_LIMIT 1.0f
 
@@ -735,16 +736,32 @@ nsLayoutUtils::IsInterCharacterRubyEnabl
     Preferences::AddBoolVarCache(&sInterCharacterRubyEnabled,
                                  INTERCHARACTER_RUBY_ENABLED_PREF_NAME,
                                  false);
   }
 
   return sInterCharacterRubyEnabled;
 }
 
+bool
+nsLayoutUtils::IsContentSelectEnabled()
+{
+  static bool sContentSelectEnabled;
+  static bool sContentSelectEnabledPrefCached = false;
+
+  if (!sContentSelectEnabledPrefCached) {
+    sContentSelectEnabledPrefCached = true;
+    Preferences::AddBoolVarCache(&sContentSelectEnabled,
+                                 CONTENT_SELECT_ENABLED_PREF_NAME,
+                                 false);
+  }
+
+  return sContentSelectEnabled;
+}
+
 void
 nsLayoutUtils::UnionChildOverflow(nsIFrame* aFrame,
                                   nsOverflowAreas& aOverflowAreas,
                                   FrameChildListIDs aSkipChildLists)
 {
   // Iterate over all children except pop-ups.
   FrameChildListIDs skip = aSkipChildLists |
       nsIFrame::kSelectPopupList | nsIFrame::kPopupList;
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -2386,16 +2386,21 @@ public:
    */
   static bool IsTextAlignUnsafeValueEnabled();
 
   /**
    * Checks whether support for inter-character ruby is enabled.
    */
   static bool IsInterCharacterRubyEnabled();
 
+  /**
+   * Checks whether content-select is enabled.
+   */
+  static bool IsContentSelectEnabled();
+
   static bool InterruptibleReflowEnabled()
   {
     return sInterruptibleReflowEnabled;
   }
 
   /**
    * Unions the overflow areas of the children of aFrame with aOverflowAreas.
    * aSkipChildLists specifies any child lists that should be skipped.