diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index ac7dacf8ac61..c7e4173f02fe 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -60,6 +60,7 @@ #include "imgIRequest.h" #include "nsIImageLoadingContent.h" #include "nsCOMPtr.h" +#include "nsCSSProps.h" #include "nsListControlFrame.h" #include "ImageLayers.h" #include "mozilla/arm.h" @@ -92,6 +93,8 @@ using namespace mozilla::layers; using namespace mozilla::dom; using namespace mozilla::layout; +#define FLEXBOX_ENABLED_PREF_NAME "layout.css.flexbox.enabled" + #ifdef DEBUG // TODO: remove, see bug 598468. bool nsLayoutUtils::gPreventAssertInCompareTreePosition = false; @@ -107,6 +110,13 @@ typedef FrameMetrics::ViewID ViewID; static ViewID sScrollIdCounter = FrameMetrics::START_SCROLL_ID; +// These are indices into kDisplayKTable. They'll be initialized +// the first time that FlexboxEnabledPrefChangeCallback() is invoked. +static int32_t sIndexOfFlexInDisplayTable; +static int32_t sIndexOfInlineFlexInDisplayTable; +// This tracks whether those ^^ indices have been initialized +static bool sAreFlexKeywordIndicesInitialized = false; + typedef nsDataHashtable ContentMap; static ContentMap* sContentMap = nullptr; static ContentMap& GetContentMap() { @@ -117,6 +127,49 @@ static ContentMap& GetContentMap() { return *sContentMap; } +// When the pref "layout.css.flexbox.enabled" changes, this function is invoked +// to let us update kDisplayKTable, to selectively disable or restore the +// entries for "-moz-flex" and "-moz-inline-flex" in that table. +#ifdef MOZ_FLEXBOX +static int +FlexboxEnabledPrefChangeCallback(const char* aPrefName, void* aClosure) +{ + MOZ_ASSERT(strncmp(aPrefName, FLEXBOX_ENABLED_PREF_NAME, + NS_ARRAY_LENGTH(FLEXBOX_ENABLED_PREF_NAME)) == 0, + "We only registered this callback for a single pref, so it " + "should only be called for that pref"); + + bool isFlexboxEnabled = + Preferences::GetBool(FLEXBOX_ENABLED_PREF_NAME, false); + + if (!sAreFlexKeywordIndicesInitialized) { + // First run: find the position of "-moz-flex" and "-moz-inline-flex" in + // kDisplayKTable. + sIndexOfFlexInDisplayTable = + nsCSSProps::FindIndexOfKeyword(eCSSKeyword__moz_flex, + nsCSSProps::kDisplayKTable); + sIndexOfInlineFlexInDisplayTable = + nsCSSProps::FindIndexOfKeyword(eCSSKeyword__moz_inline_flex, + nsCSSProps::kDisplayKTable); + + sAreFlexKeywordIndicesInitialized = true; + } + + // OK -- now, stomp on or restore the "flex" entries in kDisplayKTable, + // depending on whether the flexbox pref is enabled vs. disabled. + if (sIndexOfFlexInDisplayTable >= 0) { + nsCSSProps::kDisplayKTable[sIndexOfFlexInDisplayTable] = + isFlexboxEnabled ? eCSSKeyword__moz_flex : eCSSKeyword_UNKNOWN; + } + if (sIndexOfInlineFlexInDisplayTable >= 0) { + nsCSSProps::kDisplayKTable[sIndexOfInlineFlexInDisplayTable] = + isFlexboxEnabled ? eCSSKeyword__moz_inline_flex : eCSSKeyword_UNKNOWN; + } + + return 0; +} +#endif // MOZ_FLEXBOX + bool nsLayoutUtils::HasAnimationsForCompositor(nsIContent* aContent, nsCSSProperty aProperty) @@ -4580,6 +4633,12 @@ nsLayoutUtils::Initialize() "font.size.inflation.lineThreshold"); Preferences::AddIntVarCache(&sFontSizeInflationMappingIntercept, "font.size.inflation.mappingIntercept"); + +#ifdef MOZ_FLEXBOX + Preferences::RegisterCallback(FlexboxEnabledPrefChangeCallback, + FLEXBOX_ENABLED_PREF_NAME); + FlexboxEnabledPrefChangeCallback(FLEXBOX_ENABLED_PREF_NAME, nullptr); +#endif // MOZ_FLEXBOX } /* static */ @@ -4590,6 +4649,11 @@ nsLayoutUtils::Shutdown() delete sContentMap; sContentMap = nullptr; } + +#ifdef MOZ_FLEXBOX + Preferences::UnregisterCallback(FlexboxEnabledPrefChangeCallback, + FLEXBOX_ENABLED_PREF_NAME); +#endif // MOZ_FLEXBOX } /* static */ diff --git a/layout/style/nsCSSProps.cpp b/layout/style/nsCSSProps.cpp index 94878f3601d9..2e73b42bcc75 100644 --- a/layout/style/nsCSSProps.cpp +++ b/layout/style/nsCSSProps.cpp @@ -920,7 +920,7 @@ const int32_t nsCSSProps::kDirectionKTable[] = { eCSSKeyword_UNKNOWN,-1 }; -const int32_t nsCSSProps::kDisplayKTable[] = { +int32_t nsCSSProps::kDisplayKTable[] = { eCSSKeyword_none, NS_STYLE_DISPLAY_NONE, eCSSKeyword_inline, NS_STYLE_DISPLAY_INLINE, eCSSKeyword_block, NS_STYLE_DISPLAY_BLOCK, @@ -952,6 +952,9 @@ const int32_t nsCSSProps::kDisplayKTable[] = { eCSSKeyword__moz_groupbox, NS_STYLE_DISPLAY_GROUPBOX, #endif #ifdef MOZ_FLEXBOX + // XXXdholbert NOTE: These currently need to be the last entries in the + // table, because the "is flexbox enabled" pref that disables these will + // disable all the entries after them, too. eCSSKeyword__moz_flex, NS_STYLE_DISPLAY_FLEX, eCSSKeyword__moz_inline_flex, NS_STYLE_DISPLAY_INLINE_FLEX, #endif // MOZ_FLEXBOX @@ -1639,17 +1642,28 @@ const int32_t nsCSSProps::kColumnFillKTable[] = { eCSSKeyword_UNKNOWN, -1 }; -bool -nsCSSProps::FindKeyword(nsCSSKeyword aKeyword, const int32_t aTable[], int32_t& aResult) +int32_t +nsCSSProps::FindIndexOfKeyword(nsCSSKeyword aKeyword, const int32_t aTable[]) { int32_t index = 0; while (eCSSKeyword_UNKNOWN != nsCSSKeyword(aTable[index])) { if (aKeyword == nsCSSKeyword(aTable[index])) { - aResult = aTable[index+1]; - return true; + return index; } index += 2; } + return -1; +} + +bool +nsCSSProps::FindKeyword(nsCSSKeyword aKeyword, const int32_t aTable[], + int32_t& aResult) +{ + int32_t index = FindIndexOfKeyword(aKeyword, aTable); + if (index >= 0) { + aResult = aTable[index + 1]; + return true; + } return false; } diff --git a/layout/style/nsCSSProps.h b/layout/style/nsCSSProps.h index c13687c20ae9..f1d6f80d8c0d 100644 --- a/layout/style/nsCSSProps.h +++ b/layout/style/nsCSSProps.h @@ -194,6 +194,11 @@ public: // Sets the aStr param to the name of the propertyID static bool GetColorName(int32_t aPropID, nsCString &aStr); + // Returns the index of |aKeyword| in |aTable|, if it exists there; + // otherwise, returns -1. + // NOTE: Generally, clients should call FindKeyword() instead of this method. + static int32_t FindIndexOfKeyword(nsCSSKeyword aKeyword, const int32_t aTable[]); + // Find |aKeyword| in |aTable|, if found set |aValue| to its corresponding value. // If not found, return false and do not set |aValue|. static bool FindKeyword(nsCSSKeyword aKeyword, const int32_t aTable[], int32_t& aValue); @@ -373,7 +378,8 @@ public: static const int32_t kContentKTable[]; static const int32_t kCursorKTable[]; static const int32_t kDirectionKTable[]; - static const int32_t kDisplayKTable[]; + // Not const because we modify its entries when CSS prefs change. + static int32_t kDisplayKTable[]; static const int32_t kElevationKTable[]; static const int32_t kEmptyCellsKTable[]; #ifdef MOZ_FLEXBOX