summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/app/generated_resources.grd17
-rw-r--r--chrome/browser/cookies_tree_model.cc2
-rw-r--r--chrome/browser/resources/options/cookies_list.js776
-rw-r--r--chrome/browser/resources/options/cookies_tree.js205
-rw-r--r--chrome/browser/resources/options/cookies_view.css166
-rw-r--r--chrome/browser/resources/options/cookies_view.html197
-rw-r--r--chrome/browser/resources/options/cookies_view.js216
-rw-r--r--chrome/browser/resources/options/options.html2
-rw-r--r--chrome/browser/resources/shared/js/cr/ui/list_item.js8
-rw-r--r--chrome/browser/ui/webui/options/cookies_view_handler.cc25
10 files changed, 992 insertions, 622 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index cb9318d..bf56488 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -7517,6 +7517,15 @@ This web page was killed, either because Chrome ran out of memory, or you chose
<message name="IDS_COOKIES_DOMAIN_COLUMN_HEADER" desc="The label of the Domain header in the Cookies table">
Site
</message>
+ <message name="IDS_COOKIES_DATA_COLUMN_HEADER" desc="The label of the Locally Stored Data header in the Cookies table">
+ Locally Stored Data
+ </message>
+ <message name="IDS_COOKIES_SINGLE_COOKIE" desc="The text displayed when there is one cookie in the Cookies table">
+ 1 cookie
+ </message>
+ <message name="IDS_COOKIES_PLURAL_COOKIES" desc="The text displayed when there are two or more cookies in the Cookies table">
+ <ph name="COOKIES">$1<ex>42</ex></ph> cookies
+ </message>
<message name="IDS_COOKIES_WEB_DATABASE_DESCRIPTION_LABEL" desc="The Database Description label">
Description:
</message>
@@ -7550,6 +7559,9 @@ This web page was killed, either because Chrome ran out of memory, or you chose
<message name="IDS_COOKIES_SIZE_LABEL" desc="The Size label, to indicate how much space is taken by a database or application cache">
Size:
</message>
+ <message name="IDS_COOKIES_DATABASE_STORAGE" desc="The text shown when there is either Web Database or Indexed Database Storage (names of HTML standards) in the Cookies table">
+ Database Storage
+ </message>
<message name="IDS_COOKIES_WEB_DATABASES" desc="Label for the folder under which a list of web databases (name of a HTML standard) are displayed">
Web Databases
</message>
@@ -7562,7 +7574,10 @@ This web page was killed, either because Chrome ran out of memory, or you chose
<message name="IDS_COOKIES_SESSION_STORAGE" desc="Label for session storage (name of a HTML standard)">
Session Storage
</message>
- <message name="IDS_COOKIES_INDEXED_DB" desc="Label for Indexed Databases (name of a HTML standard)">
+ <message name="IDS_COOKIES_INDEXED_DB" desc="Label for a single Indexed Database (name of a HTML standard)">
+ Indexed Database
+ </message>
+ <message name="IDS_COOKIES_INDEXED_DBS" desc="Label for Indexed Databases (name of a HTML standard)">
Indexed Databases
</message>
<message name="IDS_COOKIES_LAST_ACCESSED_LABEL" desc="The last access date label">
diff --git a/chrome/browser/cookies_tree_model.cc b/chrome/browser/cookies_tree_model.cc
index db6bb23..c88be0c 100644
--- a/chrome/browser/cookies_tree_model.cc
+++ b/chrome/browser/cookies_tree_model.cc
@@ -462,7 +462,7 @@ CookieTreeSessionStoragesNode::GetDetailedInfo() const {
// CookieTreeIndexedDBsNode, public:
CookieTreeIndexedDBsNode::CookieTreeIndexedDBsNode()
- : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_INDEXED_DB)) {
+ : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_INDEXED_DBS)) {
}
CookieTreeIndexedDBsNode::~CookieTreeIndexedDBsNode() {}
diff --git a/chrome/browser/resources/options/cookies_list.js b/chrome/browser/resources/options/cookies_list.js
new file mode 100644
index 0000000..c5eb69d
--- /dev/null
+++ b/chrome/browser/resources/options/cookies_list.js
@@ -0,0 +1,776 @@
+// Copyright (c) 2011 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.
+
+cr.define('options', function() {
+ const DeletableItemList = options.DeletableItemList;
+ const DeletableItem = options.DeletableItem;
+ const ArrayDataModel = cr.ui.ArrayDataModel;
+ const ListSingleSelectionModel = cr.ui.ListSingleSelectionModel;
+
+ // This structure maps the various cookie type names from C++ (hence the
+ // underscores) to arrays of the different types of data each has, along with
+ // the i18n name for the description of that data type.
+ const cookieInfo = {
+ 'cookie': [ ['name', 'label_cookie_name'],
+ ['content', 'label_cookie_content'],
+ ['domain', 'label_cookie_domain'],
+ ['path', 'label_cookie_path'],
+ ['sendfor', 'label_cookie_send_for'],
+ ['accessibleToScript', 'label_cookie_accessible_to_script'],
+ ['created', 'label_cookie_created'],
+ ['expires', 'label_cookie_expires'] ],
+ 'app_cache': [ ['manifest', 'label_app_cache_manifest'],
+ ['size', 'label_local_storage_size'],
+ ['created', 'label_cookie_created'],
+ ['accessed', 'label_cookie_last_accessed'] ],
+ 'database': [ ['name', 'label_cookie_name'],
+ ['desc', 'label_webdb_desc'],
+ ['webdbSize', 'label_local_storage_size'],
+ ['modified', 'label_local_storage_last_modified'] ],
+ 'local_storage': [ ['origin', 'label_local_storage_origin'],
+ ['size', 'label_local_storage_size'],
+ ['modified', 'label_local_storage_last_modified'] ],
+ 'indexed_db': [ ['origin', 'label_indexed_db_origin'],
+ ['size', 'label_indexed_db_size'],
+ ['modified', 'label_indexed_db_last_modified'] ],
+ };
+
+ const localStrings = new LocalStrings();
+
+ /**
+ * Returns the item's height, like offsetHeight but such that it works better
+ * when the page is zoomed. See the similar calculation in @{code cr.ui.List}.
+ * @param {Element} item The item to get the height of.
+ * @return {number} The height of the item, calculated with zooming in mind.
+ */
+ function getItemHeight(item) {
+ return item.getBoundingClientRect().height;
+ }
+
+ var parentLookup = {};
+ var lookupRequests = {};
+
+ /**
+ * Creates a new list item for sites data. Note that these are created and
+ * destroyed lazily as they scroll into and out of view, so they must be
+ * stateless. We cache the expanded item in @{code CookiesList} though, so it
+ * can keep state. (Mostly just which item is selected.)
+ * @param {Object} origin Data used to create a cookie list item.
+ * @param {CookiesList} list The list that will contain this item.
+ * @constructor
+ * @extends {DeletableItem}
+ */
+ function CookieListItem(origin, list) {
+ var listItem = new DeletableItem(null);
+ listItem.__proto__ = CookieListItem.prototype;
+
+ listItem.origin = origin;
+ listItem.list = list;
+ listItem.decorate();
+
+ // This hooks up updateOrigin() to the list item, makes the top-level
+ // tree nodes (i.e., origins) register their IDs in parentLookup, and
+ // causes them to request their children if they have none. Note that we
+ // have special logic in the setter for the parent property to make sure
+ // that we can still garbage collect list items when they scroll out of
+ // view, even though it appears that we keep a direct reference.
+ if (origin) {
+ origin.parent = listItem;
+ origin.updateOrigin();
+ }
+
+ return listItem;
+ }
+
+ CookieListItem.prototype = {
+ __proto__: DeletableItem.prototype,
+
+ /** @inheritDoc */
+ decorate: function() {
+ this.siteChild = this.ownerDocument.createElement('div');
+ this.siteChild.className = 'cookie-site';
+ this.dataChild = this.ownerDocument.createElement('div');
+ this.dataChild.className = 'cookie-data';
+ this.itemsChild = this.ownerDocument.createElement('div');
+ this.itemsChild.className = 'cookie-items';
+ this.infoChild = this.ownerDocument.createElement('div');
+ this.infoChild.className = 'cookie-details hidden';
+ var remove = this.ownerDocument.createElement('button');
+ remove.textContent = localStrings.getString('remove_cookie');
+ remove.onclick = this.removeCookie_.bind(this);
+ this.infoChild.appendChild(remove);
+ var content = this.contentElement;
+ content.appendChild(this.siteChild);
+ content.appendChild(this.dataChild);
+ content.appendChild(this.itemsChild);
+ this.itemsChild.appendChild(this.infoChild);
+ if (this.origin && this.origin.data)
+ this.siteChild.textContent = this.origin.data.title;
+ this.itemList_ = [];
+ },
+
+ /** @type {boolean} */
+ get expanded() {
+ return this.expanded_;
+ },
+ set expanded(expanded) {
+ if (this.expanded_ == expanded)
+ return;
+ this.expanded_ = expanded;
+ if (expanded) {
+ this.list.expandedItem = this;
+ this.updateItems_();
+ this.classList.add('show-items');
+ } else {
+ if (this.list.expandedItem == this) {
+ this.list.leadItemHeight = 0;
+ this.list.expandedItem = null;
+ }
+ this.style.height = '';
+ this.itemsChild.style.height = '';
+ this.classList.remove('show-items');
+ }
+ },
+
+ /**
+ * The callback for the "remove" button shown when an item is selected.
+ * Requests that the currently selected cookie be removed.
+ * @private
+ */
+ removeCookie_: function() {
+ if (this.selectedIndex_ >= 0) {
+ var item = this.itemList_[this.selectedIndex_];
+ if (item && item.node)
+ chrome.send('removeCookie', [item.node.pathId]);
+ }
+ },
+
+ /**
+ * Disable animation within this cookie list item, in preparation for making
+ * changes that will need to be animated. Makes it possible to measure the
+ * contents without displaying them, to set animation targets.
+ * @private
+ */
+ disableAnimation_: function() {
+ this.itemsHeight_ = getItemHeight(this.itemsChild);
+ this.classList.add('measure-items');
+ },
+
+ /**
+ * Enable animation after changing the contents of this cookie list item.
+ * See @{code disableAnimation_}.
+ * @private
+ */
+ enableAnimation_: function() {
+ if (!this.classList.contains('measure-items'))
+ this.disableAnimation_();
+ this.itemsChild.style.height = '';
+ // This will force relayout in order to calculate the new heights.
+ var itemsHeight = getItemHeight(this.itemsChild);
+ var fixedHeight = getItemHeight(this) + itemsHeight - this.itemsHeight_;
+ this.itemsChild.style.height = this.itemsHeight_ + 'px';
+ // Force relayout before enabling animation, so that if we have
+ // changed things since the last layout, they will not be animated
+ // during subsequent layouts.
+ this.itemsChild.offsetHeight;
+ this.classList.remove('measure-items');
+ this.itemsChild.style.height = itemsHeight + 'px';
+ this.style.height = fixedHeight + 'px';
+ if (this.selected)
+ this.list.leadItemHeight = fixedHeight;
+ },
+
+ /**
+ * Updates the origin summary to reflect changes in its items.
+ * Both CookieListItem and CookieTreeNode implement this API.
+ * This implementation scans the descendants to update the text.
+ */
+ updateOrigin: function() {
+ var info = {
+ cookies: 0,
+ database: false,
+ localStorage: false,
+ appCache: false,
+ indexedDb: false
+ };
+ if (this.origin)
+ this.origin.collectSummaryInfo(info);
+ var list = [];
+ if (info.cookies > 1)
+ list.push(localStrings.getStringF('cookie_plural', info.cookies));
+ else if (info.cookies > 0)
+ list.push(localStrings.getString('cookie_singular'));
+ if (info.database || info.indexedDb)
+ list.push(localStrings.getString('cookie_database_storage'));
+ if (info.localStorage)
+ list.push(localStrings.getString('cookie_local_storage'));
+ if (info.appCache)
+ list.push(localStrings.getString('cookie_session_storage'));
+ var text = '';
+ for (var i = 0; i < list.length; ++i)
+ if (text.length > 0)
+ text += ', ' + list[i];
+ else
+ text = list[i];
+ this.dataChild.textContent = text;
+ if (this.selected)
+ this.updateItems_();
+ },
+
+ /**
+ * Updates the items section to reflect changes, animating to the new state.
+ * Removes existing contents and calls @{code CookieTreeNode.createItems}.
+ * @private
+ */
+ updateItems_: function() {
+ this.disableAnimation_();
+ this.itemsChild.textContent = '';
+ this.infoChild.classList.add('hidden');
+ this.selectedIndex_ = -1;
+ this.itemList_ = [];
+ if (this.origin)
+ this.origin.createItems(this);
+ this.itemsChild.appendChild(this.infoChild);
+ this.enableAnimation_();
+ },
+
+ /**
+ * Append a new cookie node "bubble" to this list item.
+ * @param {CookieTreeNode} node The cookie node to add a bubble for.
+ * @param {Element} div The DOM element for the bubble itself.
+ * @return {number} The index the bubble was added at.
+ */
+ appendItem: function(node, div) {
+ this.itemList_.push({node: node, div: div});
+ this.itemsChild.appendChild(div);
+ return this.itemList_.length - 1;
+ },
+
+ /**
+ * The currently selected cookie node ("cookie bubble") index.
+ * @type {number}
+ * @private
+ */
+ selectedIndex_: -1,
+
+ /**
+ * Get the currently selected cookie node ("cookie bubble") index.
+ * @type {number}
+ */
+ get selectedIndex() {
+ return this.selectedIndex_;
+ },
+
+ /**
+ * Set the currently selected cookie node ("cookie bubble") index to
+ * @{code itemIndex}, unselecting any previously selected node first.
+ * @param {number} itemIndex The index to set as the selected index.
+ */
+ set selectedIndex(itemIndex) {
+ if (itemIndex < 0 || itemIndex >= this.itemList_.length)
+ return;
+ var index = this.list.getIndexOfListItem(this);
+ if (this.selectedIndex_ >= 0) {
+ var item = this.itemList_[this.selectedIndex_];
+ if (item && item.div)
+ item.div.removeAttribute('selected');
+ }
+ this.selectedIndex_ = itemIndex;
+ this.itemList_[itemIndex].div.setAttribute('selected', '');
+ this.disableAnimation_();
+ this.itemList_[itemIndex].node.setDetailText(this.infoChild,
+ this.list.infoNodes);
+ this.infoChild.classList.remove('hidden');
+ this.enableAnimation_();
+ // If we're near the bottom of the list this may cause the list item to go
+ // beyond the end of the visible area. Fix it after the animation is done.
+ var list = this.list;
+ window.setTimeout(function() { list.scrollIndexIntoView(index); }, 150);
+ },
+ };
+
+ /**
+ * {@code CookieTreeNode}s mirror the structure of the cookie tree lazily, and
+ * contain all the actual data used to generate the {@code CookieListItem}s.
+ * @param {Object} data The data object for this node.
+ * @constructor
+ */
+ function CookieTreeNode(data) {
+ this.data = data;
+ this.children = [];
+ }
+
+ CookieTreeNode.prototype = {
+ /**
+ * Insert a cookie tree node at the given index.
+ * Both CookiesList and CookieTreeNode implement this API.
+ * @param {Object} data The data object for the node to add.
+ * @param {number} index The index at which to insert the node.
+ */
+ insertAt: function(data, index) {
+ var child = new CookieTreeNode(data);
+ this.children.splice(index, 0, child);
+ child.parent = this;
+ this.updateOrigin();
+ },
+
+ /**
+ * Remove a cookie tree node from the given index.
+ * Both CookiesList and CookieTreeNode implement this API.
+ * @param {number} index The index of the tree node to remove.
+ */
+ remove: function(index) {
+ if (index < this.children.length) {
+ this.children.splice(index, 1);
+ this.updateOrigin();
+ }
+ },
+
+ /**
+ * Clears all children.
+ * Both CookiesList and CookieTreeNode implement this API.
+ * It is used by CookiesList.loadChildren().
+ */
+ clear: function() {
+ // We might leave some garbage in parentLookup for removed children.
+ // But that should be OK because parentLookup is cleared when we
+ // reload the tree.
+ this.children = [];
+ this.updateOrigin();
+ },
+
+ /**
+ * The counter used by startBatchUpdates() and endBatchUpdates().
+ * @type {number}
+ */
+ batchCount_: 0,
+
+ /**
+ * See cr.ui.List.startBatchUpdates().
+ * Both CookiesList (via List) and CookieTreeNode implement this API.
+ */
+ startBatchUpdates: function() {
+ this.batchCount_++;
+ },
+
+ /**
+ * See cr.ui.List.endBatchUpdates().
+ * Both CookiesList (via List) and CookieTreeNode implement this API.
+ */
+ endBatchUpdates: function() {
+ if (!--this.batchCount_)
+ this.updateOrigin();
+ },
+
+ /**
+ * Requests updating the origin summary to reflect changes in this item.
+ * Both CookieListItem and CookieTreeNode implement this API.
+ */
+ updateOrigin: function() {
+ if (!this.batchCount_ && this.parent)
+ this.parent.updateOrigin();
+ },
+
+ /**
+ * Summarize the information in this node and update @{code info}.
+ * This will recurse into child nodes to summarize all descendants.
+ * @param {Object} info The info object from @{code updateOrigin}.
+ */
+ collectSummaryInfo: function(info) {
+ if (this.children.length > 0) {
+ for (var i = 0; i < this.children.length; ++i)
+ this.children[i].collectSummaryInfo(info);
+ } else if (this.data && !this.data.hasChildren) {
+ if (this.data.type == 'cookie')
+ info.cookies++;
+ else if (this.data.type == 'database')
+ info.database = true;
+ else if (this.data.type == 'local_storage')
+ info.localStorage = true;
+ else if (this.data.type == 'app_cache')
+ info.appCache = true;
+ else if (this.data.type == 'indexed_db')
+ info.indexedDb = true;
+ }
+ },
+
+ /**
+ * Create the cookie "bubbles" for this node, recursing into children
+ * if there are any. Append the cookie bubbles to @{code item}.
+ * @param {CookieListItem} item The cookie list item to create items in.
+ */
+ createItems: function(item) {
+ if (this.children.length > 0) {
+ for (var i = 0; i < this.children.length; ++i)
+ this.children[i].createItems(item);
+ } else if (this.data && !this.data.hasChildren) {
+ var text = '';
+ switch (this.data.type) {
+ case 'cookie':
+ case 'database':
+ text = this.data.name;
+ break;
+ case 'local_storage':
+ text = localStrings.getString('cookie_local_storage');
+ break;
+ case 'app_cache':
+ text = localStrings.getString('cookie_session_storage');
+ break;
+ case 'indexed_db':
+ text = localStrings.getString('cookie_indexed_db');
+ break;
+ }
+ var div = item.ownerDocument.createElement('div');
+ div.className = 'cookie-item';
+ // Help out screen readers and such: this is a clickable thing.
+ div.setAttribute('role', 'button');
+ div.textContent = text;
+ var index = item.appendItem(this, div);
+ div.onclick = function() { item.selectedIndex = index; };
+ }
+ },
+
+ /**
+ * Set the detail text to be displayed to that of this cookie tree node.
+ * Uses preallocated DOM elements for each cookie node type from @{code
+ * infoNodes}, and inserts the appropriate elements to @{code element}.
+ * @param {Element} element The DOM element to insert elements to.
+ * @param {Object.<string, {table: Element, info: Object.<string,
+ * Element>}>} infoNodes The map from cookie node types to maps from
+ * cookie attribute names to DOM elements to display cookie attribute
+ * values, created by @{code CookiesList.decorate}.
+ */
+ setDetailText: function(element, infoNodes) {
+ var table;
+ if (this.data && !this.data.hasChildren) {
+ if (cookieInfo[this.data.type]) {
+ var info = cookieInfo[this.data.type];
+ var nodes = infoNodes[this.data.type].info;
+ for (var i = 0; i < info.length; ++i) {
+ var name = info[i][0];
+ if (name != 'id' && this.data[name])
+ nodes[name].textContent = this.data[name];
+ }
+ table = infoNodes[this.data.type].table;
+ }
+ }
+ while (element.childNodes.length > 1)
+ element.removeChild(element.firstChild);
+ if (table)
+ element.insertBefore(table, element.firstChild);
+ },
+
+ /**
+ * The parent of this cookie tree node.
+ * @type {?CookieTreeNode|CookieListItem}
+ */
+ get parent(parent) {
+ // See below for an explanation of this special case.
+ if (typeof this.parent_ == 'number')
+ return this.list_.getListItemByIndex(this.parent_);
+ return this.parent_;
+ },
+ set parent(parent) {
+ if (parent == this.parent)
+ return;
+ if (parent instanceof CookieListItem) {
+ // If the parent is to be a CookieListItem, then we keep the reference
+ // to it by its containing list and list index, rather than directly.
+ // This allows the list items to be garbage collected when they scroll
+ // out of view (except the expanded item, which we cache). This is
+ // transparent except in the setter and getter, where we handle it.
+ this.parent_ = parent.listIndex;
+ this.list_ = parent.list;
+ parent.addEventListener('listIndexChange',
+ this.parentIndexChanged_.bind(this));
+ } else {
+ this.parent_ = parent;
+ }
+ if (this.data && this.data.id) {
+ if (parent)
+ parentLookup[this.data.id] = this;
+ else
+ delete parentLookup[this.data.id];
+ }
+ if (this.data && this.data.hasChildren &&
+ !this.children.length && !lookupRequests[this.data.id]) {
+ lookupRequests[this.data.id] = true;
+ chrome.send('loadCookie', [this.pathId]);
+ }
+ },
+
+ /**
+ * Called when the parent is a CookieListItem whose index has changed.
+ * See the code above that avoids keeping a direct reference to
+ * CookieListItem parents, to allow them to be garbage collected.
+ * @private
+ */
+ parentIndexChanged_: function(event) {
+ if (typeof this.parent_ == 'number') {
+ this.parent_ = event.newValue;
+ // We set a timeout to update the origin, rather than doing it right
+ // away, because this callback may occur while the list items are
+ // being repopulated following a scroll event. Calling updateOrigin()
+ // immediately could trigger relayout that would reset the scroll
+ // position within the list, among other things.
+ window.setTimeout(this.updateOrigin.bind(this), 0);
+ }
+ },
+
+ /**
+ * The cookie tree path id.
+ * @type {string}
+ */
+ get pathId() {
+ var parent = this.parent;
+ if (parent && parent instanceof CookieTreeNode)
+ return parent.pathId + ',' + this.data.id;
+ return this.data.id;
+ },
+ };
+
+ /**
+ * Creates a new cookies list.
+ * @param {Object=} opt_propertyBag Optional properties.
+ * @constructor
+ * @extends {DeletableItemList}
+ */
+ var CookiesList = cr.ui.define('list');
+
+ CookiesList.prototype = {
+ __proto__: DeletableItemList.prototype,
+
+ /** @inheritDoc */
+ decorate: function() {
+ DeletableItemList.prototype.decorate.call(this);
+ this.classList.add('cookie-list');
+ this.data_ = [];
+ this.dataModel = new ArrayDataModel(this.data_);
+ this.addEventListener('keydown', this.handleKeyLeftRight_.bind(this));
+ var sm = new ListSingleSelectionModel();
+ sm.addEventListener('change', this.cookieSelectionChange_.bind(this));
+ sm.addEventListener('leadIndexChange', this.cookieLeadChange_.bind(this));
+ this.selectionModel = sm;
+ this.infoNodes = {};
+ var doc = this.ownerDocument;
+ // Create a table for each type of site data (e.g. cookies, databases,
+ // etc.) and save it so that we can reuse it for all origins.
+ for (var type in cookieInfo) {
+ var table = doc.createElement('table');
+ table.className = 'cookie-details-table';
+ var tbody = doc.createElement('tbody');
+ table.appendChild(tbody);
+ var info = {};
+ for (var i = 0; i < cookieInfo[type].length; i++) {
+ var tr = doc.createElement('tr');
+ var name = doc.createElement('td');
+ var data = doc.createElement('td');
+ var pair = cookieInfo[type][i];
+ name.className = 'cookie-details-label';
+ name.textContent = localStrings.getString(pair[1]);
+ data.className = 'cookie-details-value';
+ data.textContent = '';
+ tr.appendChild(name);
+ tr.appendChild(data);
+ tbody.appendChild(tr);
+ info[pair[0]] = data;
+ }
+ this.infoNodes[type] = {table: table, info: info};
+ }
+ },
+
+ /**
+ * Handles key down events and looks for left and right arrows, then
+ * dispatches to the currently expanded item, if any.
+ * @param {Event} e The keydown event.
+ * @private
+ */
+ handleKeyLeftRight_: function(e) {
+ var id = e.keyIdentifier;
+ if ((id == 'Left' || id == 'Right') && this.expandedItem) {
+ var cs = this.ownerDocument.defaultView.getComputedStyle(this);
+ var rtl = cs.direction == 'rtl';
+ if ((!rtl && id == 'Left') || (rtl && id == 'Right'))
+ this.expandedItem.selectedIndex--;
+ else
+ this.expandedItem.selectedIndex++;
+ this.scrollIndexIntoView(this.expandedItem.listIndex);
+ // Prevent the page itself from scrolling.
+ e.preventDefault();
+ }
+ },
+
+ /**
+ * Called on selection model selection changes.
+ * @param {Event} ce The selection change event.
+ * @private
+ */
+ cookieSelectionChange_: function(ce) {
+ ce.changes.forEach(function(change) {
+ var listItem = this.getListItemByIndex(change.index);
+ if (listItem) {
+ if (!change.selected)
+ listItem.expanded = false;
+ else if (listItem.lead)
+ listItem.expanded = true;
+ }
+ }, this);
+ },
+
+ /**
+ * Called on selection model lead changes.
+ * @param {Event} pe The lead change event.
+ * @private
+ */
+ cookieLeadChange_: function(pe) {
+ if (pe.oldValue != -1) {
+ var listItem = this.getListItemByIndex(pe.oldValue);
+ if (listItem)
+ listItem.expanded = false;
+ }
+ if (pe.newValue != -1) {
+ var listItem = this.getListItemByIndex(pe.newValue);
+ if (listItem && listItem.selected)
+ listItem.expanded = true;
+ }
+ },
+
+ /**
+ * The currently expanded item. Used by CookieListItem above.
+ * @type {?CookieListItem}
+ */
+ expandedItem: null,
+
+ // from cr.ui.List
+ /** @inheritDoc */
+ createItem: function(data) {
+ // We use the cached expanded item in order to allow it to maintain some
+ // state (like its fixed height, and which bubble is selected).
+ if (this.expandedItem && this.expandedItem.origin == data)
+ return this.expandedItem;
+ return new CookieListItem(data, this);
+ },
+
+ // from options.DeletableItemList
+ /** @inheritDoc */
+ deleteItemAtIndex: function(index) {
+ var item = this.data_[index];
+ if (item) {
+ var pathId = item.pathId;
+ if (pathId)
+ chrome.send('removeCookie', [pathId]);
+ }
+ },
+
+ /**
+ * Insert a cookie tree node at the given index.
+ * Both CookiesList and CookieTreeNode implement this API.
+ * @param {Object} data The data object for the node to add.
+ * @param {number} index The index at which to insert the node.
+ */
+ insertAt: function(data, index) {
+ this.dataModel.splice(index, 0, new CookieTreeNode(data));
+ },
+
+ /**
+ * Remove a cookie tree node from the given index.
+ * Both CookiesList and CookieTreeNode implement this API.
+ * @param {number} index The index of the tree node to remove.
+ */
+ remove: function(index) {
+ if (index < this.data_.length)
+ this.dataModel.splice(index, 1);
+ },
+
+ /**
+ * Clears the list.
+ * Both CookiesList and CookieTreeNode implement this API.
+ * It is used by CookiesList.loadChildren().
+ */
+ clear: function() {
+ parentLookup = {};
+ this.data_ = [];
+ this.dataModel = new ArrayDataModel(this.data_);
+ this.redraw();
+ },
+
+ /**
+ * Add tree nodes by given parent.
+ * Note: this method will be O(n^2) in the general case. Use it only to
+ * populate an empty parent or to insert single nodes to avoid this.
+ * @param {Object} parent The parent node.
+ * @param {number} start Start index of where to insert nodes.
+ * @param {Array} nodesData Nodes data array.
+ * @private
+ */
+ addByParent_: function(parent, start, nodesData) {
+ if (!parent)
+ return;
+
+ parent.startBatchUpdates();
+ for (var i = 0; i < nodesData.length; ++i)
+ parent.insertAt(nodesData[i], start + i);
+ parent.endBatchUpdates();
+
+ cr.dispatchSimpleEvent(this, 'change');
+ },
+
+ /**
+ * Add tree nodes by parent id.
+ * This is used by cookies_view.js.
+ * Note: this method will be O(n^2) in the general case. Use it only to
+ * populate an empty parent or to insert single nodes to avoid this.
+ * @param {string} parentId Id of the parent node.
+ * @param {number} start Start index of where to insert nodes.
+ * @param {Array} nodesData Nodes data array.
+ */
+ addByParentId: function(parentId, start, nodesData) {
+ var parent = parentId ? parentLookup[parentId] : this;
+ this.addByParent_(parent, start, nodesData);
+ },
+
+ /**
+ * Removes tree nodes by parent id.
+ * This is used by cookies_view.js.
+ * @param {string} parentId Id of the parent node.
+ * @param {number} start Start index of nodes to remove.
+ * @param {number} count Number of nodes to remove.
+ */
+ removeByParentId: function(parentId, start, count) {
+ var parent = parentId ? parentLookup[parentId] : this;
+ if (!parent)
+ return;
+
+ parent.startBatchUpdates();
+ while (count-- > 0)
+ parent.remove(start);
+ parent.endBatchUpdates();
+
+ cr.dispatchSimpleEvent(this, 'change');
+ },
+
+ /**
+ * Loads the immediate children of given parent node.
+ * This is used by cookies_view.js.
+ * @param {string} parentId Id of the parent node.
+ * @param {Array} children The immediate children of parent node.
+ */
+ loadChildren: function(parentId, children) {
+ if (parentId)
+ delete lookupRequests[parentId];
+ var parent = parentId ? parentLookup[parentId] : this;
+ if (!parent)
+ return;
+
+ parent.startBatchUpdates();
+ parent.clear();
+ this.addByParent_(parent, 0, children);
+ parent.endBatchUpdates();
+ },
+ };
+
+ return {
+ CookiesList: CookiesList
+ };
+});
diff --git a/chrome/browser/resources/options/cookies_tree.js b/chrome/browser/resources/options/cookies_tree.js
deleted file mode 100644
index 6e8aaca..0000000
--- a/chrome/browser/resources/options/cookies_tree.js
+++ /dev/null
@@ -1,205 +0,0 @@
-// Copyright (c) 2010 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.
-
-cr.define('options', function() {
- const Tree = cr.ui.Tree;
- const TreeItem = cr.ui.TreeItem;
-
- var treeLookup = {};
-
- /**
- * Creates a new tree item for sites data.
- * @param {Object=} data Data used to create a cookie tree item.
- * @constructor
- * @extends {TreeItem}
- */
- function CookieTreeItem(data) {
- var treeItem = new TreeItem({
- label: data.title,
- data: data
- });
- treeItem.__proto__ = CookieTreeItem.prototype;
-
- if (data.icon) {
- treeItem.icon = data.icon;
- }
-
- treeItem.decorate();
- return treeItem;
- }
-
- CookieTreeItem.prototype = {
- __proto__: TreeItem.prototype,
-
- /** @inheritDoc */
- decorate: function() {
- this.hasChildren = this.data.hasChildren;
- },
-
- /** @inheritDoc */
- addAt: function(child, index) {
- TreeItem.prototype.addAt.call(this, child, index);
- if (child.data && child.data.id)
- treeLookup[child.data.id] = child;
- },
-
- /** @inheritDoc */
- remove: function(child) {
- TreeItem.prototype.remove.call(this, child);
- if (child.data && child.data.id)
- delete treeLookup[child.data.id];
- },
-
- /**
- * Clears all children.
- */
- clear: function() {
- // We might leave some garbage in treeLookup for removed children.
- // But that should be okay because treeLookup is cleared when we
- // reload the tree.
- this.lastElementChild.textContent = '';
- },
-
- /**
- * The tree path id.
- * @type {string}
- */
- get pathId() {
- var parent = this.parentItem;
- if (parent && parent instanceof CookieTreeItem) {
- return parent.pathId + ',' + this.data.id;
- } else {
- return this.data.id;
- }
- },
-
- /** @inheritDoc */
- get expanded() {
- return TreeItem.prototype.__lookupGetter__('expanded').call(this);
- },
- set expanded(b) {
- if (b && this.expanded != b)
- chrome.send('loadCookie', [this.pathId]);
-
- TreeItem.prototype.__lookupSetter__('expanded').call(this, b);
- }
- };
-
- /**
- * Creates a new cookies tree.
- * @param {Object=} opt_propertyBag Optional properties.
- * @constructor
- * @extends {Tree}
- */
- var CookiesTree = cr.ui.define('tree');
-
- CookiesTree.prototype = {
- __proto__: Tree.prototype,
-
- /** @inheritDoc */
- addAt: function(child, index) {
- Tree.prototype.addAt.call(this, child, index);
- if (child.data && child.data.id)
- treeLookup[child.data.id] = child;
- },
-
- /** @inheritDoc */
- remove: function(child) {
- Tree.prototype.remove.call(this, child);
- if (child.data && child.data.id)
- delete treeLookup[child.data.id];
- },
-
- /**
- * Clears the tree.
- */
- clear: function() {
- // Remove all fields without recreating the object since other code
- // references it.
- for (var id in treeLookup) {
- delete treeLookup[id];
- }
- this.textContent = '';
- },
-
- /**
- * Add tree nodes by given parent.
- * @param {Object} parent Parent node.
- * @param {int} start Start index of where to insert nodes.
- * @param {Array} nodesData Nodes data array.
- */
- addByParent: function(parent, start, nodesData) {
- if (!parent) {
- return;
- }
-
- for (var i = 0; i < nodesData.length; ++i) {
- parent.addAt(new CookieTreeItem(nodesData[i]), start + i);
- }
-
- cr.dispatchSimpleEvent(this, 'change');
- },
-
- /**
- * Add tree nodes by parent id.
- * @param {string} parentId Id of the parent node.
- * @param {int} start Start index of where to insert nodes.
- * @param {Array} nodesData Nodes data array.
- */
- addByParentId: function(parentId, start, nodesData) {
- var parent = parentId ? treeLookup[parentId] : this;
- this.addByParent(parent, start, nodesData);
- },
-
- /**
- * Removes tree nodes by parent id.
- * @param {string} parentId Id of the parent node.
- * @param {int} start Start index of nodes to remove.
- * @param {int} count Number of nodes to remove.
- */
- removeByParentId: function(parentId, start, count) {
- var parent = parentId ? treeLookup[parentId] : this;
- if (!parent) {
- return;
- }
-
- for (; count > 0 && parent.items.length; --count) {
- parent.remove(parent.items[start]);
- }
-
- cr.dispatchSimpleEvent(this, 'change');
- },
-
- /**
- * Clears the tree.
- */
- clear: function() {
- // Remove all fields without recreating the object since other code
- // references it.
- for (var id in treeLookup){
- delete treeLookup[id];
- }
- this.textContent = '';
- },
-
- /**
- * Loads the immediate children of given parent node.
- * @param {string} parentId Id of the parent node.
- * @param {Array} children The immediate children of parent node.
- */
- loadChildren: function(parentId, children) {
- var parent = parentId ? treeLookup[parentId] : this;
- if (!parent) {
- return;
- }
-
- parent.clear();
- this.addByParent(parent, 0, children);
- }
- };
-
- return {
- CookiesTree: CookiesTree
- };
-});
diff --git a/chrome/browser/resources/options/cookies_view.css b/chrome/browser/resources/options/cookies_view.css
index 3efe4e7..f2dd1fd 100644
--- a/chrome/browser/resources/options/cookies_view.css
+++ b/chrome/browser/resources/options/cookies_view.css
@@ -4,40 +4,164 @@ Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
*/
-.cookies-info-table {
- table-layout: fixed;
- width: 100%;
+/* styles for the cookies list elements in cookies_view.html */
+#remove-all-cookies-search-column {
+ bottom: 0;
+ position: absolute;
+ right: 0;
}
-.cookies-details-pane {
- background-color: lightgrey;
- border: 1px solid grey;
- margin: 5px 0;
+html[dir=rtl] #remove-all-cookies-search-column {
+ left: 0;
+ right: auto;
}
-.cookie-details-label {
- white-space: pre;
- vertical-align: top;
+#cookies-column-headers {
+ margin-bottom: 2px;
+ position: relative;
+ width: 100%;
}
-html[dir=ltr] .cookie-details-label {
- text-align: right;
+#cookies-column-headers h3 {
+ margin-bottom: 0;
}
-#cookiesSearchBox {
- border: 1px solid lightgrey;
- display: box;
- width: 366px;
+/* notice the width and padding for these columns match up with those below */
+#cookies-site-column {
+ display: inline-block;
+ font-weight: bold;
+ width: 11em;
}
-#cookiesTree {
- border: 1px solid lightgrey;
+#cookies-data-column {
+ -webkit-padding-start: 7px;
+ display: inline-block;
+ font-weight: bold;
+}
+
+#cookies-list {
+ border: 1px solid #D9D9D9;
+ /* it would be nice if we could make this expand as necessary up to the height
+ * of the window, but the panel doesn't have a known height and that would
+ * probably confuse cr.ui.List (which doesn't expect that) anyway */
+ height: 700px;
margin: 0;
- padding: 5px;
}
-#cookieContent {
+
+/* enable animating the height of items */
+list.cookie-list .deletable-item {
+ -webkit-transition: height .15s ease-in-out;
+}
+
+/* disable webkit-box display */
+list.cookie-list .deletable-item > :first-child {
display: block;
- width: 300px;
+}
+
+/* force the X for deleting an origin to stay at the top */
+list.cookie-list > .deletable-item > .close-button {
+ position: absolute;
+ right: 2px;
+ top: 8px;
+}
+
+html[dir=rtl] list.cookie-list > .deletable-item > .close-button {
+ left: 2px;
+ right: auto;
+}
+
+
+/* styles for the site (aka origin) and its summary */
+.cookie-site {
+ /* notice that the width, margin, and padding match up with those above */
+ -webkit-margin-end: 2px;
+ -webkit-padding-start: 5px;
+ display: inline-block;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ width: 11em;
+}
+
+.cookie-data {
+ display: inline-block;
+}
+
+
+/* styles for the individual items (cookies, etc.) */
+.cookie-items {
+ /* notice that the margin and padding match up with those above */
+ -webkit-margin-start: 11em;
+ -webkit-padding-start: 7px;
+ -webkit-transition: .15s ease-in-out;
+ height: 0;
+ opacity: 0;
+ /* make the cookie items wrap correctly */
+ white-space: normal;
+}
+
+.measure-items .cookie-items {
+ -webkit-transition: none;
+ height: auto;
+ visibility: hidden;
+}
+
+.show-items .cookie-items {
+ opacity: 1;
+}
+
+.cookie-items .cookie-item {
+ background: #E0E9F5;
+ border-radius: 5px;
+ border: 1px solid #8392AE;
+ display: inline-block;
+ font-size: 85%;
+ height: auto;
+ margin: 2px 4px 2px 0;
+ max-width: 80px;
+ min-width: 40px;
+ overflow: hidden;
+ padding: 0 3px;
+ text-align: center;
+ text-overflow: ellipsis;
+}
+
+.cookie-items .cookie-item:hover {
+ background: #EEF3F9;
+ border-color: #647187;
+}
+
+.cookie-items .cookie-item[selected] {
+ background: #F5F8F8;
+ border-color: #B2B2B2;
+}
+
+.cookie-items .cookie-item[selected]:hover {
+ background: #F5F8F8;
+ border-color: #647187;
+}
+
+
+/* styles for the cookie details box */
+.cookie-details {
+ background: #F5F8F8;
+ border-radius: 5px;
+ border: 1px solid #B2B2B2;
+ margin-top: 2px;
+ padding: 5px;
+}
+
+.cookie-details-table {
+ table-layout: fixed;
+ width: 100%;
+}
+
+.cookie-details-label {
+ vertical-align: top;
+ white-space: pre;
+ width: 10em;
+}
+
+.cookie-details-value {
word-wrap: break-word;
}
diff --git a/chrome/browser/resources/options/cookies_view.html b/chrome/browser/resources/options/cookies_view.html
index 9101853..5597c02 100644
--- a/chrome/browser/resources/options/cookies_view.html
+++ b/chrome/browser/resources/options/cookies_view.html
@@ -3,190 +3,17 @@
<span i18n-content="cookiesViewPage"></span>
</h1>
- <label><span i18n-content="label_cookie_search"></span>
- <input type=text id="cookiesSearchBox"></label>
- <button id="clearCookieSearchButton"
- i18n-content="label_cookie_clear_search"></button>
+ <div id="cookies-column-headers">
+ <div id="cookies-site-column"><h3 i18n-content="cookie_domain"></h3></div>
+ <div id="cookies-data-column"><h3 i18n-content="cookie_local_data"></h3></div>
+ <div id="remove-all-cookies-search-column">
+ <button id="remove-all-cookies-button"
+ i18n-content="remove_all_cookie"></button>
+ <input id="cookies-search-box" type="search"
+ placeholder=" Search cookies" incremental
+ results="10" autosave="org.chromium.options.cookies.search">
+ </div>
+ </div>
- <table class="cookies-info-table">
- <tr>
- <td>
- <div id="cookiesTree"></div>
- </td>
- </tr>
- <tr>
- <td>
- <div id="cookiesInfo" class="cookies-details-pane">
- <table>
- <tr>
- <td class="cookie-details-label"
- i18n-content="label_cookie_name">
- </td>
- <td><span id="cookieName"></span></td>
- </tr>
- <tr>
- <td class="cookie-details-label"
- i18n-content="label_cookie_content">
- </td>
- <td><span id="cookieContent"></span></td>
- </tr>
- <tr>
- <td class="cookie-details-label"
- i18n-content="label_cookie_domain">
- </td>
- <td><span id="cookieDomain"></span></td>
- </tr>
- <tr>
- <td class="cookie-details-label"
- i18n-content="label_cookie_path">
- </td>
- <td><span id="cookiePath"></span></td>
- </tr>
- <tr>
- <td class="cookie-details-label"
- i18n-content="label_cookie_send_for">
- </td>
- <td><span id="cookieSendFor"></span></td>
- </tr>
- <tr>
- <td class="cookie-details-label"
- i18n-content="label_cookie_accessible_to_script">
- </td>
- <td><span id="cookieAccessibleToScript"></span></td>
- </tr>
- <tr>
- <td class="cookie-details-label"
- i18n-content="label_cookie_created">
- </td>
- <td><span id="cookieCreated"></span></td>
- </tr>
- <tr>
- <td class="cookie-details-label"
- i18n-content="label_cookie_expires">
- </td>
- <td><span id="cookieExpires"></span></td>
- </tr>
- </table>
- </div>
- </td>
- </tr>
- <tr>
- <td>
- <div id="appCacheInfo" class="cookies-details-pane hidden">
- <table>
- <tr>
- <td class="cookie-details-label"
- i18n-content="label_app_cache_manifest">
- </td>
- <td><span id="appCacheManifest"></span></td>
- </tr>
- <tr>
- <td class="cookie-details-label"
- i18n-content="label_local_storage_size">
- </td>
- <td><span id="appCacheSize"></span></td>
- </tr>
- <tr>
- <td class="cookie-details-label"
- i18n-content="label_cookie_created">
- </td>
- <td><span id="appCacheCreated"></span></td>
- </tr>
- <tr>
- <td class="cookie-details-label"
- i18n-content="label_cookie_last_accessed">
- </td>
- <td><span id="appCacheLastAccessed"></span></td>
- </tr>
- </table>
- </div>
- </td>
- </tr>
- <tr>
- <td>
- <div id="webDbInfo" class="cookies-details-pane hidden">
- <table>
- <tr>
- <td class="cookie-details-label"
- i18n-content="label_cookie_name">
- </td>
- <td><span id="webdbName"></span></td>
- </tr>
- <tr>
- <td class="cookie-details-label"
- i18n-content="label_webdb_desc">
- </td>
- <td><span id="webdbDesc"></span></td>
- </tr>
- <tr>
- <td class="cookie-details-label"
- i18n-content="label_local_storage_size">
- </td>
- <td><span id="webdbSize"></span></td>
- </tr>
- <tr>
- <td class="cookie-details-label"
- i18n-content="label_local_storage_last_modified">
- </td>
- <td><span id="webdbLastModified"></span></td>
- </tr>
- </table>
- </div>
- </td>
- </tr>
- <tr>
- <td>
- <div id="localStorageInfo" class="cookies-details-pane hidden">
- <table>
- <tr>
- <td class="cookie-details-label"
- i18n-content="label_local_storage_origin">
- </td>
- <td><span id="localStorageOrigin"></span></td>
- </tr>
- <tr>
- <td class="cookie-details-label"
- i18n-content="label_local_storage_size">
- </td>
- <td><span id="localStorageSize"></span></td>
- </tr>
- <tr>
- <td class="cookie-details-label"
- i18n-content="label_local_storage_last_modified">
- </td>
- <td><span id="localStorageLastModified"></span></td>
- </tr>
- </table>
- </div>
- </td>
- </tr>
- <tr>
- <td>
- <div id="indexedDBInfo" class="cookies-details-pane hidden">
- <table>
- <tr>
- <td class="cookie-details-label"
- i18n-content="label_indexed_db_origin">
- </td>
- <td><span id="indexedDBOrigin"></span></td>
- </tr>
- <tr>
- <td class="cookie-details-label"
- i18n-content="label_indexed_db_size">
- </td>
- <td><span id="indexedDBSize"></span></td>
- </tr>
- <tr>
- <td class="cookie-details-label"
- i18n-content="label_indexed_db_last_modified">
- </td>
- <td><span id="indexedDBLastModified"></span></td>
- </tr>
- </table>
- </div>
- </td>
- </tr>
- </table>
- <button id="remove-cookie" i18n-content="remove_cookie"></button>
- <button id="remove-all-cookie" i18n-content="remove_all_cookie"></button>
+ <list id="cookies-list"></list>
</div>
diff --git a/chrome/browser/resources/options/cookies_view.js b/chrome/browser/resources/options/cookies_view.js
index 8fdd60a..5d5283e 100644
--- a/chrome/browser/resources/options/cookies_view.js
+++ b/chrome/browser/resources/options/cookies_view.js
@@ -10,7 +10,7 @@ cr.define('options', function() {
// CookiesView class:
/**
- * Encapsulated handling of ChromeOS accounts options page.
+ * Encapsulated handling of the cookies and other site data page.
* @constructor
*/
function CookiesView(model) {
@@ -27,133 +27,17 @@ cr.define('options', function() {
initializePage: function() {
OptionsPage.prototype.initializePage.call(this);
- var cookiesTree = $('cookiesTree');
+ $('cookies-search-box').addEventListener('search',
+ this.handleSearchQueryChange_.bind(this));
- options.CookiesTree.decorate(cookiesTree);
- cookiesTree.addEventListener('change',
- this.handleCookieTreeChange_.bind(this));
- cookiesTree.addEventListener('keydown', this.handleKeyDown_.bind(this));
-
- $('cookiesSearchBox').addEventListener('keydown',
- this.handleQueryEditKeyDown_.bind(this));
-
- var self = this;
- $('clearCookieSearchButton').onclick = function(e) {
- $('cookiesSearchBox').value = '';
- self.searchCookie();
- }
-
- $('remove-cookie').onclick = function(e) {
- self.removeSelectedCookie_();
- }
-
- $('remove-all-cookie').onclick = function(e) {
+ $('remove-all-cookies-button').onclick = function(e) {
chrome.send('removeAllCookies', []);
- }
+ };
- this.addEventListener('visibleChange', this.handleVisibleChange_);
+ var cookiesList = $('cookies-list');
+ options.CookiesList.decorate(cookiesList);
- this.clearCookieInfo();
- },
-
- /**
- * Set visible detailed info.
- * @param {string} name Name of the details info pane to made visible.
- */
- updateVisibleDetailedInfo: function(name) {
- const infoPaneNames = [
- 'cookiesInfo',
- 'appCacheInfo',
- 'webDbInfo',
- 'localStorageInfo',
- 'indexedDBInfo'];
-
- for (var i = 0 ; i < infoPaneNames.length; ++i) {
- var paneName = infoPaneNames[i];
- var pane = $(paneName);
- if (name == paneName) {
- pane.classList.remove('hidden');
- } else {
- pane.classList.add('hidden');
- }
- }
- },
-
- /**
- * Update remove button state.
- */
- updateRemoveButtonState: function() {
- var cookiesTree = $('cookiesTree');
- $('remove-cookie').disabled = !cookiesTree.children.length ||
- !cookiesTree.selectedItem;
- $('remove-all-cookie').disabled = !cookiesTree.children.length;
- },
-
- /**
- * Clears cookie info.
- */
- clearCookieInfo: function() {
- var noCookie = localStrings.getString('no_cookie');
- $('cookieName').textContent = noCookie;
- $('cookieContent').textContent = noCookie;
- $('cookieDomain').textContent = noCookie;
- $('cookiePath').textContent = noCookie;
- $('cookieSendFor').textContent = noCookie;
- $('cookieAccessibleToScript').textContent = noCookie;
- $('cookieCreated').textContent = noCookie;
- $('cookieExpires').textContent = noCookie;
- },
-
- /**
- * Sets cookie info to display.
- */
- setCookieInfo: function(cookie) {
- $('cookieName').textContent = cookie.name;
- $('cookieContent').textContent = cookie.content;
- $('cookieDomain').textContent = cookie.domain;
- $('cookiePath').textContent = cookie.path;
- $('cookieSendFor').textContent = cookie.sendfor;
- $('cookieAccessibleToScript').textContent = cookie.accessibleToScript;
- $('cookieCreated').textContent = cookie.created;
- $('cookieExpires').textContent = cookie.expires;
- },
-
- /**
- * Sets app cache info to display.
- */
- setAppCacheInfo: function(appCache) {
- $('appCacheManifest').textContent = appCache.manifest;
- $('appCacheSize').textContent = appCache.size;
- $('appCacheCreated').textContent = appCache.created;
- $('appCacheLastAccessed').textContent = appCache.accessed;
- },
-
- /**
- * Sets web db info to display.
- */
- setWebDbInfo: function(webDb) {
- $('webdbName').textContent = webDb.name;
- $('webdbDesc').textContent = webDb.desc;
- $('webdbSize').textContent = webDb.size;
- $('webdbLastModified').textContent = webDb.modified;
- },
-
- /**
- * Sets local storage info to display.
- */
- setLocalStorageInfo: function(localStorage) {
- $('localStorageOrigin').textContent = localStorage.origin;
- $('localStorageSize').textContent = localStorage.size;
- $('localStorageLastModified').textContent = localStorage.modified;
- },
-
- /**
- * Sets IndexedDB info to display.
- */
- setIndexedDBInfo: function(indexedDB) {
- $('indexedDBOrigin').textContent = indexedDB.origin;
- $('indexedDBSize').textContent = indexedDB.size;
- $('indexedDBLastModified').textContent = indexedDB.modified;
+ this.addEventListener('visibleChange', this.handleVisibleChange_);
},
lastQuery_ : null,
@@ -163,56 +47,21 @@ cr.define('options', function() {
*/
searchCookie: function() {
this.queryDelayTimerId_ = 0;
- var filter = $('cookiesSearchBox').value;
+ var filter = $('cookies-search-box').value;
if (this.lastQuery_ != filter) {
- chrome.send('updateCookieSearchResults', [filter]);
this.lastQuery_ = filter;
- }
- },
-
- /**
- * Handles cookie tree selection change.
- * @private
- * @param {!Event} e The change event object.
- */
- handleCookieTreeChange_: function(e) {
- this.updateRemoveButtonState();
-
- var cookiesTree = $('cookiesTree');
- var data = null;
- if (cookiesTree.selectedItem) {
- data = cookiesTree.selectedItem.data;
- }
-
- if (data && data.type == 'cookie') {
- this.setCookieInfo(data);
- this.updateVisibleDetailedInfo('cookiesInfo');
- } else if (data && data.type == 'database') {
- this.setWebDbInfo(data);
- this.updateVisibleDetailedInfo('webDbInfo');
- } else if (data && data.type == 'local_storage') {
- this.setLocalStorageInfo(data);
- this.updateVisibleDetailedInfo('localStorageInfo');
- } else if (data && data.type == 'app_cache') {
- this.setAppCacheInfo(data);
- this.updateVisibleDetailedInfo('appCacheInfo');
- } else if (data && data.type == 'indexed_db') {
- this.setIndexedDBInfo(data);
- this.updateVisibleDetailedInfo('indexedDBInfo');
- } else {
- this.clearCookieInfo();
- this.updateVisibleDetailedInfo('cookiesInfo');
+ chrome.send('updateCookieSearchResults', [filter]);
}
},
queryDelayTimerId_: 0,
/**
- * Handles query edit key down.
+ * Handles search query changes.
* @private
* @param {!Event} e The event object.
*/
- handleQueryEditKeyDown_: function(e) {
+ handleSearchQueryChange_: function(e) {
if (this.queryDelayTimerId_) {
window.clearTimeout(this.queryDelayTimerId_);
}
@@ -221,7 +70,7 @@ cr.define('options', function() {
this.searchCookie.bind(this), 500);
},
- initalized_: false,
+ initialized_: false,
/**
* Handler for OptionsPage's visible property change event.
@@ -229,53 +78,24 @@ cr.define('options', function() {
* @param {Event} e Property change event.
*/
handleVisibleChange_: function(e) {
- if (!this.initalized_ && this.visible) {
- this.initalized_ = true;
+ if (!this.initialized_ && this.visible) {
+ this.initialized_ = true;
this.searchCookie();
}
},
-
- /**
- * Remove currently selected cookie.
- * @private
- */
- removeSelectedCookie_: function() {
- var selected = cookiesTree.selectedItem;
- if (selected)
- chrome.send('removeCookie', [selected.pathId]);
- },
-
- /**
- * Handler for keydown event.
- * @private
- * @param {Event} e KeyDown event.
- */
- handleKeyDown_: function(e) {
- // If 'Remove' button is enabled and key is 'Delete' key on all platforms
- // or 'Backspace' on Mac.
- if (!$('remove-cookie').disabled &&
- (e.keyIdentifier == 'U+007F' ||
- (cr.isMac && e.keyIdentifier == 'U+0008'))) {
- // No further key handling to avoid navigation triggered by 'Backspace'
- // on Mac.
- e.preventDefault();
-
- this.removeSelectedCookie_();
- }
- }
};
// CookiesViewHandler callbacks.
CookiesView.onTreeItemAdded = function(args) {
- $('cookiesTree').addByParentId(args[0], args[1], args[2]);
+ $('cookies-list').addByParentId(args[0], args[1], args[2]);
};
CookiesView.onTreeItemRemoved = function(args) {
- $('cookiesTree').removeByParentId(args[0], args[1], args[2]);
+ $('cookies-list').removeByParentId(args[0], args[1], args[2]);
};
CookiesView.loadChildren = function(args) {
- $('cookiesTree').loadChildren(args[0], args[1]);
+ $('cookies-list').loadChildren(args[0], args[1]);
};
// Export
diff --git a/chrome/browser/resources/options/options.html b/chrome/browser/resources/options/options.html
index 2d388b9..f9b3a72 100644
--- a/chrome/browser/resources/options/options.html
+++ b/chrome/browser/resources/options/options.html
@@ -111,7 +111,7 @@
<script src="content_settings.js"></script>
<script src="content_settings_exceptions_area.js"></script>
<script src="content_settings_ui.js"></script>
-<script src="cookies_tree.js"></script>
+<script src="cookies_list.js"></script>
<script src="cookies_view.js"></script>
<script src="font_settings.js"></script>
<script src="import_data_overlay.js"></script>
diff --git a/chrome/browser/resources/shared/js/cr/ui/list_item.js b/chrome/browser/resources/shared/js/cr/ui/list_item.js
index 3b72fcc..962ab13 100644
--- a/chrome/browser/resources/shared/js/cr/ui/list_item.js
+++ b/chrome/browser/resources/shared/js/cr/ui/list_item.js
@@ -30,7 +30,7 @@ cr.define('cr.ui', function() {
* This item's index in the containing list.
* @type {number}
*/
- listIndex: -1,
+ listIndex_: -1,
/**
* Called when an element is decorated as a list item.
@@ -62,6 +62,12 @@ cr.define('cr.ui', function() {
*/
cr.defineProperty(ListItem, 'lead', cr.PropertyKind.BOOL_ATTR);
+ /**
+ * This item's index in the containing list.
+ * @type {number}
+ */
+ cr.defineProperty(ListItem, 'listIndex');
+
return {
ListItem: ListItem
};
diff --git a/chrome/browser/ui/webui/options/cookies_view_handler.cc b/chrome/browser/ui/webui/options/cookies_view_handler.cc
index a292731..4759c33 100644
--- a/chrome/browser/ui/webui/options/cookies_view_handler.cc
+++ b/chrome/browser/ui/webui/options/cookies_view_handler.cc
@@ -217,9 +217,6 @@ void CookiesViewHandler::GetLocalizedValues(
RegisterTitle(localized_strings, "cookiesViewPage",
IDS_COOKIES_WEBSITE_PERMISSIONS_WINDOW_TITLE);
- localized_strings->SetString("label_cookie_search",
- l10n_util::GetStringUTF16(IDS_COOKIES_SEARCH_LABEL));
-
localized_strings->SetString("label_cookie_name",
l10n_util::GetStringUTF16(IDS_COOKIES_COOKIE_NAME_LABEL));
localized_strings->SetString("label_cookie_content",
@@ -255,13 +252,23 @@ void CookiesViewHandler::GetLocalizedValues(
localized_strings->SetString("label_cookie_last_accessed",
l10n_util::GetStringUTF16(IDS_COOKIES_LAST_ACCESSED_LABEL));
- localized_strings->SetString("no_cookie",
- l10n_util::GetStringUTF16(IDS_COOKIES_COOKIE_NONESELECTED));
- localized_strings->SetString("unnamed",
- l10n_util::GetStringUTF16(IDS_COOKIES_WEB_DATABASE_UNNAMED_NAME));
+ localized_strings->SetString("cookie_domain",
+ l10n_util::GetStringUTF16(IDS_COOKIES_DOMAIN_COLUMN_HEADER));
+ localized_strings->SetString("cookie_local_data",
+ l10n_util::GetStringUTF16(IDS_COOKIES_DATA_COLUMN_HEADER));
+ localized_strings->SetString("cookie_singular",
+ l10n_util::GetStringUTF16(IDS_COOKIES_SINGLE_COOKIE));
+ localized_strings->SetString("cookie_plural",
+ l10n_util::GetStringUTF16(IDS_COOKIES_PLURAL_COOKIES));
+ localized_strings->SetString("cookie_database_storage",
+ l10n_util::GetStringUTF16(IDS_COOKIES_DATABASE_STORAGE));
+ localized_strings->SetString("cookie_indexed_db",
+ l10n_util::GetStringUTF16(IDS_COOKIES_INDEXED_DB));
+ localized_strings->SetString("cookie_local_storage",
+ l10n_util::GetStringUTF16(IDS_COOKIES_LOCAL_STORAGE));
+ localized_strings->SetString("cookie_session_storage",
+ l10n_util::GetStringUTF16(IDS_COOKIES_SESSION_STORAGE));
- localized_strings->SetString("label_cookie_clear_search", CleanButtonLabel(
- l10n_util::GetStringUTF16(IDS_COOKIES_CLEAR_SEARCH_LABEL)));
localized_strings->SetString("remove_cookie", CleanButtonLabel(
l10n_util::GetStringUTF16(IDS_COOKIES_REMOVE_LABEL)));
localized_strings->SetString("remove_all_cookie", CleanButtonLabel(