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

Side by Side Diff: chrome/browser/search_engines/template_url_parser.cc

Issue 10021008: Reland r131019: Move most TemplateURL data members to a new struct, TemplateURLData. This allows us… (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 8 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
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 "chrome/browser/search_engines/template_url_parser.h" 5 #include "chrome/browser/search_engines/template_url_parser.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <map> 8 #include <map>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 static void StartElementImpl(void* ctx, 138 static void StartElementImpl(void* ctx,
139 const xmlChar* name, 139 const xmlChar* name,
140 const xmlChar** atts); 140 const xmlChar** atts);
141 static void EndElementImpl(void* ctx, const xmlChar* name); 141 static void EndElementImpl(void* ctx, const xmlChar* name);
142 static void CharactersImpl(void* ctx, const xmlChar* ch, int len); 142 static void CharactersImpl(void* ctx, const xmlChar* ch, int len);
143 143
144 // Returns a heap-allocated TemplateURL representing the result of parsing. 144 // Returns a heap-allocated TemplateURL representing the result of parsing.
145 // This will be NULL if parsing failed or if the results were invalid for some 145 // This will be NULL if parsing failed or if the results were invalid for some
146 // reason (e.g. the resulting URL was not HTTP[S], a name wasn't supplied, 146 // reason (e.g. the resulting URL was not HTTP[S], a name wasn't supplied,
147 // etc.). 147 // etc.).
148 TemplateURL* GetTemplateURL(Profile* profile); 148 TemplateURL* GetTemplateURL(Profile* profile, bool show_in_default_list);
149 149
150 private: 150 private:
151 // Key is UTF8 encoded. 151 // Key is UTF8 encoded.
152 typedef std::map<std::string, ElementType> ElementNameToElementTypeMap; 152 typedef std::map<std::string, ElementType> ElementNameToElementTypeMap;
153 153
154 static void InitMapping(); 154 static void InitMapping();
155 155
156 void ParseURL(const xmlChar** atts); 156 void ParseURL(const xmlChar** atts);
157 void ParseImage(const xmlChar** atts); 157 void ParseImage(const xmlChar** atts);
158 void ParseParam(const xmlChar** atts); 158 void ParseParam(const xmlChar** atts);
159 void ProcessURLParams(); 159 void ProcessURLParams();
160 160
161 // Returns the current ElementType. 161 // Returns the current ElementType.
162 ElementType GetKnownType(); 162 ElementType GetKnownType();
163 163
164 static ElementNameToElementTypeMap* kElementNameToElementTypeMap; 164 static ElementNameToElementTypeMap* kElementNameToElementTypeMap;
165 165
166 scoped_ptr<TemplateURL> url_; 166 // Data that gets updated as we parse, and is converted to a TemplateURL by
167 // GetTemplateURL().
168 TemplateURLData data_;
167 169
168 std::vector<ElementType> elements_; 170 std::vector<ElementType> elements_;
169 bool image_is_valid_for_favicon_; 171 bool image_is_valid_for_favicon_;
170 172
171 // Character content for the current element. 173 // Character content for the current element.
172 string16 string_; 174 string16 string_;
173 175
174 TemplateURLParser::ParameterFilter* parameter_filter_; 176 TemplateURLParser::ParameterFilter* parameter_filter_;
175 177
176 // The list of parameters parsed in the Param nodes of a Url node. 178 // The list of parameters parsed in the Param nodes of a Url node.
(...skipping 13 matching lines...) Expand all
190 192
191 DISALLOW_COPY_AND_ASSIGN(TemplateURLParsingContext); 193 DISALLOW_COPY_AND_ASSIGN(TemplateURLParsingContext);
192 }; 194 };
193 195
194 // static 196 // static
195 TemplateURLParsingContext::ElementNameToElementTypeMap* 197 TemplateURLParsingContext::ElementNameToElementTypeMap*
196 TemplateURLParsingContext::kElementNameToElementTypeMap = NULL; 198 TemplateURLParsingContext::kElementNameToElementTypeMap = NULL;
197 199
198 TemplateURLParsingContext::TemplateURLParsingContext( 200 TemplateURLParsingContext::TemplateURLParsingContext(
199 TemplateURLParser::ParameterFilter* parameter_filter) 201 TemplateURLParser::ParameterFilter* parameter_filter)
200 : url_(new TemplateURL()), 202 : image_is_valid_for_favicon_(false),
201 image_is_valid_for_favicon_(false),
202 parameter_filter_(parameter_filter), 203 parameter_filter_(parameter_filter),
203 method_(GET), 204 method_(GET),
204 suggestion_method_(GET), 205 suggestion_method_(GET),
205 is_suggest_url_(false), 206 is_suggest_url_(false),
206 derive_image_from_url_(false) { 207 derive_image_from_url_(false) {
207 if (kElementNameToElementTypeMap == NULL) 208 if (kElementNameToElementTypeMap == NULL)
208 InitMapping(); 209 InitMapping();
209 // When combined with proscriptions elsewhere against updating url_->url_ to 210 // When combined with proscriptions elsewhere against updating data_->url_ to
210 // the empty string, this call ensures url_->url() will never be NULL. 211 // the empty string, this call ensures data_->url() will never be NULL.
211 url_->SetURL("x"); 212 data_.SetURL("x");
212 } 213 }
213 214
214 // static 215 // static
215 void TemplateURLParsingContext::StartElementImpl(void* ctx, 216 void TemplateURLParsingContext::StartElementImpl(void* ctx,
216 const xmlChar* name, 217 const xmlChar* name,
217 const xmlChar** atts) { 218 const xmlChar** atts) {
218 // Remove the namespace from |name|, ex: os:Url -> Url. 219 // Remove the namespace from |name|, ex: os:Url -> Url.
219 std::string node_name(XMLCharToString(name)); 220 std::string node_name(XMLCharToString(name));
220 size_t index = node_name.find_first_of(":"); 221 size_t index = node_name.find_first_of(":");
221 if (index != std::string::npos) 222 if (index != std::string::npos)
(...skipping 20 matching lines...) Expand all
242 } 243 }
243 context->string_.clear(); 244 context->string_.clear();
244 } 245 }
245 246
246 // static 247 // static
247 void TemplateURLParsingContext::EndElementImpl(void* ctx, const xmlChar* name) { 248 void TemplateURLParsingContext::EndElementImpl(void* ctx, const xmlChar* name) {
248 TemplateURLParsingContext* context = 249 TemplateURLParsingContext* context =
249 reinterpret_cast<TemplateURLParsingContext*>(ctx); 250 reinterpret_cast<TemplateURLParsingContext*>(ctx);
250 switch (context->GetKnownType()) { 251 switch (context->GetKnownType()) {
251 case TemplateURLParsingContext::SHORT_NAME: 252 case TemplateURLParsingContext::SHORT_NAME:
252 context->url_->short_name_ = context->string_; 253 context->data_.short_name = context->string_;
253 break; 254 break;
254 case TemplateURLParsingContext::IMAGE: { 255 case TemplateURLParsingContext::IMAGE: {
255 GURL image_url(UTF16ToUTF8(context->string_)); 256 GURL image_url(UTF16ToUTF8(context->string_));
256 if (image_url.SchemeIs(chrome::kDataScheme)) { 257 if (image_url.SchemeIs(chrome::kDataScheme)) {
257 // TODO (jcampan): bug 1169256: when dealing with data URL, we need to 258 // TODO (jcampan): bug 1169256: when dealing with data URL, we need to
258 // decode the data URL in the renderer. For now, we'll just point to the 259 // decode the data URL in the renderer. For now, we'll just point to the
259 // favicon from the URL. 260 // favicon from the URL.
260 context->derive_image_from_url_ = true; 261 context->derive_image_from_url_ = true;
261 } else if (context->image_is_valid_for_favicon_ && image_url.is_valid() && 262 } else if (context->image_is_valid_for_favicon_ && image_url.is_valid() &&
262 (image_url.SchemeIs(chrome::kHttpScheme) || 263 (image_url.SchemeIs(chrome::kHttpScheme) ||
263 image_url.SchemeIs(chrome::kHttpsScheme))) { 264 image_url.SchemeIs(chrome::kHttpsScheme))) {
264 context->url_->set_favicon_url(image_url); 265 context->data_.favicon_url = image_url;
265 } 266 }
266 context->image_is_valid_for_favicon_ = false; 267 context->image_is_valid_for_favicon_ = false;
267 break; 268 break;
268 } 269 }
269 case TemplateURLParsingContext::INPUT_ENCODING: { 270 case TemplateURLParsingContext::INPUT_ENCODING: {
270 std::string input_encoding = UTF16ToASCII(context->string_); 271 std::string input_encoding = UTF16ToASCII(context->string_);
271 if (IsValidEncodingString(input_encoding)) 272 if (IsValidEncodingString(input_encoding))
272 context->url_->input_encodings_.push_back(input_encoding); 273 context->data_.input_encodings.push_back(input_encoding);
273 break; 274 break;
274 } 275 }
275 case TemplateURLParsingContext::URL: 276 case TemplateURLParsingContext::URL:
276 context->ProcessURLParams(); 277 context->ProcessURLParams();
277 break; 278 break;
278 default: 279 default:
279 break; 280 break;
280 } 281 }
281 context->string_.clear(); 282 context->string_.clear();
282 context->elements_.pop_back(); 283 context->elements_.pop_back();
283 } 284 }
284 285
285 // static 286 // static
286 void TemplateURLParsingContext::CharactersImpl(void* ctx, 287 void TemplateURLParsingContext::CharactersImpl(void* ctx,
287 const xmlChar* ch, 288 const xmlChar* ch,
288 int len) { 289 int len) {
289 reinterpret_cast<TemplateURLParsingContext*>(ctx)->string_ += 290 reinterpret_cast<TemplateURLParsingContext*>(ctx)->string_ +=
290 UTF8ToUTF16(std::string(reinterpret_cast<const char*>(ch), len)); 291 UTF8ToUTF16(std::string(reinterpret_cast<const char*>(ch), len));
291 } 292 }
292 293
293 TemplateURL* TemplateURLParsingContext::GetTemplateURL(Profile* profile) { 294 TemplateURL* TemplateURLParsingContext::GetTemplateURL(
295 Profile* profile,
296 bool show_in_default_list) {
294 // Basic legality checks. 297 // Basic legality checks.
295 if (url_->short_name_.empty() || !IsHTTPRef(url_->url()) || 298 if (data_.short_name.empty() || !IsHTTPRef(data_.url()) ||
296 !IsHTTPRef(url_->suggestions_url())) 299 !IsHTTPRef(data_.suggestions_url))
297 return NULL; 300 return NULL;
298 301
299 // If the image was a data URL, use the favicon from the search URL instead. 302 // If the image was a data URL, use the favicon from the search URL instead.
300 // (see TODO inEndElementImpl()). 303 // (see TODO inEndElementImpl()).
301 GURL url(url_->url()); 304 GURL url(data_.url());
302 if (derive_image_from_url_ && url_->favicon_url().is_empty()) 305 if (derive_image_from_url_ && data_.favicon_url.is_empty())
303 url_->set_favicon_url(TemplateURL::GenerateFaviconURL(url)); 306 data_.favicon_url = TemplateURL::GenerateFaviconURL(url);
304 307
305 // TODO(jcampan): http://b/issue?id=1196285 we do not support search engines 308 // TODO(jcampan): http://b/issue?id=1196285 we do not support search engines
306 // that use POST yet. 309 // that use POST yet.
307 if (method_ == TemplateURLParsingContext::POST) 310 if (method_ == TemplateURLParsingContext::POST)
308 return NULL; 311 return NULL;
309 if (suggestion_method_ == TemplateURLParsingContext::POST) 312 if (suggestion_method_ == TemplateURLParsingContext::POST)
310 url_->SetSuggestionsURL(std::string()); 313 data_.suggestions_url.clear();
311 314
312 // Give this a keyword to facilitate tab-to-search. 315 // Give this a keyword to facilitate tab-to-search.
313 string16 keyword(TemplateURLService::GenerateKeyword(url, false)); 316 string16 keyword(TemplateURLService::GenerateKeyword(url, false));
314 DCHECK(!keyword.empty()); 317 DCHECK(!keyword.empty());
315 url_->set_keyword(keyword); 318 data_.SetKeyword(keyword);
316 return url_.release(); 319 data_.show_in_default_list = show_in_default_list;
320 return new TemplateURL(data_);
317 } 321 }
318 322
319 // static 323 // static
320 void TemplateURLParsingContext::InitMapping() { 324 void TemplateURLParsingContext::InitMapping() {
321 kElementNameToElementTypeMap = new std::map<std::string, ElementType>; 325 kElementNameToElementTypeMap = new std::map<std::string, ElementType>;
322 (*kElementNameToElementTypeMap)[kURLElement] = URL; 326 (*kElementNameToElementTypeMap)[kURLElement] = URL;
323 (*kElementNameToElementTypeMap)[kParamElement] = PARAM; 327 (*kElementNameToElementTypeMap)[kParamElement] = PARAM;
324 (*kElementNameToElementTypeMap)[kShortNameElement] = SHORT_NAME; 328 (*kElementNameToElementTypeMap)[kShortNameElement] = SHORT_NAME;
325 (*kElementNameToElementTypeMap)[kImageElement] = IMAGE; 329 (*kElementNameToElementTypeMap)[kImageElement] = IMAGE;
326 (*kElementNameToElementTypeMap)[kOpenSearchDescriptionElement] = 330 (*kElementNameToElementTypeMap)[kOpenSearchDescriptionElement] =
(...skipping 19 matching lines...) Expand all
346 is_html_url = (type == kHTMLType); 350 is_html_url = (type == kHTMLType);
347 is_suggest_url = (type == kSuggestionType); 351 is_suggest_url = (type == kSuggestionType);
348 } else if (name == kURLTemplateAttribute) { 352 } else if (name == kURLTemplateAttribute) {
349 template_url = XMLCharToString(value); 353 template_url = XMLCharToString(value);
350 } else if (name == kParamMethodAttribute) { 354 } else if (name == kParamMethodAttribute) {
351 is_post = LowerCaseEqualsASCII(XMLCharToString(value), "post"); 355 is_post = LowerCaseEqualsASCII(XMLCharToString(value), "post");
352 } 356 }
353 } 357 }
354 358
355 if (is_html_url && !template_url.empty()) { 359 if (is_html_url && !template_url.empty()) {
356 url_->SetURL(template_url); 360 data_.SetURL(template_url);
357 is_suggest_url_ = false; 361 is_suggest_url_ = false;
358 if (is_post) 362 if (is_post)
359 method_ = POST; 363 method_ = POST;
360 } else if (is_suggest_url) { 364 } else if (is_suggest_url) {
361 url_->SetSuggestionsURL(template_url); 365 data_.suggestions_url = template_url;
362 is_suggest_url_ = true; 366 is_suggest_url_ = true;
363 if (is_post) 367 if (is_post)
364 suggestion_method_ = POST; 368 suggestion_method_ = POST;
365 } 369 }
366 } 370 }
367 371
368 void TemplateURLParsingContext::ParseImage(const xmlChar** atts) { 372 void TemplateURLParsingContext::ParseImage(const xmlChar** atts) {
369 if (!atts) 373 if (!atts)
370 return; 374 return;
371 375
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
406 410
407 if (!key.empty() && 411 if (!key.empty() &&
408 (!parameter_filter_ || parameter_filter_->KeepParameter(key, value))) 412 (!parameter_filter_ || parameter_filter_->KeepParameter(key, value)))
409 extra_params_.push_back(Param(key, value)); 413 extra_params_.push_back(Param(key, value));
410 } 414 }
411 415
412 void TemplateURLParsingContext::ProcessURLParams() { 416 void TemplateURLParsingContext::ProcessURLParams() {
413 if (!parameter_filter_ && extra_params_.empty()) 417 if (!parameter_filter_ && extra_params_.empty())
414 return; 418 return;
415 419
416 GURL url(is_suggest_url_ ? url_->suggestions_url() : url_->url()); 420 GURL url(is_suggest_url_ ? data_.suggestions_url : data_.url());
417 if (url.is_empty()) 421 if (url.is_empty())
418 return; 422 return;
419 423
420 // If there is a parameter filter, parse the existing URL and remove any 424 // If there is a parameter filter, parse the existing URL and remove any
421 // unwanted parameter. 425 // unwanted parameter.
422 std::string new_query; 426 std::string new_query;
423 bool modified = false; 427 bool modified = false;
424 if (parameter_filter_) { 428 if (parameter_filter_) {
425 url_parse::Component query = url.parsed_for_possibly_invalid_spec().query; 429 url_parse::Component query = url.parsed_for_possibly_invalid_spec().query;
426 url_parse::Component key, value; 430 url_parse::Component key, value;
(...skipping 17 matching lines...) Expand all
444 for (std::vector<Param>::const_iterator iter(extra_params_.begin()); 448 for (std::vector<Param>::const_iterator iter(extra_params_.begin());
445 iter != extra_params_.end(); ++iter) 449 iter != extra_params_.end(); ++iter)
446 AppendParamToQuery(iter->first, iter->second, &new_query); 450 AppendParamToQuery(iter->first, iter->second, &new_query);
447 } 451 }
448 452
449 if (modified) { 453 if (modified) {
450 GURL::Replacements repl; 454 GURL::Replacements repl;
451 repl.SetQueryStr(new_query); 455 repl.SetQueryStr(new_query);
452 url = url.ReplaceComponents(repl); 456 url = url.ReplaceComponents(repl);
453 if (is_suggest_url_) 457 if (is_suggest_url_)
454 url_->SetSuggestionsURL(url.spec()); 458 data_.suggestions_url = url.spec();
455 else if (url.is_valid()) 459 else if (url.is_valid())
456 url_->SetURL(url.spec()); 460 data_.SetURL(url.spec());
457 } 461 }
458 } 462 }
459 463
460 TemplateURLParsingContext::ElementType 464 TemplateURLParsingContext::ElementType
461 TemplateURLParsingContext::GetKnownType() { 465 TemplateURLParsingContext::GetKnownType() {
462 if (elements_.size() == 2 && elements_[0] == OPEN_SEARCH_DESCRIPTION) 466 if (elements_.size() == 2 && elements_[0] == OPEN_SEARCH_DESCRIPTION)
463 return elements_[1]; 467 return elements_[1];
464 // We only expect PARAM nodes under the URL node. 468 // We only expect PARAM nodes under the URL node.
465 return (elements_.size() == 3 && elements_[0] == OPEN_SEARCH_DESCRIPTION && 469 return (elements_.size() == 3 && elements_[0] == OPEN_SEARCH_DESCRIPTION &&
466 elements_[1] == URL && elements_[2] == PARAM) ? PARAM : UNKNOWN; 470 elements_[1] == URL && elements_[2] == PARAM) ? PARAM : UNKNOWN;
467 } 471 }
468 472
469 473
470 // TemplateURLParser ---------------------------------------------------------- 474 // TemplateURLParser ----------------------------------------------------------
471 475
472 // static 476 // static
473 TemplateURL* TemplateURLParser::Parse( 477 TemplateURL* TemplateURLParser::Parse(
474 Profile* profile, 478 Profile* profile,
479 bool show_in_default_list,
475 const char* data, 480 const char* data,
476 size_t length, 481 size_t length,
477 TemplateURLParser::ParameterFilter* param_filter) { 482 TemplateURLParser::ParameterFilter* param_filter) {
478 // xmlSubstituteEntitiesDefault(1) makes it so that &amp; isn't mapped to 483 // xmlSubstituteEntitiesDefault(1) makes it so that &amp; isn't mapped to
479 // &#38; . Unfortunately xmlSubstituteEntitiesDefault affects global state. 484 // &#38; . Unfortunately xmlSubstituteEntitiesDefault affects global state.
480 // If this becomes problematic we'll need to provide our own entity 485 // If this becomes problematic we'll need to provide our own entity
481 // type for &amp;, or strip out &#38; by hand after parsing. 486 // type for &amp;, or strip out &#38; by hand after parsing.
482 int last_sub_entities_value = xmlSubstituteEntitiesDefault(1); 487 int last_sub_entities_value = xmlSubstituteEntitiesDefault(1);
483 TemplateURLParsingContext context(param_filter); 488 TemplateURLParsingContext context(param_filter);
484 xmlSAXHandler sax_handler; 489 xmlSAXHandler sax_handler;
485 memset(&sax_handler, 0, sizeof(sax_handler)); 490 memset(&sax_handler, 0, sizeof(sax_handler));
486 sax_handler.startElement = &TemplateURLParsingContext::StartElementImpl; 491 sax_handler.startElement = &TemplateURLParsingContext::StartElementImpl;
487 sax_handler.endElement = &TemplateURLParsingContext::EndElementImpl; 492 sax_handler.endElement = &TemplateURLParsingContext::EndElementImpl;
488 sax_handler.characters = &TemplateURLParsingContext::CharactersImpl; 493 sax_handler.characters = &TemplateURLParsingContext::CharactersImpl;
489 xmlSAXUserParseMemory(&sax_handler, &context, data, static_cast<int>(length)); 494 xmlSAXUserParseMemory(&sax_handler, &context, data, static_cast<int>(length));
490 xmlSubstituteEntitiesDefault(last_sub_entities_value); 495 xmlSubstituteEntitiesDefault(last_sub_entities_value);
491 496
492 return context.GetTemplateURL(profile); 497 return context.GetTemplateURL(profile, show_in_default_list);
493 } 498 }
OLDNEW
« no previous file with comments | « chrome/browser/search_engines/template_url_parser.h ('k') | chrome/browser/search_engines/template_url_parser_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698