diff options
-rw-r--r-- | chrome/app/generated_resources.grd | 17 | ||||
-rw-r--r-- | chrome/browser/cookies_tree_model.cc | 2 | ||||
-rw-r--r-- | chrome/browser/resources/options/cookies_list.js | 776 | ||||
-rw-r--r-- | chrome/browser/resources/options/cookies_tree.js | 205 | ||||
-rw-r--r-- | chrome/browser/resources/options/cookies_view.css | 166 | ||||
-rw-r--r-- | chrome/browser/resources/options/cookies_view.html | 197 | ||||
-rw-r--r-- | chrome/browser/resources/options/cookies_view.js | 216 | ||||
-rw-r--r-- | chrome/browser/resources/options/options.html | 2 | ||||
-rw-r--r-- | chrome/browser/resources/shared/js/cr/ui/list_item.js | 8 | ||||
-rw-r--r-- | chrome/browser/ui/webui/options/cookies_view_handler.cc | 25 |
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( |