Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/ui/bookmarks/bookmark_utils_desktop.h" | 5 #include "chrome/browser/ui/bookmarks/bookmark_utils_desktop.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/macros.h" | 8 #include "base/macros.h" |
| 9 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
| 10 #include "build/build_config.h" | 10 #include "build/build_config.h" |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 51 #include "chrome/grit/theme_resources.h" | 51 #include "chrome/grit/theme_resources.h" |
| 52 #include "ui/base/material_design/material_design_controller.h" | 52 #include "ui/base/material_design/material_design_controller.h" |
| 53 #include "ui/base/resource/resource_bundle.h" | 53 #include "ui/base/resource/resource_bundle.h" |
| 54 #endif | 54 #endif |
| 55 | 55 |
| 56 using bookmarks::BookmarkModel; | 56 using bookmarks::BookmarkModel; |
| 57 using bookmarks::BookmarkNode; | 57 using bookmarks::BookmarkNode; |
| 58 | 58 |
| 59 namespace chrome { | 59 namespace chrome { |
| 60 | 60 |
| 61 int num_bookmark_urls_before_prompting = 15; | |
| 62 | |
| 63 namespace { | 61 namespace { |
| 64 | 62 |
| 65 // Iterator that iterates through a set of BookmarkNodes returning the URLs | 63 // Returns a vector of all URLs in |nodes| and their immediate children. Only |
| 66 // for nodes that are urls, or the URLs for the children of non-url urls. | 64 // recurses one level deep, not infinitely. TODO(pkasting): It's not clear why |
| 67 // This does not recurse through all descendants, only immediate children. | 65 // this shouldn't just recurse infinitely. |
| 68 // The following illustrates | 66 std::vector<GURL> GetURLsToOpen( |
| 69 // typical usage: | 67 const std::vector<const BookmarkNode*>& nodes, |
| 70 // OpenURLIterator iterator(nodes); | 68 content::BrowserContext* browser_context = nullptr, |
| 71 // while (iterator.has_next()) { | 69 bool incognito_urls_only = false) { |
| 72 // const GURL* url = iterator.NextURL(); | 70 std::vector<GURL> urls; |
| 73 // // do something with |urll|. | |
| 74 // } | |
| 75 class OpenURLIterator { | |
| 76 public: | |
| 77 explicit OpenURLIterator(const std::vector<const BookmarkNode*>& nodes) | |
| 78 : child_index_(0), | |
| 79 next_(NULL), | |
| 80 parent_(nodes.begin()), | |
| 81 end_(nodes.end()) { | |
| 82 FindNext(); | |
| 83 } | |
| 84 | 71 |
| 85 bool has_next() { return next_ != NULL;} | 72 const auto AddUrlIfLegal = [&](const GURL url) { |
| 73 if (!incognito_urls_only || IsURLAllowedInIncognito(url, browser_context)) | |
| 74 urls.push_back(url); | |
| 75 }; | |
| 86 | 76 |
| 87 const GURL* NextURL() { | 77 for (const BookmarkNode* node : nodes) { |
| 88 if (!has_next()) { | 78 if (node->is_url()) { |
| 89 NOTREACHED(); | 79 AddUrlIfLegal(node->url()); |
| 90 return NULL; | 80 } else { |
| 91 } | 81 // If the node is not a URL, it is a folder. We want to add those of its |
| 92 | 82 // children which are URLs. |
| 93 const GURL* next = next_; | 83 for (int child_index = 0; child_index < node->child_count(); |
| 94 FindNext(); | 84 ++child_index) { |
| 95 return next; | 85 const BookmarkNode* child = node->GetChild(child_index); |
| 96 } | 86 if (child->is_url()) { |
|
Peter Kasting
2017/04/14 20:41:53
Nit: No {}
Paezagon
2017/04/14 23:32:56
Done.
| |
| 97 | 87 AddUrlIfLegal(child->url()); |
| 98 private: | |
| 99 // Seach next node which has URL. | |
| 100 void FindNext() { | |
| 101 for (; parent_ < end_; ++parent_, child_index_ = 0) { | |
| 102 if ((*parent_)->is_url()) { | |
| 103 next_ = &(*parent_)->url(); | |
| 104 ++parent_; | |
| 105 child_index_ = 0; | |
| 106 return; | |
| 107 } else { | |
| 108 for (; child_index_ < (*parent_)->child_count(); ++child_index_) { | |
| 109 const BookmarkNode* child = (*parent_)->GetChild(child_index_); | |
| 110 if (child->is_url()) { | |
| 111 next_ = &child->url(); | |
| 112 ++child_index_; | |
| 113 return; | |
| 114 } | |
| 115 } | 88 } |
| 116 } | 89 } |
| 117 } | 90 } |
| 118 next_ = NULL; | |
| 119 } | 91 } |
| 120 | 92 return urls; |
| 121 int child_index_; | 93 } |
| 122 const GURL* next_; | |
| 123 std::vector<const BookmarkNode*>::const_iterator parent_; | |
| 124 const std::vector<const BookmarkNode*>::const_iterator end_; | |
| 125 | |
| 126 DISALLOW_COPY_AND_ASSIGN(OpenURLIterator); | |
| 127 }; | |
| 128 | 94 |
| 129 #if !defined(OS_ANDROID) | 95 #if !defined(OS_ANDROID) |
| 130 bool ShouldOpenAll(gfx::NativeWindow parent, | 96 bool ShouldOpenAll(gfx::NativeWindow parent, |
| 131 const std::vector<const BookmarkNode*>& nodes) { | 97 const std::vector<const BookmarkNode*>& nodes) { |
| 132 int child_count = 0; | 98 constexpr size_t kNumBookmarkUrlsBeforePrompting = 15; |
| 133 OpenURLIterator iterator(nodes); | |
| 134 while (iterator.has_next()) { | |
| 135 iterator.NextURL(); | |
| 136 child_count++; | |
| 137 } | |
| 138 | 99 |
| 139 if (child_count < num_bookmark_urls_before_prompting) | 100 size_t child_count = GetURLsToOpen(nodes).size(); |
| 101 if (child_count < kNumBookmarkUrlsBeforePrompting) | |
| 140 return true; | 102 return true; |
| 141 | 103 |
| 142 return ShowQuestionMessageBox( | 104 return ShowQuestionMessageBox( |
| 143 parent, l10n_util::GetStringUTF16(IDS_PRODUCT_NAME), | 105 parent, l10n_util::GetStringUTF16(IDS_PRODUCT_NAME), |
| 144 l10n_util::GetStringFUTF16(IDS_BOOKMARK_BAR_SHOULD_OPEN_ALL, | 106 l10n_util::GetStringFUTF16(IDS_BOOKMARK_BAR_SHOULD_OPEN_ALL, |
| 145 base::IntToString16(child_count))) == | 107 base::SizeTToString16(child_count))) == |
| 146 MESSAGE_BOX_RESULT_YES; | 108 MESSAGE_BOX_RESULT_YES; |
| 147 } | 109 } |
| 148 #endif | 110 #endif |
| 149 | 111 |
| 150 // Returns the total number of descendants nodes. | 112 // Returns the total number of descendants nodes. |
| 151 int ChildURLCountTotal(const BookmarkNode* node) { | 113 int ChildURLCountTotal(const BookmarkNode* node) { |
| 152 int result = 0; | 114 int result = 0; |
| 153 for (int i = 0; i < node->child_count(); ++i) { | 115 for (int i = 0; i < node->child_count(); ++i) { |
| 154 const BookmarkNode* child = node->GetChild(i); | 116 const BookmarkNode* child = node->GetChild(i); |
| 155 result++; | 117 result++; |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 178 void OpenAll(gfx::NativeWindow parent, | 140 void OpenAll(gfx::NativeWindow parent, |
| 179 content::PageNavigator* navigator, | 141 content::PageNavigator* navigator, |
| 180 const std::vector<const BookmarkNode*>& nodes, | 142 const std::vector<const BookmarkNode*>& nodes, |
| 181 WindowOpenDisposition initial_disposition, | 143 WindowOpenDisposition initial_disposition, |
| 182 content::BrowserContext* browser_context) { | 144 content::BrowserContext* browser_context) { |
| 183 if (!ShouldOpenAll(parent, nodes)) | 145 if (!ShouldOpenAll(parent, nodes)) |
| 184 return; | 146 return; |
| 185 | 147 |
| 186 // Opens all |nodes| of type URL and any children of |nodes| that are of type | 148 // Opens all |nodes| of type URL and any children of |nodes| that are of type |
| 187 // URL. |navigator| is the PageNavigator used to open URLs. After the first | 149 // URL. |navigator| is the PageNavigator used to open URLs. After the first |
| 188 // url is opened |opened_first_url| is set to true and |navigator| is set to | 150 // url is opened |navigator| is set to the PageNavigator of the last active |
| 189 // the PageNavigator of the last active tab. This is done to handle a window | 151 // tab. This is done to handle a window disposition of new window, in which |
| 190 // disposition of new window, in which case we want subsequent tabs to open in | 152 // case we want subsequent tabs to open in that window. |
| 191 // that window. | 153 |
| 192 bool opened_first_url = false; | 154 std::vector<GURL> urls = GetURLsToOpen( |
| 155 nodes, browser_context, | |
| 156 initial_disposition == WindowOpenDisposition::OFF_THE_RECORD); | |
| 157 | |
| 193 WindowOpenDisposition disposition = initial_disposition; | 158 WindowOpenDisposition disposition = initial_disposition; |
| 194 OpenURLIterator iterator(nodes); | 159 for (std::vector<GURL>::const_iterator url_it = urls.begin(); |
| 195 while (iterator.has_next()) { | 160 url_it != urls.end(); ++url_it) { |
| 196 const GURL* url = iterator.NextURL(); | |
| 197 // When |initial_disposition| is OFF_THE_RECORD, a node which can't be | |
| 198 // opened in incognito window, it is detected using |browser_context|, is | |
| 199 // not opened. | |
| 200 if (initial_disposition == WindowOpenDisposition::OFF_THE_RECORD && | |
| 201 !IsURLAllowedInIncognito(*url, browser_context)) | |
| 202 continue; | |
| 203 | |
| 204 content::WebContents* opened_tab = navigator->OpenURL( | 161 content::WebContents* opened_tab = navigator->OpenURL( |
| 205 content::OpenURLParams(*url, content::Referrer(), disposition, | 162 content::OpenURLParams(*url_it, content::Referrer(), disposition, |
| 206 ui::PAGE_TRANSITION_AUTO_BOOKMARK, false)); | 163 ui::PAGE_TRANSITION_AUTO_BOOKMARK, false)); |
| 207 | 164 if (url_it == urls.begin()) { |
| 208 if (!opened_first_url) { | |
| 209 opened_first_url = true; | |
| 210 disposition = WindowOpenDisposition::NEW_BACKGROUND_TAB; | |
| 211 // We opened the first URL which may have opened a new window or clobbered | 165 // We opened the first URL which may have opened a new window or clobbered |
| 212 // the current page, reset the navigator just to be sure. |opened_tab| may | 166 // the current page, reset the navigator just to be sure. |opened_tab| may |
| 213 // be NULL in tests. | 167 // be nullptr in tests. |
|
Peter Kasting
2017/04/14 20:41:53
Nit: Just "null" in comments
Paezagon
2017/04/14 23:32:57
Done.
| |
| 214 if (opened_tab) | 168 if (opened_tab) |
| 215 navigator = opened_tab; | 169 navigator = opened_tab; |
| 170 disposition = WindowOpenDisposition::NEW_BACKGROUND_TAB; | |
| 216 } | 171 } |
| 217 } | 172 } |
| 218 } | 173 } |
| 219 | 174 |
| 220 void OpenAll(gfx::NativeWindow parent, | 175 void OpenAll(gfx::NativeWindow parent, |
| 221 content::PageNavigator* navigator, | 176 content::PageNavigator* navigator, |
| 222 const BookmarkNode* node, | 177 const BookmarkNode* node, |
| 223 WindowOpenDisposition initial_disposition, | 178 WindowOpenDisposition initial_disposition, |
| 224 content::BrowserContext* browser_context) { | 179 content::BrowserContext* browser_context) { |
| 225 std::vector<const BookmarkNode*> nodes; | 180 std::vector<const BookmarkNode*> nodes; |
| 226 nodes.push_back(node); | 181 nodes.push_back(node); |
| 227 OpenAll(parent, navigator, nodes, initial_disposition, browser_context); | 182 OpenAll(parent, navigator, std::vector<const bookmarks::BookmarkNode*>{node}, |
| 183 initial_disposition, browser_context); | |
| 184 } | |
| 185 | |
| 186 int OpenCount(gfx::NativeWindow parent, | |
| 187 const std::vector<const bookmarks::BookmarkNode*>& nodes, | |
| 188 content::BrowserContext* incognito_context) { | |
| 189 return GetURLsToOpen(nodes, incognito_context, incognito_context != nullptr) | |
| 190 .size(); | |
| 191 } | |
| 192 | |
| 193 int OpenCount(gfx::NativeWindow parent, | |
| 194 const BookmarkNode* node, | |
| 195 content::BrowserContext* incognito_context) { | |
| 196 std::vector<const BookmarkNode*> nodes; | |
| 197 nodes.push_back(node); | |
| 198 return OpenCount(parent, std::vector<const bookmarks::BookmarkNode*>{node}, | |
| 199 incognito_context); | |
| 228 } | 200 } |
| 229 | 201 |
| 230 bool ConfirmDeleteBookmarkNode(const BookmarkNode* node, | 202 bool ConfirmDeleteBookmarkNode(const BookmarkNode* node, |
| 231 gfx::NativeWindow window) { | 203 gfx::NativeWindow window) { |
| 232 DCHECK(node && node->is_folder() && !node->empty()); | 204 DCHECK(node && node->is_folder() && !node->empty()); |
| 233 return ShowQuestionMessageBox( | 205 return ShowQuestionMessageBox( |
| 234 window, l10n_util::GetStringUTF16(IDS_PRODUCT_NAME), | 206 window, l10n_util::GetStringUTF16(IDS_PRODUCT_NAME), |
| 235 l10n_util::GetPluralStringFUTF16( | 207 l10n_util::GetPluralStringFUTF16( |
| 236 IDS_BOOKMARK_EDITOR_CONFIRM_DELETE, | 208 IDS_BOOKMARK_EDITOR_CONFIRM_DELETE, |
| 237 ChildURLCountTotal(node))) == | 209 ChildURLCountTotal(node))) == |
| 238 MESSAGE_BOX_RESULT_YES; | 210 MESSAGE_BOX_RESULT_YES; |
| 239 } | 211 } |
| 240 | 212 |
| 241 void ShowBookmarkAllTabsDialog(Browser* browser) { | 213 void ShowBookmarkAllTabsDialog(Browser* browser) { |
| 242 Profile* profile = browser->profile(); | 214 Profile* profile = browser->profile(); |
| 243 BookmarkModel* model = BookmarkModelFactory::GetForBrowserContext(profile); | 215 BookmarkModel* model = BookmarkModelFactory::GetForBrowserContext(profile); |
| 244 DCHECK(model && model->loaded()); | 216 DCHECK(model && model->loaded()); |
| 245 | 217 |
| 246 const BookmarkNode* parent = GetParentForNewNodes(model); | 218 const BookmarkNode* parent = GetParentForNewNodes(model); |
| 247 BookmarkEditor::EditDetails details = | 219 BookmarkEditor::EditDetails details = |
| 248 BookmarkEditor::EditDetails::AddFolder(parent, parent->child_count()); | 220 BookmarkEditor::EditDetails::AddFolder(parent, parent->child_count()); |
| 249 GetURLsForOpenTabs(browser, &(details.urls)); | 221 GetURLsForOpenTabs(browser, &(details.urls)); |
| 250 DCHECK(!details.urls.empty()); | 222 DCHECK(!details.urls.empty()); |
| 251 | 223 |
| 252 BookmarkEditor::Show(browser->window()->GetNativeWindow(), profile, details, | 224 BookmarkEditor::Show(browser->window()->GetNativeWindow(), profile, details, |
| 253 BookmarkEditor::SHOW_TREE); | 225 BookmarkEditor::SHOW_TREE); |
| 254 } | 226 } |
| 255 | 227 |
| 256 bool HasBookmarkURLs(const std::vector<const BookmarkNode*>& selection) { | 228 bool HasBookmarkURLs(const std::vector<const BookmarkNode*>& selection) { |
| 257 OpenURLIterator iterator(selection); | 229 return !GetURLsToOpen(selection).empty(); |
| 258 return iterator.has_next(); | |
| 259 } | 230 } |
| 260 | 231 |
| 261 bool HasBookmarkURLsAllowedInIncognitoMode( | 232 bool HasBookmarkURLsAllowedInIncognitoMode( |
| 262 const std::vector<const BookmarkNode*>& selection, | 233 const std::vector<const BookmarkNode*>& selection, |
| 263 content::BrowserContext* browser_context) { | 234 content::BrowserContext* browser_context) { |
| 264 OpenURLIterator iterator(selection); | 235 return !GetURLsToOpen(selection, browser_context, true).empty(); |
| 265 while (iterator.has_next()) { | |
| 266 const GURL* url = iterator.NextURL(); | |
| 267 if (IsURLAllowedInIncognito(*url, browser_context)) | |
| 268 return true; | |
| 269 } | |
| 270 return false; | |
| 271 } | 236 } |
| 272 #endif // !defined(OS_ANDROID) | 237 #endif // !defined(OS_ANDROID) |
| 273 | 238 |
| 274 } // namespace chrome | 239 } // namespace chrome |
| OLD | NEW |