Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(205)

Side by Side Diff: chrome/browser/bookmarks/bookmark_model.cc

Issue 1912: Renames BoomarkBarModel to BookmarkModel. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 12 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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/bookmarks/bookmark_bar_model.h" 5 #include "chrome/browser/bookmarks/bookmark_model.h"
6 6
7 #include "base/gfx/png_decoder.h" 7 #include "base/gfx/png_decoder.h"
8 #include "chrome/browser/bookmarks/bookmark_storage.h" 8 #include "chrome/browser/bookmarks/bookmark_storage.h"
9 #include "chrome/browser/history/query_parser.h" 9 #include "chrome/browser/history/query_parser.h"
10 #include "chrome/browser/profile.h" 10 #include "chrome/browser/profile.h"
11 #include "chrome/common/scoped_vector.h" 11 #include "chrome/common/scoped_vector.h"
12 12
13 #include "generated_resources.h" 13 #include "generated_resources.h"
14 14
15 namespace { 15 namespace {
16 16
17 // Functions used for sorting. 17 // Functions used for sorting.
18 bool MoreRecentlyModified(BookmarkBarNode* n1, BookmarkBarNode* n2) { 18 bool MoreRecentlyModified(BookmarkNode* n1, BookmarkNode* n2) {
19 return n1->date_group_modified() > n2->date_group_modified(); 19 return n1->date_group_modified() > n2->date_group_modified();
20 } 20 }
21 21
22 bool MoreRecentlyAdded(BookmarkBarNode* n1, BookmarkBarNode* n2) { 22 bool MoreRecentlyAdded(BookmarkNode* n1, BookmarkNode* n2) {
23 return n1->date_added() > n2->date_added(); 23 return n1->date_added() > n2->date_added();
24 } 24 }
25 25
26 } // namespace 26 } // namespace
27 27
28 // BookmarkBarNode ------------------------------------------------------------ 28 // BookmarkNode ---------------------------------------------------------------
29 29
30 namespace { 30 namespace {
31 31
32 // ID for BookmarkBarNodes. 32 // ID for BookmarkNodes.
33 // Various places assume an invalid id if == 0, for that reason we start with 1. 33 // Various places assume an invalid id if == 0, for that reason we start with 1.
34 int next_id_ = 1; 34 int next_id_ = 1;
35 35
36 } 36 }
37 37
38 const SkBitmap& BookmarkBarNode::GetFavIcon() { 38 const SkBitmap& BookmarkNode::GetFavIcon() {
39 if (!loaded_favicon_) { 39 if (!loaded_favicon_) {
40 loaded_favicon_ = true; 40 loaded_favicon_ = true;
41 model_->LoadFavIcon(this); 41 model_->LoadFavIcon(this);
42 } 42 }
43 return favicon_; 43 return favicon_;
44 } 44 }
45 45
46 BookmarkBarNode::BookmarkBarNode(BookmarkBarModel* model, const GURL& url) 46 BookmarkNode::BookmarkNode(BookmarkModel* model, const GURL& url)
47 : model_(model), 47 : model_(model),
48 id_(next_id_++), 48 id_(next_id_++),
49 loaded_favicon_(false), 49 loaded_favicon_(false),
50 favicon_load_handle_(0), 50 favicon_load_handle_(0),
51 url_(url), 51 url_(url),
52 type_(!url.is_empty() ? history::StarredEntry::URL : 52 type_(!url.is_empty() ? history::StarredEntry::URL :
53 history::StarredEntry::BOOKMARK_BAR), 53 history::StarredEntry::BOOKMARK_BAR),
54 date_added_(Time::Now()) { 54 date_added_(Time::Now()) {
55 } 55 }
56 56
57 void BookmarkBarNode::Reset(const history::StarredEntry& entry) { 57 void BookmarkNode::Reset(const history::StarredEntry& entry) {
58 DCHECK(entry.type != history::StarredEntry::URL || 58 DCHECK(entry.type != history::StarredEntry::URL ||
59 entry.url == url_); 59 entry.url == url_);
60 60
61 favicon_ = SkBitmap(); 61 favicon_ = SkBitmap();
62 type_ = entry.type; 62 type_ = entry.type;
63 date_added_ = entry.date_added; 63 date_added_ = entry.date_added;
64 date_group_modified_ = entry.date_group_modified; 64 date_group_modified_ = entry.date_group_modified;
65 SetTitle(entry.title); 65 SetTitle(entry.title);
66 } 66 }
67 67
68 // BookmarkBarModel ----------------------------------------------------------- 68 // BookmarkModel --------------------------------------------------------------
69 69
70 BookmarkBarModel::BookmarkBarModel(Profile* profile) 70 BookmarkModel::BookmarkModel(Profile* profile)
71 : profile_(profile), 71 : profile_(profile),
72 loaded_(false), 72 loaded_(false),
73 #pragma warning(suppress: 4355) // Okay to pass "this" here. 73 #pragma warning(suppress: 4355) // Okay to pass "this" here.
74 root_(this, GURL()), 74 root_(this, GURL()),
75 bookmark_bar_node_(NULL), 75 bookmark_bar_node_(NULL),
76 other_node_(NULL), 76 other_node_(NULL),
77 waiting_for_history_load_(false), 77 waiting_for_history_load_(false),
78 loaded_signal_(CreateEvent(NULL, TRUE, FALSE, NULL)) { 78 loaded_signal_(CreateEvent(NULL, TRUE, FALSE, NULL)) {
79 // Create the bookmark bar and other bookmarks folders. These always exist. 79 // Create the bookmark bar and other bookmarks folders. These always exist.
80 CreateBookmarkBarNode(); 80 CreateBookmarkNode();
81 CreateOtherBookmarksNode(); 81 CreateOtherBookmarksNode();
82 82
83 // And add them to the root. 83 // And add them to the root.
84 // 84 //
85 // WARNING: order is important here, various places assume bookmark bar then 85 // WARNING: order is important here, various places assume bookmark bar then
86 // other node. 86 // other node.
87 root_.Add(0, bookmark_bar_node_); 87 root_.Add(0, bookmark_bar_node_);
88 root_.Add(1, other_node_); 88 root_.Add(1, other_node_);
89 89
90 if (!profile_) { 90 if (!profile_) {
91 // Profile is null during testing. 91 // Profile is null during testing.
92 DoneLoading(); 92 DoneLoading();
93 } 93 }
94 } 94 }
95 95
96 BookmarkBarModel::~BookmarkBarModel() { 96 BookmarkModel::~BookmarkModel() {
97 if (profile_ && store_.get()) { 97 if (profile_ && store_.get()) {
98 NotificationService::current()->RemoveObserver( 98 NotificationService::current()->RemoveObserver(
99 this, NOTIFY_FAVICON_CHANGED, Source<Profile>(profile_)); 99 this, NOTIFY_FAVICON_CHANGED, Source<Profile>(profile_));
100 } 100 }
101 101
102 if (waiting_for_history_load_) { 102 if (waiting_for_history_load_) {
103 NotificationService::current()->RemoveObserver( 103 NotificationService::current()->RemoveObserver(
104 this, NOTIFY_HISTORY_LOADED, Source<Profile>(profile_)); 104 this, NOTIFY_HISTORY_LOADED, Source<Profile>(profile_));
105 } 105 }
106 106
107 FOR_EACH_OBSERVER(BookmarkBarModelObserver, observers_, 107 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_,
108 BookmarkModelBeingDeleted(this)); 108 BookmarkModelBeingDeleted(this));
109 109
110 if (store_) { 110 if (store_) {
111 // The store maintains a reference back to us. We need to tell it we're gone 111 // The store maintains a reference back to us. We need to tell it we're gone
112 // so that it doesn't try and invoke a method back on us again. 112 // so that it doesn't try and invoke a method back on us again.
113 store_->BookmarkModelDeleted(); 113 store_->BookmarkModelDeleted();
114 } 114 }
115 } 115 }
116 116
117 void BookmarkBarModel::Load() { 117 void BookmarkModel::Load() {
118 if (store_.get()) { 118 if (store_.get()) {
119 // If the store is non-null, it means Load was already invoked. Load should 119 // If the store is non-null, it means Load was already invoked. Load should
120 // only be invoked once. 120 // only be invoked once.
121 NOTREACHED(); 121 NOTREACHED();
122 return; 122 return;
123 } 123 }
124 124
125 // Listen for changes to favicons so that we can update the favicon of the 125 // Listen for changes to favicons so that we can update the favicon of the
126 // node appropriately. 126 // node appropriately.
127 NotificationService::current()->AddObserver( 127 NotificationService::current()->AddObserver(
128 this, NOTIFY_FAVICON_CHANGED, Source<Profile>(profile_)); 128 this, NOTIFY_FAVICON_CHANGED, Source<Profile>(profile_));
129 129
130 // Load the bookmarks. BookmarkStorage notifies us when done. 130 // Load the bookmarks. BookmarkStorage notifies us when done.
131 store_ = new BookmarkStorage(profile_, this); 131 store_ = new BookmarkStorage(profile_, this);
132 store_->LoadBookmarks(false); 132 store_->LoadBookmarks(false);
133 } 133 }
134 134
135 BookmarkBarNode* BookmarkBarModel::GetParentForNewNodes() { 135 BookmarkNode* BookmarkModel::GetParentForNewNodes() {
136 std::vector<BookmarkBarNode*> nodes; 136 std::vector<BookmarkNode*> nodes;
137 137
138 GetMostRecentlyModifiedGroupNodes(&root_, 1, &nodes); 138 GetMostRecentlyModifiedGroupNodes(&root_, 1, &nodes);
139 return nodes.empty() ? bookmark_bar_node_ : nodes[0]; 139 return nodes.empty() ? bookmark_bar_node_ : nodes[0];
140 } 140 }
141 141
142 std::vector<BookmarkBarNode*> BookmarkBarModel::GetMostRecentlyModifiedGroups( 142 std::vector<BookmarkNode*> BookmarkModel::GetMostRecentlyModifiedGroups(
143 size_t max_count) { 143 size_t max_count) {
144 std::vector<BookmarkBarNode*> nodes; 144 std::vector<BookmarkNode*> nodes;
145 GetMostRecentlyModifiedGroupNodes(&root_, max_count, &nodes); 145 GetMostRecentlyModifiedGroupNodes(&root_, max_count, &nodes);
146 146
147 if (nodes.size() < max_count) { 147 if (nodes.size() < max_count) {
148 // Add the bookmark bar and other nodes if there is space. 148 // Add the bookmark bar and other nodes if there is space.
149 if (find(nodes.begin(), nodes.end(), bookmark_bar_node_) == nodes.end()) 149 if (find(nodes.begin(), nodes.end(), bookmark_bar_node_) == nodes.end())
150 nodes.push_back(bookmark_bar_node_); 150 nodes.push_back(bookmark_bar_node_);
151 151
152 if (nodes.size() < max_count && 152 if (nodes.size() < max_count &&
153 find(nodes.begin(), nodes.end(), other_node_) == nodes.end()) { 153 find(nodes.begin(), nodes.end(), other_node_) == nodes.end()) {
154 nodes.push_back(other_node_); 154 nodes.push_back(other_node_);
155 } 155 }
156 } 156 }
157 return nodes; 157 return nodes;
158 } 158 }
159 159
160 void BookmarkBarModel::GetMostRecentlyAddedEntries( 160 void BookmarkModel::GetMostRecentlyAddedEntries(
161 size_t count, 161 size_t count,
162 std::vector<BookmarkBarNode*>* nodes) { 162 std::vector<BookmarkNode*>* nodes) {
163 AutoLock url_lock(url_lock_); 163 AutoLock url_lock(url_lock_);
164 for (NodesOrderedByURLSet::iterator i = nodes_ordered_by_url_set_.begin(); 164 for (NodesOrderedByURLSet::iterator i = nodes_ordered_by_url_set_.begin();
165 i != nodes_ordered_by_url_set_.end(); ++i) { 165 i != nodes_ordered_by_url_set_.end(); ++i) {
166 std::vector<BookmarkBarNode*>::iterator insert_position = 166 std::vector<BookmarkNode*>::iterator insert_position =
167 std::upper_bound(nodes->begin(), nodes->end(), *i, &MoreRecentlyAdded); 167 std::upper_bound(nodes->begin(), nodes->end(), *i, &MoreRecentlyAdded);
168 if (nodes->size() < count || insert_position != nodes->end()) { 168 if (nodes->size() < count || insert_position != nodes->end()) {
169 nodes->insert(insert_position, *i); 169 nodes->insert(insert_position, *i);
170 while (nodes->size() > count) 170 while (nodes->size() > count)
171 nodes->pop_back(); 171 nodes->pop_back();
172 } 172 }
173 } 173 }
174 } 174 }
175 175
176 void BookmarkBarModel::GetBookmarksMatchingText( 176 void BookmarkModel::GetBookmarksMatchingText(
177 const std::wstring& text, 177 const std::wstring& text,
178 size_t max_count, 178 size_t max_count,
179 std::vector<TitleMatch>* matches) { 179 std::vector<TitleMatch>* matches) {
180 QueryParser parser; 180 QueryParser parser;
181 ScopedVector<QueryNode> query_nodes; 181 ScopedVector<QueryNode> query_nodes;
182 parser.ParseQuery(text, &query_nodes.get()); 182 parser.ParseQuery(text, &query_nodes.get());
183 if (query_nodes.empty()) 183 if (query_nodes.empty())
184 return; 184 return;
185 185
186 AutoLock url_lock(url_lock_); 186 AutoLock url_lock(url_lock_);
187 Snippet::MatchPositions match_position; 187 Snippet::MatchPositions match_position;
188 for (NodesOrderedByURLSet::iterator i = nodes_ordered_by_url_set_.begin(); 188 for (NodesOrderedByURLSet::iterator i = nodes_ordered_by_url_set_.begin();
189 i != nodes_ordered_by_url_set_.end(); ++i) { 189 i != nodes_ordered_by_url_set_.end(); ++i) {
190 if (parser.DoesQueryMatch((*i)->GetTitle(), query_nodes.get(), 190 if (parser.DoesQueryMatch((*i)->GetTitle(), query_nodes.get(),
191 &match_position)) { 191 &match_position)) {
192 matches->push_back(TitleMatch()); 192 matches->push_back(TitleMatch());
193 matches->back().node = *i; 193 matches->back().node = *i;
194 matches->back().match_positions.swap(match_position); 194 matches->back().match_positions.swap(match_position);
195 if (matches->size() == max_count) 195 if (matches->size() == max_count)
196 break; 196 break;
197 } 197 }
198 } 198 }
199 } 199 }
200 200
201 void BookmarkBarModel::Remove(BookmarkBarNode* parent, int index) { 201 void BookmarkModel::Remove(BookmarkNode* parent, int index) {
202 if (!loaded_ || !IsValidIndex(parent, index, false) || parent == &root_) { 202 if (!loaded_ || !IsValidIndex(parent, index, false) || parent == &root_) {
203 NOTREACHED(); 203 NOTREACHED();
204 return; 204 return;
205 } 205 }
206 RemoveAndDeleteNode(parent->GetChild(index)); 206 RemoveAndDeleteNode(parent->GetChild(index));
207 } 207 }
208 208
209 void BookmarkBarModel::Move(BookmarkBarNode* node, 209 void BookmarkModel::Move(BookmarkNode* node,
210 BookmarkBarNode* new_parent, 210 BookmarkNode* new_parent,
211 int index) { 211 int index) {
212 if (!loaded_ || !node || !IsValidIndex(new_parent, index, true) || 212 if (!loaded_ || !node || !IsValidIndex(new_parent, index, true) ||
213 new_parent == &root_ || node == &root_ || node == bookmark_bar_node_ || 213 new_parent == &root_ || node == &root_ || node == bookmark_bar_node_ ||
214 node == other_node_) { 214 node == other_node_) {
215 NOTREACHED(); 215 NOTREACHED();
216 return; 216 return;
217 } 217 }
218 218
219 if (new_parent->HasAncestor(node)) { 219 if (new_parent->HasAncestor(node)) {
220 // Can't make an ancestor of the node be a child of the node. 220 // Can't make an ancestor of the node be a child of the node.
221 NOTREACHED(); 221 NOTREACHED();
222 return; 222 return;
223 } 223 }
224 224
225 SetDateGroupModified(new_parent, Time::Now()); 225 SetDateGroupModified(new_parent, Time::Now());
226 226
227 BookmarkBarNode* old_parent = node->GetParent(); 227 BookmarkNode* old_parent = node->GetParent();
228 int old_index = old_parent->IndexOfChild(node); 228 int old_index = old_parent->IndexOfChild(node);
229 229
230 if (old_parent == new_parent && 230 if (old_parent == new_parent &&
231 (index == old_index || index == old_index + 1)) { 231 (index == old_index || index == old_index + 1)) {
232 // Node is already in this position, nothing to do. 232 // Node is already in this position, nothing to do.
233 return; 233 return;
234 } 234 }
235 235
236 if (old_parent == new_parent && index > old_index) 236 if (old_parent == new_parent && index > old_index)
237 index--; 237 index--;
238 new_parent->Add(index, node); 238 new_parent->Add(index, node);
239 239
240 if (store_.get()) 240 if (store_.get())
241 store_->ScheduleSave(); 241 store_->ScheduleSave();
242 242
243 FOR_EACH_OBSERVER(BookmarkBarModelObserver, observers_, 243 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_,
244 BookmarkNodeMoved(this, old_parent, old_index, 244 BookmarkNodeMoved(this, old_parent, old_index,
245 new_parent, index)); 245 new_parent, index));
246 } 246 }
247 247
248 void BookmarkBarModel::SetTitle(BookmarkBarNode* node, 248 void BookmarkModel::SetTitle(BookmarkNode* node,
249 const std::wstring& title) { 249 const std::wstring& title) {
250 if (!node) { 250 if (!node) {
251 NOTREACHED(); 251 NOTREACHED();
252 return; 252 return;
253 } 253 }
254 if (node->GetTitle() == title) 254 if (node->GetTitle() == title)
255 return; 255 return;
256 256
257 node->SetTitle(title); 257 node->SetTitle(title);
258 258
259 if (store_.get()) 259 if (store_.get())
260 store_->ScheduleSave(); 260 store_->ScheduleSave();
261 261
262 FOR_EACH_OBSERVER(BookmarkBarModelObserver, observers_, 262 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_,
263 BookmarkNodeChanged(this, node)); 263 BookmarkNodeChanged(this, node));
264 } 264 }
265 265
266 BookmarkBarNode* BookmarkBarModel::GetNodeByURL(const GURL& url) { 266 BookmarkNode* BookmarkModel::GetNodeByURL(const GURL& url) {
267 AutoLock url_lock(url_lock_); 267 AutoLock url_lock(url_lock_);
268 BookmarkBarNode tmp_node(this, url); 268 BookmarkNode tmp_node(this, url);
269 NodesOrderedByURLSet::iterator i = nodes_ordered_by_url_set_.find(&tmp_node); 269 NodesOrderedByURLSet::iterator i = nodes_ordered_by_url_set_.find(&tmp_node);
270 return (i != nodes_ordered_by_url_set_.end()) ? *i : NULL; 270 return (i != nodes_ordered_by_url_set_.end()) ? *i : NULL;
271 } 271 }
272 272
273 void BookmarkBarModel::GetBookmarks(std::vector<GURL>* urls) { 273 void BookmarkModel::GetBookmarks(std::vector<GURL>* urls) {
274 AutoLock url_lock(url_lock_); 274 AutoLock url_lock(url_lock_);
275 for (NodesOrderedByURLSet::iterator i = nodes_ordered_by_url_set_.begin(); 275 for (NodesOrderedByURLSet::iterator i = nodes_ordered_by_url_set_.begin();
276 i != nodes_ordered_by_url_set_.end(); ++i) { 276 i != nodes_ordered_by_url_set_.end(); ++i) {
277 urls->push_back((*i)->GetURL()); 277 urls->push_back((*i)->GetURL());
278 } 278 }
279 } 279 }
280 280
281 BookmarkBarNode* BookmarkBarModel::GetNodeByID(int id) { 281 BookmarkNode* BookmarkModel::GetNodeByID(int id) {
282 // TODO(sky): TreeNode needs a method that visits all nodes using a predicate. 282 // TODO(sky): TreeNode needs a method that visits all nodes using a predicate.
283 return GetNodeByID(&root_, id); 283 return GetNodeByID(&root_, id);
284 } 284 }
285 285
286 BookmarkBarNode* BookmarkBarModel::AddGroup( 286 BookmarkNode* BookmarkModel::AddGroup(
287 BookmarkBarNode* parent, 287 BookmarkNode* parent,
288 int index, 288 int index,
289 const std::wstring& title) { 289 const std::wstring& title) {
290 if (!loaded_ || parent == &root_ || !IsValidIndex(parent, index, true)) { 290 if (!loaded_ || parent == &root_ || !IsValidIndex(parent, index, true)) {
291 // Can't add to the root. 291 // Can't add to the root.
292 NOTREACHED(); 292 NOTREACHED();
293 return NULL; 293 return NULL;
294 } 294 }
295 295
296 BookmarkBarNode* new_node = new BookmarkBarNode(this, GURL()); 296 BookmarkNode* new_node = new BookmarkNode(this, GURL());
297 new_node->SetTitle(title); 297 new_node->SetTitle(title);
298 new_node->type_ = history::StarredEntry::USER_GROUP; 298 new_node->type_ = history::StarredEntry::USER_GROUP;
299 299
300 return AddNode(parent, index, new_node); 300 return AddNode(parent, index, new_node);
301 } 301 }
302 302
303 BookmarkBarNode* BookmarkBarModel::AddURL(BookmarkBarNode* parent, 303 BookmarkNode* BookmarkModel::AddURL(BookmarkNode* parent,
304 int index, 304 int index,
305 const std::wstring& title, 305 const std::wstring& title,
306 const GURL& url) { 306 const GURL& url) {
307 return AddURLWithCreationTime(parent, index, title, url, Time::Now()); 307 return AddURLWithCreationTime(parent, index, title, url, Time::Now());
308 } 308 }
309 309
310 BookmarkBarNode* BookmarkBarModel::AddURLWithCreationTime( 310 BookmarkNode* BookmarkModel::AddURLWithCreationTime(
311 BookmarkBarNode* parent, 311 BookmarkNode* parent,
312 int index, 312 int index,
313 const std::wstring& title, 313 const std::wstring& title,
314 const GURL& url, 314 const GURL& url,
315 const Time& creation_time) { 315 const Time& creation_time) {
316 if (!loaded_ || !url.is_valid() || parent == &root_ || 316 if (!loaded_ || !url.is_valid() || parent == &root_ ||
317 !IsValidIndex(parent, index, true)) { 317 !IsValidIndex(parent, index, true)) {
318 NOTREACHED(); 318 NOTREACHED();
319 return NULL; 319 return NULL;
320 } 320 }
321 321
322 BookmarkBarNode* existing_node = GetNodeByURL(url); 322 BookmarkNode* existing_node = GetNodeByURL(url);
323 if (existing_node) { 323 if (existing_node) {
324 Move(existing_node, parent, index); 324 Move(existing_node, parent, index);
325 SetTitle(existing_node, title); 325 SetTitle(existing_node, title);
326 return existing_node; 326 return existing_node;
327 } 327 }
328 328
329 SetDateGroupModified(parent, creation_time); 329 SetDateGroupModified(parent, creation_time);
330 330
331 BookmarkBarNode* new_node = new BookmarkBarNode(this, url); 331 BookmarkNode* new_node = new BookmarkNode(this, url);
332 new_node->SetTitle(title); 332 new_node->SetTitle(title);
333 new_node->date_added_ = creation_time; 333 new_node->date_added_ = creation_time;
334 new_node->type_ = history::StarredEntry::URL; 334 new_node->type_ = history::StarredEntry::URL;
335 335
336 AutoLock url_lock(url_lock_); 336 AutoLock url_lock(url_lock_);
337 nodes_ordered_by_url_set_.insert(new_node); 337 nodes_ordered_by_url_set_.insert(new_node);
338 338
339 return AddNode(parent, index, new_node); 339 return AddNode(parent, index, new_node);
340 } 340 }
341 341
342 void BookmarkBarModel::SetURLStarred(const GURL& url, 342 void BookmarkModel::SetURLStarred(const GURL& url,
343 const std::wstring& title, 343 const std::wstring& title,
344 bool is_starred) { 344 bool is_starred) {
345 BookmarkBarNode* node = GetNodeByURL(url); 345 BookmarkNode* node = GetNodeByURL(url);
346 if (is_starred && !node) { 346 if (is_starred && !node) {
347 // Add the url. 347 // Add the url.
348 BookmarkBarNode* parent = GetParentForNewNodes(); 348 BookmarkNode* parent = GetParentForNewNodes();
349 AddURL(parent, parent->GetChildCount(), title, url); 349 AddURL(parent, parent->GetChildCount(), title, url);
350 } else if (!is_starred && node) { 350 } else if (!is_starred && node) {
351 Remove(node->GetParent(), node->GetParent()->IndexOfChild(node)); 351 Remove(node->GetParent(), node->GetParent()->IndexOfChild(node));
352 } 352 }
353 } 353 }
354 354
355 void BookmarkBarModel::ResetDateGroupModified(BookmarkBarNode* node) { 355 void BookmarkModel::ResetDateGroupModified(BookmarkNode* node) {
356 SetDateGroupModified(node, Time()); 356 SetDateGroupModified(node, Time());
357 } 357 }
358 358
359 void BookmarkBarModel::FavIconLoaded(BookmarkBarNode* node) { 359 void BookmarkModel::FavIconLoaded(BookmarkNode* node) {
360 // Send out notification to the observer. 360 // Send out notification to the observer.
361 FOR_EACH_OBSERVER(BookmarkBarModelObserver, observers_, 361 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_,
362 BookmarkNodeFavIconLoaded(this, node)); 362 BookmarkNodeFavIconLoaded(this, node));
363 } 363 }
364 364
365 void BookmarkBarModel::RemoveNode(BookmarkBarNode* node, 365 void BookmarkModel::RemoveNode(BookmarkNode* node,
366 std::set<GURL>* removed_urls) { 366 std::set<GURL>* removed_urls) {
367 if (!loaded_ || !node || node == &root_ || node == bookmark_bar_node_ || 367 if (!loaded_ || !node || node == &root_ || node == bookmark_bar_node_ ||
368 node == other_node_) { 368 node == other_node_) {
369 NOTREACHED(); 369 NOTREACHED();
370 return; 370 return;
371 } 371 }
372 372
373 if (node->GetType() == history::StarredEntry::URL) { 373 if (node->GetType() == history::StarredEntry::URL) {
374 // NOTE: this is called in such a way that url_lock_ is already held. As 374 // NOTE: this is called in such a way that url_lock_ is already held. As
375 // such, this doesn't explicitly grab the lock. 375 // such, this doesn't explicitly grab the lock.
376 NodesOrderedByURLSet::iterator i = nodes_ordered_by_url_set_.find(node); 376 NodesOrderedByURLSet::iterator i = nodes_ordered_by_url_set_.find(node);
377 DCHECK(i != nodes_ordered_by_url_set_.end()); 377 DCHECK(i != nodes_ordered_by_url_set_.end());
378 nodes_ordered_by_url_set_.erase(i); 378 nodes_ordered_by_url_set_.erase(i);
379 removed_urls->insert(node->GetURL()); 379 removed_urls->insert(node->GetURL());
380 } 380 }
381 381
382 CancelPendingFavIconLoadRequests(node); 382 CancelPendingFavIconLoadRequests(node);
383 383
384 // Recurse through children. 384 // Recurse through children.
385 for (int i = node->GetChildCount() - 1; i >= 0; --i) 385 for (int i = node->GetChildCount() - 1; i >= 0; --i)
386 RemoveNode(node->GetChild(i), removed_urls); 386 RemoveNode(node->GetChild(i), removed_urls);
387 } 387 }
388 388
389 void BookmarkBarModel::OnBookmarkStorageLoadedBookmarks( 389 void BookmarkModel::OnBookmarkStorageLoadedBookmarks(
390 bool file_exists, 390 bool file_exists,
391 bool loaded_from_history) { 391 bool loaded_from_history) {
392 if (loaded_) { 392 if (loaded_) {
393 NOTREACHED(); 393 NOTREACHED();
394 return; 394 return;
395 } 395 }
396 396
397 if (file_exists || loaded_from_history || !profile_ || 397 if (file_exists || loaded_from_history || !profile_ ||
398 !profile_->GetHistoryService(Profile::EXPLICIT_ACCESS)) { 398 !profile_->GetHistoryService(Profile::EXPLICIT_ACCESS)) {
399 // The file exists, we're loaded. 399 // The file exists, we're loaded.
(...skipping 19 matching lines...) Expand all
419 if (!history->backend_loaded()) { 419 if (!history->backend_loaded()) {
420 // The backend isn't finished loading. Wait for it. 420 // The backend isn't finished loading. Wait for it.
421 waiting_for_history_load_ = true; 421 waiting_for_history_load_ = true;
422 NotificationService::current()->AddObserver( 422 NotificationService::current()->AddObserver(
423 this, NOTIFY_HISTORY_LOADED, Source<Profile>(profile_)); 423 this, NOTIFY_HISTORY_LOADED, Source<Profile>(profile_));
424 } else { 424 } else {
425 OnHistoryDone(); 425 OnHistoryDone();
426 } 426 }
427 } 427 }
428 428
429 void BookmarkBarModel::OnHistoryDone() { 429 void BookmarkModel::OnHistoryDone() {
430 if (loaded_) { 430 if (loaded_) {
431 NOTREACHED(); 431 NOTREACHED();
432 return; 432 return;
433 } 433 }
434 434
435 // If the bookmarks were stored in the db the db will have migrated them to 435 // If the bookmarks were stored in the db the db will have migrated them to
436 // a file now. Try loading from the file. 436 // a file now. Try loading from the file.
437 store_->LoadBookmarks(true); 437 store_->LoadBookmarks(true);
438 } 438 }
439 439
440 void BookmarkBarModel::DoneLoading() { 440 void BookmarkModel::DoneLoading() {
441 { 441 {
442 AutoLock url_lock(url_lock_); 442 AutoLock url_lock(url_lock_);
443 // Update nodes_ordered_by_url_set_ from the nodes. 443 // Update nodes_ordered_by_url_set_ from the nodes.
444 PopulateNodesByURL(&root_); 444 PopulateNodesByURL(&root_);
445 } 445 }
446 446
447 loaded_ = true; 447 loaded_ = true;
448 448
449 if (loaded_signal_.Get()) 449 if (loaded_signal_.Get())
450 SetEvent(loaded_signal_.Get()); 450 SetEvent(loaded_signal_.Get());
451 451
452 452
453 // Notify our direct observers. 453 // Notify our direct observers.
454 FOR_EACH_OBSERVER(BookmarkBarModelObserver, observers_, Loaded(this)); 454 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, Loaded(this));
455 455
456 // And generic notification. 456 // And generic notification.
457 NotificationService::current()->Notify( 457 NotificationService::current()->Notify(
458 NOTIFY_BOOKMARK_MODEL_LOADED, 458 NOTIFY_BOOKMARK_MODEL_LOADED,
459 Source<Profile>(profile_), 459 Source<Profile>(profile_),
460 NotificationService::NoDetails()); 460 NotificationService::NoDetails());
461 } 461 }
462 462
463 void BookmarkBarModel::RemoveAndDeleteNode(BookmarkBarNode* delete_me) { 463 void BookmarkModel::RemoveAndDeleteNode(BookmarkNode* delete_me) {
464 scoped_ptr<BookmarkBarNode> node(delete_me); 464 scoped_ptr<BookmarkNode> node(delete_me);
465 465
466 BookmarkBarNode* parent = node->GetParent(); 466 BookmarkNode* parent = node->GetParent();
467 DCHECK(parent); 467 DCHECK(parent);
468 int index = parent->IndexOfChild(node.get()); 468 int index = parent->IndexOfChild(node.get());
469 parent->Remove(index); 469 parent->Remove(index);
470 history::URLsStarredDetails details(false); 470 history::URLsStarredDetails details(false);
471 { 471 {
472 AutoLock url_lock(url_lock_); 472 AutoLock url_lock(url_lock_);
473 RemoveNode(node.get(), &details.changed_urls); 473 RemoveNode(node.get(), &details.changed_urls);
474 } 474 }
475 475
476 if (store_.get()) 476 if (store_.get())
477 store_->ScheduleSave(); 477 store_->ScheduleSave();
478 478
479 FOR_EACH_OBSERVER(BookmarkBarModelObserver, observers_, 479 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_,
480 BookmarkNodeRemoved(this, parent, index)); 480 BookmarkNodeRemoved(this, parent, index));
481 481
482 if (profile_) { 482 if (profile_) {
483 HistoryService* history = 483 HistoryService* history =
484 profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); 484 profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
485 if (history) 485 if (history)
486 history->URLsNoLongerBookmarked(details.changed_urls); 486 history->URLsNoLongerBookmarked(details.changed_urls);
487 } 487 }
488 488
489 NotificationService::current()->Notify(NOTIFY_URLS_STARRED, 489 NotificationService::current()->Notify(NOTIFY_URLS_STARRED,
490 Source<Profile>(profile_), 490 Source<Profile>(profile_),
491 Details<history::URLsStarredDetails>(&details)); 491 Details<history::URLsStarredDetails>(&details));
492 } 492 }
493 493
494 BookmarkBarNode* BookmarkBarModel::AddNode(BookmarkBarNode* parent, 494 BookmarkNode* BookmarkModel::AddNode(BookmarkNode* parent,
495 int index, 495 int index,
496 BookmarkBarNode* node) { 496 BookmarkNode* node) {
497 parent->Add(index, node); 497 parent->Add(index, node);
498 498
499 if (store_.get()) 499 if (store_.get())
500 store_->ScheduleSave(); 500 store_->ScheduleSave();
501 501
502 FOR_EACH_OBSERVER(BookmarkBarModelObserver, observers_, 502 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_,
503 BookmarkNodeAdded(this, parent, index)); 503 BookmarkNodeAdded(this, parent, index));
504 504
505 if (node->GetType() == history::StarredEntry::URL) { 505 if (node->GetType() == history::StarredEntry::URL) {
506 history::URLsStarredDetails details(true); 506 history::URLsStarredDetails details(true);
507 details.changed_urls.insert(node->GetURL()); 507 details.changed_urls.insert(node->GetURL());
508 NotificationService::current()->Notify(NOTIFY_URLS_STARRED, 508 NotificationService::current()->Notify(NOTIFY_URLS_STARRED,
509 Source<Profile>(profile_), 509 Source<Profile>(profile_),
510 Details<history::URLsStarredDetails>(&details)); 510 Details<history::URLsStarredDetails>(&details));
511 } 511 }
512 return node; 512 return node;
513 } 513 }
514 514
515 void BookmarkBarModel::BlockTillLoaded() { 515 void BookmarkModel::BlockTillLoaded() {
516 if (loaded_signal_.Get()) 516 if (loaded_signal_.Get())
517 WaitForSingleObject(loaded_signal_.Get(), INFINITE); 517 WaitForSingleObject(loaded_signal_.Get(), INFINITE);
518 } 518 }
519 519
520 BookmarkBarNode* BookmarkBarModel::GetNodeByID(BookmarkBarNode* node, 520 BookmarkNode* BookmarkModel::GetNodeByID(BookmarkNode* node, int id) {
521 int id) {
522 if (node->id() == id) 521 if (node->id() == id)
523 return node; 522 return node;
524 523
525 for (int i = 0; i < node->GetChildCount(); ++i) { 524 for (int i = 0; i < node->GetChildCount(); ++i) {
526 BookmarkBarNode* result = GetNodeByID(node->GetChild(i), id); 525 BookmarkNode* result = GetNodeByID(node->GetChild(i), id);
527 if (result) 526 if (result)
528 return result; 527 return result;
529 } 528 }
530 return NULL; 529 return NULL;
531 } 530 }
532 531
533 bool BookmarkBarModel::IsValidIndex(BookmarkBarNode* parent, 532 bool BookmarkModel::IsValidIndex(BookmarkNode* parent,
534 int index, 533 int index,
535 bool allow_end) { 534 bool allow_end) {
536 return (parent && 535 return (parent &&
537 (index >= 0 && (index < parent->GetChildCount() || 536 (index >= 0 && (index < parent->GetChildCount() ||
538 (allow_end && index == parent->GetChildCount())))); 537 (allow_end && index == parent->GetChildCount()))));
539 } 538 }
540 539
541 void BookmarkBarModel::SetDateGroupModified(BookmarkBarNode* parent, 540 void BookmarkModel::SetDateGroupModified(BookmarkNode* parent,
542 const Time time) { 541 const Time time) {
543 DCHECK(parent); 542 DCHECK(parent);
544 parent->date_group_modified_ = time; 543 parent->date_group_modified_ = time;
545 544
546 if (store_.get()) 545 if (store_.get())
547 store_->ScheduleSave(); 546 store_->ScheduleSave();
548 } 547 }
549 548
550 void BookmarkBarModel::CreateBookmarkBarNode() { 549 void BookmarkModel::CreateBookmarkNode() {
551 history::StarredEntry entry; 550 history::StarredEntry entry;
552 entry.type = history::StarredEntry::BOOKMARK_BAR; 551 entry.type = history::StarredEntry::BOOKMARK_BAR;
553 bookmark_bar_node_ = CreateRootNodeFromStarredEntry(entry); 552 bookmark_bar_node_ = CreateRootNodeFromStarredEntry(entry);
554 } 553 }
555 554
556 void BookmarkBarModel::CreateOtherBookmarksNode() { 555 void BookmarkModel::CreateOtherBookmarksNode() {
557 history::StarredEntry entry; 556 history::StarredEntry entry;
558 entry.type = history::StarredEntry::OTHER; 557 entry.type = history::StarredEntry::OTHER;
559 other_node_ = CreateRootNodeFromStarredEntry(entry); 558 other_node_ = CreateRootNodeFromStarredEntry(entry);
560 } 559 }
561 560
562 BookmarkBarNode* BookmarkBarModel::CreateRootNodeFromStarredEntry( 561 BookmarkNode* BookmarkModel::CreateRootNodeFromStarredEntry(
563 const history::StarredEntry& entry) { 562 const history::StarredEntry& entry) {
564 DCHECK(entry.type == history::StarredEntry::BOOKMARK_BAR || 563 DCHECK(entry.type == history::StarredEntry::BOOKMARK_BAR ||
565 entry.type == history::StarredEntry::OTHER); 564 entry.type == history::StarredEntry::OTHER);
566 BookmarkBarNode* node = new BookmarkBarNode(this, GURL()); 565 BookmarkNode* node = new BookmarkNode(this, GURL());
567 node->Reset(entry); 566 node->Reset(entry);
568 if (entry.type == history::StarredEntry::BOOKMARK_BAR) 567 if (entry.type == history::StarredEntry::BOOKMARK_BAR)
569 node->SetTitle(l10n_util::GetString(IDS_BOOMARK_BAR_FOLDER_NAME)); 568 node->SetTitle(l10n_util::GetString(IDS_BOOMARK_BAR_FOLDER_NAME));
570 else 569 else
571 node->SetTitle(l10n_util::GetString(IDS_BOOMARK_BAR_OTHER_FOLDER_NAME)); 570 node->SetTitle(l10n_util::GetString(IDS_BOOMARK_BAR_OTHER_FOLDER_NAME));
572 return node; 571 return node;
573 } 572 }
574 573
575 void BookmarkBarModel::OnFavIconDataAvailable( 574 void BookmarkModel::OnFavIconDataAvailable(
576 HistoryService::Handle handle, 575 HistoryService::Handle handle,
577 bool know_favicon, 576 bool know_favicon,
578 scoped_refptr<RefCountedBytes> data, 577 scoped_refptr<RefCountedBytes> data,
579 bool expired, 578 bool expired,
580 GURL icon_url) { 579 GURL icon_url) {
581 SkBitmap fav_icon; 580 SkBitmap fav_icon;
582 BookmarkBarNode* node = 581 BookmarkNode* node =
583 load_consumer_.GetClientData( 582 load_consumer_.GetClientData(
584 profile_->GetHistoryService(Profile::EXPLICIT_ACCESS), handle); 583 profile_->GetHistoryService(Profile::EXPLICIT_ACCESS), handle);
585 DCHECK(node); 584 DCHECK(node);
586 node->favicon_load_handle_ = 0; 585 node->favicon_load_handle_ = 0;
587 if (know_favicon && data.get() && 586 if (know_favicon && data.get() &&
588 PNGDecoder::Decode(&data->data, &fav_icon)) { 587 PNGDecoder::Decode(&data->data, &fav_icon)) {
589 node->favicon_ = fav_icon; 588 node->favicon_ = fav_icon;
590 FavIconLoaded(node); 589 FavIconLoaded(node);
591 } 590 }
592 } 591 }
593 592
594 void BookmarkBarModel::LoadFavIcon(BookmarkBarNode* node) { 593 void BookmarkModel::LoadFavIcon(BookmarkNode* node) {
595 if (node->GetType() != history::StarredEntry::URL) 594 if (node->GetType() != history::StarredEntry::URL)
596 return; 595 return;
597 596
598 DCHECK(node->GetURL().is_valid()); 597 DCHECK(node->GetURL().is_valid());
599 HistoryService* history_service = 598 HistoryService* history_service =
600 profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); 599 profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
601 if (!history_service) 600 if (!history_service)
602 return; 601 return;
603 602
604 HistoryService::Handle handle = history_service->GetFavIconForURL( 603 HistoryService::Handle handle = history_service->GetFavIconForURL(
605 node->GetURL(), &load_consumer_, 604 node->GetURL(), &load_consumer_,
606 NewCallback(this, &BookmarkBarModel::OnFavIconDataAvailable)); 605 NewCallback(this, &BookmarkModel::OnFavIconDataAvailable));
607 load_consumer_.SetClientData(history_service, handle, node); 606 load_consumer_.SetClientData(history_service, handle, node);
608 node->favicon_load_handle_ = handle; 607 node->favicon_load_handle_ = handle;
609 } 608 }
610 609
611 void BookmarkBarModel::CancelPendingFavIconLoadRequests(BookmarkBarNode* node) { 610 void BookmarkModel::CancelPendingFavIconLoadRequests(BookmarkNode* node) {
612 if (node->favicon_load_handle_) { 611 if (node->favicon_load_handle_) {
613 HistoryService* history = 612 HistoryService* history =
614 profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); 613 profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
615 if (history) 614 if (history)
616 history->CancelRequest(node->favicon_load_handle_); 615 history->CancelRequest(node->favicon_load_handle_);
617 node->favicon_load_handle_ = 0; 616 node->favicon_load_handle_ = 0;
618 } 617 }
619 } 618 }
620 619
621 void BookmarkBarModel::GetMostRecentlyModifiedGroupNodes( 620 void BookmarkModel::GetMostRecentlyModifiedGroupNodes(
622 BookmarkBarNode* parent, 621 BookmarkNode* parent,
623 size_t count, 622 size_t count,
624 std::vector<BookmarkBarNode*>* nodes) { 623 std::vector<BookmarkNode*>* nodes) {
625 if (parent != &root_ && parent->is_folder() && 624 if (parent != &root_ && parent->is_folder() &&
626 parent->date_group_modified() > Time()) { 625 parent->date_group_modified() > Time()) {
627 if (count == 0) { 626 if (count == 0) {
628 nodes->push_back(parent); 627 nodes->push_back(parent);
629 } else { 628 } else {
630 std::vector<BookmarkBarNode*>::iterator i = 629 std::vector<BookmarkNode*>::iterator i =
631 std::upper_bound(nodes->begin(), nodes->end(), parent, 630 std::upper_bound(nodes->begin(), nodes->end(), parent,
632 &MoreRecentlyModified); 631 &MoreRecentlyModified);
633 if (nodes->size() < count || i != nodes->end()) { 632 if (nodes->size() < count || i != nodes->end()) {
634 nodes->insert(i, parent); 633 nodes->insert(i, parent);
635 while (nodes->size() > count) 634 while (nodes->size() > count)
636 nodes->pop_back(); 635 nodes->pop_back();
637 } 636 }
638 } 637 }
639 } // else case, the root node, which we don't care about or imported nodes 638 } // else case, the root node, which we don't care about or imported nodes
640 // (which have a time of 0). 639 // (which have a time of 0).
641 for (int i = 0; i < parent->GetChildCount(); ++i) { 640 for (int i = 0; i < parent->GetChildCount(); ++i) {
642 BookmarkBarNode* child = parent->GetChild(i); 641 BookmarkNode* child = parent->GetChild(i);
643 if (child->is_folder()) 642 if (child->is_folder())
644 GetMostRecentlyModifiedGroupNodes(child, count, nodes); 643 GetMostRecentlyModifiedGroupNodes(child, count, nodes);
645 } 644 }
646 } 645 }
647 646
648 void BookmarkBarModel::Observe(NotificationType type, 647 void BookmarkModel::Observe(NotificationType type,
649 const NotificationSource& source, 648 const NotificationSource& source,
650 const NotificationDetails& details) { 649 const NotificationDetails& details) {
651 switch (type) { 650 switch (type) {
652 case NOTIFY_FAVICON_CHANGED: { 651 case NOTIFY_FAVICON_CHANGED: {
653 // Prevent the observers from getting confused for multiple favicon loads. 652 // Prevent the observers from getting confused for multiple favicon loads.
654 Details<history::FavIconChangeDetails> favicon_details(details); 653 Details<history::FavIconChangeDetails> favicon_details(details);
655 for (std::set<GURL>::const_iterator i = favicon_details->urls.begin(); 654 for (std::set<GURL>::const_iterator i = favicon_details->urls.begin();
656 i != favicon_details->urls.end(); ++i) { 655 i != favicon_details->urls.end(); ++i) {
657 BookmarkBarNode* node = GetNodeByURL(*i); 656 BookmarkNode* node = GetNodeByURL(*i);
658 if (node) { 657 if (node) {
659 // Got an updated favicon, for a URL, do a new request. 658 // Got an updated favicon, for a URL, do a new request.
660 node->InvalidateFavicon(); 659 node->InvalidateFavicon();
661 CancelPendingFavIconLoadRequests(node); 660 CancelPendingFavIconLoadRequests(node);
662 FOR_EACH_OBSERVER(BookmarkBarModelObserver, observers_, 661 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_,
663 BookmarkNodeChanged(this, node)); 662 BookmarkNodeChanged(this, node));
664 } 663 }
665 } 664 }
666 break; 665 break;
667 } 666 }
668 667
669 case NOTIFY_HISTORY_LOADED: { 668 case NOTIFY_HISTORY_LOADED: {
670 if (waiting_for_history_load_) { 669 if (waiting_for_history_load_) {
671 waiting_for_history_load_ = false; 670 waiting_for_history_load_ = false;
672 NotificationService::current()->RemoveObserver( 671 NotificationService::current()->RemoveObserver(
673 this, NOTIFY_HISTORY_LOADED, Source<Profile>(profile_)); 672 this, NOTIFY_HISTORY_LOADED, Source<Profile>(profile_));
674 OnHistoryDone(); 673 OnHistoryDone();
675 } else { 674 } else {
676 NOTREACHED(); 675 NOTREACHED();
677 } 676 }
678 break; 677 break;
679 } 678 }
680 679
681 default: 680 default:
682 NOTREACHED(); 681 NOTREACHED();
683 break; 682 break;
684 } 683 }
685 } 684 }
686 685
687 void BookmarkBarModel::PopulateNodesByURL(BookmarkBarNode* node) { 686 void BookmarkModel::PopulateNodesByURL(BookmarkNode* node) {
688 // NOTE: this is called with url_lock_ already held. As such, this doesn't 687 // NOTE: this is called with url_lock_ already held. As such, this doesn't
689 // explicitly grab the lock. 688 // explicitly grab the lock.
690 if (node->is_url()) 689 if (node->is_url())
691 nodes_ordered_by_url_set_.insert(node); 690 nodes_ordered_by_url_set_.insert(node);
692 for (int i = 0; i < node->GetChildCount(); ++i) 691 for (int i = 0; i < node->GetChildCount(); ++i)
693 PopulateNodesByURL(node->GetChild(i)); 692 PopulateNodesByURL(node->GetChild(i));
694 } 693 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698