diff options
author | mpcomplete@chromium.org <mpcomplete@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-28 17:45:33 +0000 |
---|---|---|
committer | mpcomplete@chromium.org <mpcomplete@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-28 17:45:33 +0000 |
commit | 56ad3797dc8ea7d757dc2b12d606c14cedd564e1 (patch) | |
tree | 26fab7c6d4cbb0358b404ca3eb488aae75ebe1d3 /chrome/browser/search_engines | |
parent | 79b663c6e6ddf89e85cdc566b5d4f368465bb858 (diff) | |
download | chromium_src-56ad3797dc8ea7d757dc2b12d606c14cedd564e1.zip chromium_src-56ad3797dc8ea7d757dc2b12d606c14cedd564e1.tar.gz chromium_src-56ad3797dc8ea7d757dc2b12d606c14cedd564e1.tar.bz2 |
First pass at experimental omnibox API. There are plenty of rough edges and features to work on, but it's in a usable state.
When an extension is installed that specifies an omnibox keyword in its manifest, we add that keyword to the user's list of Search Engines. The user can then edit this keyword later.
I'm leveraging most of the original search engine keyword code. An extension keyword has a special URL that identifies it as an extension keyword. There is some special case code to treat these keywords slightly differently throughout
the omnibox code.
BUG=38884
Review URL: http://codereview.chromium.org/2078021
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@48503 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/search_engines')
-rw-r--r-- | chrome/browser/search_engines/template_url.cc | 12 | ||||
-rw-r--r-- | chrome/browser/search_engines/template_url.h | 5 | ||||
-rw-r--r-- | chrome/browser/search_engines/template_url_model.cc | 82 | ||||
-rw-r--r-- | chrome/browser/search_engines/template_url_model.h | 26 | ||||
-rw-r--r-- | chrome/browser/search_engines/template_url_table_model.cc | 3 |
5 files changed, 116 insertions, 12 deletions
diff --git a/chrome/browser/search_engines/template_url.cc b/chrome/browser/search_engines/template_url.cc index d91bce9..f069a8e 100644 --- a/chrome/browser/search_engines/template_url.cc +++ b/chrome/browser/search_engines/template_url.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -12,6 +12,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/google_url_tracker.h" #include "chrome/browser/search_engines/template_url_model.h" +#include "chrome/common/url_constants.h" #include "gfx/favicon_size.h" #include "net/base/escape.h" @@ -621,3 +622,12 @@ void TemplateURL::InvalidateCachedValues() const { keyword_generated_ = false; } } + +std::string TemplateURL::GetExtensionId() const { + DCHECK(IsExtensionKeyword()); + return GURL(WideToUTF8(url_.url())).host(); +} + +bool TemplateURL::IsExtensionKeyword() const { + return GURL(WideToUTF8(url_.url())).SchemeIs(chrome::kExtensionScheme); +} diff --git a/chrome/browser/search_engines/template_url.h b/chrome/browser/search_engines/template_url.h index 1a7d779..40561ac 100644 --- a/chrome/browser/search_engines/template_url.h +++ b/chrome/browser/search_engines/template_url.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -421,6 +421,9 @@ class TemplateURL { void set_prepopulate_id(int id) { prepopulate_id_ = id; } int prepopulate_id() const { return prepopulate_id_; } + std::string GetExtensionId() const; + bool IsExtensionKeyword() const; + private: friend class WebDatabaseTest; friend class WebDatabase; diff --git a/chrome/browser/search_engines/template_url_model.cc b/chrome/browser/search_engines/template_url_model.cc index 8ad9cfe..c30a3f9 100644 --- a/chrome/browser/search_engines/template_url_model.cc +++ b/chrome/browser/search_engines/template_url_model.cc @@ -1,13 +1,13 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/browser/search_engines/template_url_model.h" - #include "app/l10n_util.h" #include "base/stl_util-inl.h" #include "base/utf_string_conversions.h" +#include "chrome/browser/extensions/extensions_service.h" #include "chrome/browser/google_url_tracker.h" #include "chrome/browser/history/history.h" #include "chrome/browser/history/history_notifications.h" @@ -16,6 +16,7 @@ #include "chrome/browser/profile.h" #include "chrome/browser/rlz/rlz.h" #include "chrome/browser/search_engines/template_url_prepopulate_data.h" +#include "chrome/common/extensions/extension.h" #include "chrome/common/notification_service.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" @@ -184,7 +185,8 @@ std::wstring TemplateURLModel::CleanUserInputKeyword( GURL TemplateURLModel::GenerateSearchURL(const TemplateURL* t_url) { DCHECK(t_url); const TemplateURLRef* search_ref = t_url->url(); - if (!search_ref || !search_ref->IsValid()) + // Extension keywords don't have host-based search URLs. + if (!search_ref || !search_ref->IsValid() || t_url->IsExtensionKeyword()) return GURL(); if (!search_ref->SupportsReplacement()) @@ -433,17 +435,13 @@ void TemplateURLModel::RemoveFromMapsByPointer( void TemplateURLModel::SetTemplateURLs( const std::vector<const TemplateURL*>& urls) { - DCHECK(template_urls_.empty()); // This should only be called on load, - // when we have no TemplateURLs. - // Add mappings for the new items. for (TemplateURLVector::const_iterator i = urls.begin(); i != urls.end(); ++i) { next_id_ = std::max(next_id_, (*i)->id()); AddToMaps(*i); + template_urls_.push_back(*i); } - - template_urls_ = urls; } std::vector<const TemplateURL*> TemplateURLModel::GetTemplateURLs() const { @@ -674,6 +672,20 @@ void TemplateURLModel::RemoveDuplicatePrepopulateIDs( } } +std::wstring TemplateURLModel::GetKeywordShortName(const std::wstring& keyword, + bool* is_extension_keyword) { + const TemplateURL* template_url = GetTemplateURLForKeyword(keyword); + + // TODO(sky): Once LocationBarView adds a listener to the TemplateURLModel + // to track changes to the model, this should become a DCHECK. + if (template_url) { + *is_extension_keyword = template_url->IsExtensionKeyword(); + return template_url->AdjustedShortNameForLocaleDirection(); + } + *is_extension_keyword = false; + return std::wstring(); +} + void TemplateURLModel::Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details) { @@ -711,6 +723,14 @@ void TemplateURLModel::NotifyLoaded() { NotificationType::TEMPLATE_URL_MODEL_LOADED, Source<TemplateURLModel>(this), NotificationService::NoDetails()); + + for (size_t i = 0; i < pending_extension_ids_.size(); ++i) { + Extension* extension = profile_->GetExtensionsService()-> + GetExtensionById(pending_extension_ids_[i], true); + if (extension) + RegisterExtensionKeyword(extension); + } + pending_extension_ids_.clear(); } void TemplateURLModel::MergeEnginesFromPrepopulateData() { @@ -1036,3 +1056,49 @@ void TemplateURLModel::GoogleBaseURLChanged() { OnTemplateURLModelChanged()); } } + +void TemplateURLModel::RegisterExtensionKeyword(Extension* extension) { + // TODO(mpcomplete): disable the keyword when the extension is disabled. + if (extension->omnibox_keyword().empty()) + return; + + Load(); + if (!loaded_) { + pending_extension_ids_.push_back(extension->id()); + return; + } + + if (GetTemplateURLForExtension(extension)) + return; // Already have this one registered (might be an upgrade). + + std::wstring keyword = UTF8ToWide(extension->omnibox_keyword()); + + TemplateURL* template_url = new TemplateURL; + template_url->set_short_name(UTF8ToWide(extension->name())); + template_url->set_keyword(keyword); + // This URL is not actually used for navigation. It holds the extension's + // ID, as well as forcing the TemplateURL to be treated as a search keyword. + template_url->SetURL( + UTF8ToWide(chrome::kExtensionScheme) + L"://" + + UTF8ToWide(extension->id()) + L"/?q={searchTerms}", 0, 0); + template_url->set_safe_for_autoreplace(false); + + Add(template_url); +} + +void TemplateURLModel::UnregisterExtensionKeyword(Extension* extension) { + const TemplateURL* url = GetTemplateURLForExtension(extension); + if (url) + Remove(url); +} + +const TemplateURL* TemplateURLModel::GetTemplateURLForExtension( + Extension* extension) const { + for (TemplateURLVector::const_iterator i = template_urls_.begin(); + i != template_urls_.end(); ++i) { + if ((*i)->IsExtensionKeyword() && (*i)->url()->GetHost() == extension->id()) + return *i; + } + + return NULL; +} diff --git a/chrome/browser/search_engines/template_url_model.h b/chrome/browser/search_engines/template_url_model.h index 5b76234..8bab7cb 100644 --- a/chrome/browser/search_engines/template_url_model.h +++ b/chrome/browser/search_engines/template_url_model.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -13,6 +13,7 @@ #include "chrome/common/notification_registrar.h" #include "testing/gtest/include/gtest/gtest_prod.h" +class Extension; class PrefService; class Profile; @@ -136,6 +137,20 @@ class TemplateURLModel : public WebDataServiceConsumer, // date passed in. void RemoveAutoGeneratedSince(base::Time created_after); + // If the given extension has an omnibox keyword, adds a TemplateURL for that + // keyword. Only 1 keyword is allowed for a given extension. If the keyword + // already exists for this extension, does nothing. + void RegisterExtensionKeyword(Extension* extension); + + // Removes the TemplateURL containing the keyword for the given extension, + // if any. + void UnregisterExtensionKeyword(Extension* extension); + + // Returns the TemplateURL associated with the keyword for this extension. + // This works by checking the extension ID, not the keyword, so it will work + // even if the user changed the keyword. + const TemplateURL* GetTemplateURLForExtension(Extension* extension) const; + // Returns the set of URLs describing the keywords. The elements are owned // by TemplateURLModel and should not be deleted. std::vector<const TemplateURL*> GetTemplateURLs() const; @@ -186,6 +201,12 @@ class TemplateURLModel : public WebDataServiceConsumer, // number changes. void RemoveDuplicatePrepopulateIDs(std::vector<const TemplateURL*>* urls); + // Returns the locale-direction-adjusted short name for the given keyword. + // Also sets the out param to indicate whether the keyword belongs to an + // extension. + std::wstring GetKeywordShortName(const std::wstring& keyword, + bool* is_extension_keyword); + // NotificationObserver method. TemplateURLModel listens for three // notification types: // . NOTIFY_HISTORY_URL_VISITED: adds keyword search terms if the visit @@ -351,6 +372,9 @@ class TemplateURLModel : public WebDataServiceConsumer, // increasing integer that is initialized from the database. TemplateURL::IDType next_id_; + // List of extension IDs waiting for Load to have keywords registered. + std::vector<std::string> pending_extension_ids_; + DISALLOW_EVIL_CONSTRUCTORS(TemplateURLModel); }; diff --git a/chrome/browser/search_engines/template_url_table_model.cc b/chrome/browser/search_engines/template_url_table_model.cc index dcad47e..653cf7e 100644 --- a/chrome/browser/search_engines/template_url_table_model.cc +++ b/chrome/browser/search_engines/template_url_table_model.cc @@ -159,7 +159,8 @@ void TemplateURLTableModel::Reload() { const TemplateURL* template_url = *i; // NOTE: we don't use ShowInDefaultList here to avoid things bouncing // the lists while editing. - if (!template_url->show_in_default_list()) + if (!template_url->show_in_default_list() && + !template_url->IsExtensionKeyword()) entries_.push_back(new ModelEntry(this, *template_url)); } |