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

Unified Diff: chrome/browser/geolocation/geolocation_content_settings_table_model.cc

Issue 1539021: Geolocation exceptions window, Windows.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 9 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/geolocation/geolocation_content_settings_table_model.cc
===================================================================
--- chrome/browser/geolocation/geolocation_content_settings_table_model.cc (revision 43621)
+++ chrome/browser/geolocation/geolocation_content_settings_table_model.cc (working copy)
@@ -5,10 +5,47 @@
#include "chrome/browser/geolocation/geolocation_content_settings_table_model.h"
#include "app/l10n_util.h"
+#include "app/l10n_util_collator.h"
#include "app/table_model_observer.h"
#include "base/utf_string_conversions.h"
+#include "chrome/common/url_constants.h"
#include "grit/generated_resources.h"
+namespace {
+// Return -1, 0, or 1 depending on whether |origin1| should be sorted before,
+// equal to, or after |origin2|.
+int CompareOrigins(const GURL& origin1, const GURL& origin2) {
+ if (origin1 == origin2)
+ return 0;
+
+ // Sort alphabetically by host name.
+ std::string origin1_host(origin1.host());
+ std::string origin2_host(origin2.host());
+ if (origin1_host != origin2_host)
+ return origin1_host < origin2_host ? -1 : 1;
+
+ // We'll show non-HTTP schemes, so sort them alphabetically, but put HTTP
+ // first.
+ std::string origin1_scheme(origin1.scheme());
+ std::string origin2_scheme(origin2.scheme());
+ if (origin1_scheme != origin2_scheme) {
+ if (origin1_scheme == chrome::kHttpScheme)
+ return -1;
+ if (origin2_scheme == chrome::kHttpScheme)
+ return 1;
+ return origin1_scheme < origin2_scheme ? -1 : 1;
+ }
+
+ // Sort by port number. This has to differ if the origins are really origins
+ // (and not longer URLs). An unspecified port will be -1 and thus
+ // automatically come first (which is what we want).
+ int origin1_port = origin1.IntPort();
+ int origin2_port = origin2.IntPort();
+ DCHECK(origin1_port != origin2_port);
+ return origin1_port < origin2_port ? -1 : 1;
+}
+} // namespace
+
GeolocationContentSettingsTableModel::GeolocationContentSettingsTableModel(
GeolocationContentSettingsMap* map)
: map_(map),
@@ -20,39 +57,55 @@
AddEntriesForOrigin(i->first, i->second);
}
-bool GeolocationContentSettingsTableModel::CanRemoveException(int row) const {
- const Entry& entry = entries_[row];
- return !(entry.origin == entry.embedding_origin &&
- static_cast<size_t>(row + 1) < entries_.size() &&
- entries_[row + 1].origin == entry.origin &&
- entry.setting == CONTENT_SETTING_DEFAULT);
+bool GeolocationContentSettingsTableModel::CanRemoveExceptions(
+ const Rows& rows) const {
+ for (Rows::const_iterator i(rows.begin()); i != rows.end(); ++i) {
+ const Entry& entry = entries_[*i];
+ if ((entry.origin == entry.embedding_origin) &&
+ (entry.setting == CONTENT_SETTING_DEFAULT)) {
+ for (size_t j = (*i) + 1;
+ (j < entries_.size()) && (entries_[j].origin == entry.origin); ++j) {
+ if (!rows.count(j))
+ return false;
+ }
+ }
+ }
+ return true;
}
-void GeolocationContentSettingsTableModel::RemoveException(int row) {
- Entry& entry = entries_[row];
- bool next_has_same_origin = static_cast<size_t>(row + 1) < entries_.size() &&
- entries_[row + 1].origin == entry.origin;
- bool has_children = entry.origin == entry.embedding_origin &&
- next_has_same_origin;
- map_->SetContentSetting(entry.origin, entry.embedding_origin,
- CONTENT_SETTING_DEFAULT);
- if (has_children) {
- entry.setting = CONTENT_SETTING_DEFAULT;
- if (observer_)
- observer_->OnItemsChanged(row, 1);
- } else if (!next_has_same_origin &&
- row > 0 &&
- entries_[row - 1].origin == entry.origin &&
- entries_[row - 1].setting == CONTENT_SETTING_DEFAULT) {
- // If we remove the last non-default child of a default parent, we should
- // remove the parent too.
- entries_.erase(entries_.begin() + row - 1, entries_.begin() + row + 1);
- if (observer_)
- observer_->OnItemsRemoved(row - 1, 2);
- } else {
- entries_.erase(entries_.begin() + row);
- if (observer_)
- observer_->OnItemsRemoved(row, 1);
+void GeolocationContentSettingsTableModel::RemoveExceptions(const Rows& rows) {
+ for (Rows::const_reverse_iterator i(rows.rbegin()); i != rows.rend(); ++i) {
+ size_t row = *i;
+ Entry* entry = &entries_[row];
+ GURL entry_origin(entry->origin); // Copy, not reference, since we'll erase
+ // |entry| before we're done with this.
+ bool next_has_same_origin = ((row + 1) < entries_.size()) &&
+ (entries_[row + 1].origin == entry_origin);
+ bool has_children = (entry_origin == entry->embedding_origin) &&
+ next_has_same_origin;
+ map_->SetContentSetting(entry_origin, entry->embedding_origin,
+ CONTENT_SETTING_DEFAULT);
+ if (has_children) {
+ entry->setting = CONTENT_SETTING_DEFAULT;
+ if (observer_)
+ observer_->OnItemsChanged(row, 1);
+ continue;
+ }
+ do {
+ entries_.erase(entries_.begin() + row); // Note: |entry| is now garbage.
+ if (observer_)
+ observer_->OnItemsRemoved(row, 1);
+ // If we remove the last non-default child of a default parent, we
+ // should remove the parent too. We do these removals one-at-a-time
+ // because the table view will end up being called back as each row is
+ // removed, in turn calling back to CanRemoveExceptions(), and if we've
+ // already removed more entries than the view has, we'll have problems.
+ if ((row == 0) || rows.count(row - 1))
+ break;
+ entry = &entries_[--row];
+ } while (!next_has_same_origin && (entry->origin == entry_origin) &&
+ (entry->origin == entry->embedding_origin) &&
+ (entry->setting == CONTENT_SETTING_DEFAULT));
}
}
@@ -72,17 +125,27 @@
int column_id) {
const Entry& entry = entries_[row];
if (column_id == IDS_EXCEPTIONS_HOSTNAME_HEADER) {
- if (entry.origin == entry.embedding_origin)
- return UTF8ToWide(
- GeolocationContentSettingsMap::OriginToString(entry.origin));
- if (entry.embedding_origin.is_empty())
- return ASCIIToWide(" ") +
+ if (entry.origin == entry.embedding_origin) {
+ return UTF8ToWide(GeolocationContentSettingsMap::OriginToString(
+ entry.origin));
+ }
+ std::wstring indent(L" ");
+ if (entry.embedding_origin.is_empty()) {
+ // NOTE: As long as the user cannot add/edit entries from the exceptions
+ // dialog, it's impossible to actually have a non-default setting for some
+ // origin "embedded on any other site", so this row will never appear. If
+ // we add the ability to add/edit exceptions, we'll need to decide when to
+ // display this and how "removing" it will function.
+ return indent +
l10n_util::GetString(IDS_EXCEPTIONS_GEOLOCATION_EMBEDDED_ANY_OTHER);
- return ASCIIToWide(" ") +
- l10n_util::GetStringF(IDS_EXCEPTIONS_GEOLOCATION_EMBEDDED_ON_HOST,
- UTF8ToWide(GeolocationContentSettingsMap::OriginToString(
- entry.embedding_origin)));
- } else if (column_id == IDS_EXCEPTIONS_ACTION_HEADER) {
+ }
+ return indent + l10n_util::GetStringF(
+ IDS_EXCEPTIONS_GEOLOCATION_EMBEDDED_ON_HOST,
+ UTF8ToWide(GeolocationContentSettingsMap::OriginToString(
+ entry.embedding_origin)));
+ }
+
+ if (column_id == IDS_EXCEPTIONS_ACTION_HEADER) {
switch (entry.setting) {
case CONTENT_SETTING_ALLOW:
return l10n_util::GetString(IDS_EXCEPTIONS_ALLOW_BUTTON);
@@ -93,11 +156,11 @@
case CONTENT_SETTING_DEFAULT:
return l10n_util::GetString(IDS_EXCEPTIONS_NOT_SET_BUTTON);
default:
- NOTREACHED();
+ break;
}
- } else {
- NOTREACHED();
}
+
+ NOTREACHED();
return std::wstring();
}
@@ -106,6 +169,55 @@
observer_ = observer;
}
+int GeolocationContentSettingsTableModel::CompareValues(int row1,
+ int row2,
+ int column_id) {
+ DCHECK(row1 >= 0 && row1 < RowCount() &&
+ row2 >= 0 && row2 < RowCount());
+
+ const Entry& entry1 = entries_[row1];
+ const Entry& entry2 = entries_[row2];
+
+ // Sort top-level requesting origins, keeping all embedded (child) rules
+ // together.
+ int origin_comparison = CompareOrigins(entry1.origin, entry2.origin);
+ if (origin_comparison == 0) {
+ // The non-embedded rule comes before all embedded rules.
+ bool entry1_origins_same = entry1.origin == entry1.embedding_origin;
+ bool entry2_origins_same = entry2.origin == entry2.embedding_origin;
+ if (entry1_origins_same != entry2_origins_same)
+ return entry1_origins_same ? -1 : 1;
+
+ // The "default" embedded rule comes after all other embedded rules.
+ bool embedding_origin1_empty = entry1.embedding_origin.is_empty();
+ bool embedding_origin2_empty = entry2.embedding_origin.is_empty();
+ if (embedding_origin1_empty != embedding_origin2_empty)
+ return embedding_origin2_empty ? -1 : 1;
+
+ origin_comparison =
+ CompareOrigins(entry1.embedding_origin, entry2.embedding_origin);
+ } else if (column_id == IDS_EXCEPTIONS_ACTION_HEADER) {
+ // The rows are in different origins. We need to find out how the top-level
+ // origins will compare.
+ while (entries_[row1].origin != entries_[row1].embedding_origin)
+ --row1;
+ while (entries_[row2].origin != entries_[row2].embedding_origin)
+ --row2;
+ }
+
+ // The entries are at the same "scope". If we're sorting by action, then do
+ // that now.
+ if (column_id == IDS_EXCEPTIONS_ACTION_HEADER) {
+ int compare_text = l10n_util::CompareStringWithCollator(
+ GetCollator(), GetText(row1, column_id), GetText(row2, column_id));
+ if (compare_text != 0)
+ return compare_text;
+ }
+
+ // Sort by the relevant origin.
+ return origin_comparison;
+}
+
void GeolocationContentSettingsTableModel::AddEntriesForOrigin(
const GURL& origin,
const GeolocationContentSettingsMap::OneOriginSettings& settings) {

Powered by Google App Engine
This is Rietveld 408576698