Skip to content

Commit

Permalink
Backed out changeset 5d97c7b1b9b5 (bug 1762018) for causing mochitest…
Browse files Browse the repository at this point in the history
… failures in test_bug232227.html CLOSED TREE
  • Loading branch information
Cristian Tuns committed Mar 31, 2022
1 parent b9e7c76 commit da85cd4
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 124 deletions.
10 changes: 10 additions & 0 deletions dom/base/nsContentUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2319,6 +2319,16 @@ bool nsContentUtils::ShouldResistFingerprinting(
return !isExemptDomain;
}

/* static */
bool nsContentUtils::UseStandinsForNativeColors() {
return ShouldResistFingerprinting(
"we want to have consistent colors across the browser if RFP is "
"enabled, so we check the global preference"
"not excluding chrome browsers or webpages, so we call the legacy "
"RFP function to prevent that") ||
StaticPrefs::ui_use_standins_for_native_colors();
}

/* static */
void nsContentUtils::CalcRoundedWindowSizeForResistingFingerprinting(
int32_t aChromeWidth, int32_t aChromeHeight, int32_t aScreenWidth,
Expand Down
3 changes: 3 additions & 0 deletions dom/base/nsContentUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,9 @@ class nsContentUtils {
*/
static bool ShouldResistFingerprinting(const char* aJustification);

// Prevent system colors from being exposed to CSS or canvas.
static bool UseStandinsForNativeColors();

// A helper function to calculate the rounded window size for fingerprinting
// resistance. The rounded size is based on the chrome UI size and available
// screen size. If the inputWidth/Height is greater than the available content
Expand Down
78 changes: 19 additions & 59 deletions layout/style/PreferenceSheet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,26 +76,22 @@ auto PreferenceSheet::PrefsKindFor(const Document& aDoc) -> PrefsKind {
return PrefsKind::Content;
}

static bool UseDocumentColors(bool aUseAcccessibilityTheme) {
static bool UseAccessibilityTheme(bool aIsChrome) {
return !aIsChrome &&
!!LookAndFeel::GetInt(LookAndFeel::IntID::UseAccessibilityTheme, 0);
}

static bool UseDocumentColors(bool aIsChrome, bool aUseAcccessibilityTheme) {
switch (StaticPrefs::browser_display_document_color_use()) {
case 1:
return true;
case 2:
return false;
return aIsChrome;
default:
return !aUseAcccessibilityTheme;
}
}

static bool UseStandinsForNativeColors() {
return nsContentUtils::ShouldResistFingerprinting(
"we want to have consistent colors across the browser if RFP is "
"enabled, so we check the global preference"
"not excluding chrome browsers or webpages, so we call the legacy "
"RFP function to prevent that") ||
StaticPrefs::ui_use_standins_for_native_colors();
}

void PreferenceSheet::Prefs::LoadColors(bool aIsLight) {
auto& colors = aIsLight ? mLightColors : mDarkColors;

Expand All @@ -106,6 +102,13 @@ void PreferenceSheet::Prefs::LoadColors(bool aIsLight) {
std::swap(colors.mDefault, colors.mDefaultBackground);
}

const bool useStandins = nsContentUtils::UseStandinsForNativeColors();
// Users should be able to choose to use system colors or preferred colors
// when HCM is disabled, and in both OS-level HCM and FF-level HCM.
// To make this possible, we don't consider UseDocumentColors and
// mUseAccessibilityTheme when computing the following bool.
const bool usePrefColors = !useStandins && !mIsChrome &&
!StaticPrefs::browser_display_use_system_colors();
const auto scheme = aIsLight ? ColorScheme::Light : ColorScheme::Dark;

// Link colors might be provided by the OS, but they might not be. If they are
Expand All @@ -116,16 +119,13 @@ void PreferenceSheet::Prefs::LoadColors(bool aIsLight) {
GetColor("browser.active_color", scheme, colors.mActiveLink);
GetColor("browser.visited_color", scheme, colors.mVisitedLink);

// Historically we've given more weight to the "use standins" setting than the
// "use system colors" one. In practice most users don't use standins because
// it's hidden behind prefs.
if (mUsePrefColors && !mUseStandins) {
if (usePrefColors) {
GetColor("browser.display.background_color", scheme,
colors.mDefaultBackground);
GetColor("browser.display.foreground_color", scheme, colors.mDefault);
} else {
using ColorID = LookAndFeel::ColorID;
const auto standins = LookAndFeel::UseStandins(mUseStandins);
const auto standins = LookAndFeel::UseStandins(useStandins);
colors.mDefault = LookAndFeel::Color(ColorID::Windowtext, scheme, standins,
colors.mDefault);
colors.mDefaultBackground = LookAndFeel::Color(
Expand Down Expand Up @@ -181,49 +181,11 @@ void PreferenceSheet::Prefs::Load(bool aIsChrome) {
*this = {};

mIsChrome = aIsChrome;

// Chrome documents always use system colors, not stand-ins, not forced, etc.
if (!aIsChrome) {
mUseAccessibilityTheme =
LookAndFeel::GetInt(LookAndFeel::IntID::UseAccessibilityTheme);
mUseDocumentColors = UseDocumentColors(mUseAccessibilityTheme);
mUsePrefColors = !StaticPrefs::browser_display_use_system_colors();
mUseStandins = UseStandinsForNativeColors();
}
mUseAccessibilityTheme = UseAccessibilityTheme(aIsChrome);

LoadColors(true);
LoadColors(false);

mColorSchemeChoice = [&] {
// When not forcing colors, we use the standard mechanism, the document is
// in control taking into account user preferences if it wishes to.
if (mUseDocumentColors) {
return ColorSchemeChoice::Standard;
}
#ifdef XP_WIN
// Windows overrides the light colors with the HCM colors when HCM is
// active, so make sure to always use the light system colors in that case.
// For the same reason, we need to force the light color set to be used.
if (mUseAccessibilityTheme) {
mMustUseLightColorSet = true;
return ColorSchemeChoice::Light;
}
#endif
// When forcing preference colors, we derive a color-scheme from those. That
// way we can use the system colors more appropriately suited for the user,
// avoiding contrast issues like bug 1762018.
if (mUsePrefColors) {
// We need to forcibly use the light color-set for this case too, as those
// are the colors exposed to the user in the preferences page.
mMustUseLightColorSet = true;
return LookAndFeel::IsDarkColor(mLightColors.mDefaultBackground)
? ColorSchemeChoice::Dark
: ColorSchemeChoice::Light;
}
// When using system colors, we can generally just use the preferred color
// scheme of the document unconditionally (modulo the HCM case above).
return ColorSchemeChoice::UserPreferred;
}();
mUseDocumentColors = UseDocumentColors(aIsChrome, mUseAccessibilityTheme);
}

void PreferenceSheet::Initialize() {
Expand All @@ -243,10 +205,8 @@ void PreferenceSheet::Initialize() {
// despite having made it into mLightColors), because it both wastes ink and
// it might interact poorly with the color adjustments we do while printing.
//
// So we override the light colors with our hardcoded default colors, and
// force the use of stand-ins.
// So we override the light colors with our hardcoded default colors.
sPrintPrefs.mLightColors = Prefs().mLightColors;
sPrintPrefs.mUseStandins = true;
}

nsAutoString useDocumentColorPref;
Expand Down
24 changes: 2 additions & 22 deletions layout/style/PreferenceSheet.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,33 +33,13 @@ struct PreferenceSheet {
} mLightColors, mDarkColors;

const Colors& ColorsFor(ColorScheme aScheme) const {
return mMustUseLightColorSet || aScheme == ColorScheme::Light
? mLightColors
: mDarkColors;
return aScheme == ColorScheme::Light ? mLightColors : mDarkColors;
}

bool mIsChrome = false;
bool mUseAccessibilityTheme = false;

bool mUseDocumentColors = true;
bool mUsePrefColors = false;
bool mUseStandins = false;
bool mMustUseLightColorSet = false;

// Sometimes we can force a color scheme on a document, or honor the
// preferred color-scheme in more cases, depending on whether we're forcing
// colors or not.
enum class ColorSchemeChoice : uint8_t {
// We're not forcing colors, use standard algorithm based on specified
// style and meta tags and so on.
Standard,
// We can honor whatever the preferred color-scheme for the document is
// (the preferred color-scheme of the user, since we're forcing colors).
UserPreferred,
Light,
Dark,
};

ColorSchemeChoice mColorSchemeChoice = ColorSchemeChoice::Standard;

// Whether the non-native theme should use real system colors for widgets.
bool NonNativeThemeShouldBeHighContrast() const;
Expand Down
2 changes: 0 additions & 2 deletions widget/LookAndFeel.h
Original file line number Diff line number Diff line change
Expand Up @@ -397,8 +397,6 @@ class LookAndFeel {
: ColorScheme::Light;
}

static bool IsDarkColor(nscolor);

enum class ChromeColorSchemeSetting { Light, Dark, System };
static ChromeColorSchemeSetting ColorSchemeSettingForChrome();
static ColorScheme ThemeDerivedColorSchemeForContent();
Expand Down
25 changes: 24 additions & 1 deletion widget/nsNativeTheme.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "mozilla/PresShell.h"
#include "mozilla/StaticPrefs_layout.h"
#include "mozilla/dom/DocumentInlines.h"
#include "mozilla/RelativeLuminanceUtils.h"
#include <algorithm>

using namespace mozilla;
Expand Down Expand Up @@ -555,6 +556,28 @@ static nsIFrame* GetBodyFrame(nsIFrame* aCanvasFrame) {
return body->GetPrimaryFrame();
}

bool nsNativeTheme::IsDarkColor(nscolor aColor) {
// Given https://www.w3.org/TR/WCAG20/#contrast-ratiodef, this is the
// threshold that tells us whether contrast is better against white or black.
//
// Contrast ratio against black is: (L + 0.05) / 0.05
// Contrast ratio against white is: 1.05 / (L + 0.05)
//
// So the intersection is:
//
// (L + 0.05) / 0.05 = 1.05 / (L + 0.05)
//
// And the solution to that equation is:
//
// sqrt(1.05 * 0.05) - 0.05
//
// So we consider a color dark if the contrast is below this threshold, and
// it's at least half-opaque.
constexpr float kThreshold = 0.179129;
return NS_GET_A(aColor) > 127 &&
RelativeLuminanceUtils::Compute(aColor) < kThreshold;
}

/* static */
bool nsNativeTheme::IsDarkBackground(nsIFrame* aFrame) {
// Try to find the scrolled frame. Note that for stuff like xul <tree> there
Expand Down Expand Up @@ -596,7 +619,7 @@ bool nsNativeTheme::IsDarkBackground(nsIFrame* aFrame) {
}
}

return LookAndFeel::IsDarkColor(color);
return IsDarkColor(color);
}

/*static*/
Expand Down
1 change: 1 addition & 0 deletions widget/nsNativeTheme.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ class nsNativeTheme : public nsITimerCallback, public nsINamed {
bool IsRangeHorizontal(nsIFrame* aFrame);

static bool IsDarkBackground(nsIFrame*);
static bool IsDarkColor(nscolor aColor);

static bool IsWidgetScrollbarPart(mozilla::StyleAppearance);

Expand Down
69 changes: 29 additions & 40 deletions widget/nsXPLookAndFeel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
#include "mozilla/PreferenceSheet.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/widget/WidgetMessageUtils.h"
#include "mozilla/RelativeLuminanceUtils.h"
#include "mozilla/Telemetry.h"
#include "mozilla/TelemetryScalarEnums.h"

Expand Down Expand Up @@ -1105,8 +1104,7 @@ void LookAndFeel::DoHandleGlobalThemeChange() {
}

static bool ShouldUseStandinsForNativeColorForNonNativeTheme(
const dom::Document& aDoc, LookAndFeel::ColorID aColor,
const PreferenceSheet::Prefs& aPrefs) {
const dom::Document& aDoc, LookAndFeel::ColorID aColor) {
using ColorID = LookAndFeel::ColorID;
if (!aDoc.ShouldAvoidNativeTheme()) {
return false;
Expand Down Expand Up @@ -1136,7 +1134,9 @@ static bool ShouldUseStandinsForNativeColorForNonNativeTheme(
case ColorID::Fieldtext:

case ColorID::Graytext:
return !aPrefs.NonNativeThemeShouldBeHighContrast();

return !PreferenceSheet::PrefsFor(aDoc)
.NonNativeThemeShouldBeHighContrast();

default:
break;
Expand All @@ -1150,28 +1150,6 @@ ColorScheme LookAndFeel::sContentColorScheme;
bool LookAndFeel::sColorSchemeInitialized;
bool LookAndFeel::sGlobalThemeChanged;

bool LookAndFeel::IsDarkColor(nscolor aColor) {
// Given https://www.w3.org/TR/WCAG20/#contrast-ratiodef, this is the
// threshold that tells us whether contrast is better against white or black.
//
// Contrast ratio against black is: (L + 0.05) / 0.05
// Contrast ratio against white is: 1.05 / (L + 0.05)
//
// So the intersection is:
//
// (L + 0.05) / 0.05 = 1.05 / (L + 0.05)
//
// And the solution to that equation is:
//
// sqrt(1.05 * 0.05) - 0.05
//
// So we consider a color dark if the contrast is below this threshold, and
// it's at least half-opaque.
constexpr float kThreshold = 0.179129;
return NS_GET_A(aColor) > 127 &&
RelativeLuminanceUtils::Compute(aColor) < kThreshold;
}

auto LookAndFeel::ColorSchemeSettingForChrome() -> ChromeColorSchemeSetting {
switch (StaticPrefs::browser_theme_toolbar_theme()) {
case 0: // Dark
Expand Down Expand Up @@ -1225,18 +1203,25 @@ void LookAndFeel::RecomputeColorSchemes() {

ColorScheme LookAndFeel::ColorSchemeForStyle(
const dom::Document& aDoc, const StyleColorSchemeFlags& aFlags) {
using Choice = PreferenceSheet::Prefs::ColorSchemeChoice;

const auto& prefs = PreferenceSheet::PrefsFor(aDoc);
switch (prefs.mColorSchemeChoice) {
case Choice::Standard:
break;
case Choice::UserPreferred:
return aDoc.PreferredColorScheme();
case Choice::Light:
if (PreferenceSheet::MayForceColors()) {
auto& prefs = PreferenceSheet::PrefsFor(aDoc);
if (!prefs.mUseDocumentColors) {
// When forcing colors, we can use our preferred color-scheme. Do this
// only if we're using system colors, as dark preference colors are not
// exposed on the UI.
//
// Also, use light if we're using a high-contrast-theme on Windows, since
// Windows overrides the light colors with HCM colors when HCM is active.
#ifdef XP_WIN
if (prefs.mUseAccessibilityTheme) {
return ColorScheme::Light;
}
#endif
if (StaticPrefs::browser_display_use_system_colors()) {
return aDoc.PreferredColorScheme();
}
return ColorScheme::Light;
case Choice::Dark:
return ColorScheme::Dark;
}
}

StyleColorSchemeFlags style(aFlags);
Expand Down Expand Up @@ -1320,11 +1305,15 @@ static bool ColorIsCSSAccessible(LookAndFeel::ColorID aId) {

LookAndFeel::UseStandins LookAndFeel::ShouldUseStandins(
const dom::Document& aDoc, ColorID aId) {
const auto& prefs = PreferenceSheet::PrefsFor(aDoc);
if (ShouldUseStandinsForNativeColorForNonNativeTheme(aDoc, aId, prefs)) {
if (ShouldUseStandinsForNativeColorForNonNativeTheme(aDoc, aId)) {
return UseStandins::Yes;
}
if (nsContentUtils::UseStandinsForNativeColors() &&
ColorIsCSSAccessible(aId) && !nsContentUtils::IsChromeDoc(&aDoc)) {
return UseStandins::Yes;
}
if (prefs.mUseStandins && ColorIsCSSAccessible(aId)) {
if (aDoc.IsStaticDocument() &&
!PreferenceSheet::ContentPrefs().mUseDocumentColors) {
return UseStandins::Yes;
}
return UseStandins::No;
Expand Down

0 comments on commit da85cd4

Please sign in to comment.