export class ServiceWorkerCacheView extends UI.SimpleView{constructor(model,cache){super(Common.UIString('Cache'));this.registerRequiredCSS('resources/serviceWorkerCacheViews.css');this._model=model;this._entriesForTest=null;this.element.classList.add('service-worker-cache-data-view');this.element.classList.add('storage-view');const editorToolbar=new UI.Toolbar('data-view-toolbar',this.element);this._splitWidget=new UI.SplitWidget(false,false);this._splitWidget.show(this.element);this._previewPanel=new UI.VBox();const resizer=this._previewPanel.element.createChild('div','cache-preview-panel-resizer');this._splitWidget.setMainWidget(this._previewPanel);this._splitWidget.installResizer(resizer);this._preview=null;this._cache=cache;this._dataGrid=null;this._refreshThrottler=new Common.Throttler(300);this._refreshButton=new UI.ToolbarButton(Common.UIString('Refresh'),'largeicon-refresh');this._refreshButton.addEventListener(UI.ToolbarButton.Events.Click,this._refreshButtonClicked,this);editorToolbar.appendToolbarItem(this._refreshButton);this._deleteSelectedButton=new UI.ToolbarButton(Common.UIString('Delete Selected'),'largeicon-delete');this._deleteSelectedButton.addEventListener(UI.ToolbarButton.Events.Click,()=>this._deleteButtonClicked(null));editorToolbar.appendToolbarItem(this._deleteSelectedButton);const entryPathFilterBox=new UI.ToolbarInput(ls`Filter by Path`,'',1);editorToolbar.appendToolbarItem(entryPathFilterBox);const entryPathFilterThrottler=new Common.Throttler(300);this._entryPathFilter='';entryPathFilterBox.addEventListener(UI.ToolbarInput.Event.TextChanged,()=>{entryPathFilterThrottler.schedule(()=>{this._entryPathFilter=entryPathFilterBox.value();return this._updateData(true);});});this._returnCount=(null);this._summaryBarElement=(null);this._loadingPromise=(null);this.update(cache);}
_resetDataGrid(){if(this._dataGrid){this._dataGrid.asWidget().detach();}
this._dataGrid=this._createDataGrid();const dataGridWidget=this._dataGrid.asWidget();this._splitWidget.setSidebarWidget(dataGridWidget);dataGridWidget.setMinimumSize(0,250);}
wasShown(){this._model.addEventListener(SDK.ServiceWorkerCacheModel.Events.CacheStorageContentUpdated,this._cacheContentUpdated,this);this._updateData(true);}
willHide(){this._model.removeEventListener(SDK.ServiceWorkerCacheModel.Events.CacheStorageContentUpdated,this._cacheContentUpdated,this);}
_showPreview(preview){if(preview&&this._preview===preview){return;}
if(this._preview){this._preview.detach();}
if(!preview){preview=new UI.EmptyWidget(Common.UIString('Select a cache entry above to preview'));}
this._preview=preview;this._preview.show(this._previewPanel.element);}
_createDataGrid(){const columns=([{id:'number',title:'#',sortable:false,width:'3px'},{id:'name',title:Common.UIString('Name'),weight:4,sortable:true},{id:'responseType',title:ls`Response-Type`,weight:1,align:DataGrid.DataGrid.Align.Right,sortable:true},{id:'contentType',title:Common.UIString('Content-Type'),weight:1,sortable:true},{id:'contentLength',title:Common.UIString('Content-Length'),weight:1,align:DataGrid.DataGrid.Align.Right,sortable:true},{id:'responseTime',title:Common.UIString('Time Cached'),width:'12em',weight:1,align:DataGrid.DataGrid.Align.Right,sortable:true}]);const dataGrid=new DataGrid.DataGrid({displayName:ls`Service Worker Cache`,columns,deleteCallback:this._deleteButtonClicked.bind(this),refreshCallback:this._updateData.bind(this,true)});dataGrid.addEventListener(DataGrid.DataGrid.Events.SortingChanged,this._sortingChanged,this);dataGrid.addEventListener(DataGrid.DataGrid.Events.SelectedNode,event=>this._previewCachedResponse(event.data.data),this);dataGrid.setStriped(true);return dataGrid;}
_sortingChanged(){if(!this._dataGrid){return;}
const accending=this._dataGrid.isSortOrderAscending();const columnId=this._dataGrid.sortColumnId();let comparator;if(columnId==='name'){comparator=(a,b)=>a._name.localeCompare(b._name);}else if(columnId==='contentType'){comparator=(a,b)=>a.data.mimeType.localeCompare(b.data.mimeType);}else if(columnId==='contentLength'){comparator=(a,b)=>a.data.resourceSize-b.data.resourceSize;}else if(columnId==='responseTime'){comparator=(a,b)=>a.data.endTime-b.data.endTime;}else if(columnId==='responseType'){comparator=(a,b)=>a._responseType.localeCompare(b._responseType);}
const children=this._dataGrid.rootNode().children.slice();this._dataGrid.rootNode().removeChildren();children.sort((a,b)=>{const result=comparator(a,b);return accending?result:-result;});children.forEach(child=>this._dataGrid.rootNode().appendChild(child));}
async _deleteButtonClicked(node){if(!node){node=this._dataGrid&&this._dataGrid.selectedNode;if(!node){return;}}
await this._model.deleteCacheEntry(this._cache,(node.data.url()));node.remove();}
update(cache){this._cache=cache;this._resetDataGrid();this._updateData(true);}
_updateSummaryBar(){if(!this._summaryBarElement){this._summaryBarElement=this.element.createChild('div','cache-storage-summary-bar');}
this._summaryBarElement.removeChildren();const span=this._summaryBarElement.createChild('span');if(this._entryPathFilter){span.textContent=ls`Matching entries: ${this._returnCount}`;}else{span.textContent=ls`Total entries: ${this._returnCount}`;}}
_updateDataCallback(skipCount,entries,returnCount){const selected=this._dataGrid.selectedNode&&this._dataGrid.selectedNode.data.url();this._refreshButton.setEnabled(true);this._entriesForTest=entries;this._returnCount=returnCount;this._updateSummaryBar();const oldEntries=new Map();const rootNode=this._dataGrid.rootNode();for(const node of rootNode.children){oldEntries.set(node.data.url,node);}
rootNode.removeChildren();let selectedNode=null;for(let i=0;i<entries.length;++i){const entry=entries[i];let node=oldEntries.get(entry.requestURL);if(!node||node.data.responseTime!==entry.responseTime){node=new DataGridNode(i,this._createRequest(entry),entry.responseType);node.selectable=true;}else{node.data.number=i;}
rootNode.appendChild(node);if(entry.requestURL===selected){selectedNode=node;}}
if(!selectedNode){this._showPreview(null);}else{selectedNode.revealAndSelect();}
this._updatedForTest();}
async _updateData(force){if(!force&&this._loadingPromise){return this._loadingPromise;}
this._refreshButton.setEnabled(false);if(this._loadingPromise){return this._loadingPromise;}
this._loadingPromise=new Promise(resolve=>{this._model.loadAllCacheData(this._cache,this._entryPathFilter,(entries,returnCount)=>{resolve([entries,returnCount]);});});const[entries,returnCount]=await this._loadingPromise;this._updateDataCallback(0,entries,returnCount);this._loadingPromise=null;}
_refreshButtonClicked(event){this._updateData(true);}
_cacheContentUpdated(event){const nameAndOrigin=event.data;if(this._cache.securityOrigin!==nameAndOrigin.origin||this._cache.cacheName!==nameAndOrigin.cacheName){return;}
this._refreshThrottler.schedule(()=>Promise.resolve(this._updateData(true)),true);}
async _previewCachedResponse(request){let preview=request[ServiceWorkerCacheView._previewSymbol];if(!preview){preview=new RequestView(request);request[ServiceWorkerCacheView._previewSymbol]=preview;}
if(request===this._dataGrid.selectedNode.data){this._showPreview(preview);}}
_createRequest(entry){const request=new SDK.NetworkRequest('cache-storage-'+entry.requestURL,entry.requestURL,'','','',null);request.requestMethod=entry.requestMethod;request.setRequestHeaders(entry.requestHeaders);request.statusCode=entry.responseStatus;request.statusText=entry.responseStatusText;request.protocol=new Common.ParsedURL(entry.requestURL).scheme;request.responseHeaders=entry.responseHeaders;request.setRequestHeadersText('');request.endTime=entry.responseTime;let header=entry.responseHeaders.find(header=>header.name.toLowerCase()==='content-type');const contentType=header?header.value:'text/plain';request.mimeType=contentType;header=entry.responseHeaders.find(header=>header.name.toLowerCase()==='content-length');request.resourceSize=(header&&header.value)|0;let resourceType=Common.ResourceType.fromMimeType(contentType);if(!resourceType){resourceType=Common.ResourceType.fromURL(entry.requestURL)||Common.resourceTypes.Other;}
request.setResourceType(resourceType);request.setContentDataProvider(this._requestContent.bind(this,request));return request;}
async _requestContent(request){const isText=request.resourceType().isTextType();const contentData={error:null,content:null,encoded:!isText};const response=await this._cache.requestCachedResponse(request.url(),request.requestHeaders());if(response){contentData.content=isText?window.atob(response.body):response.body;}
return contentData;}
_updatedForTest(){}}
ServiceWorkerCacheView._previewSymbol=Symbol('preview');export class DataGridNode extends DataGrid.DataGridNode{constructor(number,request,responseType){super(request);this._number=number;const parsed=new Common.ParsedURL(request.url());if(parsed.isValid){this._name=request.url().trimURL(parsed.domain());}else{this._name=request.url();}
this._request=request;this._responseType=responseType;}
createCell(columnId){const cell=this.createTD(columnId);let value;if(columnId==='number'){value=String(this._number);}else if(columnId==='name'){value=this._name;}else if(columnId==='responseType'){if(this._responseType==='opaqueResponse'){value='opaque';}else if(this._responseType==='opaqueRedirect'){value='opaqueredirect';}else{value=this._responseType;}}else if(columnId==='contentType'){value=this._request.mimeType;}else if(columnId==='contentLength'){value=(this._request.resourceSize|0).toLocaleString('en-US');}else if(columnId==='responseTime'){value=new Date(this._request.endTime*1000).toLocaleString();}
DataGrid.DataGrid.setElementText(cell,value||'',true);cell.title=this._request.url();return cell;}}
export class RequestView extends UI.VBox{constructor(request){super();this._tabbedPane=new UI.TabbedPane();this._tabbedPane.addEventListener(UI.TabbedPane.Events.TabSelected,this._tabSelected,this);this._resourceViewTabSetting=self.Common.settings.createSetting('cacheStorageViewTab','preview');this._tabbedPane.appendTab('headers',Common.UIString('Headers'),new Network.RequestHeadersView(request));this._tabbedPane.appendTab('preview',Common.UIString('Preview'),new Network.RequestPreviewView(request));this._tabbedPane.show(this.element);}
wasShown(){super.wasShown();this._selectTab();}
_selectTab(tabId){if(!tabId){tabId=this._resourceViewTabSetting.get();}
if(!this._tabbedPane.selectTab(tabId)){this._tabbedPane.selectTab('headers');}}
_tabSelected(event){if(!event.data.isUserGesture){return;}
this._resourceViewTabSetting.set(event.data.tabId);}}