dillon - branch off of chromium-67.0.3396.87 and apply 67.bad-dfly
[chromium-dfly.git] / ui / base / webui / web_ui_util.cc
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ui/base/webui/web_ui_util.h"
6
7 #include <vector>
8
9 #include "base/base64.h"
10 #include "base/i18n/rtl.h"
11 #include "base/logging.h"
12 #include "base/memory/ref_counted_memory.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "base/strings/string_util.h"
15 #include "base/trace_event/trace_event.h"
16 #include "build/build_config.h"
17 #include "net/base/escape.h"
18 #include "ui/base/l10n/l10n_util.h"
19 #include "ui/base/resource/resource_bundle.h"
20 #include "ui/base/template_expressions.h"
21 #include "ui/base/window_open_disposition.h"
22 #include "ui/gfx/codec/png_codec.h"
23 #include "ui/gfx/font.h"
24 #include "ui/gfx/image/image_skia.h"
25 #include "ui/resources/grit/webui_resources.h"
26 #include "ui/strings/grit/app_locale_settings.h"
27 #include "url/gurl.h"
28
29 #if defined(OS_WIN)
30 #include "base/win/windows_version.h"
31 #endif
32
33 namespace webui {
34
35 std::string GetBitmapDataUrl(const SkBitmap& bitmap) {
36   TRACE_EVENT2("oobe", "GetImageDataUrl",
37                "width", bitmap.width(), "height", bitmap.height());
38   std::vector<unsigned char> output;
39   gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, &output);
40   return GetPngDataUrl(output.data(), output.size());
41 }
42
43 std::string GetPngDataUrl(const unsigned char* data, size_t size) {
44   std::string str_url(reinterpret_cast<const char*>(data), size);
45   base::Base64Encode(str_url, &str_url);
46   str_url.insert(0, "data:image/png;base64,");
47   return str_url;
48 }
49
50 WindowOpenDisposition GetDispositionFromClick(const base::ListValue* args,
51                                               int start_index) {
52   double button = 0.0;
53   bool alt_key = false;
54   bool ctrl_key = false;
55   bool meta_key = false;
56   bool shift_key = false;
57
58   CHECK(args->GetDouble(start_index++, &button));
59   CHECK(args->GetBoolean(start_index++, &alt_key));
60   CHECK(args->GetBoolean(start_index++, &ctrl_key));
61   CHECK(args->GetBoolean(start_index++, &meta_key));
62   CHECK(args->GetBoolean(start_index++, &shift_key));
63   return ui::DispositionFromClick(
64       button == 1.0, alt_key, ctrl_key, meta_key, shift_key);
65 }
66
67 bool ParseScaleFactor(const base::StringPiece& identifier,
68                       float* scale_factor) {
69   *scale_factor = 1.0f;
70   if (identifier.empty()) {
71     LOG(WARNING) << "Invalid scale factor format: " << identifier;
72     return false;
73   }
74
75   if (*identifier.rbegin() != 'x') {
76     LOG(WARNING) << "Invalid scale factor format: " << identifier;
77     return false;
78   }
79
80   double scale = 0;
81   std::string stripped;
82   identifier.substr(0, identifier.length() - 1).CopyToString(&stripped);
83   if (!base::StringToDouble(stripped, &scale)) {
84     LOG(WARNING) << "Invalid scale factor format: " << identifier;
85     return false;
86   }
87   *scale_factor = static_cast<float>(scale);
88   return true;
89 }
90
91 // Parse a formatted frame index string into int and sets to |frame_index|.
92 bool ParseFrameIndex(const base::StringPiece& identifier, int* frame_index) {
93   *frame_index = -1;
94   if (identifier.empty()) {
95     LOG(WARNING) << "Invalid frame index format: " << identifier;
96     return false;
97   }
98
99   if (*identifier.rbegin() != ']') {
100     LOG(WARNING) << "Invalid frame index format: " << identifier;
101     return false;
102   }
103
104   unsigned frame = 0;
105   if (!base::StringToUint(identifier.substr(0, identifier.length() - 1),
106                           &frame)) {
107     LOG(WARNING) << "Invalid frame index format: " << identifier;
108     return false;
109   }
110   *frame_index = static_cast<int>(frame);
111   return true;
112 }
113
114 void ParsePathAndImageSpec(const GURL& url,
115                            std::string* path,
116                            float* scale_factor,
117                            int* frame_index) {
118   *path = net::UnescapeURLComponent(
119       url.path().substr(1),
120       net::UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS |
121           net::UnescapeRule::SPACES);
122   if (scale_factor)
123     *scale_factor = 1.0f;
124   if (frame_index)
125     *frame_index = -1;
126
127   // Detect and parse resource string ending in @<scale>x.
128   std::size_t pos = path->rfind('@');
129   if (pos != std::string::npos) {
130     base::StringPiece stripped_path(*path);
131     float factor;
132
133     if (ParseScaleFactor(stripped_path.substr(
134             pos + 1, stripped_path.length() - pos - 1), &factor)) {
135       // Strip scale factor specification from path.
136       stripped_path.remove_suffix(stripped_path.length() - pos);
137       stripped_path.CopyToString(path);
138     }
139     if (scale_factor)
140       *scale_factor = factor;
141   }
142
143   // Detect and parse resource string ending in [<frame>].
144   pos = path->rfind('[');
145   if (pos != std::string::npos) {
146     base::StringPiece stripped_path(*path);
147     int index;
148
149     if (ParseFrameIndex(
150             stripped_path.substr(pos + 1, stripped_path.length() - pos - 1),
151             &index)) {
152       // Strip frame index specification from path.
153       stripped_path.remove_suffix(stripped_path.length() - pos);
154       stripped_path.CopyToString(path);
155     }
156     if (frame_index)
157       *frame_index = index;
158   }
159 }
160
161 void ParsePathAndScale(const GURL& url,
162                        std::string* path,
163                        float* scale_factor) {
164   ParsePathAndImageSpec(url, path, scale_factor, nullptr);
165 }
166
167 void ParsePathAndFrame(const GURL& url, std::string* path, int* frame_index) {
168   ParsePathAndImageSpec(url, path, nullptr, frame_index);
169 }
170
171 void SetLoadTimeDataDefaults(const std::string& app_locale,
172                              base::DictionaryValue* localized_strings) {
173   localized_strings->SetString("fontfamily", GetFontFamily());
174   localized_strings->SetString("fontsize", GetFontSize());
175   localized_strings->SetString("language", l10n_util::GetLanguage(app_locale));
176   localized_strings->SetString("textdirection", GetTextDirection());
177 }
178
179 void SetLoadTimeDataDefaults(const std::string& app_locale,
180                              ui::TemplateReplacements* replacements) {
181   (*replacements)["fontfamily"] = GetFontFamily();
182   (*replacements)["fontsize"] = GetFontSize();
183   (*replacements)["language"] = l10n_util::GetLanguage(app_locale);
184   (*replacements)["textdirection"] = GetTextDirection();
185 }
186
187 std::string GetWebUiCssTextDefaults(base::StringPiece css_template) {
188   ui::TemplateReplacements placeholders;
189   placeholders["textDirection"] = GetTextDirection();
190   placeholders["fontFamily"] = GetFontFamily();
191   placeholders["fontSize"] = GetFontSize();
192   return ui::ReplaceTemplateExpressions(css_template, placeholders);
193 }
194
195 std::string GetWebUiCssTextDefaults() {
196   const ui::ResourceBundle& resource_bundle =
197       ui::ResourceBundle::GetSharedInstance();
198   return GetWebUiCssTextDefaults(
199       resource_bundle.GetRawDataResource(IDR_WEBUI_CSS_TEXT_DEFAULTS));
200 }
201
202 std::string GetWebUiCssTextDefaultsMd() {
203   const ui::ResourceBundle& resource_bundle =
204       ui::ResourceBundle::GetSharedInstance();
205   return GetWebUiCssTextDefaults(
206       resource_bundle.GetRawDataResource(IDR_WEBUI_CSS_TEXT_DEFAULTS_MD));
207 }
208
209 void AppendWebUiCssTextDefaults(std::string* html) {
210   html->append("<style>");
211   html->append(GetWebUiCssTextDefaults());
212   html->append("</style>");
213 }
214
215 std::string GetFontFamily() {
216   std::string font_family = l10n_util::GetStringUTF8(IDS_WEB_FONT_FAMILY);
217
218 // TODO(dnicoara) Remove Ozone check when PlatformFont support is introduced
219 // into Ozone: crbug.com/320050
220 #if (defined(OS_LINUX) || defined(OS_BSD)) && !defined(OS_CHROMEOS) && \
221     !defined(USE_OZONE)
222   font_family = ui::ResourceBundle::GetSharedInstance().GetFont(
223       ui::ResourceBundle::BaseFont).GetFontName() + ", " + font_family;
224 #endif
225
226   return font_family;
227 }
228
229 std::string GetFontSize() {
230   return l10n_util::GetStringUTF8(IDS_WEB_FONT_SIZE);
231 }
232
233 std::string GetTextDirection() {
234   return base::i18n::IsRTL() ? "rtl" : "ltr";
235 }
236
237 }  // namespace webui