123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442 |
- /*
- * Copyright (C) 2012 Google 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:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
- * OWNER OR 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.
- */
- /**
- * @constructor
- * @extends {WebInspector.View}
- * @param {WebInspector.IndexedDBModel.Database} database
- */
- WebInspector.IDBDatabaseView = function(database)
- {
- WebInspector.View.call(this);
- this.registerRequiredCSS("indexedDBViews.css");
- this.element.addStyleClass("fill");
- this.element.addStyleClass("indexed-db-database-view");
- this._headersListElement = this.element.createChild("ol", "outline-disclosure");
- this._headersTreeOutline = new TreeOutline(this._headersListElement);
- this._headersTreeOutline.expandTreeElementsWhenArrowing = true;
- this._securityOriginTreeElement = new TreeElement("", null, false);
- this._securityOriginTreeElement.selectable = false;
- this._headersTreeOutline.appendChild(this._securityOriginTreeElement);
- this._nameTreeElement = new TreeElement("", null, false);
- this._nameTreeElement.selectable = false;
- this._headersTreeOutline.appendChild(this._nameTreeElement);
- this._intVersionTreeElement = new TreeElement("", null, false);
- this._intVersionTreeElement.selectable = false;
- this._headersTreeOutline.appendChild(this._intVersionTreeElement);
- this._stringVersionTreeElement = new TreeElement("", null, false);
- this._stringVersionTreeElement.selectable = false;
- this._headersTreeOutline.appendChild(this._stringVersionTreeElement);
- this.update(database);
- }
- WebInspector.IDBDatabaseView.prototype = {
- /**
- * @param {string} name
- * @param {string} value
- */
- _formatHeader: function(name, value)
- {
- var fragment = document.createDocumentFragment();
- fragment.createChild("div", "attribute-name").textContent = name + ":";
- fragment.createChild("div", "attribute-value source-code").textContent = value;
- return fragment;
- },
- _refreshDatabase: function()
- {
- this._securityOriginTreeElement.title = this._formatHeader(WebInspector.UIString("Security origin"), this._database.databaseId.securityOrigin);
- this._nameTreeElement.title = this._formatHeader(WebInspector.UIString("Name"), this._database.databaseId.name);
- this._stringVersionTreeElement.title = this._formatHeader(WebInspector.UIString("String Version"), this._database.version);
- this._intVersionTreeElement.title = this._formatHeader(WebInspector.UIString("Integer Version"), this._database.intVersion);
- },
- /**
- * @param {WebInspector.IndexedDBModel.Database} database
- */
- update: function(database)
- {
- this._database = database;
- this._refreshDatabase();
- },
- __proto__: WebInspector.View.prototype
- }
- /**
- * @constructor
- * @extends {WebInspector.View}
- * @param {WebInspector.IndexedDBModel} model
- * @param {WebInspector.IndexedDBModel.DatabaseId} databaseId
- * @param {WebInspector.IndexedDBModel.ObjectStore} objectStore
- * @param {WebInspector.IndexedDBModel.Index} index
- */
- WebInspector.IDBDataView = function(model, databaseId, objectStore, index)
- {
- WebInspector.View.call(this);
- this.registerRequiredCSS("indexedDBViews.css");
- this._model = model;
- this._databaseId = databaseId;
- this._isIndex = !!index;
- this.element.addStyleClass("indexed-db-data-view");
- var editorToolbar = this._createEditorToolbar();
- this.element.appendChild(editorToolbar);
- this._dataGridContainer = this.element.createChild("div", "fill");
- this._dataGridContainer.addStyleClass("data-grid-container");
- this._refreshButton = new WebInspector.StatusBarButton(WebInspector.UIString("Refresh"), "refresh-storage-status-bar-item");
- this._refreshButton.addEventListener("click", this._refreshButtonClicked, this);
- this._clearButton = new WebInspector.StatusBarButton(WebInspector.UIString("Clear object store"), "clear-storage-status-bar-item");
- this._clearButton.addEventListener("click", this._clearButtonClicked, this);
- this._pageSize = 50;
- this._skipCount = 0;
- this.update(objectStore, index);
- this._entries = [];
- }
- WebInspector.IDBDataView.prototype = {
- /**
- * @return {WebInspector.DataGrid}
- */
- _createDataGrid: function()
- {
- var keyPath = this._isIndex ? this._index.keyPath : this._objectStore.keyPath;
- var columns = [];
- columns.push({id: "number", title: WebInspector.UIString("#"), width: "50px"});
- columns.push({id: "key", titleDOMFragment: this._keyColumnHeaderFragment(WebInspector.UIString("Key"), keyPath)});
- if (this._isIndex)
- columns.push({id: "primaryKey", titleDOMFragment: this._keyColumnHeaderFragment(WebInspector.UIString("Primary key"), this._objectStore.keyPath)});
- columns.push({id: "value", title: WebInspector.UIString("Value")});
- var dataGrid = new WebInspector.DataGrid(columns);
- return dataGrid;
- },
- /**
- * @param {string} prefix
- * @param {*} keyPath
- * @return {DocumentFragment}
- */
- _keyColumnHeaderFragment: function(prefix, keyPath)
- {
- var keyColumnHeaderFragment = document.createDocumentFragment();
- keyColumnHeaderFragment.appendChild(document.createTextNode(prefix));
- if (keyPath === null)
- return keyColumnHeaderFragment;
- keyColumnHeaderFragment.appendChild(document.createTextNode(" (" + WebInspector.UIString("Key path: ")));
- if (keyPath instanceof Array) {
- keyColumnHeaderFragment.appendChild(document.createTextNode("["));
- for (var i = 0; i < keyPath.length; ++i) {
- if (i != 0)
- keyColumnHeaderFragment.appendChild(document.createTextNode(", "));
- keyColumnHeaderFragment.appendChild(this._keyPathStringFragment(keyPath[i]));
- }
- keyColumnHeaderFragment.appendChild(document.createTextNode("]"));
- } else {
- var keyPathString = /** @type {string} */ (keyPath);
- keyColumnHeaderFragment.appendChild(this._keyPathStringFragment(keyPathString));
- }
- keyColumnHeaderFragment.appendChild(document.createTextNode(")"));
- return keyColumnHeaderFragment;
- },
- /**
- * @param {string} keyPathString
- * @return {DocumentFragment}
- */
- _keyPathStringFragment: function(keyPathString)
- {
- var keyPathStringFragment = document.createDocumentFragment();
- keyPathStringFragment.appendChild(document.createTextNode("\""));
- var keyPathSpan = keyPathStringFragment.createChild("span", "source-code console-formatted-string");
- keyPathSpan.textContent = keyPathString;
- keyPathStringFragment.appendChild(document.createTextNode("\""));
- return keyPathStringFragment;
- },
- /**
- * @return {Element}
- */
- _createEditorToolbar: function()
- {
- var editorToolbar = document.createElement("div");
- editorToolbar.addStyleClass("status-bar");
- editorToolbar.addStyleClass("data-view-toolbar");
- this._pageBackButton = editorToolbar.createChild("button", "back-button");
- this._pageBackButton.addStyleClass("status-bar-item");
- this._pageBackButton.title = WebInspector.UIString("Show previous page.");
- this._pageBackButton.disabled = true;
- this._pageBackButton.appendChild(document.createElement("img"));
- this._pageBackButton.addEventListener("click", this._pageBackButtonClicked.bind(this), false);
- editorToolbar.appendChild(this._pageBackButton);
- this._pageForwardButton = editorToolbar.createChild("button", "forward-button");
- this._pageForwardButton.addStyleClass("status-bar-item");
- this._pageForwardButton.title = WebInspector.UIString("Show next page.");
- this._pageForwardButton.disabled = true;
- this._pageForwardButton.appendChild(document.createElement("img"));
- this._pageForwardButton.addEventListener("click", this._pageForwardButtonClicked.bind(this), false);
- editorToolbar.appendChild(this._pageForwardButton);
- this._keyInputElement = editorToolbar.createChild("input", "key-input");
- this._keyInputElement.placeholder = WebInspector.UIString("Start from key");
- this._keyInputElement.addEventListener("paste", this._keyInputChanged.bind(this));
- this._keyInputElement.addEventListener("cut", this._keyInputChanged.bind(this));
- this._keyInputElement.addEventListener("keypress", this._keyInputChanged.bind(this));
- this._keyInputElement.addEventListener("keydown", this._keyInputChanged.bind(this));
- return editorToolbar;
- },
- _pageBackButtonClicked: function()
- {
- this._skipCount = Math.max(0, this._skipCount - this._pageSize);
- this._updateData(false);
- },
- _pageForwardButtonClicked: function()
- {
- this._skipCount = this._skipCount + this._pageSize;
- this._updateData(false);
- },
- _keyInputChanged: function()
- {
- window.setTimeout(this._updateData.bind(this, false), 0);
- },
- /**
- * @param {WebInspector.IndexedDBModel.ObjectStore} objectStore
- * @param {WebInspector.IndexedDBModel.Index} index
- */
- update: function(objectStore, index)
- {
- this._objectStore = objectStore;
- this._index = index;
- if (this._dataGrid)
- this._dataGrid.detach();
- this._dataGrid = this._createDataGrid();
- this._dataGrid.show(this._dataGridContainer);
- this._skipCount = 0;
- this._updateData(true);
- },
- /**
- * @param {string} keyString
- */
- _parseKey: function(keyString)
- {
- var result;
- try {
- result = JSON.parse(keyString);
- } catch (e) {
- result = keyString;
- }
- return result;
- },
- /**
- * @return {string}
- */
- _stringifyKey: function(key)
- {
- if (typeof(key) === "string")
- return key;
- return JSON.stringify(key);
- },
- /**
- * @param {boolean} force
- */
- _updateData: function(force)
- {
- var key = this._parseKey(this._keyInputElement.value);
- var pageSize = this._pageSize;
- var skipCount = 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;
- /**
- * @param {Array.<WebInspector.IndexedDBModel.Entry>} entries
- * @param {boolean} hasMore
- */
- function callback(entries, hasMore)
- {
- this._refreshButton.setEnabled(true);
- this.clear();
- this._entries = entries;
- for (var i = 0; i < entries.length; ++i) {
- var data = {};
- data["number"] = i + skipCount;
- data["key"] = entries[i].key;
- data["primaryKey"] = entries[i].primaryKey;
- data["value"] = entries[i].value;
- var primaryKey = JSON.stringify(this._isIndex ? entries[i].primaryKey : entries[i].key);
- var node = new WebInspector.IDBDataGridNode(data);
- this._dataGrid.rootNode().appendChild(node);
- }
- this._pageBackButton.disabled = skipCount === 0;
- this._pageForwardButton.disabled = !hasMore;
- }
- var idbKeyRange = key ? window.webkitIDBKeyRange.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));
- },
- _refreshButtonClicked: function(event)
- {
- this._updateData(true);
- },
- _clearButtonClicked: function(event)
- {
- function cleared() {
- this._clearButton.setEnabled(true);
- this._updateData(true);
- }
- this._clearButton.setEnabled(false);
- this._model.clearObjectStore(this._databaseId, this._objectStore.name, cleared.bind(this));
- },
- get statusBarItems()
- {
- return [this._refreshButton.element, this._clearButton.element];
- },
- clear: function()
- {
- this._dataGrid.rootNode().removeChildren();
- for (var i = 0; i < this._entries.length; ++i) {
- this._entries[i].key.release();
- this._entries[i].primaryKey.release();
- this._entries[i].value.release();
- }
- this._entries = [];
- },
- __proto__: WebInspector.View.prototype
- }
- /**
- * @constructor
- * @extends {WebInspector.DataGridNode}
- * @param {!Object.<string, *>} data
- */
- WebInspector.IDBDataGridNode = function(data)
- {
- WebInspector.DataGridNode.call(this, data, false);
- this.selectable = false;
- }
- WebInspector.IDBDataGridNode.prototype = {
- /**
- * @return {Element}
- */
- createCell: function(columnIdentifier)
- {
- var cell = WebInspector.DataGridNode.prototype.createCell.call(this, columnIdentifier);
- var value = this.data[columnIdentifier];
- switch (columnIdentifier) {
- case "value":
- case "key":
- case "primaryKey":
- cell.removeChildren();
- this._formatValue(cell, value);
- break;
- default:
- }
- return cell;
- },
- _formatValue: function(cell, value)
- {
- var type = value.subtype || value.type;
- var contents = cell.createChild("div", "source-code console-formatted-" + type);
- switch (type) {
- case "object":
- case "array":
- var section = new WebInspector.ObjectPropertiesSection(value, value.description)
- section.editable = false;
- section.skipProto = true;
- contents.appendChild(section.element);
- break;
- case "string":
- contents.addStyleClass("primitive-value");
- contents.appendChild(document.createTextNode("\"" + value.description + "\""));
- break;
- default:
- contents.addStyleClass("primitive-value");
- contents.appendChild(document.createTextNode(value.description));
- }
- },
- __proto__: WebInspector.DataGridNode.prototype
- }
|