import{Database,DatabaseId,Entry,Index,IndexedDBModel,ObjectStore}from'./IndexedDBModel.js';export class IDBDatabaseView extends UI.VBox{constructor(model,database){super();this._model=model;const databaseName=database?database.databaseId.name:ls`Loading\u2026`;this._reportView=new UI.ReportView(databaseName);this._reportView.show(this.contentElement);const bodySection=this._reportView.appendSection('');this._securityOriginElement=bodySection.appendField(ls`Security origin`);this._versionElement=bodySection.appendField(ls`Version`);this._objectStoreCountElement=bodySection.appendField(ls`Object stores`);const footer=this._reportView.appendSection('').appendRow();this._clearButton=UI.createTextButton(ls`Delete database`,()=>this._deleteDatabase(),ls`Delete database`);footer.appendChild(this._clearButton);this._refreshButton=UI.createTextButton(ls`Refresh database`,()=>this._refreshDatabaseButtonClicked(),ls`Refresh database`);footer.appendChild(this._refreshButton);if(database){this.update(database);}}
_refreshDatabase(){this._securityOriginElement.textContent=this._database.databaseId.securityOrigin;this._versionElement.textContent=this._database.version;this._objectStoreCountElement.textContent=Object.keys(this._database.objectStores).length;}
_refreshDatabaseButtonClicked(){this._model.refreshDatabase(this._database.databaseId);}
update(database){this._database=database;this._reportView.setTitle(this._database.databaseId.name);this._refreshDatabase();this._updatedForTests();}
_updatedForTests(){}
async _deleteDatabase(){const ok=await UI.ConfirmDialog.show(Common.UIString('Please confirm delete of "%s" database.',this._database.databaseId.name),this.element);if(ok){this._model.deleteDatabase(this._database.databaseId);}}}
export class IDBDataView extends UI.SimpleView{constructor(model,databaseId,objectStore,index,refreshObjectStoreCallback){super(Common.UIString('IDB'));this.registerRequiredCSS('resources/indexedDBViews.css');this._model=model;this._databaseId=databaseId;this._isIndex=!!index;this._refreshObjectStoreCallback=refreshObjectStoreCallback;this.element.classList.add('indexed-db-data-view','storage-view');this._refreshButton=new UI.ToolbarButton(Common.UIString('Refresh'),'largeicon-refresh');this._refreshButton.addEventListener(UI.ToolbarButton.Events.Click,this._refreshButtonClicked,this);this._deleteSelectedButton=new UI.ToolbarButton(Common.UIString('Delete selected'),'largeicon-delete');this._deleteSelectedButton.addEventListener(UI.ToolbarButton.Events.Click,()=>this._deleteButtonClicked(null));this._clearButton=new UI.ToolbarButton(Common.UIString('Clear object store'),'largeicon-clear');this._clearButton.addEventListener(UI.ToolbarButton.Events.Click,this._clearButtonClicked,this);this._needsRefresh=new UI.ToolbarItem(UI.createIconLabel(Common.UIString('Data may be stale'),'smallicon-warning'));this._needsRefresh.setVisible(false);this._needsRefresh.setTitle(Common.UIString('Some entries may have been modified'));this._createEditorToolbar();this._pageSize=50;this._skipCount=0;this.update(objectStore,index);this._entries=[];}
_createDataGrid(){const keyPath=this._isIndex?this._index.keyPath:this._objectStore.keyPath;const columns=([]);columns.push({id:'number',title:Common.UIString('#'),sortable:false,width:'50px'});columns.push({id:'key',titleDOMFragment:this._keyColumnHeaderFragment(Common.UIString('Key'),keyPath),sortable:false});if(this._isIndex){columns.push({id:'primaryKey',titleDOMFragment:this._keyColumnHeaderFragment(Common.UIString('Primary key'),this._objectStore.keyPath),sortable:false});}
columns.push({id:'value',title:Common.UIString('Value'),sortable:false});const dataGrid=new DataGrid.DataGrid({displayName:ls`Indexed DB`,columns,deleteCallback:this._deleteButtonClicked.bind(this),refreshCallback:this._updateData.bind(this,true)});dataGrid.setStriped(true);dataGrid.addEventListener(DataGrid.DataGrid.Events.SelectedNode,event=>this._updateToolbarEnablement(),this);return dataGrid;}
_keyColumnHeaderFragment(prefix,keyPath){const keyColumnHeaderFragment=createDocumentFragment();keyColumnHeaderFragment.createTextChild(prefix);if(keyPath===null){return keyColumnHeaderFragment;}
keyColumnHeaderFragment.createTextChild(' ('+Common.UIString('Key path: '));if(Array.isArray(keyPath)){keyColumnHeaderFragment.createTextChild('[');for(let i=0;i<keyPath.length;++i){if(i!==0){keyColumnHeaderFragment.createTextChild(', ');}
keyColumnHeaderFragment.appendChild(this._keyPathStringFragment(keyPath[i]));}
keyColumnHeaderFragment.createTextChild(']');}else{const keyPathString=(keyPath);keyColumnHeaderFragment.appendChild(this._keyPathStringFragment(keyPathString));}
keyColumnHeaderFragment.createTextChild(')');return keyColumnHeaderFragment;}
_keyPathStringFragment(keyPathString){const keyPathStringFragment=createDocumentFragment();keyPathStringFragment.createTextChild('"');const keyPathSpan=keyPathStringFragment.createChild('span','source-code indexed-db-key-path');keyPathSpan.textContent=keyPathString;keyPathStringFragment.createTextChild('"');return keyPathStringFragment;}
_createEditorToolbar(){const editorToolbar=new UI.Toolbar('data-view-toolbar',this.element);editorToolbar.appendToolbarItem(this._refreshButton);editorToolbar.appendToolbarItem(new UI.ToolbarSeparator());this._pageBackButton=new UI.ToolbarButton(Common.UIString('Show previous page'),'largeicon-play-back');this._pageBackButton.addEventListener(UI.ToolbarButton.Events.Click,this._pageBackButtonClicked,this);editorToolbar.appendToolbarItem(this._pageBackButton);this._pageForwardButton=new UI.ToolbarButton(Common.UIString('Show next page'),'largeicon-play');this._pageForwardButton.setEnabled(false);this._pageForwardButton.addEventListener(UI.ToolbarButton.Events.Click,this._pageForwardButtonClicked,this);editorToolbar.appendToolbarItem(this._pageForwardButton);this._keyInput=new UI.ToolbarInput(ls`Start from key`,'',0.5);this._keyInput.addEventListener(UI.ToolbarInput.Event.TextChanged,this._updateData.bind(this,false));editorToolbar.appendToolbarItem(this._keyInput);editorToolbar.appendToolbarItem(new UI.ToolbarSeparator());editorToolbar.appendToolbarItem(this._clearButton);editorToolbar.appendToolbarItem(this._deleteSelectedButton);editorToolbar.appendToolbarItem(this._needsRefresh);}
_pageBackButtonClicked(event){this._skipCount=Math.max(0,this._skipCount-this._pageSize);this._updateData(false);}
_pageForwardButtonClicked(event){this._skipCount=this._skipCount+this._pageSize;this._updateData(false);}
_populateContextMenu(contextMenu,gridNode){const node=(gridNode);if(node.valueObjectPresentation){contextMenu.revealSection().appendItem(ls`Expand Recursively`,()=>{node.valueObjectPresentation.objectTreeElement().expandRecursively();});contextMenu.revealSection().appendItem(ls`Collapse`,()=>{node.valueObjectPresentation.objectTreeElement().collapse();});}}
refreshData(){this._updateData(true);}
update(objectStore,index){this._objectStore=objectStore;this._index=index;if(this._dataGrid){this._dataGrid.asWidget().detach();}
this._dataGrid=this._createDataGrid();this._dataGrid.setRowContextMenuCallback(this._populateContextMenu.bind(this));this._dataGrid.asWidget().show(this.element);this._skipCount=0;this._updateData(true);}
_parseKey(keyString){let result;try{result=JSON.parse(keyString);}catch(e){result=keyString;}
return result;}
_updateData(force){const key=this._parseKey(this._keyInput.value());const pageSize=this._pageSize;let skipCount=this._skipCount;let selected=this._dataGrid.selectedNode?this._dataGrid.selectedNode.data['number']:0;selected=Math.max(selected,this._skipCount);this._refreshButton.setEnabled(false);this._clearButton.setEnabled(!this._isIndex);if(!force&&this._lastKey===key&&this._lastPageSize===pageSize&&this._lastSkipCount===skipCount){return;}
if(this._lastKey!==key||this._lastPageSize!==pageSize){skipCount=0;this._skipCount=0;}
this._lastKey=key;this._lastPageSize=pageSize;this._lastSkipCount=skipCount;function callback(entries,hasMore){this._refreshButton.setEnabled(true);this.clear();this._entries=entries;let selectedNode=null;for(let i=0;i<entries.length;++i){const data={};data['number']=i+skipCount;data['key']=entries[i].key;data['primaryKey']=entries[i].primaryKey;data['value']=entries[i].value;const node=new IDBDataGridNode(data);this._dataGrid.rootNode().appendChild(node);if(data['number']<=selected){selectedNode=node;}}
if(selectedNode){selectedNode.select();}
this._pageBackButton.setEnabled(!!skipCount);this._pageForwardButton.setEnabled(hasMore);this._needsRefresh.setVisible(false);this._updateToolbarEnablement();this._updatedDataForTests();}
const idbKeyRange=key?window.IDBKeyRange.lowerBound(key):null;if(this._isIndex){this._model.loadIndexData(this._databaseId,this._objectStore.name,this._index.name,idbKeyRange,skipCount,pageSize,callback.bind(this));}else{this._model.loadObjectStoreData(this._databaseId,this._objectStore.name,idbKeyRange,skipCount,pageSize,callback.bind(this));}
this._model.getMetadata(this._databaseId,this._objectStore).then(this._updateSummaryBar.bind(this));}
_updateSummaryBar(metadata){if(!this._summaryBarElement){this._summaryBarElement=this.element.createChild('div','object-store-summary-bar');}
this._summaryBarElement.removeChildren();if(!metadata){return;}
const separator='\u2002\u2758\u2002';const span=this._summaryBarElement.createChild('span');span.textContent=ls`Total entries: ${String(metadata.entriesCount)}`;if(this._objectStore.autoIncrement){span.textContent+=separator;span.textContent+=ls`Key generator value: ${String(metadata.keyGeneratorValue)}`;}}
_updatedDataForTests(){}
_refreshButtonClicked(event){this._updateData(true);}
async _clearButtonClicked(event){this._clearButton.setEnabled(false);await this._model.clearObjectStore(this._databaseId,this._objectStore.name);this._clearButton.setEnabled(true);this._updateData(true);}
markNeedsRefresh(){this._needsRefresh.setVisible(true);}
async _deleteButtonClicked(node){if(!node){node=this._dataGrid.selectedNode;if(!node){return;}}
const key=(this._isIndex?node.data.primaryKey:node.data.key);const keyValue=(key.value);await this._model.deleteEntries(this._databaseId,this._objectStore.name,window.IDBKeyRange.only(keyValue));this._refreshObjectStoreCallback();}
clear(){this._dataGrid.rootNode().removeChildren();this._entries=[];}
_updateToolbarEnablement(){const empty=!this._dataGrid||this._dataGrid.rootNode().children.length===0;this._clearButton.setEnabled(!empty);this._deleteSelectedButton.setEnabled(!empty&&this._dataGrid.selectedNode!==null);}}
export class IDBDataGridNode extends DataGrid.DataGridNode{constructor(data){super(data,false);this.selectable=true;this.valueObjectPresentation=null;}
createCell(columnIdentifier){const cell=super.createCell(columnIdentifier);const value=(this.data[columnIdentifier]);switch(columnIdentifier){case'value':cell.removeChildren();const objectPropSection=ObjectUI.ObjectPropertiesSection.defaultObjectPropertiesSection(value,undefined,true,true);cell.appendChild(objectPropSection.element);this.valueObjectPresentation=objectPropSection;break;case'key':case'primaryKey':cell.removeChildren();const objectElement=ObjectUI.ObjectPropertiesSection.defaultObjectPresentation(value,undefined,true,true);cell.appendChild(objectElement);break;default:}
return cell;}}