Commit 198fb2cf authored by Harley Li's avatar Harley Li Committed by Commit Bot

[DevTools] Expose all IndexedDB databases to DevTools

Before this patch, only the main frame's IndexedDBs are exposed in
DevTools>Application>IndexedDB panel.

Bug: 943770
Change-Id: Ia8e13e06065ca7ceedb83f8f6edf0dffabf63f2d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1539214Reviewed-by: default avatarJoel Einbinder <einbinder@chromium.org>
Commit-Queue: Haihong Li (Harley) <hhli@chromium.org>
Cr-Commit-Position: refs/heads/master@{#649705}
parent e8f29ced
...@@ -26,7 +26,6 @@ ApplicationTestRunner.dumpCacheTreeNoRefresh = async function(pathFilter) { ...@@ -26,7 +26,6 @@ ApplicationTestRunner.dumpCacheTreeNoRefresh = async function(pathFilter) {
TestRunner.addResult(' '.repeat(8) + entries.join(', ')); TestRunner.addResult(' '.repeat(8) + entries.join(', '));
} }
} }
UI.panels.resources._sidebar.cacheStorageListTreeElement.expand(); UI.panels.resources._sidebar.cacheStorageListTreeElement.expand();
if (!pathFilter) if (!pathFilter)
......
...@@ -29,7 +29,6 @@ ...@@ -29,7 +29,6 @@
*/ */
/** /**
* @implements {SDK.TargetManager.Observer} * @implements {SDK.TargetManager.Observer}
* @implements {SDK.SDKModelObserver<!Resources.DOMStorageModel>}
* @unrestricted * @unrestricted
*/ */
Resources.ApplicationPanelSidebar = class extends UI.VBox { Resources.ApplicationPanelSidebar = class extends UI.VBox {
...@@ -196,18 +195,22 @@ Resources.ApplicationPanelSidebar = class extends UI.VBox { ...@@ -196,18 +195,22 @@ Resources.ApplicationPanelSidebar = class extends UI.VBox {
this._addCookieDocument(frame); this._addCookieDocument(frame);
this._databaseModel.enable(); this._databaseModel.enable();
const indexedDBModel = this._target.model(Resources.IndexedDBModel);
if (indexedDBModel)
indexedDBModel.enable();
const cacheStorageModel = this._target.model(SDK.ServiceWorkerCacheModel); const cacheStorageModel = this._target.model(SDK.ServiceWorkerCacheModel);
if (cacheStorageModel) if (cacheStorageModel)
cacheStorageModel.enable(); cacheStorageModel.enable();
const resourceTreeModel = this._target.model(SDK.ResourceTreeModel); const resourceTreeModel = this._target.model(SDK.ResourceTreeModel);
if (resourceTreeModel) if (resourceTreeModel)
this._populateApplicationCacheTree(resourceTreeModel); this._populateApplicationCacheTree(resourceTreeModel);
SDK.targetManager.observeModels(Resources.DOMStorageModel, this); SDK.targetManager.observeModels(Resources.DOMStorageModel, /** @type {!SDK.SDKModelObserver} */ ({
modelAdded: model => this._domStorageModelAdded(model),
modelRemoved: model => this._domStorageModelRemoved(model)
}));
this.indexedDBListTreeElement._initialize(); this.indexedDBListTreeElement._initialize();
SDK.targetManager.observeModels(
Resources.IndexedDBModel, /** @type {!SDK.SDKModelObserver} */ ({
modelAdded: model => model.enable(),
modelRemoved: model => this.indexedDBListTreeElement.removeIndexedDBForModel(model)
}));
const serviceWorkerCacheModel = this._target.model(SDK.ServiceWorkerCacheModel); const serviceWorkerCacheModel = this._target.model(SDK.ServiceWorkerCacheModel);
this.cacheStorageListTreeElement._initialize(serviceWorkerCacheModel); this.cacheStorageListTreeElement._initialize(serviceWorkerCacheModel);
const backgroundServiceModel = this._target.model(Resources.BackgroundServiceModel); const backgroundServiceModel = this._target.model(Resources.BackgroundServiceModel);
...@@ -218,25 +221,22 @@ Resources.ApplicationPanelSidebar = class extends UI.VBox { ...@@ -218,25 +221,22 @@ Resources.ApplicationPanelSidebar = class extends UI.VBox {
} }
/** /**
* @override * @param {!Resources.DOMStorageModel} model
* @param {!Resources.DOMStorageModel} domStorageModel
*/ */
modelAdded(domStorageModel) { _domStorageModelAdded(model) {
domStorageModel.enable(); model.enable();
domStorageModel.storages().forEach(this._addDOMStorage.bind(this)); model.storages().forEach(this._addDOMStorage.bind(this));
domStorageModel.addEventListener(Resources.DOMStorageModel.Events.DOMStorageAdded, this._domStorageAdded, this); model.addEventListener(Resources.DOMStorageModel.Events.DOMStorageAdded, this._domStorageAdded, this);
domStorageModel.addEventListener(Resources.DOMStorageModel.Events.DOMStorageRemoved, this._domStorageRemoved, this); model.addEventListener(Resources.DOMStorageModel.Events.DOMStorageRemoved, this._domStorageRemoved, this);
} }
/** /**
* @override * @param {!Resources.DOMStorageModel} model
* @param {!Resources.DOMStorageModel} domStorageModel
*/ */
modelRemoved(domStorageModel) { _domStorageModelRemoved(model) {
domStorageModel.storages().forEach(this._removeDOMStorage.bind(this)); model.storages().forEach(this._removeDOMStorage.bind(this));
domStorageModel.removeEventListener(Resources.DOMStorageModel.Events.DOMStorageAdded, this._domStorageAdded, this); model.removeEventListener(Resources.DOMStorageModel.Events.DOMStorageAdded, this._domStorageAdded, this);
domStorageModel.removeEventListener( model.removeEventListener(Resources.DOMStorageModel.Events.DOMStorageRemoved, this._domStorageRemoved, this);
Resources.DOMStorageModel.Events.DOMStorageRemoved, this._domStorageRemoved, this);
} }
_resetWithFrames() { _resetWithFrames() {
...@@ -287,8 +287,11 @@ Resources.ApplicationPanelSidebar = class extends UI.VBox { ...@@ -287,8 +287,11 @@ Resources.ApplicationPanelSidebar = class extends UI.VBox {
this.cookieListTreeElement.removeChildren(); this.cookieListTreeElement.removeChildren();
} }
/**
* @param {!Common.Event} event
*/
_frameNavigated(event) { _frameNavigated(event) {
const frame = event.data; const frame = /** @type {!SDK.ResourceTreeFrame} */ (event.data);
if (frame.isTopFrame()) if (frame.isTopFrame())
this._reset(); this._reset();
...@@ -1137,6 +1140,15 @@ Resources.IndexedDBTreeElement = class extends Resources.StorageCategoryTreeElem ...@@ -1137,6 +1140,15 @@ Resources.IndexedDBTreeElement = class extends Resources.StorageCategoryTreeElem
} }
} }
/**
* @param {!Resources.IndexedDBModel} model
*/
removeIndexedDBForModel(model) {
const idbDatabaseTreeElements = this._idbDatabaseTreeElements.filter(element => element._model === model);
for (const idbDatabaseTreeElement of idbDatabaseTreeElements)
this._removeIDBDatabaseTreeElement(idbDatabaseTreeElement);
}
/** /**
* @override * @override
*/ */
...@@ -1186,7 +1198,13 @@ Resources.IndexedDBTreeElement = class extends Resources.StorageCategoryTreeElem ...@@ -1186,7 +1198,13 @@ Resources.IndexedDBTreeElement = class extends Resources.StorageCategoryTreeElem
const idbDatabaseTreeElement = this._idbDatabaseTreeElement(model, databaseId); const idbDatabaseTreeElement = this._idbDatabaseTreeElement(model, databaseId);
if (!idbDatabaseTreeElement) if (!idbDatabaseTreeElement)
return; return;
this._removeIDBDatabaseTreeElement(idbDatabaseTreeElement);
}
/**
* @param {!Resources.IDBDatabaseTreeElement} idbDatabaseTreeElement
*/
_removeIDBDatabaseTreeElement(idbDatabaseTreeElement) {
idbDatabaseTreeElement.clear(); idbDatabaseTreeElement.clear();
this.removeChild(idbDatabaseTreeElement); this.removeChild(idbDatabaseTreeElement);
this._idbDatabaseTreeElements.remove(idbDatabaseTreeElement); this._idbDatabaseTreeElements.remove(idbDatabaseTreeElement);
...@@ -1205,6 +1223,11 @@ Resources.IndexedDBTreeElement = class extends Resources.StorageCategoryTreeElem ...@@ -1205,6 +1223,11 @@ Resources.IndexedDBTreeElement = class extends Resources.StorageCategoryTreeElem
if (!idbDatabaseTreeElement) if (!idbDatabaseTreeElement)
return; return;
idbDatabaseTreeElement.update(database, entriesUpdated); idbDatabaseTreeElement.update(database, entriesUpdated);
this._indexedDBLoadedForTest();
}
_indexedDBLoadedForTest() {
// For sniffing in tests.
} }
/** /**
...@@ -1222,23 +1245,12 @@ Resources.IndexedDBTreeElement = class extends Resources.StorageCategoryTreeElem ...@@ -1222,23 +1245,12 @@ Resources.IndexedDBTreeElement = class extends Resources.StorageCategoryTreeElem
} }
/** /**
* @param {!Resources.IndexedDBModel.DatabaseId} databaseId
* @param {!Resources.IndexedDBModel} model * @param {!Resources.IndexedDBModel} model
* @param {!Resources.IndexedDBModel.DatabaseId} databaseId
* @return {?Resources.IDBDatabaseTreeElement} * @return {?Resources.IDBDatabaseTreeElement}
*/ */
_idbDatabaseTreeElement(model, databaseId) { _idbDatabaseTreeElement(model, databaseId) {
let index = -1; return this._idbDatabaseTreeElements.find(x => x._databaseId.equals(databaseId) && x._model === model) || null;
let i;
for (i = 0; i < this._idbDatabaseTreeElements.length; ++i) {
if (this._idbDatabaseTreeElements[i]._databaseId.equals(databaseId) &&
this._idbDatabaseTreeElements[i]._model === model) {
index = i;
break;
}
}
if (index !== -1)
return this._idbDatabaseTreeElements[i];
return null;
} }
}; };
......
...@@ -499,7 +499,7 @@ Resources.IndexedDBModel = class extends SDK.SDKModel { ...@@ -499,7 +499,7 @@ Resources.IndexedDBModel = class extends SDK.SDKModel {
} }
}; };
SDK.SDKModel.register(Resources.IndexedDBModel, SDK.Target.Capability.None, false); SDK.SDKModel.register(Resources.IndexedDBModel, SDK.Target.Capability.DOM, false);
Resources.IndexedDBModel.KeyTypes = { Resources.IndexedDBModel.KeyTypes = {
NumberType: 'number', NumberType: 'number',
......
Tests Application Panel's handling of storages in iframes.
Initial tree...
Application
Manifest
Service Workers
Clear storage
Storage
Local Storage
http://127.0.0.1:8000
http://localhost:8000
Session Storage
http://127.0.0.1:8000
http://localhost:8000
IndexedDB
Database-iframe - http://localhost:8000
Database-iframe
Database-main-frame - http://127.0.0.1:8000
Web SQL
Cookies
http://127.0.0.1:8000
http://localhost:8000
Cache
Cache Storage
Application Cache
Frames
top
Remove iframe from page...
Application
Manifest
Service Workers
Clear storage
Storage
Local Storage
http://127.0.0.1:8000
Session Storage
http://127.0.0.1:8000
IndexedDB
Database-main-frame - http://127.0.0.1:8000
Web SQL
Cookies
http://127.0.0.1:8000
http://localhost:8000
Cache
Cache Storage
Application Cache
Frames
top
Add iframe to page again...
Application
Manifest
Service Workers
Clear storage
Storage
Local Storage
http://127.0.0.1:8000
http://localhost:8000
Session Storage
http://127.0.0.1:8000
http://localhost:8000
IndexedDB
Database-main-frame - http://127.0.0.1:8000
Database-iframe - http://localhost:8000
Database-iframe
Web SQL
Cookies
http://127.0.0.1:8000
http://localhost:8000
Cache
Cache Storage
Application Cache
Frames
top
// Copyright 2019 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.
(async function() {
TestRunner.addResult(`Tests Application Panel's handling of storages in iframes.\n`);
await TestRunner.loadModule('application_test_runner');
// Note: every test that uses a storage API must manually clean-up state from previous tests.
await ApplicationTestRunner.resetState();
await TestRunner.loadModule('console_test_runner');
await TestRunner.showPanel('resources');
function createIndexedDBInMainFrame(callback) {
var mainFrameId = TestRunner.resourceTreeModel.mainFrame.id;
var model = TestRunner.mainTarget.model(Resources.IndexedDBModel);
ApplicationTestRunner.createDatabase(mainFrameId, 'Database-main-frame', () => {
var event = model.addEventListener(Resources.IndexedDBModel.Events.DatabaseAdded, () => {
Common.EventTarget.removeEventListeners([event]);
callback();
});
model.refreshDatabaseNames();
});
}
function dumpTree(node, level) {
for (var child of node.children()) {
TestRunner.addResult(' '.repeat(level) + child.listItemElement.textContent);
dumpTree(child, level + 1);
}
}
// create IndexedDB in iframe
await TestRunner.addIframe('http://localhost:8000/devtools/application-panel/resources/indexeddb-in-iframe.html', {'id': 'indexeddb_page'});
await TestRunner.addSnifferPromise(UI.panels.resources._sidebar.indexedDBListTreeElement, '_indexedDBLoadedForTest');
// create IndexedDB in main frame
await new Promise(createIndexedDBInMainFrame);
await TestRunner.addSnifferPromise(UI.panels.resources._sidebar.indexedDBListTreeElement, '_indexedDBLoadedForTest');
const view = UI.panels.resources;
TestRunner.addResult('Initial tree...\n');
dumpTree(view._sidebar._sidebarTree.rootElement(), 0);
TestRunner.addResult('\nRemove iframe from page...\n');
await TestRunner.evaluateInPageAsync(`
(function(){
let iframe = document.getElementById('indexeddb_page');
iframe.parentNode.removeChild(iframe);
})();
`);
dumpTree(view._sidebar._sidebarTree.rootElement(), 0);
TestRunner.addResult('\nAdd iframe to page again...\n');
await TestRunner.addIframe('http://localhost:8000/devtools/application-panel/resources/indexeddb-in-iframe.html', {'id': 'indexeddb_page'});
await TestRunner.addSnifferPromise(UI.panels.resources._sidebar.indexedDBListTreeElement, '_indexedDBLoadedForTest');
dumpTree(view._sidebar._sidebarTree.rootElement(), 0);
TestRunner.completeTest();
})();
...@@ -43,11 +43,6 @@ ...@@ -43,11 +43,6 @@
TestRunner.addResult('Visible view is a cookie view: ' + (view.visibleView instanceof Resources.CookieItemsView)); TestRunner.addResult('Visible view is a cookie view: ' + (view.visibleView instanceof Resources.CookieItemsView));
} }
function fireFrameNavigated() {
var rtm = TestRunner.resourceTreeModel;
rtm.dispatchEventToListeners(SDK.ResourceTreeModel.Events.FrameNavigated, rtm.mainFrame);
}
await new Promise(createIndexedDB); await new Promise(createIndexedDB);
await ApplicationTestRunner.createWebSQLDatabase('database-for-test'); await ApplicationTestRunner.createWebSQLDatabase('database-for-test');
UI.viewManager.showView('resources'); UI.viewManager.showView('resources');
......
<script>
function makeDB() {
return new Promise((resolve) => {
indexedDB.open('Database-iframe').onupgradeneeded = event => {
const db = event.target.result;
const objectStore = db.createObjectStore('Database-iframe');
objectStore.transaction.oncomplete = _ => {
indexedDB.open('Database-iframe').onsuccess = event => event.target.result
.transaction('Database-iframe', 'readwrite')
.objectStore('Database-iframe')
.add(940123, 'key');
}
resolve();
}
});
}
window.addEventListener("load", async function(e) {
await makeDB();
}, false);
</script>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment