Chromium Code Reviews| Index: Source/web/WebViewImpl.cpp |
| diff --git a/Source/web/WebViewImpl.cpp b/Source/web/WebViewImpl.cpp |
| index d60b1b8a9c1ed0e7bda7f7c8c3097e88902e522f..8a44adb06980ba0f7766099040e3e8b57f639581 100644 |
| --- a/Source/web/WebViewImpl.cpp |
| +++ b/Source/web/WebViewImpl.cpp |
| @@ -79,6 +79,7 @@ |
| #include "core/rendering/RenderView.h" |
| #include "core/rendering/RenderWidget.h" |
| #include "core/rendering/TextAutosizer.h" |
| +#include "core/rendering/compositing/CompositedLayerMapping.h" |
| #include "core/rendering/compositing/RenderLayerCompositor.h" |
| #include "modules/device_orientation/DeviceOrientationInspectorAgent.h" |
| #include "modules/encryptedmedia/MediaKeysController.h" |
| @@ -123,6 +124,7 @@ |
| #include "public/web/WebPlugin.h" |
| #include "public/web/WebPluginAction.h" |
| #include "public/web/WebRange.h" |
| +#include "public/web/WebSelection.h" |
| #include "public/web/WebTextInputInfo.h" |
| #include "public/web/WebViewClient.h" |
| #include "public/web/WebWindowFeatures.h" |
| @@ -1722,6 +1724,8 @@ void WebViewImpl::layout() |
| for (size_t i = 0; i < m_linkHighlights.size(); ++i) |
| m_linkHighlights[i]->updateGeometry(); |
| + |
| + updateLayerTreeSelection(); |
| } |
| void WebViewImpl::paint(WebCanvas* canvas, const WebRect& rect) |
| @@ -4007,6 +4011,122 @@ void WebViewImpl::updateRootLayerTransform() |
| } |
| } |
| +static FloatPoint convertTargetPointToCompositedLayerPoint(IntPoint point, RenderObject* targetRenderer, RenderObject* compositedRenderer) |
| +{ |
| + point = targetRenderer->frame()->view()->contentsToWindow(point); |
| + point = compositedRenderer->frame()->view()->windowToContents(point); |
| + return compositedRenderer->absoluteToLocal(point, UseTransforms); |
| +} |
| + |
| +static bool computeCompositedLayerAndRect(Node* node, IntRect absoluteRect, int& layerId, WebRect& layerRect) |
|
aelias_OOO_until_Jul13
2014/06/12 06:02:01
Looks very similar to the logic in LinkHighlight.c
jdduke (slow)
2014/06/12 18:03:20
Any suggestions on where to place to put such code
|
| +{ |
| + if (!node || !node->renderer()) |
| + return false; |
| + |
| + // Find the nearest enclosing composited layer and attach to it. We may need to cross frame boundaries |
| + // to find a suitable layer. |
| + RenderObject* renderer = node->renderer(); |
| + RenderLayer* renderLayer; |
| + do { |
| + renderLayer = renderer->enclosingLayer()->enclosingCompositingLayerForRepaint(); |
| + if (!renderLayer) { |
| + renderer = renderer->frame()->ownerRenderer(); |
| + if (!renderer) |
| + return false; |
| + } |
| + } while (!renderLayer); |
| + |
| + CompositedLayerMappingPtr compositedLayerMapping = renderLayer->compositingState() == PaintsIntoGroupedBacking ? renderLayer->groupedMapping() : renderLayer->compositedLayerMapping(); |
| + GraphicsLayer* graphicsLayer = renderLayer->compositingState() == PaintsIntoGroupedBacking ? compositedLayerMapping->squashingLayer() : compositedLayerMapping->mainGraphicsLayer(); |
| + |
| + if (!graphicsLayer->drawsContent()) { |
| + if (renderLayer->scrollableArea() && renderLayer->scrollableArea()->usesCompositedScrolling()) { |
| + ASSERT(renderLayer->hasCompositedLayerMapping() && renderLayer->compositedLayerMapping()->scrollingContentsLayer()); |
| + graphicsLayer = compositedLayerMapping->scrollingContentsLayer(); |
| + } |
| + } |
| + |
| + layerId = graphicsLayer->platformLayer()->id(); |
| + |
| + absoluteRect.move(-graphicsLayer->offsetFromRenderer()); |
| + |
| + FloatQuad layerQuad; |
| + layerQuad.setP1(convertTargetPointToCompositedLayerPoint(absoluteRect.minXMinYCorner(), node->renderer(), renderLayer->renderer())); |
| + layerQuad.setP2(convertTargetPointToCompositedLayerPoint(absoluteRect.maxXMinYCorner(), node->renderer(), renderLayer->renderer())); |
| + layerQuad.setP3(convertTargetPointToCompositedLayerPoint(absoluteRect.maxXMaxYCorner(), node->renderer(), renderLayer->renderer())); |
| + layerQuad.setP4(convertTargetPointToCompositedLayerPoint(absoluteRect.minXMaxYCorner(), node->renderer(), renderLayer->renderer())); |
| + layerRect = layerQuad.enclosingBoundingBox(); |
| + |
| + return true; |
| +} |
| + |
| +void WebViewImpl::updateLayerTreeSelection() |
| +{ |
| + if (!m_layerTreeView || !settings()->compositedSelectionUpdatesEnabled()) |
| + return; |
| + |
| + const LocalFrame* frame = toLocalFrame(focusedWebCoreFrame()); |
| + if (!frame || !frame->selection().isCaretOrRange()) |
| + return m_layerTreeView->clearSelection(); |
| + |
| + FrameSelection& selection = frame->selection(); |
| + |
| + // TODO(jdduke): Cache selection and compare? |
| + if (selection.isCaret()) { |
| + WebSelection webSelection; |
| + if (!computeCompositedLayerAndRect(selection.rootEditableElementOrDocumentElement(), |
| + selection.absoluteCaretBounds(), |
| + webSelection.anchorLayerId, |
| + webSelection.anchorRectInLayer)) { |
| + return m_layerTreeView->clearSelection(); |
| + } |
| + |
| + // TODO(jdduke): Populate editable bounds. |
| + webSelection.type = WebSelection::TypeInsertion; |
| + m_layerTreeView->registerSelection(webSelection); |
| + return; |
| + } |
| + |
| + RefPtrWillBeRawPtr<Range> selectedRange = selection.toNormalizedRange(); |
| + if (!selectedRange) |
| + return m_layerTreeView->clearSelection(); |
| + |
| + WebSelection webSelection; |
| + |
| + RefPtrWillBeRawPtr<Range> range(Range::create(selectedRange->startContainer()->document(), |
| + selectedRange->startContainer(), |
| + selectedRange->startOffset(), |
| + selectedRange->startContainer(), |
| + selectedRange->startOffset())); |
| + IntRect anchor = frame->editor().firstRectForRange(range.get()); |
| + if (!computeCompositedLayerAndRect(selection.start().anchorNode(), |
| + anchor, |
| + webSelection.anchorLayerId, |
| + webSelection.anchorRectInLayer)) { |
| + return m_layerTreeView->clearSelection(); |
| + } |
| + |
| + range = Range::create(selectedRange->endContainer()->document(), |
| + selectedRange->endContainer(), |
| + selectedRange->endOffset(), |
| + selectedRange->endContainer(), |
| + selectedRange->endOffset()); |
| + IntRect focus = frame->editor().firstRectForRange(range.get()); |
| + if (!computeCompositedLayerAndRect(selection.end().anchorNode(), |
| + focus, |
| + webSelection.focusLayerId, |
| + webSelection.focusRectInLayer)) { |
| + return m_layerTreeView->clearSelection(); |
| + } |
| + |
| + // TODO(jdduke): Populate editable bounds. |
| + webSelection.type = WebSelection::TypeSelection; |
| + webSelection.anchorDirection = selection.start().primaryDirection() == RTL ? WebTextDirectionRightToLeft : WebTextDirectionLeftToRight; |
| + webSelection.focusDirection = selection.end().primaryDirection() == RTL ? WebTextDirectionRightToLeft : WebTextDirectionLeftToRight; |
| + webSelection.anchorIsFirst = selection.selection().isBaseFirst(); |
| + m_layerTreeView->registerSelection(webSelection); |
| +} |
| + |
| bool WebViewImpl::detectContentOnTouch(const WebPoint& position) |
| { |
| HitTestResult touchHit = hitTestResultForWindowPos(position); |