Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(510)

Side by Side Diff: extensions/common/extension_l10n_util_unittest.cc

Issue 228073005: Move core extensions l10n code to //extensions (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: unused header is unused Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « extensions/common/extension_l10n_util.cc ('k') | extensions/common/file_util.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "base/file_util.h" 5 #include "base/file_util.h"
6 #include "base/files/file_path.h" 6 #include "base/files/file_path.h"
7 #include "base/files/scoped_temp_dir.h" 7 #include "base/files/scoped_temp_dir.h"
8 #include "base/memory/linked_ptr.h" 8 #include "base/memory/linked_ptr.h"
9 #include "base/memory/scoped_ptr.h" 9 #include "base/memory/scoped_ptr.h"
10 #include "base/path_service.h" 10 #include "base/path_service.h"
11 #include "base/strings/utf_string_conversions.h" 11 #include "base/strings/utf_string_conversions.h"
12 #include "base/values.h" 12 #include "base/values.h"
13 #include "chrome/common/chrome_paths.h" 13 #include "chrome/common/chrome_paths.h"
14 #include "chrome/common/extensions/extension_l10n_util.h"
15 #include "chrome/common/extensions/message_bundle.h"
16 #include "extensions/common/constants.h" 14 #include "extensions/common/constants.h"
17 #include "extensions/common/error_utils.h" 15 #include "extensions/common/error_utils.h"
16 #include "extensions/common/extension_l10n_util.h"
18 #include "extensions/common/manifest_constants.h" 17 #include "extensions/common/manifest_constants.h"
18 #include "extensions/common/message_bundle.h"
19 #include "testing/gmock/include/gmock/gmock.h" 19 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h" 20 #include "testing/gtest/include/gtest/gtest.h"
21 #include "ui/base/l10n/l10n_util.h" 21 #include "ui/base/l10n/l10n_util.h"
22 22
23 using extensions::kLocaleFolder; 23 using extensions::kLocaleFolder;
24 using extensions::kMessagesFilename; 24 using extensions::kMessagesFilename;
25 using extensions::MessageBundle; 25 using extensions::MessageBundle;
26 26
27 namespace errors = extensions::manifest_errors; 27 namespace errors = extensions::manifest_errors;
28 namespace keys = extensions::manifest_keys; 28 namespace keys = extensions::manifest_keys;
(...skipping 10 matching lines...) Expand all
39 39
40 base::FilePath messages_file = locale.Append(kMessagesFilename); 40 base::FilePath messages_file = locale.Append(kMessagesFilename);
41 std::string data = "{ \"name\":"; 41 std::string data = "{ \"name\":";
42 ASSERT_TRUE(base::WriteFile(messages_file, data.c_str(), data.length())); 42 ASSERT_TRUE(base::WriteFile(messages_file, data.c_str(), data.length()));
43 43
44 base::DictionaryValue manifest; 44 base::DictionaryValue manifest;
45 manifest.SetString(keys::kDefaultLocale, "en"); 45 manifest.SetString(keys::kDefaultLocale, "en");
46 std::string error; 46 std::string error;
47 EXPECT_FALSE(extension_l10n_util::ValidateExtensionLocales( 47 EXPECT_FALSE(extension_l10n_util::ValidateExtensionLocales(
48 temp.path(), &manifest, &error)); 48 temp.path(), &manifest, &error));
49 EXPECT_THAT(error, 49 EXPECT_THAT(
50 testing::HasSubstr( 50 error,
51 base::UTF16ToUTF8(messages_file.LossyDisplayName()))); 51 testing::HasSubstr(base::UTF16ToUTF8(messages_file.LossyDisplayName())));
52 } 52 }
53 53
54 TEST(ExtensionL10nUtil, GetValidLocalesEmptyLocaleFolder) { 54 TEST(ExtensionL10nUtil, GetValidLocalesEmptyLocaleFolder) {
55 base::ScopedTempDir temp; 55 base::ScopedTempDir temp;
56 ASSERT_TRUE(temp.CreateUniqueTempDir()); 56 ASSERT_TRUE(temp.CreateUniqueTempDir());
57 57
58 base::FilePath src_path = temp.path().Append(kLocaleFolder); 58 base::FilePath src_path = temp.path().Append(kLocaleFolder);
59 ASSERT_TRUE(base::CreateDirectory(src_path)); 59 ASSERT_TRUE(base::CreateDirectory(src_path));
60 60
61 std::string error; 61 std::string error;
62 std::set<std::string> locales; 62 std::set<std::string> locales;
63 EXPECT_FALSE(extension_l10n_util::GetValidLocales(src_path, 63 EXPECT_FALSE(
64 &locales, 64 extension_l10n_util::GetValidLocales(src_path, &locales, &error));
65 &error));
66 65
67 EXPECT_TRUE(locales.empty()); 66 EXPECT_TRUE(locales.empty());
68 } 67 }
69 68
70 TEST(ExtensionL10nUtil, GetValidLocalesWithValidLocaleNoMessagesFile) { 69 TEST(ExtensionL10nUtil, GetValidLocalesWithValidLocaleNoMessagesFile) {
71 base::ScopedTempDir temp; 70 base::ScopedTempDir temp;
72 ASSERT_TRUE(temp.CreateUniqueTempDir()); 71 ASSERT_TRUE(temp.CreateUniqueTempDir());
73 72
74 base::FilePath src_path = temp.path().Append(kLocaleFolder); 73 base::FilePath src_path = temp.path().Append(kLocaleFolder);
75 ASSERT_TRUE(base::CreateDirectory(src_path)); 74 ASSERT_TRUE(base::CreateDirectory(src_path));
76 ASSERT_TRUE(base::CreateDirectory(src_path.AppendASCII("sr"))); 75 ASSERT_TRUE(base::CreateDirectory(src_path.AppendASCII("sr")));
77 76
78 std::string error; 77 std::string error;
79 std::set<std::string> locales; 78 std::set<std::string> locales;
80 EXPECT_FALSE(extension_l10n_util::GetValidLocales(src_path, 79 EXPECT_FALSE(
81 &locales, 80 extension_l10n_util::GetValidLocales(src_path, &locales, &error));
82 &error));
83 81
84 EXPECT_TRUE(locales.empty()); 82 EXPECT_TRUE(locales.empty());
85 } 83 }
86 84
87 TEST(ExtensionL10nUtil, GetValidLocalesWithUnsupportedLocale) { 85 TEST(ExtensionL10nUtil, GetValidLocalesWithUnsupportedLocale) {
88 base::ScopedTempDir temp; 86 base::ScopedTempDir temp;
89 ASSERT_TRUE(temp.CreateUniqueTempDir()); 87 ASSERT_TRUE(temp.CreateUniqueTempDir());
90 88
91 base::FilePath src_path = temp.path().Append(kLocaleFolder); 89 base::FilePath src_path = temp.path().Append(kLocaleFolder);
92 ASSERT_TRUE(base::CreateDirectory(src_path)); 90 ASSERT_TRUE(base::CreateDirectory(src_path));
93 // Supported locale. 91 // Supported locale.
94 base::FilePath locale_1 = src_path.AppendASCII("sr"); 92 base::FilePath locale_1 = src_path.AppendASCII("sr");
95 ASSERT_TRUE(base::CreateDirectory(locale_1)); 93 ASSERT_TRUE(base::CreateDirectory(locale_1));
96 std::string data("whatever"); 94 std::string data("whatever");
97 ASSERT_TRUE(base::WriteFile( 95 ASSERT_TRUE(base::WriteFile(
98 locale_1.Append(kMessagesFilename), 96 locale_1.Append(kMessagesFilename), data.c_str(), data.length()));
99 data.c_str(), data.length()));
100 // Unsupported locale. 97 // Unsupported locale.
101 ASSERT_TRUE(base::CreateDirectory(src_path.AppendASCII("xxx_yyy"))); 98 ASSERT_TRUE(base::CreateDirectory(src_path.AppendASCII("xxx_yyy")));
102 99
103 std::string error; 100 std::string error;
104 std::set<std::string> locales; 101 std::set<std::string> locales;
105 EXPECT_TRUE(extension_l10n_util::GetValidLocales(src_path, 102 EXPECT_TRUE(extension_l10n_util::GetValidLocales(src_path, &locales, &error));
106 &locales,
107 &error));
108 103
109 EXPECT_FALSE(locales.empty()); 104 EXPECT_FALSE(locales.empty());
110 EXPECT_TRUE(locales.find("sr") != locales.end()); 105 EXPECT_TRUE(locales.find("sr") != locales.end());
111 EXPECT_FALSE(locales.find("xxx_yyy") != locales.end()); 106 EXPECT_FALSE(locales.find("xxx_yyy") != locales.end());
112 } 107 }
113 108
114 TEST(ExtensionL10nUtil, GetValidLocalesWithValidLocalesAndMessagesFile) { 109 TEST(ExtensionL10nUtil, GetValidLocalesWithValidLocalesAndMessagesFile) {
115 base::FilePath install_dir; 110 base::FilePath install_dir;
116 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &install_dir)); 111 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &install_dir));
117 install_dir = install_dir.AppendASCII("extensions") 112 install_dir = install_dir.AppendASCII("extensions")
118 .AppendASCII("good") 113 .AppendASCII("good")
119 .AppendASCII("Extensions") 114 .AppendASCII("Extensions")
120 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj") 115 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
121 .AppendASCII("1.0.0.0") 116 .AppendASCII("1.0.0.0")
122 .Append(kLocaleFolder); 117 .Append(kLocaleFolder);
123 118
124 std::string error; 119 std::string error;
125 std::set<std::string> locales; 120 std::set<std::string> locales;
126 EXPECT_TRUE(extension_l10n_util::GetValidLocales(install_dir, 121 EXPECT_TRUE(
127 &locales, 122 extension_l10n_util::GetValidLocales(install_dir, &locales, &error));
128 &error));
129 EXPECT_EQ(3U, locales.size()); 123 EXPECT_EQ(3U, locales.size());
130 EXPECT_TRUE(locales.find("sr") != locales.end()); 124 EXPECT_TRUE(locales.find("sr") != locales.end());
131 EXPECT_TRUE(locales.find("en") != locales.end()); 125 EXPECT_TRUE(locales.find("en") != locales.end());
132 EXPECT_TRUE(locales.find("en_US") != locales.end()); 126 EXPECT_TRUE(locales.find("en_US") != locales.end());
133 } 127 }
134 128
135 TEST(ExtensionL10nUtil, LoadMessageCatalogsValidFallback) { 129 TEST(ExtensionL10nUtil, LoadMessageCatalogsValidFallback) {
136 base::FilePath install_dir; 130 base::FilePath install_dir;
137 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &install_dir)); 131 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &install_dir));
138 install_dir = install_dir.AppendASCII("extensions") 132 install_dir = install_dir.AppendASCII("extensions")
139 .AppendASCII("good") 133 .AppendASCII("good")
140 .AppendASCII("Extensions") 134 .AppendASCII("Extensions")
141 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj") 135 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
142 .AppendASCII("1.0.0.0") 136 .AppendASCII("1.0.0.0")
143 .Append(kLocaleFolder); 137 .Append(kLocaleFolder);
144 138
145 std::string error; 139 std::string error;
146 std::set<std::string> locales; 140 std::set<std::string> locales;
147 EXPECT_TRUE(extension_l10n_util::GetValidLocales(install_dir, 141 EXPECT_TRUE(
148 &locales, 142 extension_l10n_util::GetValidLocales(install_dir, &locales, &error));
149 &error));
150 143
151 scoped_ptr<MessageBundle> bundle(extension_l10n_util::LoadMessageCatalogs( 144 scoped_ptr<MessageBundle> bundle(extension_l10n_util::LoadMessageCatalogs(
152 install_dir, "sr", "en_US", locales, &error)); 145 install_dir, "sr", "en_US", locales, &error));
153 ASSERT_FALSE(NULL == bundle.get()); 146 ASSERT_FALSE(NULL == bundle.get());
154 EXPECT_TRUE(error.empty()); 147 EXPECT_TRUE(error.empty());
155 EXPECT_EQ("Color", bundle->GetL10nMessage("color")); 148 EXPECT_EQ("Color", bundle->GetL10nMessage("color"));
156 EXPECT_EQ("Not in the US or GB.", bundle->GetL10nMessage("not_in_US_or_GB")); 149 EXPECT_EQ("Not in the US or GB.", bundle->GetL10nMessage("not_in_US_or_GB"));
157 } 150 }
158 151
159 TEST(ExtensionL10nUtil, LoadMessageCatalogsMissingFiles) { 152 TEST(ExtensionL10nUtil, LoadMessageCatalogsMissingFiles) {
160 base::ScopedTempDir temp; 153 base::ScopedTempDir temp;
161 ASSERT_TRUE(temp.CreateUniqueTempDir()); 154 ASSERT_TRUE(temp.CreateUniqueTempDir());
162 155
163 base::FilePath src_path = temp.path().Append(kLocaleFolder); 156 base::FilePath src_path = temp.path().Append(kLocaleFolder);
164 ASSERT_TRUE(base::CreateDirectory(src_path)); 157 ASSERT_TRUE(base::CreateDirectory(src_path));
165 158
166 std::set<std::string> valid_locales; 159 std::set<std::string> valid_locales;
167 valid_locales.insert("sr"); 160 valid_locales.insert("sr");
168 valid_locales.insert("en"); 161 valid_locales.insert("en");
169 std::string error; 162 std::string error;
170 EXPECT_TRUE(NULL == extension_l10n_util::LoadMessageCatalogs(src_path, 163 EXPECT_TRUE(NULL == extension_l10n_util::LoadMessageCatalogs(
171 "en", 164 src_path, "en", "sr", valid_locales, &error));
172 "sr",
173 valid_locales,
174 &error));
175 EXPECT_FALSE(error.empty()); 165 EXPECT_FALSE(error.empty());
176 } 166 }
177 167
178 TEST(ExtensionL10nUtil, LoadMessageCatalogsBadJSONFormat) { 168 TEST(ExtensionL10nUtil, LoadMessageCatalogsBadJSONFormat) {
179 base::ScopedTempDir temp; 169 base::ScopedTempDir temp;
180 ASSERT_TRUE(temp.CreateUniqueTempDir()); 170 ASSERT_TRUE(temp.CreateUniqueTempDir());
181 171
182 base::FilePath src_path = temp.path().Append(kLocaleFolder); 172 base::FilePath src_path = temp.path().Append(kLocaleFolder);
183 ASSERT_TRUE(base::CreateDirectory(src_path)); 173 ASSERT_TRUE(base::CreateDirectory(src_path));
184 174
185 base::FilePath locale = src_path.AppendASCII("sr"); 175 base::FilePath locale = src_path.AppendASCII("sr");
186 ASSERT_TRUE(base::CreateDirectory(locale)); 176 ASSERT_TRUE(base::CreateDirectory(locale));
187 177
188 std::string data = "{ \"name\":"; 178 std::string data = "{ \"name\":";
189 base::FilePath messages_file = locale.Append(kMessagesFilename); 179 base::FilePath messages_file = locale.Append(kMessagesFilename);
190 ASSERT_TRUE(base::WriteFile(messages_file, data.c_str(), data.length())); 180 ASSERT_TRUE(base::WriteFile(messages_file, data.c_str(), data.length()));
191 181
192 std::set<std::string> valid_locales; 182 std::set<std::string> valid_locales;
193 valid_locales.insert("sr"); 183 valid_locales.insert("sr");
194 valid_locales.insert("en_US"); 184 valid_locales.insert("en_US");
195 std::string error; 185 std::string error;
196 EXPECT_TRUE(NULL == extension_l10n_util::LoadMessageCatalogs(src_path, 186 EXPECT_TRUE(NULL == extension_l10n_util::LoadMessageCatalogs(
197 "en_US", 187 src_path, "en_US", "sr", valid_locales, &error));
198 "sr", 188 EXPECT_EQ(extensions::ErrorUtils::FormatErrorMessage(
199 valid_locales, 189 errors::kLocalesInvalidLocale,
200 &error)); 190 base::UTF16ToUTF8(messages_file.LossyDisplayName()),
201 EXPECT_EQ( 191 "Line: 1, column: 10, Unexpected token."),
202 extensions::ErrorUtils::FormatErrorMessage( 192 error);
203 errors::kLocalesInvalidLocale,
204 base::UTF16ToUTF8(messages_file.LossyDisplayName()),
205 "Line: 1, column: 10, Unexpected token."),
206 error);
207 } 193 }
208 194
209 TEST(ExtensionL10nUtil, LoadMessageCatalogsDuplicateKeys) { 195 TEST(ExtensionL10nUtil, LoadMessageCatalogsDuplicateKeys) {
210 base::ScopedTempDir temp; 196 base::ScopedTempDir temp;
211 ASSERT_TRUE(temp.CreateUniqueTempDir()); 197 ASSERT_TRUE(temp.CreateUniqueTempDir());
212 198
213 base::FilePath src_path = temp.path().Append(kLocaleFolder); 199 base::FilePath src_path = temp.path().Append(kLocaleFolder);
214 ASSERT_TRUE(base::CreateDirectory(src_path)); 200 ASSERT_TRUE(base::CreateDirectory(src_path));
215 201
216 base::FilePath locale_1 = src_path.AppendASCII("en"); 202 base::FilePath locale_1 = src_path.AppendASCII("en");
217 ASSERT_TRUE(base::CreateDirectory(locale_1)); 203 ASSERT_TRUE(base::CreateDirectory(locale_1));
218 204
219 std::string data = 205 std::string data =
220 "{ \"name\": { \"message\": \"something\" }, " 206 "{ \"name\": { \"message\": \"something\" }, "
221 "\"name\": { \"message\": \"something else\" } }"; 207 "\"name\": { \"message\": \"something else\" } }";
222 ASSERT_TRUE(base::WriteFile(locale_1.Append(kMessagesFilename), 208 ASSERT_TRUE(base::WriteFile(
223 data.c_str(), data.length())); 209 locale_1.Append(kMessagesFilename), data.c_str(), data.length()));
224 210
225 base::FilePath locale_2 = src_path.AppendASCII("sr"); 211 base::FilePath locale_2 = src_path.AppendASCII("sr");
226 ASSERT_TRUE(base::CreateDirectory(locale_2)); 212 ASSERT_TRUE(base::CreateDirectory(locale_2));
227 213
228 ASSERT_TRUE(base::WriteFile(locale_2.Append(kMessagesFilename), 214 ASSERT_TRUE(base::WriteFile(
229 data.c_str(), data.length())); 215 locale_2.Append(kMessagesFilename), data.c_str(), data.length()));
230 216
231 std::set<std::string> valid_locales; 217 std::set<std::string> valid_locales;
232 valid_locales.insert("sr"); 218 valid_locales.insert("sr");
233 valid_locales.insert("en"); 219 valid_locales.insert("en");
234 std::string error; 220 std::string error;
235 // JSON parser hides duplicates. We are going to get only one key/value 221 // JSON parser hides duplicates. We are going to get only one key/value
236 // pair at the end. 222 // pair at the end.
237 scoped_ptr<MessageBundle> message_bundle( 223 scoped_ptr<MessageBundle> message_bundle(
238 extension_l10n_util::LoadMessageCatalogs(src_path, 224 extension_l10n_util::LoadMessageCatalogs(
239 "en", 225 src_path, "en", "sr", valid_locales, &error));
240 "sr",
241 valid_locales,
242 &error));
243 EXPECT_TRUE(NULL != message_bundle.get()); 226 EXPECT_TRUE(NULL != message_bundle.get());
244 EXPECT_TRUE(error.empty()); 227 EXPECT_TRUE(error.empty());
245 } 228 }
246 229
247 // Caller owns the returned object. 230 // Caller owns the returned object.
248 MessageBundle* CreateManifestBundle() { 231 MessageBundle* CreateManifestBundle() {
249 linked_ptr<base::DictionaryValue> catalog(new base::DictionaryValue); 232 linked_ptr<base::DictionaryValue> catalog(new base::DictionaryValue);
250 233
251 base::DictionaryValue* name_tree = new base::DictionaryValue(); 234 base::DictionaryValue* name_tree = new base::DictionaryValue();
252 name_tree->SetString("message", "name"); 235 name_tree->SetString("message", "name");
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
512 EXPECT_TRUE( 495 EXPECT_TRUE(
513 extension_l10n_util::LocalizeManifest(*messages, &manifest, &error)); 496 extension_l10n_util::LocalizeManifest(*messages, &manifest, &error));
514 497
515 std::string result; 498 std::string result;
516 ASSERT_TRUE(manifest.GetString(keys::kName, &result)); 499 ASSERT_TRUE(manifest.GetString(keys::kName, &result));
517 EXPECT_EQ("name", result); 500 EXPECT_EQ("name", result);
518 501
519 ASSERT_TRUE(manifest.GetString(keys::kDescription, &result)); 502 ASSERT_TRUE(manifest.GetString(keys::kDescription, &result));
520 EXPECT_EQ("description", result); 503 EXPECT_EQ("description", result);
521 504
522 ASSERT_TRUE(manifest.GetString("commands.first_command.description", 505 ASSERT_TRUE(
523 &result)); 506 manifest.GetString("commands.first_command.description", &result));
524 EXPECT_EQ("first command", result); 507 EXPECT_EQ("first command", result);
525 508
526 ASSERT_TRUE(manifest.GetString("commands.second_command.description", 509 ASSERT_TRUE(
527 &result)); 510 manifest.GetString("commands.second_command.description", &result));
528 EXPECT_EQ("second command", result); 511 EXPECT_EQ("second command", result);
529 512
530 EXPECT_TRUE(error.empty()); 513 EXPECT_TRUE(error.empty());
531 } 514 }
532 515
533 TEST(ExtensionL10nUtil, LocalizeManifestWithShortName) { 516 TEST(ExtensionL10nUtil, LocalizeManifestWithShortName) {
534 base::DictionaryValue manifest; 517 base::DictionaryValue manifest;
535 manifest.SetString(keys::kName, "extension name"); 518 manifest.SetString(keys::kName, "extension name");
536 manifest.SetString(keys::kShortName, "__MSG_short_name__"); 519 manifest.SetString(keys::kShortName, "__MSG_short_name__");
537 520
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
670 std::vector<std::string> fallback_locales; 653 std::vector<std::string> fallback_locales;
671 extension_l10n_util::GetAllFallbackLocales("en_US", "all", &fallback_locales); 654 extension_l10n_util::GetAllFallbackLocales("en_US", "all", &fallback_locales);
672 ASSERT_EQ(3U, fallback_locales.size()); 655 ASSERT_EQ(3U, fallback_locales.size());
673 656
674 CHECK_EQ("en_US", fallback_locales[0]); 657 CHECK_EQ("en_US", fallback_locales[0]);
675 CHECK_EQ("en", fallback_locales[1]); 658 CHECK_EQ("en", fallback_locales[1]);
676 CHECK_EQ("all", fallback_locales[2]); 659 CHECK_EQ("all", fallback_locales[2]);
677 } 660 }
678 661
679 } // namespace 662 } // namespace
OLDNEW
« no previous file with comments | « extensions/common/extension_l10n_util.cc ('k') | extensions/common/file_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698