blob: 3f58c23d0d23d590102256e853c9a01f1e946f57 [file] [log] [blame]
<!DOCTYPE html> <!-- webkit-test-runner [ internal:UndoManagerAPIEnabled=true ] -->
<html>
<meta charset="utf8">
<head>
<script src="../../resources/js-test.js"></script>
<script src="../editing.js"></script>
<script>
jsTestIsAsync = true;
function objectCountAfterSimulatingMemoryPressureAndGarbageCollection() {
internals.beginSimulatedMemoryPressure();
internals.endSimulatedMemoryPressure();
GCController.collect();
return GCController.getJSObjectCount();
}
async function runTest() {
description("Verifies that JSUndoItems are deleted when they are no longer needed by the platform clipboard. This test requires WebKitTestRunner.");
if (!window.GCController)
return;
editor = document.getElementById("editor");
editor.focus();
const undoItemCount = 1000;
for (let i = 0; i < undoItemCount; ++i) {
document.undoManager.addItem(new UndoItem({
label: "",
undo: () => { },
redo: () => { }
}));
}
for (let i = 0; i < undoItemCount; ++i)
document.execCommand("Undo");
objectCountBeforeClearingUndoStack = objectCountAfterSimulatingMemoryPressureAndGarbageCollection();
selectAllCommand();
typeCharacterCommand("E");
// Wait until almost all of the wrappers are collected. For each UndoItem, we expect a total of 3 wrappers:
// one each for the undo and redo handlers, and one for the UndoItem itself. However, we also give ourselves
// some wiggle room for additional wrappers created when calling some testing helper functions. This is
// still a useful test, since it will time out in the case where either our undo items or their undo/redo
// handlers are not properly relinquished once they're no longer needed.
const minimumNumberOfWrappersToCollectBeforePassing = 3 * undoItemCount - 300;
objectCountAfterClearingUndoStack = objectCountBeforeClearingUndoStack;
var tries = 0;
while (objectCountBeforeClearingUndoStack - objectCountAfterClearingUndoStack < minimumNumberOfWrappersToCollectBeforePassing) {
await new Promise(resolve => setTimeout(resolve, 100));
objectCountAfterClearingUndoStack = objectCountAfterSimulatingMemoryPressureAndGarbageCollection();
if (tries++ > 10)
break;
}
shouldBeGreaterThanOrEqual("objectCountBeforeClearingUndoStack - objectCountAfterClearingUndoStack", `${minimumNumberOfWrappersToCollectBeforePassing}`);
finishJSTest();
}
</script>
</head>
<body onload="runTest()">
<div contenteditable id="editor"></div>
<pre id="description"></pre>
<pre id="console"></pre>
</body>
</html>