Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(951)

Unified Diff: Source/web/WebViewImpl.cpp

Issue 302993003: Route selection bounds updates through WebLayerTreeView (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Attach to proper scrolling layer Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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);

Powered by Google App Engine
This is Rietveld 408576698