blob: 662db308cb0bdac36b3c2f1cb4d7664b38e3d687 [file] [log] [blame]
<!DOCTYPE html>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
html {
font-family: Ahem;
font-size: 10px;
}
#testArea {
position: absolute;
right: 50px;
top: 50px;
}
#target {
width: 10px;
height: 10px;
}
#frame {
width: 100px;
height: 100px;
margin-top: 30px;
}
</style>
<body onload="runTest();">
<div id=testArea>
<div id=target></div>
<iframe id=frame srcdoc='<body style="margin: 5px"><iframe width=75
height=75></iframe></body>'></iframe>
</div>
<script src="../../resources/js-test.js"></script>
<script src="../../resources/gesture-util.js"></script>
<script>
setPrintTestResultsLazily();
jsTestIsAsync = true;
if (window.internals)
internals.settings.setViewportEnabled(true);
var unique_event_id = 1;
description("Count how many hit tests are required for various event " +
"scenarios. Hit tests can be expensive and it's often tempting " +
"to add more. These values should only ever be changed to go " +
"down, not up.");
function hitTestCountDelta(doc)
{
var lastCount = 0;
if ('lastHitTestCount' in doc)
lastCount = doc.lastHitTestCount;
var newCount = internals.hitTestCount(doc);
doc.lastHitTestCount = newCount;
return newCount - lastCount;
}
function hitTestCacheHitsDelta(doc)
{
var lastCount = 0;
if ('lastHitTestCacheHits' in doc)
lastCount = doc.lastHitTestCacheHits;
var newCount = internals.hitTestCacheHits(doc);
doc.lastHitTestCacheHits = newCount;
return newCount - lastCount;
}
async function logCounts(label, documents, eventSenderFunction)
{
if (eventSenderFunction) {
if (label == 'TouchScroll' || label == 'MouseWheelScroll')
await eventSenderFunction();
else
eventSenderFunction();
}
var countStr = '';
for(var i = 0; i < documents.length; i++) {
var hits = hitTestCountDelta(documents[i]);
var cacheHits = hitTestCacheHitsDelta(documents[i]);
countStr += ' ' + (hits - cacheHits) + "+" + cacheHits;
}
debug(label + ':' + countStr);
}
function clearCounts(documents)
{
for(var i = 0; i < documents.length; i++) {
documents[i].lastHitTestCount = internals.hitTestCount(documents[i]);
documents[i].lastHitTestCacheHits =
internals.hitTestCacheHits(documents[i]);
}
}
async function sendEvents(targetX, targetY, documents)
{
logCounts('Initial', documents);
logCounts('MouseMove', documents, function() {
eventSender.mouseMoveTo(targetX, targetY);
});
logCounts('MouseDown', documents, function() {
eventSender.mouseDown();
});
logCounts('MouseUp', documents, function() {
eventSender.mouseUp();
});
logCounts('Wheel', documents, function() {
eventSender.mouseScrollBy(0, 5, false, false, 0, false);
});
logCounts('TouchStart', documents, function() {
eventSender.addTouchPoint(targetX, targetY, 15, 15);
eventSender.touchStart(unique_event_id + 1);
});
logCounts('TouchMove', documents, function() {
eventSender.updateTouchPoint(0, targetX + 1, targetY, 15, 15);
eventSender.touchMove(unique_event_id + 2);
});
logCounts('TouchEnd', documents, function() {
eventSender.releaseTouchPoint(0);
eventSender.touchEnd(unique_event_id + 3);
});
logCounts('GestureTapDown', documents, function() {
eventSender.gestureTapDown(targetX, targetY, 30, 30,
unique_event_id + 1);
});
logCounts('GestureShowPress', documents, function() {
eventSender.gestureShowPress(targetX, targetY, 30, 30,
unique_event_id + 3);
});
logCounts('GestureTap', documents, function() {
// We don't want to tap on an existing selection so we clear
// selections.
window.getSelection().empty();
eventSender.gestureTap(targetX, targetY, 1, 30, 30,
unique_event_id + 3);
});
logCounts('GestureTapCancel', documents, function() {
eventSender.gestureTapCancel(targetX, targetY);
});
logCounts('DoubleFingerTouch', documents, function() {
eventSender.addTouchPoint(targetX+1, targetY+1, 15, 15);
eventSender.touchStart();
eventSender.addTouchPoint(targetX+4, targetY+4, 15, 15);
eventSender.touchStart();
eventSender.releaseTouchPoint(0);
eventSender.releaseTouchPoint(1);
eventSender.touchEnd();
});
// smoothScrollWithXY function returns a Promise object, so we use await
// operator to wait for a Promise. eventSender does not need await.
// smoothScrollWithXY with touch input simulates a real touch scroll, which
// consists of a sequence of events, such as touch start, tap down, tap
// cancel, scroll begin and these events will do a hit-test, which causes
// the hit test count greater than 1.
await logCounts('TouchScroll', documents, async function() {
await smoothScrollWithXY(0, 1, targetX, targetY,
GestureSourceType.TOUCH_INPUT, SPEED_INSTANT);
});
// smoothScrollWithXY function returns a Promise object, so we use await
// operator to wait for a Promise. eventSender does not need await.
// smoothScrollWithXY with mouse input simulates a real touch scroll, which
// consists of a sequence of events, such as mouse wheel, scroll begin, and
// these events will do a hit-test, which causes the hit test count greater
// than 1.
await logCounts('MouseWheelScroll', documents, async function() {
await smoothScrollWithXY(0, 1, targetX, targetY,
GestureSourceType.Mouse_INPUT, SPEED_INSTANT);
});
unique_event_id = unique_event_id + 3;
// Leap forward to reset click count, so mouse down will not generate a
// double click.
eventSender.leapForward(1000);
}
async function runTestForDocuments(targetX, targetY, documents)
{
clearCounts(documents);
await sendEvents(targetX, targetY, documents);
}
function centerOf(element) {
var targetRect = element.getBoundingClientRect();
return {
x: targetRect.left + targetRect.width / 2,
y: targetRect.top + targetRect.height / 2
};
}
async function runTest() {
debug('Event on a simple div');
debug('---------------------');
var point = centerOf(document.getElementById('target'));
await runTestForDocuments(point.x, point.y, [document]);
debug('');
debug('Event entirely over one iframe nested in another');
debug('---------------------');
var frame = document.getElementById('frame');
var doc2 = frame.contentDocument;
var doc3 = doc2.querySelector('iframe').contentDocument;
var point = centerOf(frame);
await runTestForDocuments(point.x, point.y, [document, doc2, doc3]);
debug('');
debug('Event near boundary of two iframes');
debug('---------------------');
var rect = frame.getBoundingClientRect();
await runTestForDocuments(rect.left + 3, rect.top + 3,
[document, doc2, doc3]);
debug('');
internals.settings.setViewportEnabled(false);
debug('Event on a simple div (desktop viewport)');
debug('---------------------');
var point = centerOf(document.getElementById('target'));
await runTestForDocuments(point.x, point.y, [document]);
debug('');
internals.settings.setViewportEnabled(true);
finishJSTest();
}
</script>
</body>