1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
|
// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/cookies_table_model.h"
#include "app/l10n_util.h"
#include "app/table_model_observer.h"
#include "app/resource_bundle.h"
#include "base/string_util.h"
#include "chrome/browser/profile.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "net/url_request/url_request_context.h"
#include "third_party/skia/include/core/SkBitmap.h"
///////////////////////////////////////////////////////////////////////////////
// CookiesTableModel, public:
CookiesTableModel::CookiesTableModel(Profile* profile)
: profile_(profile) {
LoadCookies();
}
std::string CookiesTableModel::GetDomainAt(int index) {
DCHECK(index >= 0 && index < RowCount());
return shown_cookies_.at(index)->first;
}
net::CookieMonster::CanonicalCookie& CookiesTableModel::GetCookieAt(
int index) {
DCHECK(index >= 0 && index < RowCount());
return shown_cookies_.at(index)->second;
}
void CookiesTableModel::RemoveCookies(int start_index, int remove_count) {
if (remove_count <= 0) {
NOTREACHED();
return;
}
net::CookieMonster* monster =
profile_->GetRequestContext()->cookie_store()->GetCookieMonster();
// We need to update the searched results list, the full cookie list,
// and the view. We walk through the search results list (which is what
// is displayed) and map these back to the full cookie list. They should
// be in the same sort order, and always exist, so we can just walk once.
// We can't delete any entries from all_cookies_ without invaliding all of
// our pointers after it (which are in shown_cookies), so we go backwards.
CookiePtrList::iterator first = shown_cookies_.begin() + start_index;
CookiePtrList::iterator last = first + remove_count;
CookieList::iterator all_it = all_cookies_.end();
while (last != first) {
--last;
--all_it;
// Seek to the corresponding entry in all_cookies_
while (&*all_it != *last) --all_it;
// Delete the cookie from the monster
monster->DeleteCookie(all_it->first, all_it->second, true);
all_it = all_cookies_.erase(all_it);
}
// By deleting entries from all_cookies, we just possibly moved stuff around
// and have thus invalidated all of our pointers, so rebuild shown_cookies.
// We could do this all better if there was a way to mark elements of
// all_cookies as dead instead of deleting, but this should be fine for now.
DoFilter();
if (observer_)
observer_->OnItemsRemoved(start_index, remove_count);
}
void CookiesTableModel::RemoveAllShownCookies() {
RemoveCookies(0, RowCount());
}
///////////////////////////////////////////////////////////////////////////////
// CookiesTableModel, TableModel implementation:
int CookiesTableModel::RowCount() {
return static_cast<int>(shown_cookies_.size());
}
std::wstring CookiesTableModel::GetText(int row, int column_id) {
DCHECK(row >= 0 && row < RowCount());
switch (column_id) {
case IDS_COOKIES_DOMAIN_COLUMN_HEADER:
{
// Domain cookies start with a trailing dot, but we will show this
// in the cookie details, show it without the dot in the list.
std::string& domain = shown_cookies_.at(row)->first;
std::wstring wide_domain;
if (!domain.empty() && domain[0] == '.')
wide_domain = UTF8ToWide(domain.substr(1));
else
wide_domain = UTF8ToWide(domain);
// Force domain to be LTR
if (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT)
l10n_util::WrapStringWithLTRFormatting(&wide_domain);
return wide_domain;
}
break;
case IDS_COOKIES_NAME_COLUMN_HEADER: {
std::wstring name = UTF8ToWide(shown_cookies_.at(row)->second.Name());
l10n_util::AdjustStringForLocaleDirection(name, &name);
return name;
break;
}
}
NOTREACHED();
return L"";
}
SkBitmap CookiesTableModel::GetIcon(int row) {
static SkBitmap* icon = ResourceBundle::GetSharedInstance().GetBitmapNamed(
IDR_COOKIE_ICON);
return *icon;
}
void CookiesTableModel::SetObserver(TableModelObserver* observer) {
observer_ = observer;
}
int CookiesTableModel::CompareValues(int row1, int row2, int column_id) {
if (column_id == IDS_COOKIES_DOMAIN_COLUMN_HEADER) {
// Sort ignore the '.' prefix for domain cookies.
net::CookieMonster::CookieListPair* cp1 = shown_cookies_[row1];
net::CookieMonster::CookieListPair* cp2 = shown_cookies_[row2];
bool is1domain = !cp1->first.empty() && cp1->first[0] == '.';
bool is2domain = !cp2->first.empty() && cp2->first[0] == '.';
// They are both either domain or host cookies, sort them normally.
if (is1domain == is2domain)
return cp1->first.compare(cp2->first);
// One (but only one) is a domain cookie, skip the beginning '.'.
return is1domain ?
cp1->first.compare(1, cp1->first.length() - 1, cp2->first) :
-cp2->first.compare(1, cp2->first.length() - 1, cp1->first);
}
return TableModel::CompareValues(row1, row2, column_id);
}
///////////////////////////////////////////////////////////////////////////////
// CookiesTableModel, private:
// Returns true if |cookie| matches the specified filter, where "match" is
// defined as the cookie's domain, name and value contains filter text
// somewhere.
static bool ContainsFilterText(
const std::string& domain,
const net::CookieMonster::CanonicalCookie& cookie,
const std::string& filter) {
return domain.find(filter) != std::string::npos ||
cookie.Name().find(filter) != std::string::npos ||
cookie.Value().find(filter) != std::string::npos;
}
void CookiesTableModel::LoadCookies() {
// mmargh mmargh mmargh!
net::CookieMonster* cookie_monster =
profile_->GetRequestContext()->cookie_store()->GetCookieMonster();
all_cookies_ = cookie_monster->GetAllCookies();
DoFilter();
}
void CookiesTableModel::DoFilter() {
std::string utf8_filter = WideToUTF8(filter_);
bool has_filter = !utf8_filter.empty();
shown_cookies_.clear();
CookieList::iterator iter = all_cookies_.begin();
for (; iter != all_cookies_.end(); ++iter) {
if (!has_filter ||
ContainsFilterText(iter->first, iter->second, utf8_filter)) {
shown_cookies_.push_back(&*iter);
}
}
}
void CookiesTableModel::UpdateSearchResults(const std::wstring& filter) {
filter_ = filter;
DoFilter();
observer_->OnModelChanged();
}
|