haikuwebkit/ManualTests/plugins/plugin-paint-causes-layout....

40 lines
958 B
HTML
Raw Permalink Normal View History

2010-12-22 Simon Fraser <simon.fraser@apple.com> Reviewed by Darin Adler. Cache snapshots of plug-ins before painting, to avoid script running during painting https://bugs.webkit.org/show_bug.cgi?id=51493 When FrameView is asked to do a flattening paint (e.g. when Safari snapshots, or when printing), plug-ins which otherwise use the CA rendering model are sent a paint event. Some plug-ins may run script while handling this event, or out of process plug-ins may process queued requests at this time. Running script while inside layout or painting can have bad consequences, because it can result in arbitrary changes to the render tree. This patch avoids sending plug-ins paint events inside of painting. Instead, we ask the plug-ins to cache a snapshot before we paint, and then the software paint simply draws that snapshot. Requires manual test, because the bug happens when Safari does a page snapshot. It's not possible to tell the Test Netscape Plug-in to paint without laying out, making an automated test impossible. * manual-tests/plugins/plugin-paint-causes-layout.html: Added. * page/FrameView.h: * page/FrameView.cpp: (WebCore::FrameView::paintContents): Notify all enclosed widgets that a flattening paint is going to happen. (WebCore::FrameView::notifyWidgetsInAllFrames): Utility method that tells the RenderView in all subframes to notify their widgets. * platform/Widget.h: (WebCore::Widget::notifyWidget): Generic method that can be used to send messages to widgets. Current messages are just 'before flattening paint' and 'after flattening paint'. Message has no payload. * rendering/RenderView.h: * rendering/RenderView.cpp: (WebCore::RenderView::getRetainedWidgets): (WebCore::RenderView::releaseWidgets): Factor code out of updateWidgetPositions(), since we use it in two places now. (WebCore::RenderView::updateWidgetPositions): Use getRetainedWidgets() etc. (WebCore::RenderView::notifyWidgets): Retain all the widgets, then send them all the message. * rendering/RenderWidget.h: * rendering/RenderWidget.cpp: (WebCore::RenderWidget::notifyWidget): Pass the message to the widget. * Plugins/Hosted/WebHostedNetscapePluginView.mm: (-[WebHostedNetscapePluginView drawRect:]): If we have a cached snapshot, draw it. Also only send the snapshot message to the plugin proxy if we know we're snapshotting, since even if creating the snapshot image failed, we still don't want to call to the plug-in. * Plugins/WebBaseNetscapePluginView.h: Add a retained NSImage member for the snapshot. * Plugins/WebBaseNetscapePluginView.mm: (-[WebBaseNetscapePluginView cacheSnapshot]): Create an image and draw the snapshot into it. (-[WebBaseNetscapePluginView clearCachedSnapshot]): Clear the snapshot. * Plugins/WebNetscapePluginView.mm: (-[WebNetscapePluginView drawRect:]): If we have a cached snapshot, use it. * WebCoreSupport/WebFrameLoaderClient.mm: (NetscapePluginWidget::notifyWidget): Implement notifyWidget() and use it to cache and clear the snapshots. Canonical link: https://commits.webkit.org/64863@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@74524 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2010-12-23 01:17:45 +00:00
<!DOCTYPE html>
<html>
<head>
<style type="text/css" media="screen">
embed {
position: absolute;
margin: 10px;
}
.container {
position: relative;
border: 2px solid blue;
padding: 20px;
width: 100px;
}
</style>
<script type="text/javascript" charset="utf-8">
function hideFirst()
{
var firstDiv = document.getElementById('first');
if (!firstDiv)
return;
firstDiv.parentNode.removeChild(firstDiv);
document.body.clientWidth;
}
</script>
</head>
<body>
<embed type="application/x-webkit-test-netscape" onpaintevent="hideFirst()" drawingmodel="coreanimation"></embed>
<p>This test should not assert or crash when loaded in Safari, when Safari captures a snapshot.</p>
<div id="first" class="container">
</div>
</body>
</html>