blob: 4fbc05573eced874475d8d8edf7d59dd27f86d7b [file] [log] [blame]
/*
* Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
WI.IndexedDatabaseObjectStoreContentView = class IndexedDatabaseObjectStoreContentView extends WI.ContentView
{
constructor(objectStoreOrIndex)
{
super(objectStoreOrIndex);
this.element.classList.add("indexed-database-object-store");
if (objectStoreOrIndex instanceof WI.IndexedDatabaseObjectStore) {
this._objectStore = objectStoreOrIndex;
this._objectStoreIndex = null;
} else if (objectStoreOrIndex instanceof WI.IndexedDatabaseObjectStoreIndex) {
this._objectStore = objectStoreOrIndex.parentObjectStore;
this._objectStoreIndex = objectStoreOrIndex;
}
function displayKeyPath(keyPath)
{
if (!keyPath)
return "";
if (keyPath instanceof Array)
return keyPath.join(WI.UIString(", "));
console.assert(keyPath instanceof String || typeof keyPath === "string");
return keyPath;
}
var displayPrimaryKeyPath = displayKeyPath(this._objectStore.keyPath);
var columnInfo = {
primaryKey: {title: displayPrimaryKeyPath ? WI.UIString("Primary Key \u2014 %s").format(displayPrimaryKeyPath) : WI.UIString("Primary Key")},
key: {},
value: {title: WI.UIString("Value")}
};
if (this._objectStoreIndex) {
// When there is an index, show the key path in the Key column.
var displayIndexKeyPath = displayKeyPath(this._objectStoreIndex.keyPath);
columnInfo.key.title = WI.UIString("Index Key \u2014 %s").format(displayIndexKeyPath);
} else {
// Only need to show Key for indexes -- it is the same as Primary Key
// when there is no index being used.
delete columnInfo.key;
}
this._dataGrid = new WI.DataGrid(columnInfo);
this._dataGrid.variableHeightRows = true;
this._dataGrid.filterDelegate = this;
this._dataGrid.scrollContainer.addEventListener("scroll", this._dataGridScrolled.bind(this));
this.addSubview(this._dataGrid);
this._entries = [];
this._fetchingMoreData = false;
this._fetchMoreData();
this._filterBarNavigationItem = new WI.FilterBarNavigationItem;
this._filterBarNavigationItem.filterBar.addEventListener(WI.FilterBar.Event.FilterDidChange, this._handleFilterBarFilterDidChange, this);
this._refreshButtonNavigationItem = new WI.ButtonNavigationItem("indexed-database-object-store-refresh", WI.UIString("Refresh"), "Images/ReloadFull.svg", 13, 13);
this._refreshButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._refreshButtonClicked, this);
this._clearButtonNavigationItem = new WI.ButtonNavigationItem("indexed-database-object-store-clear", WI.UIString("Clear object store"), "Images/NavigationItemTrash.svg", 15, 15);
this._clearButtonNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;
this._clearButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._clearButtonClicked, this);
}
// Public
get navigationItems()
{
return [
this._filterBarNavigationItem,
new WI.DividerNavigationItem,
this._refreshButtonNavigationItem,
this._clearButtonNavigationItem,
];
}
closed()
{
super.closed();
this._reset();
}
saveToCookie(cookie)
{
cookie.type = WI.ContentViewCookieType.IndexedDatabaseObjectStore;
cookie.securityOrigin = this._objectStore.parentDatabase.securityOrigin;
cookie.databaseName = this._objectStore.parentDatabase.name;
cookie.objectStoreName = this._objectStore.name;
cookie.objectStoreIndexName = this._objectStoreIndex && this._objectStoreIndex.name;
}
get scrollableElements()
{
return [this._dataGrid.scrollContainer];
}
get canFocusFilterBar()
{
return true;
}
focusFilterBar()
{
this._filterBarNavigationItem.filterBar.focus();
}
// Protected
dataGridMatchNodeAgainstCustomFilters(node)
{
let filterBar = this._filterBarNavigationItem.filterBar;
filterBar.invalid = false;
let filterText = filterBar.filters.text;
if (!filterText)
return true;
let regex = WI.SearchUtilities.filterRegExpForString(filterText, WI.SearchUtilities.defaultSettings);
if (!regex) {
filterBar.invalid = true;
return true;
}
// Iterate over each cell.
for (let child of node.element.children) {
if (regex.test(child.textContent))
return true;
}
return false;
}
// Private
_reset()
{
for (var entry of this._entries) {
entry.primaryKey.release();
entry.key.release();
entry.value.release();
}
this._entries = [];
this._dataGrid.removeChildren();
}
_dataGridScrolled()
{
if (!this._moreEntriesAvailable || !this._dataGrid.isScrolledToLastRow())
return;
this._fetchMoreData();
}
_fetchMoreData()
{
if (this._fetchingMoreData)
return;
function processEntries(entries, moreAvailable)
{
this._entries.pushAll(entries);
this._moreEntriesAvailable = moreAvailable;
for (var entry of entries) {
var dataGridNode = new WI.IndexedDatabaseEntryDataGridNode(entry);
this._dataGrid.appendChild(dataGridNode);
}
this._fetchingMoreData = false;
if (moreAvailable && this._dataGrid.isScrolledToLastRow())
this._fetchMoreData();
}
this._fetchingMoreData = true;
WI.indexedDBManager.requestIndexedDatabaseData(this._objectStore, this._objectStoreIndex, this._entries.length, 25, processEntries.bind(this));
}
_handleFilterBarFilterDidChange(event)
{
this._dataGrid.filterDidChange();
}
_refreshButtonClicked()
{
this._reset();
this._fetchMoreData();
}
_clearButtonClicked()
{
WI.indexedDBManager.clearObjectStore(this._objectStore);
this._reset();
}
};