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_util.h" | 9 #include "base/strings/string_util.h" |
10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
11 #include "base/values.h" | 11 #include "base/values.h" |
12 #include "content/public/common/manifest.h" | 12 #include "content/public/common/manifest.h" |
13 | 13 |
| 14 namespace content { |
| 15 |
14 namespace { | 16 namespace { |
15 | 17 |
| 18 enum TrimType { |
| 19 Trim, |
| 20 NoTrim |
| 21 }; |
| 22 |
| 23 base::NullableString16 ParseString(const base::DictionaryValue& dictionary, |
| 24 const std::string& key, |
| 25 TrimType trim) { |
| 26 if (!dictionary.HasKey(key)) |
| 27 return base::NullableString16(); |
| 28 |
| 29 base::string16 value; |
| 30 if (!dictionary.GetString(key, &value)) { |
| 31 // TODO(mlamouri): provide a custom message to the developer console about |
| 32 // the property being incorrectly set. |
| 33 return base::NullableString16(); |
| 34 } |
| 35 |
| 36 if (trim == Trim) |
| 37 base::TrimWhitespace(value, base::TRIM_ALL, &value); |
| 38 return base::NullableString16(value, false); |
| 39 } |
| 40 |
16 // Parses the 'name' field of the manifest, as defined in: | 41 // Parses the 'name' field of the manifest, as defined in: |
17 // http://w3c.github.io/manifest/#dfn-steps-for-processing-the-name-member | 42 // http://w3c.github.io/manifest/#dfn-steps-for-processing-the-name-member |
18 // Returns the parsed string if any, a null string if the parsing failed. | 43 // Returns the parsed string if any, a null string if the parsing failed. |
19 base::NullableString16 ParseName(const base::DictionaryValue& dictionary) { | 44 base::NullableString16 ParseName(const base::DictionaryValue& dictionary) { |
20 if (!dictionary.HasKey("name")) | 45 return ParseString(dictionary, "name", Trim); |
21 return base::NullableString16(); | |
22 | |
23 base::string16 name; | |
24 if (!dictionary.GetString("name", &name)) { | |
25 // TODO(mlamouri): provide a custom message to the developer console. | |
26 return base::NullableString16(); | |
27 } | |
28 | |
29 base::TrimWhitespace(name, base::TRIM_ALL, &name); | |
30 return base::NullableString16(name, false); | |
31 } | 46 } |
32 | 47 |
33 // Parses the 'short_name' field of the manifest, as defined in: | 48 // Parses the 'short_name' field of the manifest, as defined in: |
34 // http://w3c.github.io/manifest/#dfn-steps-for-processing-the-short-name-member | 49 // http://w3c.github.io/manifest/#dfn-steps-for-processing-the-short-name-member |
35 // Returns the parsed string if any, a null string if the parsing failed. | 50 // Returns the parsed string if any, a null string if the parsing failed. |
36 base::NullableString16 ParseShortName( | 51 base::NullableString16 ParseShortName( |
37 const base::DictionaryValue& dictionary) { | 52 const base::DictionaryValue& dictionary) { |
38 if (!dictionary.HasKey("short_name")) | 53 return ParseString(dictionary, "short_name", Trim); |
39 return base::NullableString16(); | |
40 | |
41 base::string16 short_name; | |
42 if (!dictionary.GetString("short_name", &short_name)) { | |
43 // TODO(mlamouri): provide a custom message to the developer console. | |
44 return base::NullableString16(); | |
45 } | |
46 | |
47 base::TrimWhitespace(short_name, base::TRIM_ALL, &short_name); | |
48 return base::NullableString16(short_name, false); | |
49 } | 54 } |
50 | 55 |
51 // Parses the 'start_url' field of the manifest, as defined in: | 56 // Parses the 'start_url' field of the manifest, as defined in: |
52 // http://w3c.github.io/manifest/#dfn-steps-for-processing-the-start_url-member | 57 // http://w3c.github.io/manifest/#dfn-steps-for-processing-the-start_url-member |
53 // Returns the parsed GURL if any, an empty GURL if the parsing failed. | 58 // Returns the parsed GURL if any, an empty GURL if the parsing failed. |
54 GURL ParseStartURL(const base::DictionaryValue& dictionary, | 59 GURL ParseStartURL(const base::DictionaryValue& dictionary, |
55 const GURL& manifest_url, | 60 const GURL& manifest_url, |
56 const GURL& document_url) { | 61 const GURL& document_url) { |
57 if (!dictionary.HasKey("start_url")) | 62 base::NullableString16 start_url_str = |
| 63 ParseString(dictionary, "start_url", NoTrim); |
| 64 |
| 65 if (start_url_str.is_null()) |
58 return GURL(); | 66 return GURL(); |
59 | 67 |
60 base::string16 start_url_str; | 68 GURL start_url = manifest_url.Resolve(start_url_str.string()); |
61 if (!dictionary.GetString("start_url", &start_url_str)) { | |
62 // TODO(mlamouri): provide a custom message to the developer console. | |
63 return GURL(); | |
64 } | |
65 | |
66 GURL start_url = manifest_url.Resolve(start_url_str); | |
67 if (!start_url.is_valid()) | 69 if (!start_url.is_valid()) |
68 return GURL(); | 70 return GURL(); |
69 | 71 |
70 if (start_url.GetOrigin() != document_url.GetOrigin()) { | 72 if (start_url.GetOrigin() != document_url.GetOrigin()) { |
71 // TODO(mlamouri): provide a custom message to the developer console. | 73 // TODO(mlamouri): provide a custom message to the developer console. |
72 return GURL(); | 74 return GURL(); |
73 } | 75 } |
74 | 76 |
75 return start_url; | 77 return start_url; |
76 } | 78 } |
77 | 79 |
| 80 // Parses the 'display' field of the manifest, as defined in: |
| 81 // http://w3c.github.io/manifest/#dfn-steps-for-processing-the-display-member |
| 82 // Returns the parsed DisplayMode if any, DISPLAY_MODE_UNSPECIFIED if the |
| 83 // parsing failed. |
| 84 Manifest::DisplayMode ParseDisplay(const base::DictionaryValue& dictionary) { |
| 85 base::NullableString16 display = ParseString(dictionary, "display", Trim); |
| 86 |
| 87 if (display.is_null()) |
| 88 return Manifest::DISPLAY_MODE_UNSPECIFIED; |
| 89 |
| 90 if (LowerCaseEqualsASCII(display.string(), "fullscreen")) |
| 91 return Manifest::DISPLAY_MODE_FULLSCREEN; |
| 92 else if (LowerCaseEqualsASCII(display.string(), "standalone")) |
| 93 return Manifest::DISPLAY_MODE_STANDALONE; |
| 94 else if (LowerCaseEqualsASCII(display.string(), "minimal-ui")) |
| 95 return Manifest::DISPLAY_MODE_MINIMAL_UI; |
| 96 else if (LowerCaseEqualsASCII(display.string(), "browser")) |
| 97 return Manifest::DISPLAY_MODE_BROWSER; |
| 98 else |
| 99 return Manifest::DISPLAY_MODE_UNSPECIFIED; |
| 100 } |
| 101 |
78 } // anonymous namespace | 102 } // anonymous namespace |
79 | 103 |
80 namespace content { | |
81 | |
82 Manifest ManifestParser::Parse(const base::StringPiece& json, | 104 Manifest ManifestParser::Parse(const base::StringPiece& json, |
83 const GURL& manifest_url, | 105 const GURL& manifest_url, |
84 const GURL& document_url) { | 106 const GURL& document_url) { |
85 scoped_ptr<base::Value> value(base::JSONReader::Read(json)); | 107 scoped_ptr<base::Value> value(base::JSONReader::Read(json)); |
86 if (!value) { | 108 if (!value) { |
87 // TODO(mlamouri): get the JSON parsing error and report it to the developer | 109 // TODO(mlamouri): get the JSON parsing error and report it to the developer |
88 // console. | 110 // console. |
89 return Manifest(); | 111 return Manifest(); |
90 } | 112 } |
91 | 113 |
92 if (value->GetType() != base::Value::TYPE_DICTIONARY) { | 114 if (value->GetType() != base::Value::TYPE_DICTIONARY) { |
93 // TODO(mlamouri): provide a custom message to the developer console. | 115 // TODO(mlamouri): provide a custom message to the developer console. |
94 return Manifest(); | 116 return Manifest(); |
95 } | 117 } |
96 | 118 |
97 base::DictionaryValue* dictionary = 0; | 119 base::DictionaryValue* dictionary = 0; |
98 value->GetAsDictionary(&dictionary); | 120 value->GetAsDictionary(&dictionary); |
99 if (!dictionary) { | 121 if (!dictionary) { |
100 // TODO(mlamouri): provide a custom message to the developer console. | 122 // TODO(mlamouri): provide a custom message to the developer console. |
101 return Manifest(); | 123 return Manifest(); |
102 } | 124 } |
103 | 125 |
104 Manifest manifest; | 126 Manifest manifest; |
105 | 127 |
106 manifest.name = ParseName(*dictionary); | 128 manifest.name = ParseName(*dictionary); |
107 manifest.short_name = ParseShortName(*dictionary); | 129 manifest.short_name = ParseShortName(*dictionary); |
108 manifest.start_url = ParseStartURL(*dictionary, manifest_url, document_url); | 130 manifest.start_url = ParseStartURL(*dictionary, manifest_url, document_url); |
| 131 manifest.display = ParseDisplay(*dictionary); |
109 | 132 |
110 return manifest; | 133 return manifest; |
111 } | 134 } |
112 | 135 |
113 } // namespace content | 136 } // namespace content |
OLD | NEW |