Commit 903c89b7 authored by Sigurdur Asgeirsson's avatar Sigurdur Asgeirsson Committed by Commit Bot

RC: Better presentation and sorting for chrome://discards DB tab.

Bug: 874968
Change-Id: Ie7b655ece8e9a98c73bb529181a79e3d9a7b7586
Reviewed-on: https://chromium-review.googlesource.com/1231922
Commit-Queue: Sigurður Ásgeirsson <siggi@chromium.org>
Reviewed-by: default avatarDemetrios Papadopoulos <dpapad@chromium.org>
Reviewed-by: default avatarChris Hamilton <chrisha@chromium.org>
Cr-Commit-Position: refs/heads/master@{#593172}
parent dec72e86
...@@ -86,6 +86,8 @@ ...@@ -86,6 +86,8 @@
<include name="IDR_DISCARDS_JS" file="resources\discards\discards.js" type="BINDATA" /> <include name="IDR_DISCARDS_JS" file="resources\discards\discards.js" type="BINDATA" />
<include name="IDR_DISCARDS_LIFECYCLE_UNIT_STATE_MOJO_JS" file="${root_gen_dir}\chrome\browser\resource_coordinator\lifecycle_unit_state.mojom.js" use_base_dir="false" type="BINDATA" /> <include name="IDR_DISCARDS_LIFECYCLE_UNIT_STATE_MOJO_JS" file="${root_gen_dir}\chrome\browser\resource_coordinator\lifecycle_unit_state.mojom.js" use_base_dir="false" type="BINDATA" />
<include name="IDR_DISCARDS_MOJO_JS" file="${root_gen_dir}\chrome\browser\ui\webui\discards\discards.mojom.js" use_base_dir="false" type="BINDATA" /> <include name="IDR_DISCARDS_MOJO_JS" file="${root_gen_dir}\chrome\browser\ui\webui\discards\discards.mojom.js" use_base_dir="false" type="BINDATA" />
<include name="IDR_DISCARDS_SORTED_TABLE_BEHAVIOR_HTML" file="resources\discards\sorted_table_behavior.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
<include name="IDR_DISCARDS_SORTED_TABLE_BEHAVIOR_JS" file="resources\discards\sorted_table_behavior.js" type="BINDATA" />
</if> </if>
<if expr="is_win"> <if expr="is_win">
<include name="IDR_ABOUT_CONFLICTS_HTML" file="resources\conflicts\about_conflicts.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" /> <include name="IDR_ABOUT_CONFLICTS_HTML" file="resources\conflicts\about_conflicts.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
......
...@@ -12,6 +12,13 @@ js_type_check("closure_compile") { ...@@ -12,6 +12,13 @@ js_type_check("closure_compile") {
] ]
} }
js_library("sorted_table_behavior") {
deps = [
"//ui/webui/resources/js:assert",
"//ui/webui/resources/js:util",
]
}
js_library("discards") { js_library("discards") {
deps = [ deps = [
"//ui/webui/resources/js:assert", "//ui/webui/resources/js:assert",
...@@ -22,6 +29,7 @@ js_library("discards") { ...@@ -22,6 +29,7 @@ js_library("discards") {
js_library("database_tab") { js_library("database_tab") {
deps = [ deps = [
":discards", ":discards",
":sorted_table_behavior",
"//ui/webui/resources/js:assert", "//ui/webui/resources/js:assert",
"//ui/webui/resources/js:util", "//ui/webui/resources/js:util",
] ]
...@@ -36,6 +44,7 @@ js_library("database_tab") { ...@@ -36,6 +44,7 @@ js_library("database_tab") {
js_library("discards_tab") { js_library("discards_tab") {
deps = [ deps = [
":discards", ":discards",
":sorted_table_behavior",
"//ui/webui/resources/js:assert", "//ui/webui/resources/js:assert",
"//ui/webui/resources/js:icon", "//ui/webui/resources/js:icon",
"//ui/webui/resources/js:util", "//ui/webui/resources/js:util",
......
...@@ -8,6 +8,10 @@ general use and is not localized. ...@@ -8,6 +8,10 @@ general use and is not localized.
--> -->
<link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/html/polymer.html">
<link rel="import" href="sorted_table_behavior.html">
<link rel="import" href="chrome://resources/html/assert.html">
<script src="chrome://resources/js/cr.js"></script>
<dom-module id="database-tab"> <dom-module id="database-tab">
<template> <template>
<style> <style>
...@@ -35,21 +39,40 @@ general use and is not localized. ...@@ -35,21 +39,40 @@ general use and is not localized.
display: flex; display: flex;
justify-content: flex-start; justify-content: flex-start;
} }
table th[data-sort-key] {
cursor: pointer;
}
th div.header-cell-container::after {
content: '▲';
opacity: 0;
}
th.sort-column div.header-cell-container::after {
content: '▲';
opacity: 1;
}
th.sort-column-reverse div.header-cell-container::after {
content: '▼';
opacity: 1;
}
</style> </style>
<table> <table>
<thead> <thead>
<tr> <tr>
<th> <th data-sort-key="origin" class="sort-column" on-click="onSortClick">
<div class="header-cell-container"> <div class="header-cell-container">
Origin Origin
</div> </div>
</th> </th>
<th> <th data-sort-key="dirty" on-click="onSortClick">
<div class="header-cell-container"> <div class="header-cell-container">
Dirty Dirty
</div> </div>
</th> </th>
<th> <th data-sort-key="lastLoaded" on-click="onSortClick">
<div class="header-cell-container"> <div class="header-cell-container">
Last Loaded Last Loaded
</div> </div>
...@@ -86,37 +109,38 @@ general use and is not localized. ...@@ -86,37 +109,38 @@ general use and is not localized.
</div> </div>
</div> </div>
</th> </th>
<th> <th data-sort-key="cpuUsage" on-click="onSortClick">
<div class="header-cell-container"> <div class="header-cell-container">
<div> <div>
<div>Average CPU usage</div> <div>Average</div>
<div>(microseconds)</div> <div>CPU Usage</div>
</div> </div>
</div> </div>
</th> </th>
<th> <th data-sort-key="memoryUsage" on-click="onSortClick">
<div class="header-cell-container"> <div class="header-cell-container">
<div> <div>
<div>Average Memory</div> <div>Average Memory</div>
<div>Footprint (kb)</div> <div>Footprint</div>
</div> </div>
</div> </div>
</th> </th>
<th> <th data-sort-key="loadDuration" on-click="onSortClick">
<div class="header-cell-container"> <div class="header-cell-container">
<div> <div>
<div>Average Load</div> <div>Average Load</div>
<div>Time (us)</div> <div>Time</div>
</div> </div>
</div> </div>
</th> </th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<template is="dom-repeat" sort="compareRows_" items="[[rows_]]"> <template is="dom-repeat" items="[[rows_]]"
sort="[[computeSortFunction_(sortKey, sortReverse)]]">
<tr> <tr>
<td class="origin-cell">[[item.origin]]</td> <td class="origin-cell">[[item.origin]]</td>
<td class="dirty-cell">[[boolToString_(item.dirty)]]</td> <td class="dirty-cell">[[boolToString_(item.isDirty)]]</td>
<td>[[lastUseToString_(item.value.lastLoaded)]]</td> <td>[[lastUseToString_(item.value.lastLoaded)]]</td>
<td>[[featureToString_(item.value.updatesFaviconInBackground)]]</td> <td>[[featureToString_(item.value.updatesFaviconInBackground)]]</td>
<td>[[featureToString_(item.value.updatesTitleInBackground)]]</td> <td>[[featureToString_(item.value.updatesTitleInBackground)]]</td>
......
...@@ -2,9 +2,189 @@ ...@@ -2,9 +2,189 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
cr.define('database_tab', function() {
'use strict';
/**
* Compares two db rows by their origin.
* @param {mojom.SiteCharacteristicsDatabaseEntry} a The first value being
* compared.
* @param {mojom.SiteCharacteristicsDatabaseEntry} b The second value being
* compared.
* @return {number} A negative number if a < b, 0 if a == b, and a positive
* number if a > b.
*/
function compareRowsByOrigin(a, b) {
return a.origin.localeCompare(b.origin);
}
/**
* Compares two db rows by their dirty bit.
* @param {mojom.SiteCharacteristicsDatabaseEntry} a The first value being
* compared.
* @param {mojom.SiteCharacteristicsDatabaseEntry} b The second value being
* compared.
* @return {number} A negative number if a < b, 0 if a == b, and a positive
* number if a > b.
*/
function compareRowsByIsDirty(a, b) {
return a.isDirty - b.isDirty;
}
/**
* Compares two db rows by their last load time.
* @param {mojom.SiteCharacteristicsDatabaseEntry} a The first value being
* compared.
* @param {mojom.SiteCharacteristicsDatabaseEntry} b The second value being
* compared.
* @return {number} A negative number if a < b, 0 if a == b, and a positive
* number if a > b.
*/
function compareRowsByLastLoaded(a, b) {
return a.value.lastLoaded - a.value.lastLoaded;
}
/**
* Compares two db rows by their CPU usage.
* @param {mojom.SiteCharacteristicsDatabaseEntry} a The first value being
* compared.
* @param {mojom.SiteCharacteristicsDatabaseEntry} b The second value being
* compared.
* @return {number} A negative number if a < b, 0 if a == b, and a positive
* number if a > b.
*/
function compareRowsByCpuUsage(a, b) {
const keyA =
a.value.loadTimeEstimates ? a.value.loadTimeEstimates.avgCpuUsageUs : 0;
const keyB =
b.value.loadTimeEstimates ? b.value.loadTimeEstimates.avgCpuUsageUs : 0;
return keyA - keyB;
}
/**
* Compares two db rows by their memory usage.
* @param {mojom.SiteCharacteristicsDatabaseEntry} a The first value being
* compared.
* @param {mojom.SiteCharacteristicsDatabaseEntry} b The second value being
* compared.
* @return {number} A negative number if a < b, 0 if a == b, and a positive
* number if a > b.
*/
function compareRowsByMemoryUsage(a, b) {
const keyA = a.value.loadTimeEstimates ?
a.value.loadTimeEstimates.avgFootprintKb :
0;
const keyB = b.value.loadTimeEstimates ?
b.value.loadTimeEstimates.avgFootprintKb :
0;
return keyA - keyB;
}
/**
* Compares two db rows by their load duration.
* @param {mojom.SiteCharacteristicsDatabaseEntry} a The first value being
* compared.
* @param {mojom.SiteCharacteristicsDatabaseEntry} b The second value being
* compared.
* @return {number} A negative number if a < b, 0 if a == b, and a positive
* number if a > b.
*/
function compareRowsByLoadDuration(a, b) {
const keyA = a.value.loadTimeEstimates ?
a.value.loadTimeEstimates.avgLoadDurationUs :
0;
const keyB = b.value.loadTimeEstimates ?
b.value.loadTimeEstimates.avgLoadDurationUs :
0;
return keyA - keyB;
}
/**
* @param {string} sortKey The sort key to get a function for.
* @return {function(mojom.SiteCharacteristicsDatabaseEntry,
mojom.SiteCharacteristicsDatabaseEntry): number}
* A comparison function that compares two tab infos, returns
* negative number if a < b, 0 if a == b, and a positive
* number if a > b.
*/
function getSortFunctionForKey(sortKey) {
switch (sortKey) {
case 'origin':
return compareRowsByOrigin;
case 'dirty':
return compareRowsByIsDirty;
case 'lastLoaded':
return compareRowsByLastLoaded;
case 'cpuUsage':
return compareRowsByCpuUsage;
case 'memoryUsage':
return compareRowsByMemoryUsage;
case 'loadDuration':
return compareRowsByLoadDuration;
default:
assertNotReached('Unknown sortKey: ' + sortKey);
}
}
/**
* @param {number} time A time in microseconds.
* @return {string} A friendly, human readable string representing the input
* time with units.
*/
function microsecondsToString(time) {
if (time < 1000)
return time.toString() + ' µs';
time /= 1000;
if (time < 1000)
return time.toFixed(2) + ' ms';
time /= 1000;
return time.toFixed(2) + ' s';
}
/**
* @param {number} value A memory amount in kilobytes.
* @return {string} A friendly, human readable string representing the input
* time with units.
*/
function kilobytesToString(value) {
if (value < 1000)
return value.toString() + ' KB';
value /= 1000;
if (value < 1000)
return value.toFixed(1) + ' MB';
value /= 1000;
return value.toFixed(1) + ' GB';
}
/**
* @param {!Object} item The item to retrieve a load time estimate for.
* @param {string} propertyName Name of the load time estimate to retrieve.
* @return {string} The requested load time estimate or 'N/A' if unavailable.
*/
function formatLoadTimeEstimate(item, propertyName) {
if (!item.value || !item.value.loadTimeEstimates)
return 'N/A';
const value = item.value.loadTimeEstimates[propertyName];
if (propertyName.endsWith('Us')) {
return microsecondsToString(value);
} else if (propertyName.endsWith('Kb')) {
return kilobytesToString(value);
}
return value.toString();
}
return {
getSortFunctionForKey: getSortFunctionForKey,
formatLoadTimeEstimate: formatLoadTimeEstimate,
};
});
Polymer({ Polymer({
is: 'database-tab', is: 'database-tab',
behaviors: [SortedTableBehavior],
properties: { properties: {
/** /**
* List of database rows. * List of database rows.
...@@ -26,6 +206,7 @@ Polymer({ ...@@ -26,6 +206,7 @@ Polymer({
/** @override */ /** @override */
ready: function() { ready: function() {
this.setSortKey('origin');
this.requestedOrigins_ = {}; this.requestedOrigins_ = {};
this.uiHandler_ = discards.getOrCreateUiHandler(); this.uiHandler_ = discards.getOrCreateUiHandler();
...@@ -62,19 +243,28 @@ Polymer({ ...@@ -62,19 +243,28 @@ Polymer({
}, },
/** /**
* Compares two db rows by their origin. * Returns a sort function to compare tab infos based on the provided sort key
* @param {mojom.SiteCharacteristicsDatabaseEntry} a The first value being * and a boolean reverse flag.
* compared. * @param {string} sortKey The sort key for the returned function.
* @param {mojom.SiteCharacteristicsDatabaseEntry} b The second value being * @param {boolean} sortReverse True if sorting is reversed.
* compared. * @return {function({Object}, {Object}): number}
* @return {number} A negative number if a < b, 0 if a == b, and a positive * A comparison function that compares two tab infos, returns
* negative number if a < b, 0 if a == b, and a positive
* number if a > b. * number if a > b.
* @private * @private
*/ */
compareRows_: function(a, b) { computeSortFunction_: function(sortKey, sortReverse) {
return a.origin.localeCompare(b.origin); // Polymer 2 may invoke multi-property observers before all properties
}, // are defined.
if (!sortKey)
return (a, b) => 0;
const sortFunction = database_tab.getSortFunctionForKey(sortKey);
return (a, b) => {
const comp = sortFunction(a, b);
return sortReverse ? -comp : comp;
};
},
/** /**
* @param {boolean} value The value to convert. * @param {boolean} value The value to convert.
...@@ -127,9 +317,6 @@ Polymer({ ...@@ -127,9 +317,6 @@ Polymer({
* @private * @private
*/ */
getLoadTimeEstimate_: function(item, propertyName) { getLoadTimeEstimate_: function(item, propertyName) {
if (!item.value || !item.value.loadTimeEstimates) return database_tab.formatLoadTimeEstimate(item, propertyName);
return 'N/A';
return item.value.loadTimeEstimates[propertyName].toString();
}, },
}); });
...@@ -10,6 +10,8 @@ general use and is not localized. ...@@ -10,6 +10,8 @@ general use and is not localized.
<link rel="import" href="chrome://resources/html/action_link.html"> <link rel="import" href="chrome://resources/html/action_link.html">
<link rel="import" href="chrome://resources/html/action_link_css.html"> <link rel="import" href="chrome://resources/html/action_link_css.html">
<link rel="import" href="chrome://resources/html/assert.html">
<link rel="import" href="sorted_table_behavior.html">
<dom-module id="discards-tab"> <dom-module id="discards-tab">
<template> <template>
...@@ -147,9 +149,10 @@ general use and is not localized. ...@@ -147,9 +149,10 @@ general use and is not localized.
[Urgent discard a tab now] [Urgent discard a tab now]
</div> </div>
<table id="tab-discard-info-table"> <table id="tab-discard-info-table">
<thead on-click="onHeaderClick_"> <thead >
<tr id="tab-discards-info-table-header"> <tr id="tab-discards-info-table-header">
<th data-sort-key="utilityRank" class="sort-column"> <th data-sort-key="utilityRank" class="sort-column"
on-click="onSortClick">
<div class="header-cell-container"> <div class="header-cell-container">
<div> <div>
<div>Utility</div> <div>Utility</div>
...@@ -157,7 +160,7 @@ general use and is not localized. ...@@ -157,7 +160,7 @@ general use and is not localized.
</div> </div>
</div> </div>
</th> </th>
<th data-sort-key="reactivationScore"> <th data-sort-key="reactivationScore" on-click="onSortClick">
<div class="header-cell-container"> <div class="header-cell-container">
<div> <div>
<div>Reactivation</div> <div>Reactivation</div>
...@@ -165,7 +168,7 @@ general use and is not localized. ...@@ -165,7 +168,7 @@ general use and is not localized.
</div> </div>
</div> </div>
</th> </th>
<th data-sort-key="siteEngagementScore"> <th data-sort-key="siteEngagementScore" on-click="onSortClick">
<div class="header-cell-container"> <div class="header-cell-container">
<div> <div>
<div>Site</div> <div>Site</div>
...@@ -174,27 +177,27 @@ general use and is not localized. ...@@ -174,27 +177,27 @@ general use and is not localized.
</div> </div>
</div> </div>
</th> </th>
<th data-sort-key="title"> <th data-sort-key="title" on-click="onSortClick">
<div class="header-cell-container"> <div class="header-cell-container">
Tab Title Tab Title
</div> </div>
</th> </th>
<th data-sort-key="tabUrl"> <th data-sort-key="tabUrl" on-click="onSortClick">
<div class="header-cell-container"> <div class="header-cell-container">
Tab URL Tab URL
</div> </div>
</th> </th>
<th data-sort-key="visibility"> <th data-sort-key="visibility" on-click="onSortClick">
<div class="header-cell-container"> <div class="header-cell-container">
Visibility Visibility
</div> </div>
</th> </th>
<th data-sort-key="loadingState""> <th data-sort-key="loadingState" on-click="onSortClick">
<div class="header-cell-container"> <div class="header-cell-container">
Loading State Loading State
</div> </div>
</th> </th>
<th data-sort-key="state"> <th data-sort-key="state" on-click="onSortClick">
<div class="header-cell-container"> <div class="header-cell-container">
<div> <div>
<div>Lifecycle</div> <div>Lifecycle</div>
...@@ -202,17 +205,17 @@ general use and is not localized. ...@@ -202,17 +205,17 @@ general use and is not localized.
</div> </div>
</div> </div>
</th> </th>
<th data-sort-key="canFreeze"> <th data-sort-key="canFreeze" on-click="onSortClick">
<div class="header-cell-container"> <div class="header-cell-container">
Can freeze? Can freeze?
</div> </div>
</th> </th>
<th data-sort-key="canDiscard"> <th data-sort-key="canDiscard" on-click="onSortClick">
<div class="header-cell-container"> <div class="header-cell-container">
Can discard? Can discard?
</div> </div>
</th> </th>
<th data-sort-key="discardCount"> <th data-sort-key="discardCount" on-click="onSortClick">
<div class="header-cell-container"> <div class="header-cell-container">
<div> <div>
<div>Discard</div> <div>Discard</div>
...@@ -220,7 +223,7 @@ general use and is not localized. ...@@ -220,7 +223,7 @@ general use and is not localized.
</div> </div>
</div> </div>
</div></th> </div></th>
<th data-sort-key="isAutoDiscardable"> <th data-sort-key="isAutoDiscardable" on-click="onSortClick">
<div class="header-cell-container"> <div class="header-cell-container">
<div> <div>
<div>Auto</div> <div>Auto</div>
...@@ -228,7 +231,7 @@ general use and is not localized. ...@@ -228,7 +231,7 @@ general use and is not localized.
</div> </div>
</div> </div>
</th> </th>
<th data-sort-key="lastActiveSeconds"> <th data-sort-key="lastActiveSeconds" on-click="onSortClick">
<div class="header-cell-container"> <div class="header-cell-container">
Last Active Last Active
</div> </div>
...@@ -242,7 +245,7 @@ general use and is not localized. ...@@ -242,7 +245,7 @@ general use and is not localized.
</thead> </thead>
<tbody id="tab-discards-info-table-body"> <tbody id="tab-discards-info-table-body">
<template is="dom-repeat" <template is="dom-repeat"
sort="[[computeSortFunction_(sortKey_, sortReverse_)]]" sort="[[computeSortFunction_(sortKey, sortReverse)]]"
items="[[tabInfos_]]"> items="[[tabInfos_]]">
<tr> <tr>
<td>[[item.utilityRank]]</td> <td>[[item.utilityRank]]</td>
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
Polymer({ Polymer({
is: 'discards-tab', is: 'discards-tab',
behaviors: [SortedTableBehavior],
properties: { properties: {
/** /**
* List of tabinfos. * List of tabinfos.
...@@ -13,24 +15,6 @@ Polymer({ ...@@ -13,24 +15,6 @@ Polymer({
tabInfos_: { tabInfos_: {
type: Array, type: Array,
}, },
/**
* The current sort key, exposed to allow dom-repeat to observe changes
* to it for re-sorting on changes.
*/
sortKey_: {
type: String,
value: 'utilityRank',
},
/**
* True if sorting in reverse, expowsed to allow dom-repeat to observe
* changes to it for re-sorting on changes.
*/
sortReverse_: {
type: Boolean,
value: false,
},
}, },
/** @private The current update timer if any. */ /** @private The current update timer if any. */
...@@ -41,6 +25,7 @@ Polymer({ ...@@ -41,6 +25,7 @@ Polymer({
/** @override */ /** @override */
ready: function() { ready: function() {
this.setSortKey('utilityRank');
this.uiHandler_ = discards.getOrCreateUiHandler(); this.uiHandler_ = discards.getOrCreateUiHandler();
this.updateTable_(); this.updateTable_();
...@@ -58,6 +43,11 @@ Polymer({ ...@@ -58,6 +43,11 @@ Polymer({
* @private * @private
*/ */
computeSortFunction_: function(sortKey, sortReverse) { computeSortFunction_: function(sortKey, sortReverse) {
// Polymer 2.0 may invoke multi-property observers before all properties
// are defined.
if (!sortKey)
return (a, b) => 0;
return function(a, b) { return function(a, b) {
const comp = discards.compareTabDiscardsInfos(sortKey, a, b); const comp = discards.compareTabDiscardsInfos(sortKey, a, b);
return sortReverse ? -comp : comp; return sortReverse ? -comp : comp;
...@@ -298,19 +288,6 @@ Polymer({ ...@@ -298,19 +288,6 @@ Polymer({
return item.cannotDiscardReasons.join('<br />'); return item.cannotDiscardReasons.join('<br />');
}, },
/**
* Sets a new sort key for this item, or toggles the sorting order if called
* with the current sort key.
* @param {string} sortKey The new sort key.
* @private
*/
setSortKey_: function(sortKey) {
if (this.sortKey_ == sortKey)
this.sortReverse_ = !this.sortReverse_;
else
this.sortKey_ = sortKey;
},
/** /**
* Tests whether an item can be loaded. * Tests whether an item can be loaded.
* @param {mojom.TabDiscardsInfo} item The item in question. * @param {mojom.TabDiscardsInfo} item The item in question.
...@@ -363,47 +340,6 @@ Polymer({ ...@@ -363,47 +340,6 @@ Polymer({
return false; return false;
}, },
/**
* Invoked when the table header is tapped, sets a new sort key and updates
* element styles to present the new sort key.
* @param {Event} e The event.
* @private
*/
onHeaderClick_: function(e) {
// Find the sortKey of the clicked header by walking up the path, looking
// for an element with a sortKey.
/**
* A sort key header element.
* @typedef {{
* dataset: {
* sortKey: string
* },
* }}
*/
let newElement = null;
for (let i = 0; i < e.path.length; ++i) {
if (e.path[i].dataset.sortKey) {
newElement = e.path[i];
break;
}
}
// Remove the presentation styles on the old sort header.
const target = e.currentTarget;
let oldElement = target.querySelector('.sort-column');
if (oldElement) {
oldElement.classList.remove('sort-column');
} else {
oldElement = target.querySelector('.sort-column-reverse');
oldElement.classList.remove('sort-column-reverse');
}
// Update the sort key and the styles on the new sort header.
this.setSortKey_(newElement.dataset.sortKey);
const newClass = this.sortReverse_ ? 'sort-column-reverse' : 'sort-column';
newElement.classList.add(newClass);
},
/** /**
* Event handler that toggles the auto discardable flag on an item. * Event handler that toggles the auto discardable flag on an item.
* @param {Event} e The event. * @param {Event} e The event.
......
<!--
Copyright 2018 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.
-->
<script src="sorted_table_behavior.js"></script>
// Copyright 2018 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.
/**
* This behavior bundles functionality common to sortable tables.
*
* @polymerBehavior
*/
const SortedTableBehavior = {
properties: {
/**
* The current sort key, used for computing the appropriate sort function.
*/
sortKey: {
type: String,
},
/**
* True if sorting in reverse, used for computing the appropriate sort
* function.
*/
sortReverse: {
type: Boolean,
value: false,
},
},
/**
* Sets a new sort key for this item.
* @param {string} sortKey The new sort key.
* @public
*/
setSortKey: function(sortKey) {
this.sortKey = sortKey;
},
/**
* Invoked when a header is clicked, sets a new sort key and updates
* element styles to present the new sort key.
* @param {Event} e The event.
* @public
*/
onSortClick: function(e) {
// Remove the presentation style on the old sort header.
let oldElement = this.$$('.sort-column, .sort-column-reverse');
if (oldElement) {
oldElement.classList.remove('sort-column');
oldElement.classList.remove('sort-column-reverse');
}
const newSortKey = e.currentTarget.dataset.sortKey;
if (newSortKey == this.sortKey) {
this.sortReverse = !this.sortReverse;
} else {
this.setSortKey(newSortKey);
}
// Update the sort key and the styles on the new sort header.
const newClass = this.sortReverse ? 'sort-column-reverse' : 'sort-column';
e.currentTarget.classList.add(newClass);
},
};
...@@ -367,10 +367,15 @@ DiscardsUI::DiscardsUI(content::WebUI* web_ui) ...@@ -367,10 +367,15 @@ DiscardsUI::DiscardsUI(content::WebUI* web_ui)
IDR_DISCARDS_DISCARDS_MAIN_HTML); IDR_DISCARDS_DISCARDS_MAIN_HTML);
source->AddResourcePath("discards_main.js", IDR_DISCARDS_DISCARDS_MAIN_JS); source->AddResourcePath("discards_main.js", IDR_DISCARDS_DISCARDS_MAIN_JS);
source->AddResourcePath("discards_tab.js", IDR_DISCARDS_DISCARDS_TAB_JS);
source->AddResourcePath("discards_tab.html", IDR_DISCARDS_DISCARDS_TAB_HTML);
source->AddResourcePath("database_tab.js", IDR_DISCARDS_DATABASE_TAB_JS);
source->AddResourcePath("database_tab.html", IDR_DISCARDS_DATABASE_TAB_HTML); source->AddResourcePath("database_tab.html", IDR_DISCARDS_DATABASE_TAB_HTML);
source->AddResourcePath("database_tab.js", IDR_DISCARDS_DATABASE_TAB_JS);
source->AddResourcePath("discards_tab.html", IDR_DISCARDS_DISCARDS_TAB_HTML);
source->AddResourcePath("discards_tab.js", IDR_DISCARDS_DISCARDS_TAB_JS);
source->AddResourcePath("sorted_table_behavior.html",
IDR_DISCARDS_SORTED_TABLE_BEHAVIOR_HTML);
source->AddResourcePath("sorted_table_behavior.js",
IDR_DISCARDS_SORTED_TABLE_BEHAVIOR_JS);
// Full paths (relative to src) are important for Mojom generated files. // Full paths (relative to src) are important for Mojom generated files.
source->AddResourcePath("chrome/browser/ui/webui/discards/discards.mojom.js", source->AddResourcePath("chrome/browser/ui/webui/discards/discards.mojom.js",
IDR_DISCARDS_MOJO_JS); IDR_DISCARDS_MOJO_JS);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment