| 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; | 61 size_t kNumBookmarkUrlsBeforePrompting = 15; |
| 62 | 62 |
| 63 namespace { | 63 namespace { |
| 64 | 64 |
| 65 // Iterator that iterates through a set of BookmarkNodes returning the URLs | 65 // 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. | 66 // recurses one level deep, not infinitely. TODO(pkasting): It's not clear why |
| 67 // This does not recurse through all descendants, only immediate children. | 67 // this shouldn't just recurse infinitely. |
| 68 // The following illustrates | 68 std::vector<GURL> GetURLsToOpen( |
| 69 // typical usage: | 69 const std::vector<const BookmarkNode*>& nodes, |
| 70 // OpenURLIterator iterator(nodes); | 70 content::BrowserContext* browser_context = nullptr, |
| 71 // while (iterator.has_next()) { | 71 bool incognito_urls_only = false) { |
| 72 // const GURL* url = iterator.NextURL(); | 72 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 | 73 |
| 85 bool has_next() { return next_ != NULL;} | 74 const auto AddUrlIfLegal = [&](const GURL url) { |
| 75 if (!incognito_urls_only || IsURLAllowedInIncognito(url, browser_context)) |
| 76 urls.push_back(url); |
| 77 }; |
| 86 | 78 |
| 87 const GURL* NextURL() { | 79 for (const BookmarkNode* node : nodes) { |
| 88 if (!has_next()) { | 80 if (node->is_url()) { |
| 89 NOTREACHED(); | 81 AddUrlIfLegal(node->url()); |
| 90 return NULL; | 82 } else { |
| 91 } | 83 // If the node is not a URL, it is a folder. We want to add those of its |
| 92 | 84 // children which are URLs. |
| 93 const GURL* next = next_; | 85 for (int child_index = 0; child_index < node->child_count(); |
| 94 FindNext(); | 86 ++child_index) { |
| 95 return next; | 87 const BookmarkNode* child = node->GetChild(child_index); |
| 96 } | 88 if (child->is_url()) |
| 97 | 89 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 } | |
| 116 } | 90 } |
| 117 } | 91 } |
| 118 next_ = NULL; | |
| 119 } | 92 } |
| 120 | 93 return urls; |
| 121 int child_index_; | 94 } |
| 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 | 95 |
| 129 #if !defined(OS_ANDROID) | 96 #if !defined(OS_ANDROID) |
| 130 bool ShouldOpenAll(gfx::NativeWindow parent, | 97 bool ShouldOpenAll(gfx::NativeWindow parent, |
| 131 const std::vector<const BookmarkNode*>& nodes) { | 98 const std::vector<const BookmarkNode*>& nodes) { |
| 132 int child_count = 0; | 99 size_t child_count = GetURLsToOpen(nodes).size(); |
| 133 OpenURLIterator iterator(nodes); | 100 if (child_count < kNumBookmarkUrlsBeforePrompting) |
| 134 while (iterator.has_next()) { | |
| 135 iterator.NextURL(); | |
| 136 child_count++; | |
| 137 } | |
| 138 | |
| 139 if (child_count < num_bookmark_urls_before_prompting) | |
| 140 return true; | 101 return true; |
| 141 | 102 |
| 142 return ShowQuestionMessageBox( | 103 return ShowQuestionMessageBox( |
| 143 parent, l10n_util::GetStringUTF16(IDS_PRODUCT_NAME), | 104 parent, l10n_util::GetStringUTF16(IDS_PRODUCT_NAME), |
| 144 l10n_util::GetStringFUTF16(IDS_BOOKMARK_BAR_SHOULD_OPEN_ALL, | 105 l10n_util::GetStringFUTF16(IDS_BOOKMARK_BAR_SHOULD_OPEN_ALL, |
| 145 base::IntToString16(child_count))) == | 106 base::SizeTToString16(child_count))) == |
| 146 MESSAGE_BOX_RESULT_YES; | 107 MESSAGE_BOX_RESULT_YES; |
| 147 } | 108 } |
| 148 #endif | 109 #endif |
| 149 | 110 |
| 150 // Returns the total number of descendants nodes. | 111 // Returns the total number of descendants nodes. |
| 151 int ChildURLCountTotal(const BookmarkNode* node) { | 112 int ChildURLCountTotal(const BookmarkNode* node) { |
| 152 int result = 0; | 113 int result = 0; |
| 153 for (int i = 0; i < node->child_count(); ++i) { | 114 for (int i = 0; i < node->child_count(); ++i) { |
| 154 const BookmarkNode* child = node->GetChild(i); | 115 const BookmarkNode* child = node->GetChild(i); |
| 155 result++; | 116 result++; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 178 void OpenAll(gfx::NativeWindow parent, | 139 void OpenAll(gfx::NativeWindow parent, |
| 179 content::PageNavigator* navigator, | 140 content::PageNavigator* navigator, |
| 180 const std::vector<const BookmarkNode*>& nodes, | 141 const std::vector<const BookmarkNode*>& nodes, |
| 181 WindowOpenDisposition initial_disposition, | 142 WindowOpenDisposition initial_disposition, |
| 182 content::BrowserContext* browser_context) { | 143 content::BrowserContext* browser_context) { |
| 183 if (!ShouldOpenAll(parent, nodes)) | 144 if (!ShouldOpenAll(parent, nodes)) |
| 184 return; | 145 return; |
| 185 | 146 |
| 186 // Opens all |nodes| of type URL and any children of |nodes| that are of type | 147 // 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 | 148 // 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 | 149 // 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 | 150 // 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 | 151 // case we want subsequent tabs to open in that window. |
| 191 // that window. | 152 |
| 192 bool opened_first_url = false; | 153 std::vector<GURL> urls = GetURLsToOpen( |
| 154 nodes, browser_context, |
| 155 initial_disposition == WindowOpenDisposition::OFF_THE_RECORD); |
| 156 |
| 193 WindowOpenDisposition disposition = initial_disposition; | 157 WindowOpenDisposition disposition = initial_disposition; |
| 194 OpenURLIterator iterator(nodes); | 158 for (std::vector<GURL>::const_iterator url_it = urls.begin(); |
| 195 while (iterator.has_next()) { | 159 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( | 160 content::WebContents* opened_tab = navigator->OpenURL( |
| 205 content::OpenURLParams(*url, content::Referrer(), disposition, | 161 content::OpenURLParams(*url_it, content::Referrer(), disposition, |
| 206 ui::PAGE_TRANSITION_AUTO_BOOKMARK, false)); | 162 ui::PAGE_TRANSITION_AUTO_BOOKMARK, false)); |
| 207 | 163 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 | 164 // 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 | 165 // the current page, reset the navigator just to be sure. |opened_tab| may |
| 213 // be NULL in tests. | 166 // be null in tests. |
| 214 if (opened_tab) | 167 if (opened_tab) |
| 215 navigator = opened_tab; | 168 navigator = opened_tab; |
| 169 disposition = WindowOpenDisposition::NEW_BACKGROUND_TAB; |
| 216 } | 170 } |
| 217 } | 171 } |
| 218 } | 172 } |
| 219 | 173 |
| 220 void OpenAll(gfx::NativeWindow parent, | 174 void OpenAll(gfx::NativeWindow parent, |
| 221 content::PageNavigator* navigator, | 175 content::PageNavigator* navigator, |
| 222 const BookmarkNode* node, | 176 const BookmarkNode* node, |
| 223 WindowOpenDisposition initial_disposition, | 177 WindowOpenDisposition initial_disposition, |
| 224 content::BrowserContext* browser_context) { | 178 content::BrowserContext* browser_context) { |
| 225 std::vector<const BookmarkNode*> nodes; | 179 std::vector<const BookmarkNode*> nodes; |
| 226 nodes.push_back(node); | 180 nodes.push_back(node); |
| 227 OpenAll(parent, navigator, nodes, initial_disposition, browser_context); | 181 OpenAll(parent, navigator, std::vector<const bookmarks::BookmarkNode*>{node}, |
| 182 initial_disposition, browser_context); |
| 183 } |
| 184 |
| 185 int OpenCount(gfx::NativeWindow parent, |
| 186 const std::vector<const bookmarks::BookmarkNode*>& nodes, |
| 187 content::BrowserContext* incognito_context) { |
| 188 return GetURLsToOpen(nodes, incognito_context, incognito_context != nullptr) |
| 189 .size(); |
| 190 } |
| 191 |
| 192 int OpenCount(gfx::NativeWindow parent, |
| 193 const BookmarkNode* node, |
| 194 content::BrowserContext* incognito_context) { |
| 195 std::vector<const BookmarkNode*> nodes; |
| 196 nodes.push_back(node); |
| 197 return OpenCount(parent, std::vector<const bookmarks::BookmarkNode*>{node}, |
| 198 incognito_context); |
| 228 } | 199 } |
| 229 | 200 |
| 230 bool ConfirmDeleteBookmarkNode(const BookmarkNode* node, | 201 bool ConfirmDeleteBookmarkNode(const BookmarkNode* node, |
| 231 gfx::NativeWindow window) { | 202 gfx::NativeWindow window) { |
| 232 DCHECK(node && node->is_folder() && !node->empty()); | 203 DCHECK(node && node->is_folder() && !node->empty()); |
| 233 return ShowQuestionMessageBox( | 204 return ShowQuestionMessageBox( |
| 234 window, l10n_util::GetStringUTF16(IDS_PRODUCT_NAME), | 205 window, l10n_util::GetStringUTF16(IDS_PRODUCT_NAME), |
| 235 l10n_util::GetPluralStringFUTF16( | 206 l10n_util::GetPluralStringFUTF16( |
| 236 IDS_BOOKMARK_EDITOR_CONFIRM_DELETE, | 207 IDS_BOOKMARK_EDITOR_CONFIRM_DELETE, |
| 237 ChildURLCountTotal(node))) == | 208 ChildURLCountTotal(node))) == |
| 238 MESSAGE_BOX_RESULT_YES; | 209 MESSAGE_BOX_RESULT_YES; |
| 239 } | 210 } |
| 240 | 211 |
| 241 void ShowBookmarkAllTabsDialog(Browser* browser) { | 212 void ShowBookmarkAllTabsDialog(Browser* browser) { |
| 242 Profile* profile = browser->profile(); | 213 Profile* profile = browser->profile(); |
| 243 BookmarkModel* model = BookmarkModelFactory::GetForBrowserContext(profile); | 214 BookmarkModel* model = BookmarkModelFactory::GetForBrowserContext(profile); |
| 244 DCHECK(model && model->loaded()); | 215 DCHECK(model && model->loaded()); |
| 245 | 216 |
| 246 const BookmarkNode* parent = GetParentForNewNodes(model); | 217 const BookmarkNode* parent = GetParentForNewNodes(model); |
| 247 BookmarkEditor::EditDetails details = | 218 BookmarkEditor::EditDetails details = |
| 248 BookmarkEditor::EditDetails::AddFolder(parent, parent->child_count()); | 219 BookmarkEditor::EditDetails::AddFolder(parent, parent->child_count()); |
| 249 GetURLsForOpenTabs(browser, &(details.urls)); | 220 GetURLsForOpenTabs(browser, &(details.urls)); |
| 250 DCHECK(!details.urls.empty()); | 221 DCHECK(!details.urls.empty()); |
| 251 | 222 |
| 252 BookmarkEditor::Show(browser->window()->GetNativeWindow(), profile, details, | 223 BookmarkEditor::Show(browser->window()->GetNativeWindow(), profile, details, |
| 253 BookmarkEditor::SHOW_TREE); | 224 BookmarkEditor::SHOW_TREE); |
| 254 } | 225 } |
| 255 | 226 |
| 256 bool HasBookmarkURLs(const std::vector<const BookmarkNode*>& selection) { | 227 bool HasBookmarkURLs(const std::vector<const BookmarkNode*>& selection) { |
| 257 OpenURLIterator iterator(selection); | 228 return !GetURLsToOpen(selection).empty(); |
| 258 return iterator.has_next(); | |
| 259 } | 229 } |
| 260 | 230 |
| 261 bool HasBookmarkURLsAllowedInIncognitoMode( | 231 bool HasBookmarkURLsAllowedInIncognitoMode( |
| 262 const std::vector<const BookmarkNode*>& selection, | 232 const std::vector<const BookmarkNode*>& selection, |
| 263 content::BrowserContext* browser_context) { | 233 content::BrowserContext* browser_context) { |
| 264 OpenURLIterator iterator(selection); | 234 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 } | 235 } |
| 272 #endif // !defined(OS_ANDROID) | 236 #endif // !defined(OS_ANDROID) |
| 273 | 237 |
| 274 } // namespace chrome | 238 } // namespace chrome |
| OLD | NEW |