798 lines
38 KiB
Diff
798 lines
38 KiB
Diff
From: csagan5 <32685696+csagan5@users.noreply.github.com>
|
|
Date: Thu, 18 Feb 2021 21:22:52 +0100
|
|
Subject: Add menu item to bookmark all tabs
|
|
|
|
License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html
|
|
---
|
|
chrome/android/java/res/menu/main_menu.xml | 7 ++
|
|
.../chrome/browser/ChromeTabbedActivity.java | 24 +++++++
|
|
.../browser/bookmarks/BookmarkBridge.java | 67 +++++++++++++++++++
|
|
.../bookmarks/android/bookmark_bridge.cc | 44 ++++++++++++
|
|
.../bookmarks/android/bookmark_bridge.h | 8 +++
|
|
.../browser/bookmarks/bookmark_html_writer.cc | 11 ++-
|
|
.../dialogs/DownloadLocationCustomView.java | 4 +-
|
|
.../strings/android_chrome_strings.grd | 3 +
|
|
components/bookmark_bar_strings.grdp | 6 ++
|
|
.../bookmarks/browser/bookmark_codec.cc | 20 +++++-
|
|
components/bookmarks/browser/bookmark_codec.h | 7 +-
|
|
.../browser/bookmark_load_details.cc | 8 ++-
|
|
.../bookmarks/browser/bookmark_load_details.h | 2 +
|
|
.../bookmarks/browser/bookmark_model.cc | 3 +-
|
|
components/bookmarks/browser/bookmark_model.h | 7 ++
|
|
components/bookmarks/browser/bookmark_node.cc | 11 +++
|
|
components/bookmarks/browser/bookmark_node.h | 3 +
|
|
.../bookmarks/browser/bookmark_storage.cc | 2 +
|
|
.../bookmarks/browser/bookmark_uuids.cc | 3 +
|
|
components/bookmarks/browser/bookmark_uuids.h | 1 +
|
|
components/bookmarks/browser/model_loader.cc | 8 ++-
|
|
.../bookmark_specifics_conversions.cc | 1 +
|
|
22 files changed, 236 insertions(+), 14 deletions(-)
|
|
|
|
diff --git a/chrome/android/java/res/menu/main_menu.xml b/chrome/android/java/res/menu/main_menu.xml
|
|
--- a/chrome/android/java/res/menu/main_menu.xml
|
|
+++ b/chrome/android/java/res/menu/main_menu.xml
|
|
@@ -71,6 +71,10 @@ found in the LICENSE file.
|
|
<item android:id="@+id/all_bookmarks_menu_id"
|
|
android:title="@string/menu_bookmarks"
|
|
android:icon="@drawable/btn_star_filled" />
|
|
+ <item android:id="@+id/bookmark_all_tabs_menu_id"
|
|
+ android:title="@string/menu_bookmark_all_tabs"
|
|
+ android:titleCondensed="@string/menu_bookmark_all_tabs"
|
|
+ android:icon="@drawable/ic_folder_blue_24dp" />
|
|
<item android:id="@+id/recent_tabs_menu_id"
|
|
android:title="@string/menu_recent_tabs"
|
|
android:icon="@drawable/devices_black_24dp" />
|
|
@@ -186,6 +190,9 @@ found in the LICENSE file.
|
|
<item android:id="@+id/close_all_incognito_tabs_menu_id"
|
|
android:title="@string/menu_close_all_incognito_tabs"
|
|
android:icon="@drawable/btn_close_white" />
|
|
+ <item android:id="@+id/bookmark_all_tabs_menu_id"
|
|
+ android:title="@string/menu_bookmark_all_tabs"
|
|
+ android:icon="@drawable/ic_folder_blue_24dp" />
|
|
<item android:id="@+id/menu_select_tabs"
|
|
android:title="@string/menu_select_tabs"
|
|
android:icon="@drawable/ic_select_tabs" />
|
|
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
|
|
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
|
|
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
|
|
@@ -89,6 +89,7 @@ import org.chromium.chrome.browser.base.ColdStartTracker;
|
|
import org.chromium.chrome.browser.bookmarks.BookmarkUtils;
|
|
import org.chromium.chrome.browser.browserservices.intents.WebappConstants;
|
|
import org.chromium.chrome.browser.compositor.CompositorViewHolder;
|
|
+import org.chromium.chrome.browser.bookmarks.BookmarkModel;
|
|
import org.chromium.chrome.browser.compositor.layouts.Layout;
|
|
import org.chromium.chrome.browser.compositor.layouts.LayoutManagerChrome;
|
|
import org.chromium.chrome.browser.compositor.layouts.LayoutManagerChromePhone;
|
|
@@ -2950,6 +2951,8 @@ public class ChromeTabbedActivity extends ChromeActivity<ChromeActivityComponent
|
|
getTabModelSelectorSupplier().get(),
|
|
() -> getTabModelSelector().closeAllTabs());
|
|
RecordUserAction.record("MobileMenuCloseAllTabs");
|
|
+ } else if (id == R.id.bookmark_all_tabs_menu_id) {
|
|
+ bookmarkAllTabs();
|
|
} else if (id == R.id.close_all_incognito_tabs_menu_id) {
|
|
// Close only incognito tabs
|
|
CloseAllTabsDialog.show(
|
|
@@ -3021,6 +3024,27 @@ public class ChromeTabbedActivity extends ChromeActivity<ChromeActivityComponent
|
|
getTabModalLifetimeHandler().onOmniboxFocusChanged(hasFocus);
|
|
}
|
|
|
|
+ private void bookmarkAllTabs() {
|
|
+ TabModel tabModel = getTabModelSelector().getCurrentModel();
|
|
+ int count = tabModel.getCount();
|
|
+ Log.i(TAG, "bookmarkAllTabs(): %d tabs to bookmark", count);
|
|
+ if (count == 0) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ final BookmarkModel bookmarkModel = mBookmarkModelSupplier.get();
|
|
+ bookmarkModel.finishLoadingBookmarkModel(() -> {
|
|
+ for (int i = 0; i < tabModel.getCount(); i++) {
|
|
+ Tab tab = tabModel.getTabAt(i);
|
|
+ if (tab.isNativePage()) {
|
|
+ continue;
|
|
+ }
|
|
+ bookmarkModel.addToTabsCollection(this, tab);
|
|
+ }
|
|
+ bookmarkModel.finishedAddingToTabsCollection(this, getSnackbarManager());
|
|
+ });
|
|
+ }
|
|
+
|
|
private void recordLauncherShortcutAction(boolean isIncognito) {
|
|
if (isIncognito) {
|
|
RecordUserAction.record("Android.LauncherShortcut.NewIncognitoTab");
|
|
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java
|
|
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java
|
|
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java
|
|
@@ -18,11 +18,17 @@ import org.jni_zero.NativeMethods;
|
|
|
|
import org.chromium.base.Callback;
|
|
import org.chromium.base.ContextUtils;
|
|
+import org.chromium.base.Log;
|
|
import org.chromium.base.ObserverList;
|
|
import org.chromium.base.ThreadUtils;
|
|
import org.chromium.base.metrics.RecordUserAction;
|
|
import org.chromium.chrome.browser.partnerbookmarks.PartnerBookmarksShim;
|
|
import org.chromium.chrome.browser.profiles.Profile;
|
|
+import org.chromium.chrome.browser.tab.Tab;
|
|
+import org.chromium.chrome.browser.ui.messages.snackbar.Snackbar;
|
|
+import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager;
|
|
+import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager.SnackbarController;
|
|
+import org.chromium.chrome.R;
|
|
import org.chromium.components.bookmarks.BookmarkId;
|
|
import org.chromium.components.bookmarks.BookmarkItem;
|
|
import org.chromium.components.bookmarks.BookmarkType;
|
|
@@ -82,6 +88,8 @@ import org.chromium.ui.modaldialog.DialogDismissalCause;
|
|
class BookmarkBridge {
|
|
private final ObserverList<BookmarkModelObserver> mObservers = new ObserverList<>();
|
|
|
|
+ private static final String TAG = "BookmarkBridge";
|
|
+
|
|
private long mNativeBookmarkBridge;
|
|
private boolean mIsDestroyed;
|
|
private boolean mIsDoingExtensiveChanges;
|
|
@@ -402,6 +410,16 @@ class BookmarkBridge {
|
|
return mMobileFolderId;
|
|
}
|
|
|
|
+ /**
|
|
+ * @return The BookmarkId for the Tabs collecction folder node
|
|
+ */
|
|
+ public BookmarkId getTabsCollectionFolderId() {
|
|
+ ThreadUtils.assertOnUiThread();
|
|
+ assert mIsNativeBookmarkModelLoaded;
|
|
+ return BookmarkBridgeJni.get().getTabsCollectionFolderId(
|
|
+ mNativeBookmarkBridge, BookmarkBridge.this);
|
|
+ }
|
|
+
|
|
/** Returns Id representing the special "other" folder from bookmark model. */
|
|
public BookmarkId getOtherFolderId() {
|
|
ThreadUtils.assertOnUiThread();
|
|
@@ -1092,6 +1110,50 @@ class BookmarkBridge {
|
|
.addToReadingList(mNativeBookmarkBridge, parentId, title, url);
|
|
}
|
|
|
|
+ // Used to bookmark all tabs in a specific folder, created if not existing
|
|
+ public BookmarkId addToTabsCollection(Context context, Tab tab) {
|
|
+ BookmarkId parent = getTabsCollectionFolderId();
|
|
+ BookmarkId existingId = BookmarkBridgeJni.get().getBookmarkIdForTabsCollection(
|
|
+ mNativeBookmarkBridge, tab.getOriginalUrl());
|
|
+ if (existingId != null && existingId.getId() != BookmarkId.INVALID_ID) {
|
|
+ BookmarkId existingBookmarkId = new BookmarkId(existingId.getId(), BookmarkType.NORMAL);
|
|
+ BookmarkItem existingBookmark = getBookmarkById(existingBookmarkId);
|
|
+ if (parent.equals(existingBookmark.getParentId())) {
|
|
+ // bookmark already exists in the tabs collection folder
|
|
+ return existingBookmarkId;
|
|
+ }
|
|
+ }
|
|
+ BookmarkId bookmarkId =
|
|
+ addBookmark(parent, getChildCount(parent), tab.getTitle(), tab.getUrl());
|
|
+
|
|
+ if (bookmarkId == null) {
|
|
+ Log.e(TAG,
|
|
+ "Failed to add bookmarks: parentTypeAndId %s", parent);
|
|
+ }
|
|
+ return bookmarkId;
|
|
+ }
|
|
+
|
|
+ public void finishedAddingToTabsCollection(Activity activity, SnackbarManager snackbarManager) {
|
|
+ BookmarkId parent = getTabsCollectionFolderId();
|
|
+
|
|
+ BookmarkItem bookmarkItem = getBookmarkById(parent);
|
|
+ String folderName;
|
|
+ if (bookmarkItem != null) {
|
|
+ folderName = bookmarkItem.getTitle();
|
|
+ } else {
|
|
+ folderName = "";
|
|
+ }
|
|
+ SnackbarController snackbarController = new SnackbarController() {
|
|
+ @Override
|
|
+ public void onAction(Object actionData) {
|
|
+ }
|
|
+ };
|
|
+ Snackbar snackbar = Snackbar.make(folderName, snackbarController, Snackbar.TYPE_ACTION,
|
|
+ Snackbar.UMA_BOOKMARK_ADDED)
|
|
+ .setTemplateText(activity.getString(R.string.bookmark_page_saved_folder));
|
|
+ snackbarManager.showSnackbar(snackbar);
|
|
+ }
|
|
+
|
|
/**
|
|
* Helper method to mark an item as read.
|
|
*
|
|
@@ -1334,6 +1396,9 @@ class BookmarkBridge {
|
|
|
|
BookmarkId getMostRecentlyAddedUserBookmarkIdForUrl(long nativeBookmarkBridge, GURL url);
|
|
|
|
+ BookmarkId getBookmarkIdForTabsCollection(
|
|
+ long nativeBookmarkBridge, GURL url);
|
|
+
|
|
BookmarkItem getBookmarkById(long nativeBookmarkBridge, long id, int type);
|
|
|
|
void getTopLevelFolderIds(
|
|
@@ -1353,6 +1418,8 @@ class BookmarkBridge {
|
|
|
|
BookmarkId getRootFolderId(long nativeBookmarkBridge);
|
|
|
|
+ BookmarkId getTabsCollectionFolderId(long nativeBookmarkBridge, BookmarkBridge caller);
|
|
+
|
|
BookmarkId getMobileFolderId(long nativeBookmarkBridge);
|
|
|
|
BookmarkId getOtherFolderId(long nativeBookmarkBridge);
|
|
diff --git a/chrome/browser/bookmarks/android/bookmark_bridge.cc b/chrome/browser/bookmarks/android/bookmark_bridge.cc
|
|
--- a/chrome/browser/bookmarks/android/bookmark_bridge.cc
|
|
+++ b/chrome/browser/bookmarks/android/bookmark_bridge.cc
|
|
@@ -367,6 +367,33 @@ void BookmarkBridge::GetImageUrlForBookmark(
|
|
base::BindOnce(&HandleImageUrlResponse, callback));
|
|
}
|
|
|
|
+base::android::ScopedJavaLocalRef<jobject>
|
|
+BookmarkBridge::GetBookmarkIdForTabsCollection(
|
|
+ JNIEnv* env,
|
|
+ const JavaParamRef<jobject>& url) {
|
|
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
|
+
|
|
+ GURL gurl = *url::GURLAndroid::ToNativeGURL(env, url);
|
|
+
|
|
+ bookmarks::BookmarkModel* model =
|
|
+ BookmarkModelFactory::GetForBrowserContext(profile_);
|
|
+
|
|
+ std::vector<raw_ptr<const bookmarks::BookmarkNode, VectorExperimental>> nodes =
|
|
+ model->GetNodesByURL(gurl);
|
|
+ std::sort(nodes.begin(), nodes.end(), &bookmarks::MoreRecentlyAdded);
|
|
+
|
|
+ for (const BookmarkNode* node : nodes) {
|
|
+ for (const auto& child : model->tabs_collection_node()->children()) {
|
|
+ if (node->id() == child->id()) {
|
|
+ return JavaBookmarkIdCreateBookmarkId(env, node->id(),
|
|
+ GetBookmarkType(node));
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return nullptr;
|
|
+}
|
|
+
|
|
base::android::ScopedJavaLocalRef<jobject>
|
|
BookmarkBridge::GetMostRecentlyAddedUserBookmarkIdForUrl(
|
|
JNIEnv* env,
|
|
@@ -482,6 +509,7 @@ void BookmarkBridge::GetAllFoldersWithDepths(
|
|
// Vector to temporarily contain all child bookmarks at same level for sorting
|
|
std::vector<const BookmarkNode*> bookmarks = {
|
|
bookmark_model_->mobile_node(),
|
|
+ bookmark_model_->tabs_collection_node(),
|
|
bookmark_model_->bookmark_bar_node(),
|
|
bookmark_model_->other_node(),
|
|
};
|
|
@@ -539,6 +567,11 @@ std::vector<const BookmarkNode*> BookmarkBridge::GetTopLevelFolderIdsImpl(
|
|
top_level_folders.push_back(root_child.get());
|
|
}
|
|
|
|
+ for (const auto& node : bookmark_model_->tabs_collection_node()->children()) {
|
|
+ if (node->is_folder())
|
|
+ top_level_folders.push_back(node.get());
|
|
+ }
|
|
+
|
|
if (account_reading_list_manager_ &&
|
|
account_reading_list_manager_->GetRoot()) {
|
|
top_level_folders.push_back(account_reading_list_manager_->GetRoot());
|
|
@@ -1176,6 +1209,17 @@ void BookmarkBridge::GetBookmarksOfType(
|
|
AddBookmarkNodesToBookmarkIdList(env, j_list, results);
|
|
}
|
|
|
|
+ScopedJavaLocalRef<jobject> BookmarkBridge::GetTabsCollectionFolderId(
|
|
+ JNIEnv* env,
|
|
+ const JavaParamRef<jobject>& obj) {
|
|
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
|
+ const BookmarkNode* tabs_collection_node = bookmark_model_->tabs_collection_node();
|
|
+ ScopedJavaLocalRef<jobject> folder_id_obj =
|
|
+ JavaBookmarkIdCreateBookmarkId(
|
|
+ env, tabs_collection_node->id(), GetBookmarkType(tabs_collection_node));
|
|
+ return folder_id_obj;
|
|
+}
|
|
+
|
|
ScopedJavaLocalRef<jobject> BookmarkBridge::AddFolder(
|
|
JNIEnv* env,
|
|
const JavaParamRef<jobject>& j_parent_id_obj,
|
|
diff --git a/chrome/browser/bookmarks/android/bookmark_bridge.h b/chrome/browser/bookmarks/android/bookmark_bridge.h
|
|
--- a/chrome/browser/bookmarks/android/bookmark_bridge.h
|
|
+++ b/chrome/browser/bookmarks/android/bookmark_bridge.h
|
|
@@ -77,6 +77,10 @@ class BookmarkBridge : public ProfileObserver,
|
|
const base::android::JavaParamRef<jobject>& j_url,
|
|
const base::android::JavaParamRef<jobject>& j_callback);
|
|
|
|
+ base::android::ScopedJavaLocalRef<jobject> GetBookmarkIdForTabsCollection(
|
|
+ JNIEnv* env,
|
|
+ const base::android::JavaParamRef<jobject>& url);
|
|
+
|
|
base::android::ScopedJavaLocalRef<jobject>
|
|
GetMostRecentlyAddedUserBookmarkIdForUrl(
|
|
JNIEnv* env,
|
|
@@ -227,6 +231,10 @@ class BookmarkBridge : public ProfileObserver,
|
|
const base::android::JavaParamRef<jobject>& j_list,
|
|
jint type);
|
|
|
|
+ base::android::ScopedJavaLocalRef<jobject> GetTabsCollectionFolderId(
|
|
+ JNIEnv* env,
|
|
+ const base::android::JavaParamRef<jobject>& obj);
|
|
+
|
|
base::android::ScopedJavaLocalRef<jobject> AddFolder(
|
|
JNIEnv* env,
|
|
const base::android::JavaParamRef<jobject>& j_parent_id_obj,
|
|
diff --git a/chrome/browser/bookmarks/bookmark_html_writer.cc b/chrome/browser/bookmarks/bookmark_html_writer.cc
|
|
--- a/chrome/browser/bookmarks/bookmark_html_writer.cc
|
|
+++ b/chrome/browser/bookmarks/bookmark_html_writer.cc
|
|
@@ -168,7 +168,8 @@ class Writer : public base::RefCountedThreadSafe<Writer> {
|
|
BookmarkCodec codec;
|
|
bookmarks_ =
|
|
codec.Encode(model->bookmark_bar_node(), model->other_node(),
|
|
- model->mobile_node(), /*sync_metadata_str=*/std::string());
|
|
+ model->mobile_node(), model->tabs_collection_node(),
|
|
+ /*sync_metadata_str=*/std::string());
|
|
}
|
|
|
|
Writer(const Writer&) = delete;
|
|
@@ -195,15 +196,19 @@ class Writer : public base::RefCountedThreadSafe<Writer> {
|
|
roots->FindDict(BookmarkCodec::kOtherBookmarkFolderNameKey);
|
|
base::Value::Dict* mobile_folder_value =
|
|
roots->FindDict(BookmarkCodec::kMobileBookmarkFolderNameKey);
|
|
+ base::Value::Dict* tabs_collection_value =
|
|
+ roots->FindDict(BookmarkCodec::kTabsBookmarkFolderNameKey);
|
|
DCHECK(root_folder_value);
|
|
DCHECK(other_folder_value);
|
|
DCHECK(mobile_folder_value);
|
|
+ DCHECK(tabs_collection_value);
|
|
|
|
IncrementIndent();
|
|
|
|
if (!WriteNode(*root_folder_value, BookmarkNode::BOOKMARK_BAR) ||
|
|
!WriteNode(*other_folder_value, BookmarkNode::OTHER_NODE) ||
|
|
- !WriteNode(*mobile_folder_value, BookmarkNode::MOBILE)) {
|
|
+ !WriteNode(*mobile_folder_value, BookmarkNode::MOBILE) ||
|
|
+ !WriteNode(*tabs_collection_value, BookmarkNode::TABS_COLLECTION)) {
|
|
NotifyOnFinish(BookmarksExportObserver::Result::kCouldNotWriteNodes);
|
|
return;
|
|
}
|
|
@@ -467,6 +472,8 @@ void BookmarkFaviconFetcher::ExportBookmarks() {
|
|
BookmarkModelFactory::GetForBrowserContext(profile_)->other_node());
|
|
ExtractUrls(
|
|
BookmarkModelFactory::GetForBrowserContext(profile_)->mobile_node());
|
|
+ ExtractUrls(
|
|
+ BookmarkModelFactory::GetForBrowserContext(profile_)->tabs_collection_node());
|
|
if (!bookmark_urls_.empty())
|
|
FetchNextFavicon();
|
|
else
|
|
diff --git a/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/dialogs/DownloadLocationCustomView.java b/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/dialogs/DownloadLocationCustomView.java
|
|
--- a/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/dialogs/DownloadLocationCustomView.java
|
|
+++ b/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/dialogs/DownloadLocationCustomView.java
|
|
@@ -85,7 +85,7 @@ public class DownloadLocationCustomView extends ScrollView
|
|
mDirectoryAdapter.update();
|
|
}
|
|
|
|
- void setTitle(CharSequence title) {
|
|
+ public void setTitle(CharSequence title) {
|
|
mTitle.setText(title);
|
|
}
|
|
|
|
@@ -93,7 +93,7 @@ public class DownloadLocationCustomView extends ScrollView
|
|
mSubtitleView.setText(subtitle);
|
|
}
|
|
|
|
- void setFileName(CharSequence fileName) {
|
|
+ public void setFileName(CharSequence fileName) {
|
|
mFileName.setText(fileName);
|
|
}
|
|
|
|
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd
|
|
--- a/chrome/browser/ui/android/strings/android_chrome_strings.grd
|
|
+++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
|
|
@@ -3875,6 +3875,9 @@ To change this setting, <ph name="BEGIN_LINK">BEGIN_LINK</ph>clear the Chrome da
|
|
<message name="IDS_MENU_SELECT_TABS" desc="Menu item for bulk editing tabs. [CHAR_LIMIT=27]">
|
|
Select tabs
|
|
</message>
|
|
+ <message name="IDS_MENU_BOOKMARK_ALL_TABS" desc="Menu item to bookmark all tabs. [CHAR-LIMIT=27]">
|
|
+ Bookmark all tabs
|
|
+ </message>
|
|
<message name="IDS_MENU_GET_IMAGE_DESCRIPTIONS" desc="Menu item to start getting alt text accessibility image labels/descriptions [CHAR_LIMIT=27]">
|
|
Get image descriptions
|
|
</message>
|
|
diff --git a/components/bookmark_bar_strings.grdp b/components/bookmark_bar_strings.grdp
|
|
--- a/components/bookmark_bar_strings.grdp
|
|
+++ b/components/bookmark_bar_strings.grdp
|
|
@@ -20,6 +20,9 @@
|
|
<message name="IDS_BOOKMARK_BAR_MOBILE_FOLDER_NAME" desc="Name shown in the tree for the mobile bookmarks folder">
|
|
Mobile bookmarks
|
|
</message>
|
|
+ <message name="IDS_BOOKMARK_BAR_TABS_COLLECTION_FOLDER_NAME" desc="Name shown in the tree for the tabs collection bookmarks folder">
|
|
+ Tabs collection
|
|
+ </message>
|
|
<message name="IDS_BOOKMARK_BAR_OTHER_FOLDER_NAME" desc="Name shown in the tree for the other bookmarks folder">
|
|
Other bookmarks
|
|
</message>
|
|
@@ -34,6 +37,9 @@
|
|
<message name="IDS_BOOKMARK_BAR_MOBILE_FOLDER_NAME" desc="In Title Case: Name shown in the tree for the mobile bookmarks folder">
|
|
Mobile Bookmarks
|
|
</message>
|
|
+ <message name="IDS_BOOKMARK_BAR_TABS_COLLECTION_FOLDER_NAME" desc="Name shown in the tree for the tabs collection bookmarks folder">
|
|
+ Tabs Collection
|
|
+ </message>
|
|
<message name="IDS_BOOKMARK_BAR_OTHER_FOLDER_NAME" desc="In Title Case: Name shown in the tree for the other bookmarks folder">
|
|
Other Bookmarks
|
|
</message>
|
|
diff --git a/components/bookmarks/browser/bookmark_codec.cc b/components/bookmarks/browser/bookmark_codec.cc
|
|
--- a/components/bookmarks/browser/bookmark_codec.cc
|
|
+++ b/components/bookmarks/browser/bookmark_codec.cc
|
|
@@ -35,6 +35,7 @@ const char BookmarkCodec::kBookmarkBarFolderNameKey[] = "bookmark_bar";
|
|
const char BookmarkCodec::kOtherBookmarkFolderNameKey[] = "other";
|
|
// The value is left as 'synced' for historical reasons.
|
|
const char BookmarkCodec::kMobileBookmarkFolderNameKey[] = "synced";
|
|
+const char BookmarkCodec::kTabsBookmarkFolderNameKey[] = "tabs";
|
|
const char BookmarkCodec::kVersionKey[] = "version";
|
|
const char BookmarkCodec::kChecksumKey[] = "checksum";
|
|
const char BookmarkCodec::kIdKey[] = "id";
|
|
@@ -72,6 +73,7 @@ base::Value::Dict BookmarkCodec::Encode(
|
|
const BookmarkNode* bookmark_bar_node,
|
|
const BookmarkNode* other_folder_node,
|
|
const BookmarkNode* mobile_folder_node,
|
|
+ const BookmarkNode* tabs_folder_node,
|
|
std::string sync_metadata_str) {
|
|
ids_reassigned_ = false;
|
|
uuids_reassigned_ = false;
|
|
@@ -91,6 +93,8 @@ base::Value::Dict BookmarkCodec::Encode(
|
|
roots.Set(kBookmarkBarFolderNameKey, EncodeNode(bookmark_bar_node));
|
|
roots.Set(kOtherBookmarkFolderNameKey, EncodeNode(other_folder_node));
|
|
roots.Set(kMobileBookmarkFolderNameKey, EncodeNode(mobile_folder_node));
|
|
+ if (tabs_folder_node)
|
|
+ roots.Set(kTabsBookmarkFolderNameKey, EncodeNode(tabs_folder_node));
|
|
|
|
FinalizeChecksum();
|
|
// We are going to store the computed checksum. So set stored checksum to be
|
|
@@ -107,6 +111,7 @@ bool BookmarkCodec::Decode(const base::Value::Dict& value,
|
|
BookmarkNode* bb_node,
|
|
BookmarkNode* other_folder_node,
|
|
BookmarkNode* mobile_folder_node,
|
|
+ BookmarkNode* tabs_folder_node,
|
|
int64_t* max_id,
|
|
std::string* sync_metadata_str) {
|
|
const int64_t max_already_assigned_id =
|
|
@@ -117,7 +122,8 @@ bool BookmarkCodec::Decode(const base::Value::Dict& value,
|
|
base::Uuid::ParseLowercase(kBookmarkBarNodeUuid),
|
|
base::Uuid::ParseLowercase(kOtherBookmarksNodeUuid),
|
|
base::Uuid::ParseLowercase(kMobileBookmarksNodeUuid),
|
|
- base::Uuid::ParseLowercase(kManagedNodeUuid)};
|
|
+ base::Uuid::ParseLowercase(kManagedNodeUuid),
|
|
+ base::Uuid::ParseLowercase(kTabsCollectionBookmarksNodeUuid)};
|
|
ids_reassigned_ = false;
|
|
uuids_reassigned_ = false;
|
|
ids_valid_ = true;
|
|
@@ -125,13 +131,14 @@ bool BookmarkCodec::Decode(const base::Value::Dict& value,
|
|
stored_checksum_.clear();
|
|
InitializeChecksum();
|
|
bool success = DecodeHelper(bb_node, other_folder_node, mobile_folder_node,
|
|
+ tabs_folder_node,
|
|
value, sync_metadata_str);
|
|
FinalizeChecksum();
|
|
// If either the checksums differ or some IDs were missing/not unique,
|
|
// reassign IDs.
|
|
if (!ids_valid_ || computed_checksum_ != stored_checksum_) {
|
|
maximum_id_ = max_already_assigned_id;
|
|
- ReassignIDs(bb_node, other_folder_node, mobile_folder_node);
|
|
+ ReassignIDs(bb_node, other_folder_node, mobile_folder_node, tabs_folder_node);
|
|
}
|
|
*max_id = maximum_id_ + 1;
|
|
return success;
|
|
@@ -189,6 +196,7 @@ base::Value::Dict BookmarkCodec::EncodeMetaInfo(
|
|
bool BookmarkCodec::DecodeHelper(BookmarkNode* bb_node,
|
|
BookmarkNode* other_folder_node,
|
|
BookmarkNode* mobile_folder_node,
|
|
+ BookmarkNode* tabs_folder_node,
|
|
const base::Value::Dict& value,
|
|
std::string* sync_metadata_str) {
|
|
std::optional<int> version = value.FindInt(kVersionKey);
|
|
@@ -213,6 +221,8 @@ bool BookmarkCodec::DecodeHelper(BookmarkNode* bb_node,
|
|
roots->FindDict(kOtherBookmarkFolderNameKey);
|
|
const base::Value::Dict* mobile_folder_value =
|
|
roots->FindDict(kMobileBookmarkFolderNameKey);
|
|
+ const base::Value::Dict* tabs_folder_value =
|
|
+ roots->FindDict(kTabsBookmarkFolderNameKey);
|
|
|
|
if (!bb_value || !other_folder_value || !mobile_folder_value)
|
|
return false;
|
|
@@ -220,6 +230,8 @@ bool BookmarkCodec::DecodeHelper(BookmarkNode* bb_node,
|
|
DecodeNode(*bb_value, nullptr, bb_node);
|
|
DecodeNode(*other_folder_value, nullptr, other_folder_node);
|
|
DecodeNode(*mobile_folder_value, nullptr, mobile_folder_node);
|
|
+ if (tabs_folder_value)
|
|
+ DecodeNode(*tabs_folder_value, nullptr, tabs_folder_node);
|
|
|
|
if (sync_metadata_str) {
|
|
const std::string* sync_metadata_str_base64 =
|
|
@@ -459,11 +471,13 @@ void BookmarkCodec::DecodeMetaInfoHelper(
|
|
|
|
void BookmarkCodec::ReassignIDs(BookmarkNode* bb_node,
|
|
BookmarkNode* other_node,
|
|
- BookmarkNode* mobile_node) {
|
|
+ BookmarkNode* mobile_node,
|
|
+ BookmarkNode* tabs_folder_node) {
|
|
ids_.clear();
|
|
ReassignIDsHelper(bb_node);
|
|
ReassignIDsHelper(other_node);
|
|
ReassignIDsHelper(mobile_node);
|
|
+ ReassignIDsHelper(tabs_folder_node);
|
|
ids_reassigned_ = true;
|
|
}
|
|
|
|
diff --git a/components/bookmarks/browser/bookmark_codec.h b/components/bookmarks/browser/bookmark_codec.h
|
|
--- a/components/bookmarks/browser/bookmark_codec.h
|
|
+++ b/components/bookmarks/browser/bookmark_codec.h
|
|
@@ -39,6 +39,7 @@ class BookmarkCodec {
|
|
const BookmarkNode* bookmark_bar_node,
|
|
const BookmarkNode* other_folder_node,
|
|
const BookmarkNode* mobile_folder_node,
|
|
+ const BookmarkNode* tabs_folder_node,
|
|
std::string sync_metadata_str);
|
|
|
|
// Decodes the previously encoded value to the specified nodes as well as
|
|
@@ -57,6 +58,7 @@ class BookmarkCodec {
|
|
BookmarkNode* bb_node,
|
|
BookmarkNode* other_folder_node,
|
|
BookmarkNode* mobile_folder_node,
|
|
+ BookmarkNode* tabs_folder_node,
|
|
int64_t* max_node_id,
|
|
std::string* sync_metadata_str);
|
|
|
|
@@ -82,6 +84,7 @@ class BookmarkCodec {
|
|
static const char kBookmarkBarFolderNameKey[];
|
|
static const char kOtherBookmarkFolderNameKey[];
|
|
static const char kMobileBookmarkFolderNameKey[];
|
|
+ static const char kTabsBookmarkFolderNameKey[];
|
|
static const char kVersionKey[];
|
|
static const char kChecksumKey[];
|
|
static const char kIdKey[];
|
|
@@ -114,6 +117,7 @@ class BookmarkCodec {
|
|
bool DecodeHelper(BookmarkNode* bb_node,
|
|
BookmarkNode* other_folder_node,
|
|
BookmarkNode* mobile_folder_node,
|
|
+ BookmarkNode* tabs_folder_node,
|
|
const base::Value::Dict& value,
|
|
std::string* sync_metadata_str);
|
|
|
|
@@ -124,7 +128,8 @@ class BookmarkCodec {
|
|
// Reassigns bookmark IDs for all nodes.
|
|
void ReassignIDs(BookmarkNode* bb_node,
|
|
BookmarkNode* other_node,
|
|
- BookmarkNode* mobile_node);
|
|
+ BookmarkNode* mobile_node,
|
|
+ BookmarkNode* tabs_folder_node);
|
|
|
|
// Helper to recursively reassign IDs.
|
|
void ReassignIDsHelper(BookmarkNode* node);
|
|
diff --git a/components/bookmarks/browser/bookmark_load_details.cc b/components/bookmarks/browser/bookmark_load_details.cc
|
|
--- a/components/bookmarks/browser/bookmark_load_details.cc
|
|
+++ b/components/bookmarks/browser/bookmark_load_details.cc
|
|
@@ -15,7 +15,7 @@ namespace {
|
|
|
|
// Number of top-level permanent folders excluding the managed node and account
|
|
// bookmarks.
|
|
-constexpr size_t kNumDefaultTopLevelPermanentFolders = 3u;
|
|
+constexpr size_t kNumDefaultTopLevelPermanentFolders = 4u;
|
|
|
|
} // namespace
|
|
|
|
@@ -40,6 +40,8 @@ BookmarkLoadDetails::BookmarkLoadDetails()
|
|
root_node_->Add(BookmarkPermanentNode::CreateOtherBookmarks(/*id=*/0)));
|
|
mobile_folder_node_ = static_cast<BookmarkPermanentNode*>(
|
|
root_node_->Add(BookmarkPermanentNode::CreateMobileBookmarks(/*id=*/0)));
|
|
+ tabs_collection_folder_node_ = static_cast<BookmarkPermanentNode*>(
|
|
+ root_node_->Add(BookmarkPermanentNode::CreateTabsCollectionBookmarks(/*id=*/0)));
|
|
|
|
CHECK_EQ(kNumDefaultTopLevelPermanentFolders, root_node_->children().size());
|
|
}
|
|
@@ -105,8 +107,8 @@ void BookmarkLoadDetails::AddManagedNode(
|
|
|
|
void BookmarkLoadDetails::CreateIndices() {
|
|
local_or_syncable_uuid_index_.insert(root_node_.get());
|
|
- static_assert(kNumDefaultTopLevelPermanentFolders == 3u,
|
|
- "The code below assumes three permanent nodes");
|
|
+ static_assert(kNumDefaultTopLevelPermanentFolders == 4u,
|
|
+ "The code below assumes 4 permanent nodes");
|
|
for (const auto& child : root_node_->children()) {
|
|
if (child.get() == account_bb_node_ ||
|
|
child.get() == account_other_folder_node_ ||
|
|
diff --git a/components/bookmarks/browser/bookmark_load_details.h b/components/bookmarks/browser/bookmark_load_details.h
|
|
--- a/components/bookmarks/browser/bookmark_load_details.h
|
|
+++ b/components/bookmarks/browser/bookmark_load_details.h
|
|
@@ -39,6 +39,7 @@ class BookmarkLoadDetails {
|
|
BookmarkPermanentNode* bb_node() { return bb_node_; }
|
|
BookmarkPermanentNode* mobile_folder_node() { return mobile_folder_node_; }
|
|
BookmarkPermanentNode* other_folder_node() { return other_folder_node_; }
|
|
+ BookmarkPermanentNode* tabs_collection_folder_node() { return tabs_collection_folder_node_; }
|
|
|
|
// Account permanent nodes (null unless `AddAccountPermanentNodes()` is
|
|
// called).
|
|
@@ -138,6 +139,7 @@ class BookmarkLoadDetails {
|
|
raw_ptr<BookmarkPermanentNode> bb_node_;
|
|
raw_ptr<BookmarkPermanentNode> other_folder_node_;
|
|
raw_ptr<BookmarkPermanentNode> mobile_folder_node_;
|
|
+ raw_ptr<BookmarkPermanentNode> tabs_collection_folder_node_;
|
|
raw_ptr<BookmarkPermanentNode> account_bb_node_;
|
|
raw_ptr<BookmarkPermanentNode> account_other_folder_node_;
|
|
raw_ptr<BookmarkPermanentNode> account_mobile_folder_node_;
|
|
diff --git a/components/bookmarks/browser/bookmark_model.cc b/components/bookmarks/browser/bookmark_model.cc
|
|
--- a/components/bookmarks/browser/bookmark_model.cc
|
|
+++ b/components/bookmarks/browser/bookmark_model.cc
|
|
@@ -846,7 +846,7 @@ bool BookmarkModel::HasBookmarks() const {
|
|
bool BookmarkModel::HasNoUserCreatedBookmarksOrFolders() const {
|
|
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
|
return bookmark_bar_node_->children().empty() &&
|
|
- other_node_->children().empty() && mobile_node_->children().empty();
|
|
+ other_node_->children().empty() && mobile_node_->children().empty() && tabs_collection_node_->children().empty();
|
|
}
|
|
|
|
bool BookmarkModel::IsBookmarked(const GURL& url) const {
|
|
@@ -1191,6 +1191,7 @@ void BookmarkModel::DoneLoading(std::unique_ptr<BookmarkLoadDetails> details) {
|
|
bookmark_bar_node_ = details->bb_node();
|
|
other_node_ = details->other_folder_node();
|
|
mobile_node_ = details->mobile_folder_node();
|
|
+ tabs_collection_node_ = details->tabs_collection_folder_node();
|
|
|
|
account_bookmark_bar_node_ = details->account_bb_node();
|
|
account_other_node_ = details->account_other_folder_node();
|
|
diff --git a/components/bookmarks/browser/bookmark_model.h b/components/bookmarks/browser/bookmark_model.h
|
|
--- a/components/bookmarks/browser/bookmark_model.h
|
|
+++ b/components/bookmarks/browser/bookmark_model.h
|
|
@@ -159,6 +159,12 @@ class BookmarkModel final : public BookmarkUndoProvider,
|
|
// bookmarks in the account storage).
|
|
const BookmarkNode* account_mobile_node() const;
|
|
|
|
+ // Returns the 'mobile' node. This is NULL until loaded.
|
|
+ const BookmarkNode* tabs_collection_node() const {
|
|
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
|
+ return tabs_collection_node_;
|
|
+ }
|
|
+
|
|
bool is_root_node(const BookmarkNode* node) const {
|
|
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
|
return node == root_;
|
|
@@ -619,6 +625,7 @@ class BookmarkModel final : public BookmarkUndoProvider,
|
|
raw_ptr<BookmarkPermanentNode> account_bookmark_bar_node_ = nullptr;
|
|
raw_ptr<BookmarkPermanentNode> account_other_node_ = nullptr;
|
|
raw_ptr<BookmarkPermanentNode> account_mobile_node_ = nullptr;
|
|
+ raw_ptr<BookmarkPermanentNode> tabs_collection_node_ = nullptr;
|
|
|
|
// The maximum ID assigned to the bookmark nodes in the model.
|
|
int64_t next_node_id_ = 1;
|
|
diff --git a/components/bookmarks/browser/bookmark_node.cc b/components/bookmarks/browser/bookmark_node.cc
|
|
--- a/components/bookmarks/browser/bookmark_node.cc
|
|
+++ b/components/bookmarks/browser/bookmark_node.cc
|
|
@@ -161,6 +161,8 @@ bool BookmarkPermanentNode::IsTypeVisibleWhenEmpty(Type type) {
|
|
#endif
|
|
|
|
switch (type) {
|
|
+ case bookmarks::BookmarkNode::TABS_COLLECTION:
|
|
+ return !is_desktop;
|
|
case BookmarkNode::URL:
|
|
NOTREACHED_NORETURN();
|
|
case BookmarkNode::FOLDER:
|
|
@@ -211,6 +213,15 @@ BookmarkPermanentNode::CreateMobileBookmarks(int64_t id) {
|
|
l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_MOBILE_FOLDER_NAME)));
|
|
}
|
|
|
|
+// static
|
|
+std::unique_ptr<BookmarkPermanentNode>
|
|
+BookmarkPermanentNode::CreateTabsCollectionBookmarks(int64_t id) {
|
|
+ // base::WrapUnique() used because the constructor is private.
|
|
+ return base::WrapUnique(new BookmarkPermanentNode(
|
|
+ id, TABS_COLLECTION, base::Uuid::ParseLowercase(kTabsCollectionBookmarksNodeUuid),
|
|
+ l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_TABS_COLLECTION_FOLDER_NAME)));
|
|
+}
|
|
+
|
|
BookmarkPermanentNode::BookmarkPermanentNode(int64_t id,
|
|
Type type,
|
|
const base::Uuid& uuid,
|
|
diff --git a/components/bookmarks/browser/bookmark_node.h b/components/bookmarks/browser/bookmark_node.h
|
|
--- a/components/bookmarks/browser/bookmark_node.h
|
|
+++ b/components/bookmarks/browser/bookmark_node.h
|
|
@@ -35,6 +35,7 @@ class BookmarkNode : public ui::TreeNode<BookmarkNode>, public TitledUrlNode {
|
|
FOLDER,
|
|
BOOKMARK_BAR,
|
|
OTHER_NODE,
|
|
+ TABS_COLLECTION,
|
|
MOBILE
|
|
};
|
|
|
|
@@ -231,6 +232,8 @@ class BookmarkPermanentNode : public BookmarkNode {
|
|
int64_t id);
|
|
static std::unique_ptr<BookmarkPermanentNode> CreateMobileBookmarks(
|
|
int64_t id);
|
|
+ static std::unique_ptr<BookmarkPermanentNode> CreateTabsCollectionBookmarks(
|
|
+ int64_t id);
|
|
|
|
// Returns whether the permanent node of type `type` should be visible even
|
|
// when it is empty (i.e. no children).
|
|
diff --git a/components/bookmarks/browser/bookmark_storage.cc b/components/bookmarks/browser/bookmark_storage.cc
|
|
--- a/components/bookmarks/browser/bookmark_storage.cc
|
|
+++ b/components/bookmarks/browser/bookmark_storage.cc
|
|
@@ -45,6 +45,7 @@ base::Value::Dict EncodeModelToDict(
|
|
case BookmarkStorage::kSelectLocalOrSyncableNodes:
|
|
return codec.Encode(
|
|
model->bookmark_bar_node(), model->other_node(), model->mobile_node(),
|
|
+ model->tabs_collection_node(),
|
|
model->client()->EncodeLocalOrSyncableBookmarkSyncMetadata());
|
|
case BookmarkStorage::kSelectAccountNodes:
|
|
if (!model->account_bookmark_bar_node()) {
|
|
@@ -59,6 +60,7 @@ base::Value::Dict EncodeModelToDict(
|
|
return codec.Encode(model->account_bookmark_bar_node(),
|
|
model->account_other_node(),
|
|
model->account_mobile_node(),
|
|
+ nullptr,
|
|
model->client()->EncodeAccountBookmarkSyncMetadata());
|
|
}
|
|
|
|
diff --git a/components/bookmarks/browser/bookmark_uuids.cc b/components/bookmarks/browser/bookmark_uuids.cc
|
|
--- a/components/bookmarks/browser/bookmark_uuids.cc
|
|
+++ b/components/bookmarks/browser/bookmark_uuids.cc
|
|
@@ -35,6 +35,9 @@ const char kManagedNodeUuid[] = "323123f4-9381-5aee-80e6-ea5fca2f7672";
|
|
// see https://crbug.com/1484372 for details.
|
|
const char kShoppingCollectionUuid[] = "89fc5b66-beb6-56c1-a99b-70635d7df201";
|
|
|
|
+const char kTabsCollectionBookmarksNodeUuid[] =
|
|
+ "00000000-0000-4000-a000-000000000006";
|
|
+
|
|
// This value is the result of exercising sync's function
|
|
// syncer::InferGuidForLegacyBookmark() with an empty input.
|
|
const char kBannedUuidDueToPastSyncBug[] =
|
|
diff --git a/components/bookmarks/browser/bookmark_uuids.h b/components/bookmarks/browser/bookmark_uuids.h
|
|
--- a/components/bookmarks/browser/bookmark_uuids.h
|
|
+++ b/components/bookmarks/browser/bookmark_uuids.h
|
|
@@ -14,6 +14,7 @@ extern const char kBookmarkBarNodeUuid[];
|
|
extern const char kOtherBookmarksNodeUuid[];
|
|
extern const char kMobileBookmarksNodeUuid[];
|
|
extern const char kManagedNodeUuid[];
|
|
+extern const char kTabsCollectionBookmarksNodeUuid[];
|
|
extern const char kShoppingCollectionUuid[];
|
|
|
|
// A bug in sync caused some problematic UUIDs to be produced.
|
|
diff --git a/components/bookmarks/browser/model_loader.cc b/components/bookmarks/browser/model_loader.cc
|
|
--- a/components/bookmarks/browser/model_loader.cc
|
|
+++ b/components/bookmarks/browser/model_loader.cc
|
|
@@ -71,6 +71,8 @@ std::unique_ptr<BookmarkLoadDetails> LoadBookmarks(
|
|
BookmarkPermanentNode::CreateOtherBookmarks(0);
|
|
std::unique_ptr<BookmarkPermanentNode> account_mobile_folder_node =
|
|
BookmarkPermanentNode::CreateMobileBookmarks(0);
|
|
+ std::unique_ptr<BookmarkPermanentNode> tabs_collection_folder_node =
|
|
+ BookmarkPermanentNode::CreateTabsCollectionBookmarks(0);
|
|
|
|
std::optional<base::Value::Dict> root_dict =
|
|
LoadFileToDict(account_file_path);
|
|
@@ -78,7 +80,8 @@ std::unique_ptr<BookmarkLoadDetails> LoadBookmarks(
|
|
if (root_dict.has_value() &&
|
|
codec.Decode(*root_dict, /*already_assigned_ids=*/{},
|
|
account_bb_node.get(), account_other_folder_node.get(),
|
|
- account_mobile_folder_node.get(), &max_node_id,
|
|
+ account_mobile_folder_node.get(),
|
|
+ tabs_collection_folder_node.get(), &max_node_id,
|
|
&sync_metadata_str)) {
|
|
ids_assigned_to_account_nodes = codec.release_assigned_ids();
|
|
|
|
@@ -110,7 +113,8 @@ std::unique_ptr<BookmarkLoadDetails> LoadBookmarks(
|
|
if (root_dict.has_value() &&
|
|
codec.Decode(*root_dict, std::move(ids_assigned_to_account_nodes),
|
|
details->bb_node(), details->other_folder_node(),
|
|
- details->mobile_folder_node(), &max_node_id,
|
|
+ details->mobile_folder_node(),
|
|
+ details->tabs_collection_folder_node(), &max_node_id,
|
|
&sync_metadata_str)) {
|
|
details->set_local_or_syncable_sync_metadata_str(
|
|
std::move(sync_metadata_str));
|
|
diff --git a/components/sync_bookmarks/bookmark_specifics_conversions.cc b/components/sync_bookmarks/bookmark_specifics_conversions.cc
|
|
--- a/components/sync_bookmarks/bookmark_specifics_conversions.cc
|
|
+++ b/components/sync_bookmarks/bookmark_specifics_conversions.cc
|
|
@@ -445,6 +445,7 @@ sync_pb::BookmarkSpecifics::Type GetProtoTypeFromBookmarkNode(
|
|
case bookmarks::BookmarkNode::BOOKMARK_BAR:
|
|
case bookmarks::BookmarkNode::OTHER_NODE:
|
|
case bookmarks::BookmarkNode::MOBILE:
|
|
+ case bookmarks::BookmarkNode::TABS_COLLECTION:
|
|
DCHECK(node->is_folder());
|
|
return sync_pb::BookmarkSpecifics::FOLDER;
|
|
}
|
|
--
|