| 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 |