Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/renderer/manifest/manifest_parser.h" | 5 #include "content/renderer/manifest/manifest_parser.h" |
| 6 | 6 |
| 7 #include "base/json/json_reader.h" | 7 #include "base/json/json_reader.h" |
| 8 #include "base/strings/nullable_string16.h" | 8 #include "base/strings/nullable_string16.h" |
| 9 #include "base/strings/string_number_conversions.h" | |
| 10 #include "base/strings/string_split.h" | |
| 9 #include "base/strings/string_util.h" | 11 #include "base/strings/string_util.h" |
| 10 #include "base/strings/utf_string_conversions.h" | 12 #include "base/strings/utf_string_conversions.h" |
| 11 #include "base/values.h" | 13 #include "base/values.h" |
| 12 #include "content/public/common/manifest.h" | 14 #include "content/public/common/manifest.h" |
| 15 #include "ui/gfx/geometry/size.h" | |
| 13 | 16 |
| 14 namespace content { | 17 namespace content { |
| 15 | 18 |
| 16 namespace { | 19 namespace { |
| 17 | 20 |
| 18 enum TrimType { | 21 enum TrimType { |
| 19 Trim, | 22 Trim, |
| 20 NoTrim | 23 NoTrim |
| 21 }; | 24 }; |
| 22 | 25 |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 158 // http://w3c.github.io/manifest/#dfn-steps-for-processing-a-density-member-of-a n-icon | 161 // http://w3c.github.io/manifest/#dfn-steps-for-processing-a-density-member-of-a n-icon |
| 159 // Returns the parsed double if any, Manifest::Icon::kDefaultDensity if the | 162 // Returns the parsed double if any, Manifest::Icon::kDefaultDensity if the |
| 160 // parsing failed. | 163 // parsing failed. |
| 161 double ParseIconDensity(const base::DictionaryValue& icon) { | 164 double ParseIconDensity(const base::DictionaryValue& icon) { |
| 162 double density; | 165 double density; |
| 163 if (!icon.GetDouble("density", &density) || density <= 0) | 166 if (!icon.GetDouble("density", &density) || density <= 0) |
| 164 return Manifest::Icon::kDefaultDensity; | 167 return Manifest::Icon::kDefaultDensity; |
| 165 return density; | 168 return density; |
| 166 } | 169 } |
| 167 | 170 |
| 171 // Helper function that returns whether the given |str| is a valid width or | |
| 172 // height value for an icon sizes per: | |
| 173 // https://html.spec.whatwg.org/multipage/semantics.html#attr-link-sizes | |
| 174 bool IsValidIconWidthOrHeight(const std::string& str) { | |
| 175 if (str[0] == '0') | |
|
Avi (use Gerrit)
2014/09/22 15:15:14
Please check the length to be >= 1 before blindly
mlamouri (slow - plz ping)
2014/09/22 15:31:51
Done.
| |
| 176 return false; | |
| 177 for (size_t i = 0; i < str.size(); ++i) | |
| 178 if (!IsAsciiDigit(str[i])) | |
| 179 return false; | |
| 180 return true; | |
| 181 } | |
| 182 | |
| 183 // Parses the 'sizes' attribute of an icon as described in the HTML spec: | |
| 184 // https://html.spec.whatwg.org/multipage/semantics.html#attr-link-sizes | |
| 185 // Return a vector of gfx::Size that contains the valid sizes found. "Any" is | |
| 186 // represented by gfx::Size(0, 0). | |
| 187 // TODO(mlamouri): this is implemented as a separate function because it should | |
| 188 // be refactored with the other icon sizes parsing implementations, see | |
| 189 // http://crbug.com/416477 | |
| 190 std::vector<gfx::Size> ParseIconSizesHTML(const base::string16& sizes_str16) { | |
| 191 if (!base::IsStringASCII(sizes_str16)) | |
| 192 return std::vector<gfx::Size>(); | |
| 193 | |
| 194 std::vector<gfx::Size> sizes; | |
| 195 std::string sizes_str = | |
| 196 base::StringToLowerASCII(base::UTF16ToUTF8(sizes_str16)); | |
| 197 std::vector<std::string> sizes_str_list; | |
| 198 base::SplitStringAlongWhitespace(sizes_str, &sizes_str_list); | |
| 199 | |
| 200 for (size_t i = 0; i < sizes_str_list.size(); ++i) { | |
| 201 std::string& size_str = sizes_str_list[i]; | |
| 202 if (size_str == "any") { | |
| 203 sizes.push_back(gfx::Size(0, 0)); | |
| 204 continue; | |
| 205 } | |
| 206 | |
| 207 // It is expected that [0] => width and [1] => height after the split. | |
| 208 std::vector<std::string> size_list; | |
| 209 base::SplitStringDontTrim(size_str, L'x', &size_list); | |
| 210 if (size_list.size() != 2) | |
| 211 continue; | |
| 212 if (!IsValidIconWidthOrHeight(size_list[0]) || | |
| 213 !IsValidIconWidthOrHeight(size_list[1])) { | |
| 214 continue; | |
| 215 } | |
| 216 | |
| 217 int width, height; | |
| 218 if (!base::StringToInt(size_list[0], &width) || | |
| 219 !base::StringToInt(size_list[1], &height)) { | |
| 220 continue; | |
| 221 } | |
| 222 | |
| 223 sizes.push_back(gfx::Size(width, height)); | |
| 224 } | |
| 225 | |
| 226 return sizes; | |
| 227 } | |
| 228 | |
| 229 // Parses the 'sizes' field of an icon, as defined in: | |
| 230 // http://w3c.github.io/manifest/#dfn-steps-for-processing-a-sizes-member-of-an- icon | |
| 231 // Returns a vector of gfx::Size with the successfully parsed sizes, if any. An | |
| 232 // empty vector if the field was not present or empty. "Any" is represented by | |
| 233 // gfx::Size(0, 0). | |
| 234 std::vector<gfx::Size> ParseIconSizes(const base::DictionaryValue& icon) { | |
| 235 base::NullableString16 sizes_str = ParseString(icon, "sizes", NoTrim); | |
| 236 | |
| 237 return sizes_str.is_null() ? std::vector<gfx::Size>() | |
| 238 : ParseIconSizesHTML(sizes_str.string()); | |
| 239 } | |
| 240 | |
| 241 // Parses the 'icons' field of a Manifest, as defined in: | |
| 242 // http://w3c.github.io/manifest/#dfn-steps-for-processing-the-icons-member | |
| 243 // Returns a vector of Manifest::Icon with the successfully parsed icons, if | |
| 244 // any. An empty vector if the field was not present or empty. | |
| 168 std::vector<Manifest::Icon> ParseIcons(const base::DictionaryValue& dictionary, | 245 std::vector<Manifest::Icon> ParseIcons(const base::DictionaryValue& dictionary, |
| 169 const GURL& manifest_url) { | 246 const GURL& manifest_url) { |
| 170 std::vector<Manifest::Icon> icons; | 247 std::vector<Manifest::Icon> icons; |
| 171 if (!dictionary.HasKey("icons")) | 248 if (!dictionary.HasKey("icons")) |
| 172 return icons; | 249 return icons; |
| 173 | 250 |
| 174 const base::ListValue* icons_list = 0; | 251 const base::ListValue* icons_list = 0; |
| 175 if (!dictionary.GetList("icons", &icons_list)) { | 252 if (!dictionary.GetList("icons", &icons_list)) { |
| 176 // TODO(mlamouri): provide a custom message to the developer console about | 253 // TODO(mlamouri): provide a custom message to the developer console about |
| 177 // the property being incorrectly set. | 254 // the property being incorrectly set. |
| 178 return icons; | 255 return icons; |
| 179 } | 256 } |
| 180 | 257 |
| 181 for (size_t i = 0; i < icons_list->GetSize(); ++i) { | 258 for (size_t i = 0; i < icons_list->GetSize(); ++i) { |
| 182 const base::DictionaryValue* icon_dictionary = 0; | 259 const base::DictionaryValue* icon_dictionary = 0; |
| 183 if (!icons_list->GetDictionary(i, &icon_dictionary)) | 260 if (!icons_list->GetDictionary(i, &icon_dictionary)) |
| 184 continue; | 261 continue; |
| 185 | 262 |
| 186 Manifest::Icon icon; | 263 Manifest::Icon icon; |
| 187 icon.src = ParseIconSrc(*icon_dictionary, manifest_url); | 264 icon.src = ParseIconSrc(*icon_dictionary, manifest_url); |
| 188 // An icon MUST have a valid src. If it does not, it MUST be ignored. | 265 // An icon MUST have a valid src. If it does not, it MUST be ignored. |
| 189 if (!icon.src.is_valid()) | 266 if (!icon.src.is_valid()) |
| 190 continue; | 267 continue; |
| 191 icon.type = ParseIconType(*icon_dictionary); | 268 icon.type = ParseIconType(*icon_dictionary); |
| 192 icon.density = ParseIconDensity(*icon_dictionary); | 269 icon.density = ParseIconDensity(*icon_dictionary); |
| 193 // TODO(mlamouri): icon.sizes | 270 icon.sizes = ParseIconSizes(*icon_dictionary); |
| 194 | 271 |
| 195 icons.push_back(icon); | 272 icons.push_back(icon); |
| 196 } | 273 } |
| 197 | 274 |
| 198 return icons; | 275 return icons; |
| 199 } | 276 } |
| 200 | 277 |
| 201 } // anonymous namespace | 278 } // anonymous namespace |
| 202 | 279 |
| 203 Manifest ManifestParser::Parse(const base::StringPiece& json, | 280 Manifest ManifestParser::Parse(const base::StringPiece& json, |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 228 manifest.short_name = ParseShortName(*dictionary); | 305 manifest.short_name = ParseShortName(*dictionary); |
| 229 manifest.start_url = ParseStartURL(*dictionary, manifest_url, document_url); | 306 manifest.start_url = ParseStartURL(*dictionary, manifest_url, document_url); |
| 230 manifest.display = ParseDisplay(*dictionary); | 307 manifest.display = ParseDisplay(*dictionary); |
| 231 manifest.orientation = ParseOrientation(*dictionary); | 308 manifest.orientation = ParseOrientation(*dictionary); |
| 232 manifest.icons = ParseIcons(*dictionary, manifest_url); | 309 manifest.icons = ParseIcons(*dictionary, manifest_url); |
| 233 | 310 |
| 234 return manifest; | 311 return manifest; |
| 235 } | 312 } |
| 236 | 313 |
| 237 } // namespace content | 314 } // namespace content |
| OLD | NEW |