15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/bookmarks/bookmark_utils.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/basictypes.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/bookmarks/bookmark_model_factory.h" 12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/extensions/api/commands/command_service.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/search/search.h" 151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/ui/app_list/app_list_util.h" 16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/ui/bookmarks/bookmark_editor.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_navigator.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_window.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/simple_message_box.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/pref_names.h" 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/common/url_constants.h" 241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/grit/chromium_strings.h" 251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/grit/generated_resources.h" 26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/bookmarks/browser/bookmark_model.h" 275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "components/search/search.h" 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "components/user_prefs/user_prefs.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h" 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/net_util.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(ENABLE_EXTENSIONS) 341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/extension_registry.h" 351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/common/extension_set.h" 361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif 371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chrome { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int num_bookmark_urls_before_prompting = 15; 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// The ways in which extensions may customize the bookmark shortcut. 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)enum BookmarkShortcutDisposition { 46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BOOKMARK_SHORTCUT_DISPOSITION_UNCHANGED, 47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BOOKMARK_SHORTCUT_DISPOSITION_REMOVED, 48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BOOKMARK_SHORTCUT_DISPOSITION_OVERRIDDEN 49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}; 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Iterator that iterates through a set of BookmarkNodes returning the URLs 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// for nodes that are urls, or the URLs for the children of non-url urls. 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This does not recurse through all descendants, only immediate children. 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The following illustrates 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// typical usage: 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// OpenURLIterator iterator(nodes); 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// while (iterator.has_next()) { 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// const GURL* url = iterator.NextURL(); 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// // do something with |urll|. 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// } 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class OpenURLIterator { 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) explicit OpenURLIterator(const std::vector<const BookmarkNode*>& nodes) 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : child_index_(0), 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) next_(NULL), 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) parent_(nodes.begin()), 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) end_(nodes.end()) { 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FindNext(); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool has_next() { return next_ != NULL;} 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL* NextURL() { 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!has_next()) { 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED(); 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL* next = next_; 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FindNext(); 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return next; 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Seach next node which has URL. 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void FindNext() { 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (; parent_ < end_; ++parent_, child_index_ = 0) { 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((*parent_)->is_url()) { 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) next_ = &(*parent_)->url(); 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++parent_; 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child_index_ = 0; 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (; child_index_ < (*parent_)->child_count(); ++child_index_) { 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const BookmarkNode* child = (*parent_)->GetChild(child_index_); 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (child->is_url()) { 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) next_ = &child->url(); 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++child_index_; 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) next_ = NULL; 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int child_index_; 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL* next_; 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<const BookmarkNode*>::const_iterator parent_; 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::vector<const BookmarkNode*>::const_iterator end_; 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(OpenURLIterator); 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ShouldOpenAll(gfx::NativeWindow parent, 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<const BookmarkNode*>& nodes) { 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int child_count = 0; 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OpenURLIterator iterator(nodes); 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (iterator.has_next()) { 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iterator.NextURL(); 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child_count++; 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (child_count < num_bookmark_urls_before_prompting) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ShowMessageBox(parent, 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l10n_util::GetStringUTF16(IDS_PRODUCT_NAME), 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l10n_util::GetStringFUTF16(IDS_BOOKMARK_BAR_SHOULD_OPEN_ALL, 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::IntToString16(child_count)), 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MESSAGE_BOX_TYPE_QUESTION) == MESSAGE_BOX_RESULT_YES; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns the total number of descendants nodes. 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ChildURLCountTotal(const BookmarkNode* node) { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int result = 0; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < node->child_count(); ++i) { 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* child = node->GetChild(i); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result++; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (child->is_folder()) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result += ChildURLCountTotal(child); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns in |urls|, the url and title pairs for each open tab in browser. 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetURLsForOpenTabs(Browser* browser, 148a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::vector<std::pair<GURL, base::string16> >* urls) { 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int i = 0; i < browser->tab_strip_model()->count(); ++i) { 150a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::pair<GURL, base::string16> entry; 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetURLAndTitleToBookmark(browser->tab_strip_model()->GetWebContentsAt(i), 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &(entry.first), &(entry.second)); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) urls->push_back(entry); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Indicates how the bookmark shortcut has been changed by extensions associated 158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// with |profile|, if at all. 159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)BookmarkShortcutDisposition GetBookmarkShortcutDisposition(Profile* profile) { 1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(ENABLE_EXTENSIONS) 161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) extensions::CommandService* command_service = 162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) extensions::CommandService::Get(profile); 163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) extensions::ExtensionRegistry* registry = 165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) extensions::ExtensionRegistry::Get(profile); 166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!registry) 167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return BOOKMARK_SHORTCUT_DISPOSITION_UNCHANGED; 168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const extensions::ExtensionSet& extension_set = 170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) registry->enabled_extensions(); 171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // This flag tracks whether any extension wants the disposition to be 173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // removed. 174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool removed = false; 175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (extensions::ExtensionSet::const_iterator i = extension_set.begin(); 176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) i != extension_set.end(); 177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ++i) { 178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Use the overridden disposition if any extension wants it. 1791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (command_service->OverridesBookmarkShortcut(i->get())) 180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return BOOKMARK_SHORTCUT_DISPOSITION_OVERRIDDEN; 181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!removed && 1831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci extensions::CommandService::RemovesBookmarkShortcut(i->get())) { 184a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) removed = true; 1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (removed) 189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return BOOKMARK_SHORTCUT_DISPOSITION_REMOVED; 1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif 191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return BOOKMARK_SHORTCUT_DISPOSITION_UNCHANGED; 192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OpenAll(gfx::NativeWindow parent, 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::PageNavigator* navigator, 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<const BookmarkNode*>& nodes, 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WindowOpenDisposition initial_disposition, 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::BrowserContext* browser_context) { 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ShouldOpenAll(parent, nodes)) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Opens all |nodes| of type URL and any children of |nodes| that are of type 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // URL. |navigator| is the PageNavigator used to open URLs. After the first 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // url is opened |opened_first_url| is set to true and |navigator| is set to 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the PageNavigator of the last active tab. This is done to handle a window 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // disposition of new window, in which case we want subsequent tabs to open in 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // that window. 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool opened_first_url = false; 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WindowOpenDisposition disposition = initial_disposition; 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OpenURLIterator iterator(nodes); 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (iterator.has_next()) { 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL* url = iterator.NextURL(); 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // When |initial_disposition| is OFF_THE_RECORD, a node which can't be 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // opened in incognito window, it is detected using |browser_context|, is 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // not opened. 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (initial_disposition == OFF_THE_RECORD && 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !IsURLAllowedInIncognito(*url, browser_context)) 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::WebContents* opened_tab = navigator->OpenURL( 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::OpenURLParams(*url, content::Referrer(), disposition, 2241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ui::PAGE_TRANSITION_AUTO_BOOKMARK, false)); 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!opened_first_url) { 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) opened_first_url = true; 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) disposition = NEW_BACKGROUND_TAB; 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We opened the first URL which may have opened a new window or clobbered 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the current page, reset the navigator just to be sure. |opened_tab| may 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // be NULL in tests. 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (opened_tab) 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) navigator = opened_tab; 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OpenAll(gfx::NativeWindow parent, 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::PageNavigator* navigator, 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node, 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WindowOpenDisposition initial_disposition, 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::BrowserContext* browser_context) { 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<const BookmarkNode*> nodes; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nodes.push_back(node); 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OpenAll(parent, navigator, nodes, initial_disposition, browser_context); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ConfirmDeleteBookmarkNode(const BookmarkNode* node, 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::NativeWindow window) { 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(node && node->is_folder() && !node->empty()); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ShowMessageBox(window, 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l10n_util::GetStringUTF16(IDS_PRODUCT_NAME), 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l10n_util::GetStringFUTF16Int(IDS_BOOKMARK_EDITOR_CONFIRM_DELETE, 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChildURLCountTotal(node)), 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MESSAGE_BOX_TYPE_QUESTION) == MESSAGE_BOX_RESULT_YES; 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ShowBookmarkAllTabsDialog(Browser* browser) { 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile = browser->profile(); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile); 261b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) DCHECK(model && model->loaded()); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const BookmarkNode* parent = model->GetParentForNewNodes(); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkEditor::EditDetails details = 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BookmarkEditor::EditDetails::AddFolder(parent, parent->child_count()); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetURLsForOpenTabs(browser, &(details.urls)); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!details.urls.empty()); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkEditor::Show(browser->window()->GetNativeWindow(), profile, details, 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkEditor::SHOW_TREE); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HasBookmarkURLs(const std::vector<const BookmarkNode*>& selection) { 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OpenURLIterator iterator(selection); 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return iterator.has_next(); 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool HasBookmarkURLsAllowedInIncognitoMode( 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::vector<const BookmarkNode*>& selection, 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::BrowserContext* browser_context) { 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OpenURLIterator iterator(selection); 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (iterator.has_next()) { 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL* url = iterator.NextURL(); 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (IsURLAllowedInIncognito(*url, browser_context)) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)GURL GetURLToBookmark(content::WebContents* web_contents) { 291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(web_contents); 292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return IsInstantNTP(web_contents) ? 293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GURL(kChromeUINewTabURL) : web_contents->GetURL(); 294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetURLAndTitleToBookmark(content::WebContents* web_contents, 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL* url, 298a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16* title) { 299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *url = GetURLToBookmark(web_contents); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *title = web_contents->GetTitle(); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ToggleBookmarkBarWhenVisible(content::BrowserContext* browser_context) { 3045e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) PrefService* prefs = user_prefs::UserPrefs::Get(browser_context); 3051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const bool always_show = 3061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci !prefs->GetBoolean(bookmarks::prefs::kShowBookmarkBar); 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The user changed when the bookmark bar is shown, update the preferences. 3091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci prefs->SetBoolean(bookmarks::prefs::kShowBookmarkBar, always_show); 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 FormatBookmarkURLForDisplay(const GURL& url, 3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const PrefService* prefs) { 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string languages; 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (prefs) 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) languages = prefs->GetString(prefs::kAcceptLanguages); 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Because this gets re-parsed by FixupURL(), it's safe to omit the scheme 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // and trailing slash, and unescape most characters. However, it's 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // important not to drop any username/password, or unescape anything that 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // changes the URL's meaning. 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return net::FormatUrl( 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) url, languages, 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::kFormatUrlOmitAll & ~net::kFormatUrlOmitUsernamePassword, 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::UnescapeRule::SPACES, NULL, NULL, NULL); 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 328f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool IsAppsShortcutEnabled(Profile* profile, 329f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) chrome::HostDesktopType host_desktop_type) { 330f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Supervised users can not have apps installed currently so there's no need 331f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // to show the apps shortcut. 332f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (profile->IsSupervised()) 3337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return false; 3347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 335f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Don't show the apps shortcut in ash since the app launcher is enabled. 336f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (host_desktop_type == chrome::HOST_DESKTOP_TYPE_ASH) 337f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return false; 338f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 339f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return chrome::IsInstantExtendedAPIEnabled() && !profile->IsOffTheRecord(); 340f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 341f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 342f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool ShouldShowAppsShortcutInBookmarkBar( 343f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Profile* profile, 344f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) chrome::HostDesktopType host_desktop_type) { 345f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return IsAppsShortcutEnabled(profile, host_desktop_type) && 3461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci profile->GetPrefs()->GetBoolean( 3471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bookmarks::prefs::kShowAppsShortcutInBookmarkBar); 348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 350a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ShouldRemoveBookmarkThisPageUI(Profile* profile) { 351a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return GetBookmarkShortcutDisposition(profile) == 352a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BOOKMARK_SHORTCUT_DISPOSITION_REMOVED; 353a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 354a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 355effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbool ShouldRemoveBookmarkOpenPagesUI(Profile* profile) { 3561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(ENABLE_EXTENSIONS) 357effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch extensions::ExtensionRegistry* registry = 358effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch extensions::ExtensionRegistry::Get(profile); 359effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!registry) 360effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return false; 361effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 362effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const extensions::ExtensionSet& extension_set = 363effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch registry->enabled_extensions(); 364effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 365effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch for (extensions::ExtensionSet::const_iterator i = extension_set.begin(); 366effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch i != extension_set.end(); 367effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ++i) { 3681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (extensions::CommandService::RemovesBookmarkOpenPagesShortcut(i->get())) 369effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return true; 370effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 3711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif 372effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 373effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return false; 374effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 375effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace chrome 377