Chromium Code Reviews| Index: third_party/WebKit/Source/web/DevToolsEmulator.cpp |
| diff --git a/third_party/WebKit/Source/web/DevToolsEmulator.cpp b/third_party/WebKit/Source/web/DevToolsEmulator.cpp |
| index 848f4e121489e3eb3daee48891475e134128abbc..2807b12b1f32004f38f68a5b3e0df84abc2e3cec 100644 |
| --- a/third_party/WebKit/Source/web/DevToolsEmulator.cpp |
| +++ b/third_party/WebKit/Source/web/DevToolsEmulator.cpp |
| @@ -11,6 +11,7 @@ |
| #include "core/page/Page.h" |
| #include "core/style/ComputedStyle.h" |
| #include "platform/RuntimeEnabledFeatures.h" |
| +#include "platform/geometry/FloatRect.h" |
| #include "public/platform/WebLayerTreeView.h" |
| #include "web/WebInputEventConversion.h" |
| #include "web/WebLocalFrameImpl.h" |
| @@ -219,7 +220,7 @@ void DevToolsEmulator::enableDeviceEmulation(const WebDeviceEmulationParams& par |
| disableMobileEmulation(); |
| m_webViewImpl->setCompositorDeviceScaleFactorOverride(params.deviceScaleFactor); |
| - m_webViewImpl->setRootLayerTransform(WebSize(params.offset.x, params.offset.y), params.scale); |
| + updateRootLayerTransform(); |
| // TODO(dgozman): mainFrameImpl() is null when it's remote. Figure out how |
| // we end up with enabling emulation in this case. |
| if (m_webViewImpl->mainFrameImpl()) { |
| @@ -238,8 +239,8 @@ void DevToolsEmulator::disableDeviceEmulation() |
| m_webViewImpl->page()->settings().setDeviceScaleAdjustment(m_embedderDeviceScaleAdjustment); |
| disableMobileEmulation(); |
| m_webViewImpl->setCompositorDeviceScaleFactorOverride(0.f); |
| - m_webViewImpl->setRootLayerTransform(WebSize(0.f, 0.f), 1.f); |
| m_webViewImpl->setPageScaleFactor(1.f); |
| + updateRootLayerTransform(); |
| // mainFrameImpl() could be null during cleanup or remote <-> local swap. |
| if (m_webViewImpl->mainFrameImpl()) { |
| if (Document* document = m_webViewImpl->mainFrameImpl()->frame()->document()) |
| @@ -319,6 +320,105 @@ void DevToolsEmulator::disableMobileEmulation() |
| m_webViewImpl->mainFrameImpl()->frameView()->layout(); |
| } |
| +void DevToolsEmulator::setVisualTransformOverride(const WebFloatRect& area, float scale) |
| +{ |
| + if (!m_visualTransformOverride) |
| + m_visualTransformOverride = VisualTransformOverride(); |
| + |
| + m_visualTransformOverride->area = area; |
| + m_visualTransformOverride->scale = scale; |
| + |
| + // Ensure that all content inside the area is painted. |
| + if (m_webViewImpl->mainFrameImpl()) |
| + m_webViewImpl->mainFrameImpl()->frameView()->setVisibleContentRectForPainting(enclosingIntRect(area)); |
|
chrishtr
2016/08/12 20:56:22
Why can't this be accomplished by changing the wid
Eric Seckler
2016/08/12 21:37:53
I don't think width&height would suffice, since we
chrishtr
2016/08/12 21:41:36
Why would you want it to be different than the cur
Eric Seckler
2016/08/12 21:55:36
We want to record+render only the screenshot area,
chrishtr
2016/08/12 22:03:43
Is the objection to scrolling to the desired area
Eric Seckler
2016/08/12 22:15:46
Correct. Javascript can listen for scroll events a
|
| + |
| + // Disable clipping on the visual viewport layer, to ensure the whole area is painted. |
| + GraphicsLayer* containerLayer = m_webViewImpl->page()->frameHost().visualViewport().containerLayer(); |
| + if (containerLayer) { |
| + m_visualTransformOverride->originalVisualViewportMasking = containerLayer->masksToBounds(); |
| + containerLayer->setMasksToBounds(false); |
| + } |
| + |
| + // Move the correct (scaled) content area to show in the top left of the |
| + // CompositorFrame via the root transform. |
| + updateRootLayerTransform(); |
| +} |
| + |
| +void DevToolsEmulator::clearVisualTransformOverride() |
| +{ |
| + if (!m_visualTransformOverride) |
| + return; |
| + |
| + bool originalMasking = m_visualTransformOverride->originalVisualViewportMasking; |
| + m_visualTransformOverride = WTF::nullopt; |
| + |
| + // Restore original state. |
| + if (m_webViewImpl->mainFrameImpl()) |
| + m_webViewImpl->mainFrameImpl()->frameView()->resetVisibleContentRectForPainting(); |
| + GraphicsLayer* containerLayer = m_webViewImpl->page()->frameHost().visualViewport().containerLayer(); |
| + if (containerLayer) |
| + containerLayer->setMasksToBounds(originalMasking); |
| + updateRootLayerTransform(); |
| +} |
| + |
| +void DevToolsEmulator::mainFrameScrollOrScaleChanged() |
| +{ |
| + // Visual transform override has to take current page scale and scroll |
| + // offset into account. Update the transform if override is active. |
| + if (m_visualTransformOverride) |
| + updateRootLayerTransform(); |
| +} |
| + |
| +void DevToolsEmulator::applyDeviceEmulationTransform(TransformationMatrix* transform) |
| +{ |
| + if (m_deviceMetricsEnabled) { |
| + WebSize offset(m_emulationParams.offset.x, m_emulationParams.offset.y); |
| + // Scale first, so that translation is unaffected. |
| + transform->translate(offset.width, offset.height); |
| + transform->scale(m_emulationParams.scale); |
| + if (m_webViewImpl->mainFrameImpl()) |
| + m_webViewImpl->mainFrameImpl()->setInputEventsTransformForEmulation(offset, m_emulationParams.scale); |
| + } else { |
| + if (m_webViewImpl->mainFrameImpl()) |
| + m_webViewImpl->mainFrameImpl()->setInputEventsTransformForEmulation(WebSize(0, 0), 1.0); |
| + } |
| +} |
| + |
| +void DevToolsEmulator::applyVisualTransformOverride(TransformationMatrix* transform) |
| +{ |
| + if (!m_visualTransformOverride) |
| + return; |
| + |
| + // Transform operations follow in reverse application. |
| + // Last, scale positioned area according to override. |
| + transform->scale(m_visualTransformOverride->scale); |
| + |
| + // Translate while taking into account current scroll offset. |
| + WebSize scrollOffset = m_webViewImpl->mainFrame()->scrollOffset(); |
| + WebFloatPoint visualOffset = m_webViewImpl->visualViewportOffset(); |
| + float scrollX = scrollOffset.width + visualOffset.x; |
| + float scrollY = scrollOffset.height + visualOffset.y; |
| + transform->translate( |
| + -m_visualTransformOverride->area.x + scrollX, |
| + -m_visualTransformOverride->area.y + scrollY); |
| + |
| + // First, reverse page scale, so we don't have to take it into account for |
| + // calculation of the translation. |
| + transform->scale(1. / m_webViewImpl->pageScaleFactor()); |
| +} |
| + |
| +void DevToolsEmulator::updateRootLayerTransform() |
| +{ |
| + TransformationMatrix transform; |
| + |
| + // Apply device emulation transform first, so that it is affected by the |
| + // visual transform override. |
| + applyVisualTransformOverride(&transform); |
| + applyDeviceEmulationTransform(&transform); |
| + |
| + m_webViewImpl->setRootLayerTransform(transform); |
| +} |
| + |
| void DevToolsEmulator::setTouchEventEmulationEnabled(bool enabled) |
| { |
| if (m_touchEventEmulationEnabled == enabled) |