feat: support more color formats for backgroundColor (#31868)

This commit is contained in:
Shelley Vohr 2022-03-21 18:35:54 +01:00 committed by GitHub
parent 4b8b492b62
commit db79734bfb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 144 additions and 55 deletions

View file

@ -643,11 +643,11 @@ bool BaseWindow::IsTabletMode() const {
}
void BaseWindow::SetBackgroundColor(const std::string& color_name) {
SkColor color = ParseHexColor(color_name);
SkColor color = ParseCSSColor(color_name);
window_->SetBackgroundColor(color);
}
std::string BaseWindow::GetBackgroundColor() {
std::string BaseWindow::GetBackgroundColor(gin_helper::Arguments* args) {
return ToRGBHex(window_->GetBackgroundColor());
}

View file

@ -159,7 +159,7 @@ class BaseWindow : public gin_helper::TrackableObject<BaseWindow>,
bool IsKiosk();
bool IsTabletMode() const;
virtual void SetBackgroundColor(const std::string& color_name);
std::string GetBackgroundColor();
std::string GetBackgroundColor(gin_helper::Arguments* args);
void SetHasShadow(bool has_shadow);
bool HasShadow();
void SetOpacity(const double opacity);

View file

@ -154,11 +154,11 @@ gfx::Rect BrowserView::GetBounds() {
}
void BrowserView::SetBackgroundColor(const std::string& color_name) {
view_->SetBackgroundColor(ParseHexColor(color_name));
view_->SetBackgroundColor(ParseCSSColor(color_name));
if (web_contents()) {
auto* wc = web_contents()->web_contents();
wc->SetPageBaseBackgroundColor(ParseHexColor(color_name));
wc->SetPageBaseBackgroundColor(ParseCSSColor(color_name));
}
}

View file

@ -370,7 +370,7 @@ void BrowserWindow::Blur() {
void BrowserWindow::SetBackgroundColor(const std::string& color_name) {
BaseWindow::SetBackgroundColor(color_name);
SkColor color = ParseHexColor(color_name);
SkColor color = ParseCSSColor(color_name);
web_contents()->SetPageBaseBackgroundColor(color);
auto* rwhv = web_contents()->GetRenderWidgetHostView();
if (rwhv) {
@ -384,7 +384,7 @@ void BrowserWindow::SetBackgroundColor(const std::string& color_name) {
auto* web_preferences =
WebContentsPreferences::From(api_web_contents_->web_contents());
if (web_preferences) {
web_preferences->SetBackgroundColor(ParseHexColor(color_name));
web_preferences->SetBackgroundColor(ParseCSSColor(color_name));
}
}
}

View file

@ -773,7 +773,7 @@ WebContents::WebContents(v8::Isolate* isolate,
// and we then need to pull it back out and check it here.
std::string background_color;
options.GetHidden(options::kBackgroundColor, &background_color);
bool transparent = ParseHexColor(background_color) == SK_ColorTRANSPARENT;
bool transparent = ParseCSSColor(background_color) == SK_ColorTRANSPARENT;
content::WebContents::CreateParams params(session->browser_context());
auto* view = new OffScreenWebContentsView(

View file

@ -241,7 +241,7 @@ void NativeWindow::InitFromOptions(const gin_helper::Dictionary& options) {
#endif
std::string color;
if (options.Get(options::kBackgroundColor, &color)) {
SetBackgroundColor(ParseHexColor(color));
SetBackgroundColor(ParseCSSColor(color));
} else if (!transparent()) {
// For normal window, use white as default background.
SetBackgroundColor(SK_ColorWHITE);

View file

@ -339,7 +339,7 @@ static NSString* const ImageScrubberItemIdentifier = @"scrubber.image.item";
}
- (NSColor*)colorFromHexColorString:(const std::string&)colorString {
SkColor color = electron::ParseHexColor(colorString);
SkColor color = electron::ParseCSSColor(colorString);
return skia::SkColorToDeviceNSColor(color);
}

View file

@ -235,7 +235,7 @@ void WebContentsPreferences::Merge(
}
std::string background_color;
if (web_preferences.GetHidden(options::kBackgroundColor, &background_color))
background_color_ = ParseHexColor(background_color);
background_color_ = ParseCSSColor(background_color);
std::string safe_dialogs_message;
if (web_preferences.Get("safeDialogsMessage", &safe_dialogs_message))
safe_dialogs_message_ = safe_dialogs_message;

View file

@ -4,46 +4,54 @@
#include "shell/common/color_util.h"
#include <cmath>
#include <utility>
#include <vector>
#include "base/strings/string_number_conversions.h"
#include "base/cxx17_backports.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "content/public/common/color_parser.h"
#include "ui/gfx/color_utils.h"
namespace {
bool IsHexFormat(const std::string& str) {
// Must be either #ARGB or #AARRGGBB.
bool is_hex_length = str.length() == 5 || str.length() == 9;
if (str[0] != '#' || !is_hex_length)
return false;
if (!std::all_of(str.begin() + 1, str.end(), ::isxdigit))
return false;
return true;
}
} // namespace
namespace electron {
SkColor ParseHexColor(const std::string& color_string) {
// Check the string for incorrect formatting.
if (color_string.empty() || color_string[0] != '#')
return SK_ColorWHITE;
// Prepend FF if alpha channel is not specified.
std::string source = color_string.substr(1);
if (source.size() == 3)
source.insert(0, "F");
else if (source.size() == 6)
source.insert(0, "FF");
// Convert the string from #FFF format to #FFFFFF format.
std::string formatted_color;
if (source.size() == 4) {
for (size_t i = 0; i < 4; ++i) {
formatted_color += source[i];
formatted_color += source[i];
SkColor ParseCSSColor(const std::string& color_string) {
// ParseCssColorString expects RGBA and we historically use ARGB
// so we need to convert before passing to ParseCssColorString.
std::string color_str = color_string;
if (IsHexFormat(color_str)) {
if (color_str.length() == 5) {
// #ARGB => #RGBA
std::swap(color_str[1], color_str[4]);
} else {
// #AARRGGBB => #RRGGBBAA
std::swap(color_str[1], color_str[7]);
std::swap(color_str[2], color_str[8]);
}
} else if (source.size() == 8) {
formatted_color = source;
} else {
return SK_ColorWHITE;
}
// Convert the string to an integer and make sure it is in the correct value
// range.
std::vector<uint8_t> bytes;
if (!base::HexStringToBytes(formatted_color, &bytes))
return SK_ColorWHITE;
SkColor color;
if (!content::ParseCssColorString(color_str, &color))
color = SK_ColorWHITE;
return SkColorSetARGB(bytes[0], bytes[1], bytes[2], bytes[3]);
return color;
}
std::string ToRGBHex(SkColor color) {

View file

@ -11,12 +11,14 @@
namespace electron {
// Parse hex color like "#FFF" or "#EFEFEF"
SkColor ParseHexColor(const std::string& color_string);
// Parses a CSS-style color string from hex, rgb(), rgba(),
// hsl(), hsla(), or color name formats.
SkColor ParseCSSColor(const std::string& color_string);
// Convert color to RGB hex value like "#ABCDEF"
// Convert color to RGB hex value like "#RRGGBB".
std::string ToRGBHex(SkColor color);
// Convert color to RGBA hex value like "#RRGGBBAA".
std::string ToRGBAHex(SkColor color, bool include_hash = true);
} // namespace electron