blob: 6df5654f9d8c6184e868e3bcc90cf669ad966574 [file] [log] [blame]
Avi Drissman4a8573c2022-09-09 19:35:541// Copyright 2012 The Chromium Authors
[email protected]0a3ca082012-10-03 13:39:412// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/ui/bookmarks/bookmark_utils.h"
6
avi655876a2015-12-25 07:18:157#include <stddef.h>
8
Hans Wennborg1790e6b2020-04-24 19:10:339#include "base/check.h"
Caroline Rising5b1ac062021-03-26 15:56:3510#include "base/feature_list.h"
Avi Drissman9269d4ed2023-01-07 01:38:0611#include "base/functional/bind.h"
Ali Hijazie63cbaf62023-12-20 19:29:3512#include "base/memory/raw_ptr.h"
Hans Wennborg1790e6b2020-04-24 19:10:3313#include "base/notreached.h"
Katie De7c84a42020-04-13 16:12:4414#include "base/strings/utf_string_conversions.h"
avi655876a2015-12-25 07:18:1515#include "build/build_config.h"
Monica Bastaa5df4922024-10-14 12:10:1416#include "chrome/browser/bookmarks/bookmark_merged_surface_service.h"
17#include "chrome/browser/bookmarks/bookmark_merged_surface_service_factory.h"
[email protected]345d7d32012-10-03 23:10:1818#include "chrome/browser/bookmarks/bookmark_model_factory.h"
[email protected]345d7d32012-10-03 23:10:1819#include "chrome/browser/profiles/profile.h"
[email protected]62d83ce2013-03-27 18:52:5420#include "chrome/browser/search/search.h"
Pengchao Cai55da3ae02024-03-13 17:27:2621#include "chrome/browser/ui/ui_features.h"
[email protected]03020ff2012-11-29 12:08:1722#include "chrome/common/pref_names.h"
[email protected]a46e9b52013-05-04 14:18:0323#include "chrome/common/url_constants.h"
[email protected]a90c8ca2014-05-20 17:16:0424#include "components/bookmarks/browser/bookmark_model.h"
andresantoso72e58e1e2015-01-07 18:04:3325#include "components/bookmarks/browser/bookmark_node_data.h"
brettwe1f0af8b2015-10-09 21:30:4626#include "components/bookmarks/common/bookmark_pref_names.h"
Monica Bastab49e0af2024-09-27 17:13:4627#include "components/bookmarks/managed/managed_bookmark_service.h"
Katie De7c84a42020-04-13 16:12:4428#include "components/dom_distiller/core/url_constants.h"
29#include "components/dom_distiller/core/url_utils.h"
brettwb1fc1b82016-02-02 00:19:0830#include "components/prefs/pref_service.h"
[email protected]720b10492014-07-23 08:48:4031#include "components/search/search.h"
Side Yilmaz79ae7d72021-10-04 17:38:4832#include "components/strings/grit/components_strings.h"
rsleevi24f64dc22015-08-07 21:39:2133#include "components/url_formatter/url_formatter.h"
[email protected]75fee372013-03-06 00:42:4434#include "components/user_prefs/user_prefs.h"
Elly Fong-Jones60969ec2017-10-05 19:28:1135#include "components/vector_icons/vector_icons.h"
[email protected]0a3ca082012-10-03 13:39:4136#include "content/public/browser/web_contents.h"
andresantoso72e58e1e2015-01-07 18:04:3337#include "ui/base/dragdrop/drag_drop_types.h"
38#include "ui/base/dragdrop/drop_target_event.h"
Henrique Ferreiroaf214ed5b2021-02-12 20:40:0039#include "ui/base/dragdrop/mojom/drag_drop_types.mojom.h"
Side Yilmaz79ae7d72021-10-04 17:38:4840#include "ui/base/l10n/l10n_util.h"
Peter Kastingf81f0d52020-03-11 01:51:0841#include "ui/base/pointer/touch_ui_controller.h"
Shibalik Mohapatra2fc38e12023-06-19 06:04:4342#include "ui/base/ui_base_features.h"
Zoraiz Naeem496356e42025-02-11 02:50:1243#include "ui/color/color_variant.h"
[email protected]0a3ca082012-10-03 13:39:4144
jackhouce97cfa2015-09-04 02:34:4645#if defined(TOOLKIT_VIEWS)
Peter Kasting2a4b9bfb2021-07-10 01:41:5946#include "chrome/grit/theme_resources.h"
47#include "ui/base/resource/resource_bundle.h"
Peter Kasting77b59a82022-03-18 00:06:2748#include "ui/base/themed_vector_icon.h"
Peter Kasting618a92e2021-09-22 16:45:4949#include "ui/color/color_id.h"
50#include "ui/color/color_provider.h"
Peter Kastingb20c69082019-06-27 05:17:1851#include "ui/gfx/canvas.h"
estadebd242032015-10-29 20:16:2252#include "ui/gfx/color_utils.h"
David Sanders03ee601f2022-02-22 02:23:0053#include "ui/gfx/image/image_skia_rep.h"
Peter Kastingb20c69082019-06-27 05:17:1854#include "ui/gfx/image/image_skia_source.h"
estade144150672015-09-01 20:58:3855#include "ui/gfx/paint_vector_icon.h"
Peter Kastingb20c69082019-06-27 05:17:1856#include "ui/gfx/scoped_canvas.h"
Peter Kasting2460a8d62019-06-29 01:46:3557#include "ui/resources/grit/ui_resources.h"
estade876515ed2015-09-08 18:38:3958#endif
59
[email protected]ecb9a2a2012-10-10 14:11:4760namespace chrome {
[email protected]0a3ca082012-10-03 13:39:4161namespace {
62
Henrique Ferreiroaf214ed5b2021-02-12 20:40:0063using ::bookmarks::BookmarkModel;
64using ::bookmarks::BookmarkNode;
65using ::ui::mojom::DragOperation;
Monica Bastaa5df4922024-10-14 12:10:1466using PermanentFolderType = BookmarkParentFolder::PermanentFolderType;
Henrique Ferreiroaf214ed5b2021-02-12 20:40:0067
Peter Kastingb20c69082019-06-27 05:17:1868#if defined(TOOLKIT_VIEWS)
69// Image source that flips the supplied source image in RTL.
70class RTLFlipSource : public gfx::ImageSkiaSource {
71 public:
72 explicit RTLFlipSource(gfx::ImageSkia source) : source_(std::move(source)) {}
73 ~RTLFlipSource() override = default;
74
75 // gfx::ImageSkiaSource:
76 gfx::ImageSkiaRep GetImageForScale(float scale) override {
77 gfx::Canvas canvas(source_.size(), scale, false);
78 gfx::ScopedCanvas scoped_canvas(&canvas);
79 scoped_canvas.FlipIfRTL(source_.width());
80 canvas.DrawImageInt(source_, 0, 0);
81 return gfx::ImageSkiaRep(canvas.GetBitmap(), scale);
82 }
83
84 private:
85 const gfx::ImageSkia source_;
86};
Peter Kastingb20c69082019-06-27 05:17:1887#endif // defined(TOOLKIT_VIEWS)
estade144150672015-09-01 20:58:3888
Monica Bastaa5df4922024-10-14 12:10:1489// Returns true if the `dragged_node` can be dropped on `drop_parent` at
90// `index`. A drop is not allowed on a managed node. A drop from a separate
91// profile or a URL is allowed, where as a drop from the same profile is only
92// allowed if:
93// - The `dragged_node` is not an ancestor of `drop_parent`
94// - The `dragged _node` isn't already a child of `drop_parent` at `index`.
95bool IsValidBookmarkDropLocation(
96 const BookmarkMergedSurfaceService* bookmark_merged_service,
97 const bookmarks::BookmarkNode* dragged_node,
98 bool dragged_from_same_profile,
99 const BookmarkParentFolder& drop_parent,
100 size_t index) {
101 if (bookmark_merged_service->IsParentFolderManaged(drop_parent)) {
102 // Drop on a managed node is not allowed.
103 return false;
104 }
105
106 if (!dragged_from_same_profile) {
107 // If the drop is not on a managed node, always accept if node from another
108 // profile or the user is dragging a URL.
109 // Note: It is expected if the user is dragging a URL
110 // `dragged_from_same_profile` is false as a URL is not associated with a
111 // profile.
112 return true;
113 }
114
115 // `dragged_node` is null if the node is from another profile or the user is
116 // dragging a url. In both cases, `dragged_from_same_profile` is expected to
117 // be false. For dragging a node within the same profile, the `dragged_node`
118 // must be not null.
119 CHECK(dragged_node);
120 CHECK(!dragged_node->is_root());
121 CHECK(!dragged_node->is_permanent_node());
122 // Don't allow the drop if the user is attempting to drop on the node being
123 // dragged.
124 if (drop_parent.HasDirectChildNode(dragged_node)) {
125 // Reordering.
126 size_t node_index = bookmark_merged_service->GetIndexOf(dragged_node);
127 if (index == node_index || index == node_index + 1) {
128 return false;
129 }
130 }
131
132 // drop_parent can't accept a child that is an ancestor.
133 if (drop_parent.HoldsNonPermanentFolder() &&
134 drop_parent.as_non_permanent_folder()->HasAncestor(dragged_node)) {
135 return false;
136 }
137
138 return true;
139}
140
[email protected]ecb9a2a2012-10-10 14:11:47141} // namespace
[email protected]0a3ca082012-10-03 13:39:41142
[email protected]a46e9b52013-05-04 14:18:03143GURL GetURLToBookmark(content::WebContents* web_contents) {
144 DCHECK(web_contents);
Peter Kastinga4863242024-12-23 00:19:43145 if (search::IsInstantNTP(web_contents)) {
Katie De7c84a42020-04-13 16:12:44146 return GURL(kChromeUINewTabURL);
Peter Kastinga4863242024-12-23 00:19:43147 }
Katie De7c84a42020-04-13 16:12:44148 // Users cannot bookmark Reader Mode pages directly, so the bookmark
149 // interaction is as if it were with the original page.
Sharon Yangdb87eea2021-12-23 21:53:18150 if (dom_distiller::url_utils::IsDistilledPage(
151 web_contents->GetVisibleURL())) {
Katie De7c84a42020-04-13 16:12:44152 return dom_distiller::url_utils::GetOriginalUrlFromDistillerUrl(
Sharon Yangdb87eea2021-12-23 21:53:18153 web_contents->GetVisibleURL());
Katie De7c84a42020-04-13 16:12:44154 }
Sharon Yangdb87eea2021-12-23 21:53:18155 return web_contents->GetVisibleURL();
[email protected]a46e9b52013-05-04 14:18:03156}
157
Elly Fong-Jonesba41c892021-04-23 23:17:27158bool GetURLAndTitleToBookmark(content::WebContents* web_contents,
[email protected]ecb9a2a2012-10-10 14:11:47159 GURL* url,
Jan Wilken Dörrie3f97e292021-03-11 18:07:14160 std::u16string* title) {
Elly Fong-Jonesba41c892021-04-23 23:17:27161 GURL u = GetURLToBookmark(web_contents);
Peter Kastinga4863242024-12-23 00:19:43162 if (!u.is_valid()) {
Elly Fong-Jonesba41c892021-04-23 23:17:27163 return false;
Peter Kastinga4863242024-12-23 00:19:43164 }
Elly Fong-Jonesba41c892021-04-23 23:17:27165 *url = u;
Sharon Yangdb87eea2021-12-23 21:53:18166 if (dom_distiller::url_utils::IsDistilledPage(
167 web_contents->GetVisibleURL())) {
Katie De7c84a42020-04-13 16:12:44168 // Users cannot bookmark Reader Mode pages directly. Instead, a bookmark
169 // is added for the original page and original title.
170 *title =
171 base::UTF8ToUTF16(dom_distiller::url_utils::GetTitleFromDistillerUrl(
Sharon Yangdb87eea2021-12-23 21:53:18172 web_contents->GetVisibleURL()));
Katie De7c84a42020-04-13 16:12:44173 } else {
174 *title = web_contents->GetTitle();
175 }
Side Yilmaz79ae7d72021-10-04 17:38:48176
177 // Use "New tab" as title if the current page is NTP even in incognito mode.
Peter Kastinga4863242024-12-23 00:19:43178 if (u == GURL(chrome::kChromeUINewTabURL)) {
Side Yilmaz79ae7d72021-10-04 17:38:48179 *title = l10n_util::GetStringUTF16(IDS_NEW_TAB_TITLE);
Peter Kastinga4863242024-12-23 00:19:43180 }
Side Yilmaz79ae7d72021-10-04 17:38:48181
Elly Fong-Jonesba41c892021-04-23 23:17:27182 return true;
[email protected]ecb9a2a2012-10-10 14:11:47183}
184
[email protected]03020ff2012-11-29 12:08:17185void ToggleBookmarkBarWhenVisible(content::BrowserContext* browser_context) {
[email protected]c7141feb2013-06-11 13:00:16186 PrefService* prefs = user_prefs::UserPrefs::Get(browser_context);
tfarina3bddbe112014-08-28 05:29:32187 const bool always_show =
188 !prefs->GetBoolean(bookmarks::prefs::kShowBookmarkBar);
[email protected]03020ff2012-11-29 12:08:17189
190 // The user changed when the bookmark bar is shown, update the preferences.
tfarina3bddbe112014-08-28 05:29:32191 prefs->SetBoolean(bookmarks::prefs::kShowBookmarkBar, always_show);
[email protected]03020ff2012-11-29 12:08:17192}
193
Jan Wilken Dörrie3f97e292021-03-11 18:07:14194std::u16string FormatBookmarkURLForDisplay(const GURL& url) {
[email protected]998615d92013-01-15 07:49:52195 // Because this gets re-parsed by FixupURL(), it's safe to omit the scheme
elawrencefa34e542016-10-03 18:41:02196 // and trailing slash, and unescape most characters. However, it's
[email protected]998615d92013-01-15 07:49:52197 // important not to drop any username/password, or unescape anything that
198 // changes the URL's meaning.
elawrencefa34e542016-10-03 18:41:02199 url_formatter::FormatUrlTypes format_types =
Christopher Grant91efeb32017-08-10 22:24:35200 url_formatter::kFormatUrlOmitDefaults &
elawrencefa34e542016-10-03 18:41:02201 ~url_formatter::kFormatUrlOmitUsernamePassword;
202
203 // If username is present, we must not omit the scheme because FixupURL() will
204 // subsequently interpret the username as a scheme. crbug.com/639126
Peter Kastinga4863242024-12-23 00:19:43205 if (url.has_username()) {
elawrencefa34e542016-10-03 18:41:02206 format_types &= ~url_formatter::kFormatUrlOmitHTTP;
Peter Kastinga4863242024-12-23 00:19:43207 }
elawrencefa34e542016-10-03 18:41:02208
Ryan Hamilton7f3bd3d2022-04-23 00:07:39209 return url_formatter::FormatUrl(url, format_types, base::UnescapeRule::SPACES,
elawrencefa34e542016-10-03 18:41:02210 nullptr, nullptr, nullptr);
[email protected]998615d92013-01-15 07:49:52211}
212
scottmgcf186a32016-02-17 05:26:55213bool IsAppsShortcutEnabled(Profile* profile) {
Eric Willigers67edc4442022-03-08 22:09:01214#if BUILDFLAG(IS_CHROMEOS)
James Cookf9d34d22017-10-04 16:39:35215 // Chrome OS uses the app list / app launcher.
scottmgcf186a32016-02-17 05:26:55216 return false;
217#else
sdefresne51bbec7b2015-08-03 14:18:13218 return search::IsInstantExtendedAPIEnabled() && !profile->IsOffTheRecord();
scottmgcf186a32016-02-17 05:26:55219#endif
[email protected]4a0f0502013-11-20 05:33:21220}
221
scottmgcf186a32016-02-17 05:26:55222bool ShouldShowAppsShortcutInBookmarkBar(Profile* profile) {
223 return IsAppsShortcutEnabled(profile) &&
tfarina3bddbe112014-08-28 05:29:32224 profile->GetPrefs()->GetBoolean(
225 bookmarks::prefs::kShowAppsShortcutInBookmarkBar);
[email protected]62d83ce2013-03-27 18:52:54226}
227
Pengchao Cai55da3ae02024-03-13 17:27:26228bool ShouldShowTabGroupsInBookmarkBar(Profile* profile) {
229 return profile->GetPrefs()->GetBoolean(
230 bookmarks::prefs::kShowTabGroupsInBookmarkBar);
231}
232
andresantoso72e58e1e2015-01-07 18:04:33233int GetBookmarkDragOperation(content::BrowserContext* browser_context,
234 const BookmarkNode* node) {
235 PrefService* prefs = user_prefs::UserPrefs::Get(browser_context);
pke3e0d5c92016-08-08 09:07:30236 BookmarkModel* model =
237 BookmarkModelFactory::GetForBrowserContext(browser_context);
andresantoso72e58e1e2015-01-07 18:04:33238
239 int move = ui::DragDropTypes::DRAG_MOVE;
240 if (!prefs->GetBoolean(bookmarks::prefs::kEditBookmarksEnabled) ||
Mikel Astizc4d80652023-09-21 15:08:43241 model->client()->IsNodeManaged(node)) {
andresantoso72e58e1e2015-01-07 18:04:33242 move = ui::DragDropTypes::DRAG_NONE;
243 }
Peter Kastinga4863242024-12-23 00:19:43244 if (node->is_url()) {
andresantoso72e58e1e2015-01-07 18:04:33245 return ui::DragDropTypes::DRAG_COPY | ui::DragDropTypes::DRAG_LINK | move;
Peter Kastinga4863242024-12-23 00:19:43246 }
andresantoso72e58e1e2015-01-07 18:04:33247 return ui::DragDropTypes::DRAG_COPY | move;
248}
249
Henrique Ferreiroaf214ed5b2021-02-12 20:40:00250DragOperation GetPreferredBookmarkDropOperation(int source_operations,
251 int operations) {
andresantoso72e58e1e2015-01-07 18:04:33252 int common_ops = (source_operations & operations);
Peter Kastinga4863242024-12-23 00:19:43253 if (!common_ops) {
Henrique Ferreiroaf214ed5b2021-02-12 20:40:00254 return DragOperation::kNone;
Peter Kastinga4863242024-12-23 00:19:43255 }
256 if (ui::DragDropTypes::DRAG_COPY & common_ops) {
Henrique Ferreiroaf214ed5b2021-02-12 20:40:00257 return DragOperation::kCopy;
Peter Kastinga4863242024-12-23 00:19:43258 }
259 if (ui::DragDropTypes::DRAG_LINK & common_ops) {
Henrique Ferreiroaf214ed5b2021-02-12 20:40:00260 return DragOperation::kLink;
Peter Kastinga4863242024-12-23 00:19:43261 }
262 if (ui::DragDropTypes::DRAG_MOVE & common_ops) {
Henrique Ferreiroaf214ed5b2021-02-12 20:40:00263 return DragOperation::kMove;
Peter Kastinga4863242024-12-23 00:19:43264 }
Henrique Ferreiroaf214ed5b2021-02-12 20:40:00265 return DragOperation::kNone;
andresantoso72e58e1e2015-01-07 18:04:33266}
267
Henrique Ferreiroaf214ed5b2021-02-12 20:40:00268DragOperation GetBookmarkDropOperation(Profile* profile,
269 const ui::DropTargetEvent& event,
270 const bookmarks::BookmarkNodeData& data,
Monica Bastaa5df4922024-10-14 12:10:14271 const BookmarkParentFolder& parent,
Henrique Ferreiroaf214ed5b2021-02-12 20:40:00272 size_t index) {
Monica Bastaa5df4922024-10-14 12:10:14273 if (data.size() != 1) {
274 // Currently only accept one dragged element (bookmark node/url) at a time.
Henrique Ferreiroaf214ed5b2021-02-12 20:40:00275 return DragOperation::kNone;
Mikel Astizc4d80652023-09-21 15:08:43276 }
andresantoso72e58e1e2015-01-07 18:04:33277
Monica Bastaa5df4922024-10-14 12:10:14278 BookmarkMergedSurfaceService* const bookmark_merged_service =
279 BookmarkMergedSurfaceServiceFactory::GetForProfile(profile);
280 const BookmarkNode* const dragged_node = data.GetFirstNode(
281 bookmark_merged_service->bookmark_model(), profile->GetPath());
282 if (!IsValidBookmarkDropLocation(bookmark_merged_service, dragged_node,
283 data.IsFromProfilePath(profile->GetPath()),
284 parent, index)) {
285 return DragOperation::kNone;
286 }
287
andresantoso72e58e1e2015-01-07 18:04:33288 if (dragged_node) {
289 // User is dragging from this profile.
Monica Bastaa5df4922024-10-14 12:10:14290 if (bookmark_merged_service->IsNodeManaged(dragged_node)) {
andresantoso72e58e1e2015-01-07 18:04:33291 // Do a copy instead of a move when dragging bookmarks that the user can't
292 // modify.
Henrique Ferreiroaf214ed5b2021-02-12 20:40:00293 return DragOperation::kCopy;
andresantoso72e58e1e2015-01-07 18:04:33294 }
Henrique Ferreiroaf214ed5b2021-02-12 20:40:00295 return DragOperation::kMove;
andresantoso72e58e1e2015-01-07 18:04:33296 }
297
298 // User is dragging from another app, copy.
Monica Bastaa5df4922024-10-14 12:10:14299 return GetPreferredBookmarkDropOperation(
300 event.source_operations(),
andresantoso72e58e1e2015-01-07 18:04:33301 ui::DragDropTypes::DRAG_COPY | ui::DragDropTypes::DRAG_LINK);
302}
303
Monica Bastab49e0af2024-09-27 17:13:46304bool CanAllBeEditedByUser(
305 bookmarks::ManagedBookmarkService* managed_bookmark_service,
306 const std::vector<
307 raw_ptr<const bookmarks::BookmarkNode, VectorExperimental>>& nodes) {
308 if (!managed_bookmark_service) {
309 return true;
310 }
311
312 for (const bookmarks::BookmarkNode* node : nodes) {
313 if (managed_bookmark_service->IsNodeManaged(node)) {
314 return false;
315 }
316 }
317 return true;
318}
319
jackhouce97cfa2015-09-04 02:34:46320#if defined(TOOLKIT_VIEWS)
Shibalik Mohapatrabb097822023-06-26 18:10:17321
322gfx::ImageSkia GetBookmarkFolderImageFromVectorIcon(
323 BookmarkFolderIconType icon_type,
Zoraiz Naeem496356e42025-02-11 02:50:12324 ui::ColorVariant color,
Shibalik Mohapatrabb097822023-06-26 18:10:17325 const ui::ColorProvider* color_provider) {
326 const gfx::VectorIcon* id;
327 gfx::ImageSkia folder;
328 if (icon_type == BookmarkFolderIconType::kNormal) {
Alison Gale4828f80e2024-05-16 17:24:42329 id = &vector_icons::kFolderChromeRefreshIcon;
Shibalik Mohapatrabb097822023-06-26 18:10:17330 } else {
Alison Gale4828f80e2024-05-16 17:24:42331 id = &vector_icons::kFolderManagedRefreshIcon;
Shibalik Mohapatrabb097822023-06-26 18:10:17332 }
Zoraiz Naeem496356e42025-02-11 02:50:12333
Zoraiz Naeemcd4d6a82025-03-19 18:28:18334 const ui::ThemedVectorIcon icon(id, color);
Shibalik Mohapatrabb097822023-06-26 18:10:17335 folder = icon.GetImageSkia(color_provider);
336 return folder;
337}
338
Zoraiz Naeem496356e42025-02-11 02:50:12339ui::ImageModel GetBookmarkFolderIcon(BookmarkFolderIconType icon_type,
340 ui::ColorVariant color) {
Peter Kasting2a4b9bfb2021-07-10 01:41:59341 int default_id = IDR_FOLDER_CLOSED;
Xiaohan Wange9439fd2022-01-18 21:00:31342#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
Peter Kasting2a4b9bfb2021-07-10 01:41:59343 // This block must be #ifdefed because only these platforms actually have this
344 // resource ID.
Monica Bastaa5df4922024-10-14 12:10:14345 if (icon_type == BookmarkFolderIconType::kManaged) {
Peter Kasting2a4b9bfb2021-07-10 01:41:59346 default_id = IDR_BOOKMARK_BAR_FOLDER_MANAGED;
Monica Bastaa5df4922024-10-14 12:10:14347 }
estade055a5522016-08-05 21:45:24348#endif
Peter Kasting2a4b9bfb2021-07-10 01:41:59349 const auto generator = [](int default_id, BookmarkFolderIconType icon_type,
Zoraiz Naeem496356e42025-02-11 02:50:12350 ui::ColorVariant color,
Peter Kasting618a92e2021-09-22 16:45:49351 const ui::ColorProvider* color_provider) {
Peter Kasting2a4b9bfb2021-07-10 01:41:59352 gfx::ImageSkia folder;
Alison Gale4828f80e2024-05-16 17:24:42353 folder =
354 GetBookmarkFolderImageFromVectorIcon(icon_type, color, color_provider);
Peter Kasting2a4b9bfb2021-07-10 01:41:59355 return gfx::ImageSkia(std::make_unique<RTLFlipSource>(folder),
356 folder.size());
357 };
358 const gfx::Size size =
359 ui::ResourceBundle::GetSharedInstance().GetImageNamed(default_id).Size();
360 return ui::ImageModel::FromImageGenerator(
361 base::BindRepeating(generator, default_id, icon_type, std::move(color)),
362 size);
estade144150672015-09-01 20:58:38363}
364#endif
365
[email protected]0a3ca082012-10-03 13:39:41366} // namespace chrome