From 813fbf95af77a531c57a8c497345ad2c61d475b3 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Thu, 18 Jun 2015 14:10:49 +0200 Subject: BASELINE: Update chromium to 44.0.2403.47 Change-Id: Ie056fedba95cf5e5c76b30c4b2c80fca4764aa2f Reviewed-by: Oswald Buddenhagen --- .../WebKit/Source/web/WebPluginContainerImpl.cpp | 230 +++++++++++++-------- 1 file changed, 139 insertions(+), 91 deletions(-) (limited to 'chromium/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp') 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 + 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(-origin.x()), static_cast(-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(-origin.x()), static_cast(-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 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 WebPluginContainerImpl::v8ObjectForElement() if (!scriptState->contextIsValid()) return v8::Local(); - v8::Handle v8value = toV8(m_element.get(), scriptState->context()->Global(), scriptState->isolate()); + v8::Local v8value = toV8(m_element.get(), scriptState->context()->Global(), scriptState->isolate()); + if (v8value.IsEmpty()) + return v8::Local(); ASSERT(v8value->IsObject()); - return v8::Handle::Cast(v8value); + return v8::Local::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::Cast(result)); + return toCoreString(v8::Local::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 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 protector(this); + v8::Local 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(); + 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(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& 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& 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 -- cgit v1.2.1