summaryrefslogtreecommitdiff
path: root/chromium/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2015-06-18 14:10:49 +0200
committerOswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>2015-06-18 13:53:24 +0000
commit813fbf95af77a531c57a8c497345ad2c61d475b3 (patch)
tree821b2c8de8365f21b6c9ba17a236fb3006a1d506 /chromium/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp
parentaf6588f8d723931a298c995fa97259bb7f7deb55 (diff)
downloadqtwebengine-chromium-813fbf95af77a531c57a8c497345ad2c61d475b3.tar.gz
BASELINE: Update chromium to 44.0.2403.47
Change-Id: Ie056fedba95cf5e5c76b30c4b2c80fca4764aa2f Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
Diffstat (limited to 'chromium/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp')
-rw-r--r--chromium/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp230
1 files changed, 139 insertions, 91 deletions
diff --git a/chromium/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp b/chromium/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp
index b7936a71f15..90f6ab0f74c 100644
--- a/chromium/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp
+++ b/chromium/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp
@@ -33,6 +33,7 @@
#include "web/WebPluginContainerImpl.h"
#include "bindings/core/v8/ScriptController.h"
+#include "bindings/core/v8/ScriptSourceCode.h"
#include "bindings/core/v8/V8Element.h"
#include "bindings/core/v8/V8NPObject.h"
#include "core/HTMLNames.h"
@@ -48,18 +49,18 @@
#include "core/frame/LocalFrame.h"
#include "core/html/HTMLFormElement.h"
#include "core/html/HTMLPlugInElement.h"
-#include "core/loader/FormState.h"
+#include "core/layout/HitTestResult.h"
+#include "core/layout/LayoutBox.h"
+#include "core/layout/LayoutPart.h"
#include "core/loader/FrameLoadRequest.h"
#include "core/page/Chrome.h"
#include "core/page/EventHandler.h"
#include "core/page/FocusController.h"
#include "core/page/Page.h"
#include "core/page/scrolling/ScrollingCoordinator.h"
-#include "core/plugins/PluginOcclusionSupport.h"
-#include "core/rendering/HitTestResult.h"
-#include "core/rendering/RenderBox.h"
-#include "core/rendering/RenderLayer.h"
-#include "core/rendering/RenderPart.h"
+#include "core/paint/DeprecatedPaintLayer.h"
+#include "core/paint/LayoutObjectDrawingRecorder.h"
+#include "modules/plugins/PluginOcclusionSupport.h"
#include "platform/HostWindow.h"
#include "platform/KeyboardCodes.h"
#include "platform/PlatformGestureEvent.h"
@@ -80,11 +81,11 @@
#include "public/platform/WebURL.h"
#include "public/platform/WebURLError.h"
#include "public/platform/WebURLRequest.h"
-#include "public/platform/WebVector.h"
#include "public/web/WebElement.h"
#include "public/web/WebInputEvent.h"
#include "public/web/WebPlugin.h"
#include "public/web/WebPrintParams.h"
+#include "public/web/WebPrintPresetOptions.h"
#include "public/web/WebViewClient.h"
#include "web/ChromeClientImpl.h"
#include "web/ScrollbarGroup.h"
@@ -93,6 +94,8 @@
#include "web/WebViewImpl.h"
#include "wtf/Assertions.h"
+#include <base/debug/stack_trace.h>
+
namespace blink {
// Public methods --------------------------------------------------------------
@@ -103,31 +106,43 @@ void WebPluginContainerImpl::setFrameRect(const IntRect& frameRect)
reportGeometry();
}
-void WebPluginContainerImpl::paint(GraphicsContext* gc, const IntRect& damageRect)
+void WebPluginContainerImpl::layoutIfNeeded()
+{
+ RELEASE_ASSERT(m_webPlugin);
+ m_webPlugin->layoutIfNeeded();
+}
+
+void WebPluginContainerImpl::paint(GraphicsContext* context, const IntRect& rect)
{
if (!parent())
return;
- // Don't paint anything if the plugin doesn't intersect the damage rect.
- if (!frameRect().intersects(damageRect))
+ // Don't paint anything if the plugin doesn't intersect.
+ if (!frameRect().intersects(rect))
return;
- gc->save();
+ LayoutObjectDrawingRecorder drawingRecorder(*context, *m_element->layoutObject(), DisplayItem::Type::WebPlugin, rect);
+ if (drawingRecorder.canUseCachedDrawing())
+ return;
+
+ context->save();
ASSERT(parent()->isFrameView());
FrameView* view = toFrameView(parent());
- // The plugin is positioned in window coordinates, so it needs to be painted
- // in window coordinates.
- IntPoint origin = view->contentsToWindow(IntPoint(0, 0));
- gc->translate(static_cast<float>(-origin.x()), static_cast<float>(-origin.y()));
+ // The plugin is positioned in the root frame's coordinates, so it needs to
+ // be painted in them too.
+ IntPoint origin = view->contentsToRootFrame(IntPoint(0, 0));
+ context->translate(static_cast<float>(-origin.x()), static_cast<float>(-origin.y()));
- WebCanvas* canvas = gc->canvas();
+ WebCanvas* canvas = context->canvas();
- IntRect windowRect = view->contentsToWindow(damageRect);
+ IntRect windowRect = view->contentsToRootFrame(rect);
+ m_isInPaint = true;
m_webPlugin->paint(canvas, windowRect);
+ m_isInPaint = false;
- gc->restore();
+ context->restore();
}
void WebPluginContainerImpl::invalidateRect(const IntRect& rect)
@@ -135,22 +150,29 @@ void WebPluginContainerImpl::invalidateRect(const IntRect& rect)
if (!parent())
return;
- RenderBox* renderer = toRenderBox(m_element->renderer());
+ LayoutBox* layoutObject = toLayoutBox(m_element->layoutObject());
+ if (!layoutObject)
+ return;
IntRect dirtyRect = rect;
- dirtyRect.move(renderer->borderLeft() + renderer->paddingLeft(),
- renderer->borderTop() + renderer->paddingTop());
+ dirtyRect.move(
+ layoutObject->borderLeft() + layoutObject->paddingLeft(),
+ layoutObject->borderTop() + layoutObject->paddingTop());
+
+ m_pendingInvalidationRect.unite(dirtyRect);
- // For querying RenderLayer::compositingState().
- // This code should be correct.
- DisableCompositingQueryAsserts disabler;
- renderer->invalidatePaintRectangle(dirtyRect);
+ // Check layout before setting needs layout, as this method may be called
+ // while layout is in progress and we do not wish to layout again in that case.
+ // TODO(schenney): Investigate how to fix this. See comment #15 and #16 on
+ // https://codereview.chromium.org/1076283002/, crbug.com/476660
+ if (!m_isInPaint && !layoutObject->needsLayout())
+ layoutObject->setNeedsLayout("Plugin Paint Invalidation");
}
-void WebPluginContainerImpl::setFocus(bool focused)
+void WebPluginContainerImpl::setFocus(bool focused, WebFocusType focusType)
{
- Widget::setFocus(focused);
- m_webPlugin->updateFocus(focused);
+ Widget::setFocus(focused, focusType);
+ m_webPlugin->updateFocus(focused, focusType);
}
void WebPluginContainerImpl::show()
@@ -305,10 +327,10 @@ void WebPluginContainerImpl::setWebLayer(WebLayer* layer)
m_element->setNeedsCompositingUpdate();
// Being composited or not affects the self painting layer bit
- // on the RenderLayer.
- if (RenderPart* renderer = m_element->renderPart()) {
- ASSERT(renderer->hasLayer());
- renderer->layer()->updateSelfPaintingLayer();
+ // on the DeprecatedPaintLayer.
+ if (LayoutPart* layoutObject = m_element->layoutPart()) {
+ ASSERT(layoutObject->hasLayer());
+ layoutObject->layer()->updateSelfPaintingLayer();
}
}
@@ -322,9 +344,9 @@ bool WebPluginContainerImpl::isPrintScalingDisabled() const
return m_webPlugin->isPrintScalingDisabled();
}
-int WebPluginContainerImpl::getCopiesToPrint() const
+bool WebPluginContainerImpl::getPrintPresetOptionsFromDocument(WebPrintPresetOptions* presetOptions) const
{
- return m_webPlugin->getCopiesToPrint();
+ return m_webPlugin->getPrintPresetOptionsFromDocument(presetOptions);
}
int WebPluginContainerImpl::printBegin(const WebPrintParams& printParams) const
@@ -391,16 +413,23 @@ void WebPluginContainerImpl::scrollRect(const WebRect& rect)
invalidateRect(rect);
}
+void WebPluginContainerImpl::setNeedsLayout()
+{
+ if (m_element->layoutObject())
+ m_element->layoutObject()->setNeedsLayoutAndFullPaintInvalidation("Plugin needs layout");
+}
+
void WebPluginContainerImpl::reportGeometry()
{
- if (!parent())
+ // We cannot compute geometry without a parent or layoutObject.
+ if (!parent() || !m_element || !m_element->layoutObject())
return;
- IntRect windowRect, clipRect;
+ IntRect windowRect, clipRect, unobscuredRect;
Vector<IntRect> cutOutRects;
- calculateGeometry(frameRect(), windowRect, clipRect, cutOutRects);
+ calculateGeometry(windowRect, clipRect, unobscuredRect, cutOutRects);
- m_webPlugin->updateGeometry(windowRect, clipRect, cutOutRects, isVisible());
+ m_webPlugin->updateGeometry(windowRect, clipRect, unobscuredRect, cutOutRects, isVisible());
if (m_scrollbarGroup) {
m_scrollbarGroup->scrollAnimator()->contentsResized();
@@ -438,10 +467,12 @@ v8::Local<v8::Object> WebPluginContainerImpl::v8ObjectForElement()
if (!scriptState->contextIsValid())
return v8::Local<v8::Object>();
- v8::Handle<v8::Value> v8value = toV8(m_element.get(), scriptState->context()->Global(), scriptState->isolate());
+ v8::Local<v8::Value> v8value = toV8(m_element.get(), scriptState->context()->Global(), scriptState->isolate());
+ if (v8value.IsEmpty())
+ return v8::Local<v8::Object>();
ASSERT(v8value->IsObject());
- return v8::Handle<v8::Object>::Cast(v8value);
+ return v8::Local<v8::Object>::Cast(v8value);
}
WebString WebPluginContainerImpl::executeScriptURL(const WebURL& url, bool popupsAllowed)
@@ -463,7 +494,7 @@ WebString WebPluginContainerImpl::executeScriptURL(const WebURL& url, bool popup
// Failure is reported as a null string.
if (result.IsEmpty() || !result->IsString())
return WebString();
- return toCoreString(v8::Handle<v8::String>::Cast(result));
+ return toCoreString(v8::Local<v8::String>::Cast(result));
}
void WebPluginContainerImpl::loadFrameRequest(const WebURLRequest& request, const WebString& target, bool notifyNeeded, void* notifyData)
@@ -483,7 +514,6 @@ void WebPluginContainerImpl::loadFrameRequest(const WebURLRequest& request, cons
}
FrameLoadRequest frameRequest(frame->document(), request.toResourceRequest(), target);
- UserGestureIndicator gestureIndicator(request.hasUserGesture() ? DefinitelyProcessingNewUserGesture : PossiblyProcessingUserGesture);
frame->loader().load(frameRequest);
}
@@ -495,6 +525,9 @@ void WebPluginContainerImpl::zoomLevelChanged(double zoomLevel)
bool WebPluginContainerImpl::isRectTopmost(const WebRect& rect)
{
+ if (!m_element)
+ return false;
+
LocalFrame* frame = m_element->document().frame();
if (!frame)
return false;
@@ -505,8 +538,8 @@ bool WebPluginContainerImpl::isRectTopmost(const WebRect& rect)
LayoutPoint center = documentRect.center();
// Make the rect we're checking (the point surrounded by padding rects) contained inside the requested rect. (Note that -1/2 is 0.)
LayoutSize padding((documentRect.width() - 1) / 2, (documentRect.height() - 1) / 2);
- HitTestResult result = frame->eventHandler().hitTestResultAtPoint(center, HitTestRequest::ReadOnly | HitTestRequest::Active, padding);
- const HitTestResult::NodeSet& nodes = result.rectBasedTestResult();
+ HitTestResult result = frame->eventHandler().hitTestResultAtPoint(center, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::ListBased, padding);
+ const HitTestResult::NodeSet& nodes = result.listBasedTestResult();
if (nodes.size() != 1)
return false;
return nodes.first().get() == m_element;
@@ -540,22 +573,22 @@ void WebPluginContainerImpl::setWantsWheelEvents(bool wantsWheelEvents)
}
}
-WebPoint WebPluginContainerImpl::windowToLocalPoint(const WebPoint& point)
+WebPoint WebPluginContainerImpl::rootFrameToLocalPoint(const WebPoint& pointInRootFrame)
{
FrameView* view = toFrameView(parent());
if (!view)
- return point;
- WebPoint windowPoint = view->windowToContents(point);
- return roundedIntPoint(m_element->renderer()->absoluteToLocal(LayoutPoint(windowPoint), UseTransforms));
+ return pointInRootFrame;
+ WebPoint pointInContent = view->rootFrameToContents(pointInRootFrame);
+ return roundedIntPoint(m_element->layoutObject()->absoluteToLocal(FloatPoint(pointInContent), UseTransforms));
}
-WebPoint WebPluginContainerImpl::localToWindowPoint(const WebPoint& point)
+WebPoint WebPluginContainerImpl::localToRootFramePoint(const WebPoint& pointInLocal)
{
FrameView* view = toFrameView(parent());
if (!view)
- return point;
- IntPoint absolutePoint = roundedIntPoint(m_element->renderer()->localToAbsolute(LayoutPoint(point), UseTransforms));
- return view->contentsToWindow(absolutePoint);
+ return pointInLocal;
+ IntPoint absolutePoint = roundedIntPoint(m_element->layoutObject()->localToAbsolute(FloatPoint(pointInLocal), UseTransforms));
+ return view->contentsToRootFrame(absolutePoint);
}
void WebPluginContainerImpl::didReceiveResponse(const ResourceResponse& response)
@@ -590,7 +623,23 @@ WebLayer* WebPluginContainerImpl::platformLayer() const
v8::Local<v8::Object> WebPluginContainerImpl::scriptableObject(v8::Isolate* isolate)
{
+ // The plugin may be destroyed due to re-entrancy when calling
+ // v8ScriptableObject below. crbug.com/458776. Hold a reference to the
+ // plugin container to prevent this from happening. For Oilpan, 'this'
+ // is already stack reachable, so redundant.
+ RefPtrWillBeRawPtr<WebPluginContainerImpl> protector(this);
+
v8::Local<v8::Object> object = m_webPlugin->v8ScriptableObject(isolate);
+
+ // If the plugin has been destroyed and the reference on the stack is the
+ // only one left, then don't return the scriptable object.
+#if ENABLE(OILPAN)
+ if (!m_webPlugin)
+#else
+ if (hasOneRef())
+#endif
+ return v8::Local<v8::Object>();
+
if (!object.IsEmpty()) {
// WebPlugin implementation can't provide the obsolete NPObject at the same time:
ASSERT(!m_webPlugin->scriptableObject());
@@ -660,21 +709,14 @@ void WebPluginContainerImpl::willEndLiveResize()
m_scrollbarGroup->willEndLiveResize();
}
-bool WebPluginContainerImpl::paintCustomOverhangArea(GraphicsContext* context, const IntRect& horizontalOverhangArea, const IntRect& verticalOverhangArea, const IntRect& dirtyRect)
-{
- Color fillColor(0xCC, 0xCC, 0xCC);
- context->fillRect(intersection(horizontalOverhangArea, dirtyRect), fillColor);
- context->fillRect(intersection(verticalOverhangArea, dirtyRect), fillColor);
- return true;
-}
-
// Private methods -------------------------------------------------------------
WebPluginContainerImpl::WebPluginContainerImpl(HTMLPlugInElement* element, WebPlugin* webPlugin)
- : FrameDestructionObserver(element->document().frame())
+ : LocalFrameLifecycleObserver(element->document().frame())
, m_element(element)
, m_webPlugin(webPlugin)
, m_webLayer(nullptr)
+ , m_isInPaint(false)
, m_touchEventRequestType(TouchEventRequestTypeNone)
, m_wantsWheelEvents(false)
#if ENABLE(OILPAN)
@@ -728,10 +770,10 @@ void WebPluginContainerImpl::shouldDisposePlugin()
}
#endif
-void WebPluginContainerImpl::trace(Visitor* visitor)
+DEFINE_TRACE(WebPluginContainerImpl)
{
visitor->trace(m_element);
- FrameDestructionObserver::trace(visitor);
+ LocalFrameLifecycleObserver::trace(visitor);
PluginView::trace(visitor);
}
@@ -749,7 +791,7 @@ void WebPluginContainerImpl::handleMouseEvent(MouseEvent* event)
// in the call to HandleEvent. See http://b/issue?id=1362948
FrameView* parentView = toFrameView(parent());
- WebMouseEventBuilder webEvent(this, m_element->renderer(), *event);
+ WebMouseEventBuilder webEvent(this, m_element->layoutObject(), *event);
if (webEvent.type == WebInputEvent::Undefined)
return;
@@ -799,7 +841,7 @@ void WebPluginContainerImpl::handleDragEvent(MouseEvent* event)
return;
DataTransfer* dataTransfer = event->dataTransfer();
- WebDragData dragData(dataTransfer->dataObject());
+ WebDragData dragData = dataTransfer->dataObject()->toWebDragData();
WebDragOperationsMask dragOperationMask = static_cast<WebDragOperationsMask>(dataTransfer->sourceOperation());
WebPoint dragScreenLocation(event->screenX(), event->screenY());
WebPoint dragLocation(event->absoluteLocation().x() - location().x(), event->absoluteLocation().y() - location().y());
@@ -809,7 +851,7 @@ void WebPluginContainerImpl::handleDragEvent(MouseEvent* event)
void WebPluginContainerImpl::handleWheelEvent(WheelEvent* event)
{
- WebMouseWheelEventBuilder webEvent(this, m_element->renderer(), *event);
+ WebMouseWheelEventBuilder webEvent(this, m_element->layoutObject(), *event);
if (webEvent.type == WebInputEvent::Undefined)
return;
@@ -867,7 +909,7 @@ void WebPluginContainerImpl::handleTouchEvent(TouchEvent* event)
case TouchEventRequestTypeNone:
return;
case TouchEventRequestTypeRaw: {
- WebTouchEventBuilder webEvent(this, m_element->renderer(), *event);
+ WebTouchEventBuilder webEvent(m_element->layoutObject(), *event);
if (webEvent.type == WebInputEvent::Undefined)
return;
@@ -896,7 +938,7 @@ static inline bool gestureScrollHelper(ScrollbarGroup* scrollbarGroup, ScrollDir
void WebPluginContainerImpl::handleGestureEvent(GestureEvent* event)
{
- WebGestureEventBuilder webEvent(this, m_element->renderer(), *event);
+ WebGestureEventBuilder webEvent(m_element->layoutObject(), *event);
if (webEvent.type == WebInputEvent::Undefined)
return;
if (event->type() == EventTypeNames::gesturetapdown)
@@ -907,7 +949,7 @@ void WebPluginContainerImpl::handleGestureEvent(GestureEvent* event)
return;
}
- if (webEvent.type == WebInputEvent::GestureScrollUpdate || webEvent.type == WebInputEvent::GestureScrollUpdateWithoutPropagation) {
+ if (webEvent.type == WebInputEvent::GestureScrollUpdate) {
if (!m_scrollbarGroup)
return;
if (gestureScrollHelper(m_scrollbarGroup.get(), ScrollLeft, ScrollRight, webEvent.data.scrollUpdate.deltaX))
@@ -920,7 +962,7 @@ void WebPluginContainerImpl::handleGestureEvent(GestureEvent* event)
void WebPluginContainerImpl::synthesizeMouseEventIfPossible(TouchEvent* event)
{
- WebMouseEventBuilder webEvent(this, m_element->renderer(), *event);
+ WebMouseEventBuilder webEvent(this, m_element->layoutObject(), *event);
if (webEvent.type == WebInputEvent::Undefined)
return;
@@ -938,40 +980,46 @@ void WebPluginContainerImpl::focusPlugin()
containingFrame.document()->setFocusedElement(m_element);
}
-void WebPluginContainerImpl::calculateGeometry(const IntRect& frameRect,
- IntRect& windowRect,
- IntRect& clipRect,
- Vector<IntRect>& cutOutRects)
+void WebPluginContainerImpl::issuePaintInvalidations()
{
- windowRect = toFrameView(parent())->contentsToWindow(frameRect);
+ if (m_pendingInvalidationRect.isEmpty())
+ return;
- // Calculate a clip-rect so that we don't overlap the scrollbars, etc.
- clipRect = windowClipRect();
- clipRect.move(-windowRect.x(), -windowRect.y());
+ LayoutBox* layoutObject = toLayoutBox(m_element->layoutObject());
+ if (!layoutObject)
+ return;
- getPluginOcclusions(m_element, this->parent(), frameRect, cutOutRects);
- // Convert to the plugin position.
- for (size_t i = 0; i < cutOutRects.size(); i++)
- cutOutRects[i].move(-frameRect.x(), -frameRect.y());
+ layoutObject->invalidatePaintRectangle(LayoutRect(m_pendingInvalidationRect));
+ m_pendingInvalidationRect = IntRect();
}
-IntRect WebPluginContainerImpl::windowClipRect() const
+void WebPluginContainerImpl::calculateGeometry(IntRect& windowRect, IntRect& clipRect, IntRect& unobscuredRect, Vector<IntRect>& cutOutRects)
{
- // Start by clipping to our bounds.
- IntRect clipRect =
- convertToContainingWindow(IntRect(0, 0, width(), height()));
+ windowRect = toFrameView(parent())->contentsToRootFrame(frameRect());
+
+ // Calculate a clip-rect so that we don't overlap the scrollbars, etc.
+ clipRect = convertToContainingWindow(IntRect(0, 0, width(), height()));
+ unobscuredRect = clipRect;
- // document().renderView() can be 0 when we receive messages from the
+ // document().layoutView() can be 0 when we receive messages from the
// plugins while we are destroying a frame.
// FIXME: Can we just check m_element->document().isActive() ?
- if (m_element->renderer()->document().renderView()) {
+ if (m_element->layoutObject()->document().layoutView()) {
// Take our element and get the clip rect from the enclosing layer and
// frame view.
- clipRect.intersect(
- m_element->document().view()->windowClipRectForFrameOwner(m_element));
+ IntRect elementUnobscuredRect;
+ IntRect elementWindowClipRect = m_element->document().view()->clipRectsForFrameOwner(m_element, &elementUnobscuredRect);
+ clipRect.intersect(elementWindowClipRect);
+ unobscuredRect.intersect(elementUnobscuredRect);
}
- return clipRect;
+ clipRect.move(-windowRect.x(), -windowRect.y());
+ unobscuredRect.move(-windowRect.x(), -windowRect.y());
+
+ getPluginOcclusions(m_element, this->parent(), frameRect(), cutOutRects);
+ // Convert to the plugin position.
+ for (size_t i = 0; i < cutOutRects.size(); i++)
+ cutOutRects[i].move(-frameRect().x(), -frameRect().y());
}
bool WebPluginContainerImpl::pluginShouldPersist() const