Commit c33ab0fb authored by Leonard Grey's avatar Leonard Grey Committed by Commit Bot

Commander: bookmark command source

Adds commands for opening bookmarks:
- A composite command labeled "Open Bookmarks..." that allows searching
bookmarks when selected.
- If user input is "long enough" (currently two characters, will be
tuned), "noun first" bookmarks will begin to surface at top level.

Bug: 1014639
Change-Id: I910e9ba4992e7705cce2f8c5e23104c8ba6f408e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2535677Reviewed-by: default avatarAvi Drissman <avi@chromium.org>
Commit-Queue: Leonard Grey <lgrey@chromium.org>
Cr-Commit-Position: refs/heads/master@{#827378}
parent 62767f8a
<iron-iconset-svg name="commander-icons" size="24">
<svg>
<defs>
<!-- copied from
components/neterror/resources/images/generic-globe.svg -->
<g id="bookmark"><path d="M12 2c5.52 0 10 4.48 10 10s-4.48 10-10 10S2 17.52 2 12 6.48 2 12 2zM4 12h4.4c3.407.022 4.922 1.73 4.543 5.127H9.488v2.47a8.004 8.004 0 0 0 10.498-8.083C19.327 12.504 18.332 13 17 13c-2.137 0-3.206-.916-3.206-2.75h-3.748c-.274-2.728.683-4.092 2.87-4.092 0-.975.327-1.597.811-1.97A8.004 8.004 0 0 0 4 12z"></path></g>
<!-- from MD icons-->
<g id="chrome"><path d="M12 7.5h8.9C19.3 4.2 15.9 2 12 2 8.9 2 6.1 3.4 4.3 5.6l3.3 5.7c.3-2.1 2.2-3.8 4.4-3.8zm0 9c-1.7 0-3.1-.9-3.9-2.3L3.6 6.5C2.6 8.1 2 10 2 12c0 5 3.6 9.1 8.4 9.9l3.3-5.7c-.6.2-1.1.3-1.7.3zm4.5-4.5c0 .8-.2 1.6-.6 2.2L11.4 22h.6c5.5 0 10-4.5 10-10 0-1.2-.2-2.4-.6-3.5h-6.6c1 .8 1.7 2.1 1.7 3.5z"></path><circle cx="12" cy="12" r="3.5"></circle></g>
<g id="tab"><path d="M0 0h24v24H0V0zm0 0h24v24H0V0z" fill="none"></path><path d="M21 3H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H3V5h10v4h8v10z"></path></g>
......
......@@ -42,9 +42,9 @@ export class CommanderOptionElement extends PolymerElement {
computeIcon_() {
switch (this.model.entity) {
case Entity.COMMAND:
// TODO(lgrey): Need a vector of this. Using generic for now.
case Entity.BOOKMARK:
return 'commander-icons:chrome';
case Entity.BOOKMARK:
return 'commander-icons:bookmark';
case Entity.TAB:
return 'commander-icons:tab';
case Entity.WINDOW:
......
......@@ -910,6 +910,8 @@ static_library("ui") {
"collected_cookies_infobar_delegate.h",
"commander/apps_command_source.cc",
"commander/apps_command_source.h",
"commander/bookmark_command_source.cc",
"commander/bookmark_command_source.h",
"commander/command_source.cc",
"commander/command_source.h",
"commander/commander.cc",
......
// Copyright 2020 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/ui/commander/bookmark_command_source.h"
#include "base/i18n/case_conversion.h"
#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/bookmarks/bookmark_model_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_tabstrip.h"
#include "chrome/browser/ui/commander/commander_backend.h"
#include "chrome/browser/ui/commander/commander_view_model.h"
#include "chrome/browser/ui/commander/fuzzy_finder.h"
#include "components/bookmarks/browser/bookmark_model.h"
#include "components/bookmarks/browser/url_and_title.h"
namespace commander {
namespace {
// The minimum size the input should have before the source returns commands to
// open specific bookmarks without the user choosing "Open Bookmark..." first.
// TODO(lgrey): Centralize this constant when more composite commands are added.
size_t constexpr kNounFirstMinimum = 2;
std::unique_ptr<CommandItem> CreateOpenBookmarkItem(
const bookmarks::UrlAndTitle& bookmark,
Browser* browser) {
auto item = std::make_unique<CommandItem>();
item->title = bookmark.title;
item->entity_type = CommandItem::Entity::kBookmark;
// base::Unretained is safe because commands are reset when a browser is
// closed.
item->command = base::BindOnce(&chrome::AddTabAt, base::Unretained(browser),
GURL(bookmark.url), -1, true, base::nullopt);
return item;
}
CommandSource::CommandResults GetMatchingBookmarks(
Browser* browser,
const base::string16& input) {
CommandSource::CommandResults results;
bookmarks::BookmarkModel* model =
BookmarkModelFactory::GetForBrowserContext(browser->profile());
// This should have been checked already.
DCHECK(model && model->loaded());
std::vector<bookmarks::UrlAndTitle> bookmarks;
model->GetBookmarks(&bookmarks);
const base::string16& folded_input = base::i18n::FoldCase(input);
std::vector<gfx::Range> ranges;
for (bookmarks::UrlAndTitle& bookmark : bookmarks) {
double score = FuzzyFind(folded_input, bookmark.title, &ranges);
if (score > 0) {
auto item = CreateOpenBookmarkItem(bookmark, browser);
item->score = score;
item->matched_ranges = ranges;
results.push_back(std::move(item));
}
}
return results;
}
} // namespace
BookmarkCommandSource::BookmarkCommandSource() = default;
BookmarkCommandSource::~BookmarkCommandSource() = default;
CommandSource::CommandResults BookmarkCommandSource::GetCommands(
const base::string16& input,
Browser* browser) const {
CommandSource::CommandResults results;
bookmarks::BookmarkModel* model =
BookmarkModelFactory::GetForBrowserContext(browser->profile());
// Just no-op instead of waiting for the model to load, since this isn't
// a persistent UI surface and they can just try again.
if (!model || !model->loaded() || !model->HasBookmarks())
return results;
if (input.size() >= kNounFirstMinimum) {
results = GetMatchingBookmarks(browser, input);
}
const base::string16& folded_input = base::i18n::FoldCase(input);
std::vector<gfx::Range> ranges;
// TODO(lgrey): Temporarily using an untranslated string since it's not
// yet clear which commands will ship.
base::string16 open_title = base::ASCIIToUTF16("Open bookmark...");
double score = FuzzyFind(folded_input, open_title, &ranges);
if (score > 0) {
auto verb = std::make_unique<CommandItem>();
verb->title = open_title;
verb->score = score;
verb->matched_ranges = ranges;
// base::Unretained is safe because commands are cleared on browser close.
verb->command = std::make_pair(
open_title,
base::BindRepeating(&GetMatchingBookmarks, base::Unretained(browser)));
results.push_back(std::move(verb));
}
return results;
}
} // namespace commander
// Copyright 2020 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.
#ifndef CHROME_BROWSER_UI_COMMANDER_BOOKMARK_COMMAND_SOURCE_H_
#define CHROME_BROWSER_UI_COMMANDER_BOOKMARK_COMMAND_SOURCE_H_
#include "chrome/browser/ui/commander/command_source.h"
namespace commander {
// Provides an "Open Bookmark..." composite command which lets the user
// search for a bookmark to open. If the user has typed a minimum threshold
// of characters, this will also return matching individual bookmark commands
// directly.
class BookmarkCommandSource : public CommandSource {
public:
BookmarkCommandSource();
~BookmarkCommandSource() override;
BookmarkCommandSource(const BookmarkCommandSource& other) = delete;
BookmarkCommandSource& operator=(const BookmarkCommandSource& other) = delete;
// Command source overrides
CommandSource::CommandResults GetCommands(const base::string16& input,
Browser* browser) const override;
};
} // namespace commander
#endif // CHROME_BROWSER_UI_COMMANDER_BOOKMARK_COMMAND_SOURCE_H_
......@@ -8,6 +8,7 @@
#include "build/branding_buildflags.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/commander/apps_command_source.h"
#include "chrome/browser/ui/commander/bookmark_command_source.h"
#include "chrome/browser/ui/commander/commander_view_model.h"
#include "chrome/browser/ui/commander/simple_command_source.h"
#include "third_party/abseil-cpp/absl/types/variant.h"
......@@ -24,6 +25,7 @@ CommanderController::CommandSources CreateDefaultSources() {
#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
sources.push_back(std::make_unique<AppsCommandSource>());
#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING)
sources.push_back(std::make_unique<BookmarkCommandSource>());
return sources;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment