debug-server-next
Version:
Dev server for hippy-core.
260 lines (259 loc) • 10.4 kB
JavaScript
// Copyright 2021 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.
import * as i18n from '../../core/i18n/i18n.js';
import * as Platform from '../../core/platform/platform.js';
import * as DataGrid from '../../ui/legacy/components/data_grid/data_grid.js';
import * as UI from '../../ui/legacy/legacy.js';
import { CHECKING, DOWNLOADING, IDLE, OBSOLETE, UNCACHED, UPDATEREADY } from './ApplicationCacheModel.js';
const UIStrings = {
/**
*@description Text in Application Cache Items View of the Application panel
*/
appcache: 'AppCache',
/**
*@description Text to delete something
*/
deleteString: 'Delete',
/**
*@description Text in Application Cache Items View of the Application panel
*/
noApplicationCacheInformation: 'No Application Cache information available.',
/**
*@description Text to indicate the network connectivity is online
*/
online: 'Online',
/**
*@description Text to indicate the network connectivity is offline
*/
offline: 'Offline',
/**
*@description Text that refers to the resources of the web page
*/
resource: 'Resource',
/**
*@description Text that refers to some types
*/
typeString: 'Type',
/**
*@description Text for the size of something
*/
sizeString: 'Size',
/**
*@description Text in Application Panel Sidebar of the Application panel
*/
applicationCache: 'Application Cache',
};
const str_ = i18n.i18n.registerUIStrings('panels/application/ApplicationCacheItemsView.ts', UIStrings);
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
export class ApplicationCacheItemsView extends UI.View.SimpleView {
_model;
_deleteButton;
_connectivityIcon;
_statusIcon;
_frameId;
_emptyWidget;
_nodeResources;
_viewDirty;
_status;
_manifest;
_creationTime;
_updateTime;
_size;
_resources;
_dataGrid;
constructor(model, frameId) {
super(i18nString(UIStrings.appcache));
this._model = model;
this.element.classList.add('storage-view', 'table');
this._deleteButton = new UI.Toolbar.ToolbarButton(i18nString(UIStrings.deleteString), 'largeicon-delete');
this._deleteButton.setVisible(false);
this._deleteButton.addEventListener(UI.Toolbar.ToolbarButton.Events.Click, this._deleteButtonClicked, this);
this._connectivityIcon = document.createElement('span', { is: 'dt-icon-label' });
this._connectivityIcon.style.margin = '0 2px 0 5px';
this._statusIcon = document.createElement('span', { is: 'dt-icon-label' });
this._statusIcon.style.margin = '0 2px 0 5px';
this._frameId = frameId;
this._emptyWidget = new UI.EmptyWidget.EmptyWidget(i18nString(UIStrings.noApplicationCacheInformation));
this._emptyWidget.show(this.element);
this._markDirty();
const status = this._model.frameManifestStatus(frameId);
this.updateStatus(status);
this.updateNetworkState(this._model.onLine);
this._deleteButton.element.style.display = 'none';
this._nodeResources = new WeakMap();
}
async toolbarItems() {
return [
this._deleteButton,
new UI.Toolbar.ToolbarItem(this._connectivityIcon),
new UI.Toolbar.ToolbarSeparator(),
new UI.Toolbar.ToolbarItem(this._statusIcon),
];
}
wasShown() {
this._maybeUpdate();
}
willHide() {
this._deleteButton.setVisible(false);
}
_maybeUpdate() {
if (!this.isShowing() || !this._viewDirty) {
return;
}
this._update();
this._viewDirty = false;
}
_markDirty() {
this._viewDirty = true;
}
updateStatus(status) {
const oldStatus = this._status;
this._status = status;
const statusInformation = new Map([
// We should never have UNCACHED status, since we remove frames with UNCACHED application cache status from the tree.
[UNCACHED, { type: 'smallicon-red-ball', text: 'UNCACHED' }],
[IDLE, { type: 'smallicon-green-ball', text: 'IDLE' }],
[CHECKING, { type: 'smallicon-orange-ball', text: 'CHECKING' }],
[DOWNLOADING, { type: 'smallicon-orange-ball', text: 'DOWNLOADING' }],
[UPDATEREADY, { type: 'smallicon-green-ball', text: 'UPDATEREADY' }],
[OBSOLETE, { type: 'smallicon-red-ball', text: 'OBSOLETE' }],
]);
const info = statusInformation.get(status) || statusInformation.get(UNCACHED);
if (info) {
this._statusIcon.type = info.type;
this._statusIcon.textContent = info.text;
}
if (this.isShowing() && this._status === IDLE && (oldStatus === UPDATEREADY || !this._resources)) {
this._markDirty();
}
this._maybeUpdate();
}
updateNetworkState(isNowOnline) {
if (isNowOnline) {
this._connectivityIcon.type = 'smallicon-green-ball';
this._connectivityIcon.textContent = i18nString(UIStrings.online);
}
else {
this._connectivityIcon.type = 'smallicon-red-ball';
this._connectivityIcon.textContent = i18nString(UIStrings.offline);
}
}
async _update() {
const applicationCache = await this._model.requestApplicationCache(this._frameId);
if (!applicationCache || !applicationCache.manifestURL) {
delete this._manifest;
delete this._creationTime;
delete this._updateTime;
delete this._size;
delete this._resources;
this._emptyWidget.show(this.element);
this._deleteButton.setVisible(false);
if (this._dataGrid) {
this._dataGrid.element.classList.add('hidden');
}
return;
}
// FIXME: are these variables needed anywhere else?
this._manifest = applicationCache.manifestURL;
this._creationTime = applicationCache.creationTime;
this._updateTime = applicationCache.updateTime;
this._size = applicationCache.size;
this._resources = applicationCache.resources;
if (!this._dataGrid) {
this._createDataGrid();
}
this._populateDataGrid();
if (this._dataGrid) {
this._dataGrid.autoSizeColumns(20, 80);
this._dataGrid.element.classList.remove('hidden');
}
this._emptyWidget.detach();
this._deleteButton.setVisible(true);
// FIXME: For Chrome, put creationTime and updateTime somewhere.
// NOTE: localizedString has not yet been added.
// i18nString("(%s) Created: %s Updated: %s", this._size, this._creationTime, this._updateTime);
}
_createDataGrid() {
const columns = [
{ id: 'resource', title: i18nString(UIStrings.resource), sort: DataGrid.DataGrid.Order.Ascending, sortable: true },
{ id: 'type', title: i18nString(UIStrings.typeString), sortable: true },
{ id: 'size', title: i18nString(UIStrings.sizeString), align: DataGrid.DataGrid.Align.Right, sortable: true },
];
const parameters = {
displayName: i18nString(UIStrings.applicationCache),
columns,
editCallback: undefined,
deleteCallback: undefined,
refreshCallback: undefined,
};
this._dataGrid = new DataGrid.DataGrid.DataGridImpl(parameters);
this._dataGrid.setStriped(true);
this._dataGrid.asWidget().show(this.element);
this._dataGrid.addEventListener(DataGrid.DataGrid.Events.SortingChanged, this._populateDataGrid, this);
}
_populateDataGrid() {
if (!this._dataGrid) {
return;
}
const selectedResource = (this._dataGrid.selectedNode ? this._nodeResources.get(this._dataGrid.selectedNode) : null) || null;
const sortDirection = this._dataGrid.isSortOrderAscending() ? 1 : -1;
function numberCompare(field, resource1, resource2) {
return sortDirection * (resource1[field] - resource2[field]);
}
function localeCompare(field, resource1, resource2) {
return sortDirection * resource1[field].localeCompare(resource2[field]);
}
let comparator = null;
switch (this._dataGrid.sortColumnId()) {
case 'resource':
comparator = localeCompare.bind(null, 'url');
break;
case 'type':
comparator = localeCompare.bind(null, 'type');
break;
case 'size':
comparator = numberCompare.bind(null, 'size');
break;
}
this._dataGrid.rootNode().removeChildren();
if (!this._resources) {
return;
}
if (comparator) {
this._resources.sort(comparator);
}
let nodeToSelect;
for (let i = 0; i < this._resources.length; ++i) {
const resource = this._resources[i];
const data = {
resource: resource.url,
type: resource.type,
size: Platform.NumberUtilities.bytesToString(resource.size),
};
const node = new DataGrid.DataGrid.DataGridNode(data);
this._nodeResources.set(node, resource);
node.selectable = true;
this._dataGrid.rootNode().appendChild(node);
if (resource === selectedResource) {
nodeToSelect = node;
nodeToSelect.selected = true;
}
}
if (!nodeToSelect && this._dataGrid.rootNode().children.length) {
this._dataGrid.rootNode().children[0].selected = true;
}
}
_deleteButtonClicked(_event) {
if (!this._dataGrid || !this._dataGrid.selectedNode) {
return;
}
// FIXME: Delete Button semantics are not yet defined. (Delete a single, or all?)
this._deleteCallback(this._dataGrid.selectedNode);
}
_deleteCallback(_node) {
// FIXME: Should we delete a single (selected) resource or all resources?
// ProtocolClient.inspectorBackend.deleteCachedResource(...)
// this._update();
}
}