зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1434579 - Fix infinite scrolling for indexedDB in storage inspector;r=miker
MozReview-Commit-ID: 7ZyxqDPxHTK --HG-- extra : rebase_source : e6c4fd13ad514b52b7aa38c0f507cc1438a1e893
This commit is contained in:
Родитель
8c326e567e
Коммит
d31555e033
|
@ -15,6 +15,7 @@ support-files =
|
|||
storage-listings-usercontextid.html
|
||||
storage-listings-with-fragment.html
|
||||
storage-localstorage.html
|
||||
storage-overflow-indexeddb.html
|
||||
storage-overflow.html
|
||||
storage-search.html
|
||||
storage-secured-iframe.html
|
||||
|
@ -57,6 +58,7 @@ tags = usercontextid
|
|||
[browser_storage_indexeddb_delete.js]
|
||||
[browser_storage_indexeddb_delete_blocked.js]
|
||||
[browser_storage_indexeddb_duplicate_names.js]
|
||||
[browser_storage_indexeddb_overflow.js]
|
||||
[browser_storage_localstorage_add.js]
|
||||
[browser_storage_localstorage_edit.js]
|
||||
[browser_storage_localstorage_error.js]
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// Test endless scrolling when a lot of items are present in the storage
|
||||
// inspector table for IndexedDB.
|
||||
"use strict";
|
||||
|
||||
const ITEMS_PER_PAGE = 50;
|
||||
|
||||
add_task(async function() {
|
||||
await openTabAndSetupStorage(MAIN_DOMAIN + "storage-overflow-indexeddb.html");
|
||||
|
||||
info("Run the tests with short DevTools");
|
||||
await runTests();
|
||||
|
||||
info("Close Toolbox");
|
||||
const target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
await gDevTools.closeToolbox(target);
|
||||
|
||||
await finishTests();
|
||||
});
|
||||
|
||||
async function runTests() {
|
||||
gUI.tree.expandAll();
|
||||
|
||||
await selectTreeItem(["indexedDB",
|
||||
"http://test1.example.org",
|
||||
"database (default)",
|
||||
"store"]);
|
||||
checkCellLength(ITEMS_PER_PAGE);
|
||||
|
||||
await scroll();
|
||||
checkCellLength(ITEMS_PER_PAGE * 2);
|
||||
}
|
|
@ -1,3 +1,7 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// Test endless scrolling when a lot of items are present in the storage
|
||||
// inspector table.
|
||||
"use strict";
|
||||
|
@ -47,14 +51,6 @@ async function runTests() {
|
|||
checkCellValues("DEC");
|
||||
}
|
||||
|
||||
function checkCellLength(len) {
|
||||
const cells = gPanelWindow.document
|
||||
.querySelectorAll("#name .table-widget-cell");
|
||||
const msg = `Table should initially display ${len} items`;
|
||||
|
||||
is(cells.length, len, msg);
|
||||
}
|
||||
|
||||
function checkCellValues(order) {
|
||||
const cells = [...gPanelWindow.document
|
||||
.querySelectorAll("#name .table-widget-cell")];
|
||||
|
@ -63,14 +59,3 @@ function checkCellValues(order) {
|
|||
is(cell.value, `item-${i}`, `Cell value is correct (${order}).`);
|
||||
});
|
||||
}
|
||||
|
||||
async function scroll() {
|
||||
const $ = id => gPanelWindow.document.querySelector(id);
|
||||
const table = $("#storage-table .table-widget-body");
|
||||
const cell = $("#name .table-widget-cell");
|
||||
const cellHeight = cell.getBoundingClientRect().height;
|
||||
|
||||
const onStoresUpdate = gUI.once("store-objects-updated");
|
||||
table.scrollTop += cellHeight * 50;
|
||||
await onStoresUpdate;
|
||||
}
|
||||
|
|
|
@ -1003,3 +1003,21 @@ async function performAdd(store) {
|
|||
|
||||
is(rowId, value, `Row '${rowId}' was successfully added.`);
|
||||
}
|
||||
|
||||
function checkCellLength(len) {
|
||||
const cells = gPanelWindow.document.querySelectorAll("#name .table-widget-cell");
|
||||
const msg = `Table should initially display ${len} items`;
|
||||
|
||||
is(cells.length, len, msg);
|
||||
}
|
||||
|
||||
async function scroll() {
|
||||
const $ = id => gPanelWindow.document.querySelector(id);
|
||||
const table = $("#storage-table .table-widget-body");
|
||||
const cell = $("#name .table-widget-cell");
|
||||
const cellHeight = cell.getBoundingClientRect().height;
|
||||
|
||||
const onStoresUpdate = gUI.once("store-objects-updated");
|
||||
table.scrollTop += cellHeight * 50;
|
||||
await onStoresUpdate;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
Bug 1171903 - Storage Inspector endless scrolling
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Storage inspector endless scrolling test</title>
|
||||
</head>
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
"use strict";
|
||||
|
||||
window.setup = async function() {
|
||||
await new Promise(resolve => {
|
||||
const open = indexedDB.open("database", 1);
|
||||
open.onupgradeneeded = function() {
|
||||
const db = open.result;
|
||||
const store = db.createObjectStore("store", {keyPath: "id"});
|
||||
store.transaction.oncomplete = () => {
|
||||
const transaction = db.transaction(["store"], "readwrite");
|
||||
for (let i = 1; i < 150; i++) {
|
||||
transaction.objectStore("store").add({id: i});
|
||||
}
|
||||
|
||||
transaction.oncomplete = function() {
|
||||
db.close();
|
||||
resolve();
|
||||
};
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
function deleteDB(dbName, storage) {
|
||||
return new Promise(resolve => {
|
||||
indexedDB.deleteDatabase(dbName, { storage: storage }).onsuccess = resolve;
|
||||
});
|
||||
}
|
||||
|
||||
window.clear = async function() {
|
||||
await deleteDB("database", "temporary");
|
||||
await deleteDB("database", "default");
|
||||
await deleteDB("database", "persistent");
|
||||
|
||||
dump(`removed indexedDB data from ${document.location}\n`);
|
||||
};
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -337,7 +337,7 @@ StorageActors.defaults = function(typeName, observationTopics) {
|
|||
* - data - The requested values.
|
||||
*/
|
||||
async getStoreObjects(host, names, options = {}) {
|
||||
let offset = options.offset || 0;
|
||||
const offset = options.offset || 0;
|
||||
let size = options.size || MAX_STORE_OBJECT_COUNT;
|
||||
if (size > MAX_STORE_OBJECT_COUNT) {
|
||||
size = MAX_STORE_OBJECT_COUNT;
|
||||
|
@ -381,19 +381,6 @@ StorageActors.defaults = function(typeName, observationTopics) {
|
|||
}
|
||||
|
||||
toReturn.total = this.getObjectsSize(host, names, options);
|
||||
|
||||
if (offset > toReturn.total) {
|
||||
// In this case, toReturn.data is an empty array.
|
||||
toReturn.offset = toReturn.total;
|
||||
toReturn.data = [];
|
||||
} else {
|
||||
// We need to use natural sort before slicing.
|
||||
const sorted = toReturn.data.sort((a, b) => {
|
||||
return naturalSortCaseInsensitive(a[sortOn], b[sortOn]);
|
||||
});
|
||||
const sliced = sorted.slice(offset, offset + size);
|
||||
toReturn.data = sliced.map(a => this.toStoreObject(a));
|
||||
}
|
||||
} else {
|
||||
let obj = await this.getValuesForHost(host, undefined, undefined,
|
||||
this.hostVsStores, principal);
|
||||
|
@ -402,19 +389,28 @@ StorageActors.defaults = function(typeName, observationTopics) {
|
|||
}
|
||||
|
||||
toReturn.total = obj.length;
|
||||
toReturn.data = obj;
|
||||
}
|
||||
|
||||
if (offset > toReturn.total) {
|
||||
// In this case, toReturn.data is an empty array.
|
||||
toReturn.offset = offset = toReturn.total;
|
||||
toReturn.data = [];
|
||||
if (offset > toReturn.total) {
|
||||
// In this case, toReturn.data is an empty array.
|
||||
toReturn.offset = toReturn.total;
|
||||
toReturn.data = [];
|
||||
} else {
|
||||
// We need to use natural sort before slicing.
|
||||
const sorted = toReturn.data.sort((a, b) => {
|
||||
return naturalSortCaseInsensitive(a[sortOn], b[sortOn]);
|
||||
});
|
||||
let sliced;
|
||||
if (this.typeName === "indexedDB") {
|
||||
// indexedDB's getValuesForHost never returns *all* values available but only
|
||||
// a slice, starting at the expected offset. Therefore the result is already
|
||||
// sliced as expected.
|
||||
sliced = sorted;
|
||||
} else {
|
||||
// We need to use natural sort before slicing.
|
||||
const sorted = obj.sort((a, b) => {
|
||||
return naturalSortCaseInsensitive(a[sortOn], b[sortOn]);
|
||||
});
|
||||
const sliced = sorted.slice(offset, offset + size);
|
||||
toReturn.data = sliced.map(object => this.toStoreObject(object));
|
||||
sliced = sorted.slice(offset, offset + size);
|
||||
}
|
||||
toReturn.data = sliced.map(a => this.toStoreObject(a));
|
||||
}
|
||||
|
||||
return toReturn;
|
||||
|
@ -2358,15 +2354,15 @@ var indexedDBHelpers = {
|
|||
objectStore: objectStore,
|
||||
id: id,
|
||||
index: options.index,
|
||||
offset: 0,
|
||||
offset: options.offset,
|
||||
size: options.size
|
||||
});
|
||||
return this.backToChild("getValuesForHost", {result: result});
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns all or requested entries from a particular objectStore from the db
|
||||
* in the given host.
|
||||
* Returns requested entries (or at most MAX_STORE_OBJECT_COUNT) from a particular
|
||||
* objectStore from the db in the given host.
|
||||
*
|
||||
* @param {string} host
|
||||
* The given host.
|
||||
|
|
Загрузка…
Ссылка в новой задаче