Esempio n. 1
0
bool VisualViewport::magnifyScaleAroundAnchor(float magnifyDelta,
                                              const FloatPoint& anchor) {
  const float oldPageScale = scale();
  const float newPageScale =
      frameHost().chromeClient().clampPageScaleFactorToLimits(magnifyDelta *
                                                              oldPageScale);
  if (newPageScale == oldPageScale)
    return false;
  if (!mainFrame() || !mainFrame()->view())
    return false;

  // Keep the center-of-pinch anchor in a stable position over the course
  // of the magnify.
  FloatPoint anchorAtOldScale = anchor.scaledBy(1.f / oldPageScale);
  FloatPoint anchorAtNewScale = anchor.scaledBy(1.f / newPageScale);
  FloatSize anchorDelta = anchorAtOldScale - anchorAtNewScale;

  // First try to use the anchor's delta to scroll the FrameView.
  FloatSize anchorDeltaUnusedByScroll = anchorDelta;

  // Manually bubble any remaining anchor delta up to the visual viewport.
  FloatPoint newLocation(FloatPoint(getScrollOffset()) +
                         anchorDeltaUnusedByScroll);
  setScaleAndLocation(newPageScale, newLocation);
  return true;
}
bool VisualViewport::magnifyScaleAroundAnchor(float magnifyDelta, const FloatPoint& anchor)
{
    const float oldPageScale = scale();
    const float newPageScale = frameHost().chromeClient().clampPageScaleFactorToLimits(
        magnifyDelta * oldPageScale);
    if (newPageScale == oldPageScale)
        return false;
    if (!mainFrame() || !mainFrame()->view())
        return false;

    // Keep the center-of-pinch anchor in a stable position over the course
    // of the magnify.
    FloatPoint anchorAtOldScale = anchor.scaledBy(1.f / oldPageScale);
    FloatPoint anchorAtNewScale = anchor.scaledBy(1.f / newPageScale);
    FloatSize anchorDelta = anchorAtOldScale - anchorAtNewScale;

    // First try to use the anchor's delta to scroll the FrameView.
    FloatSize anchorDeltaUnusedByScroll = anchorDelta;

    if (!frameHost().settings().invertViewportScrollOrder()) {
        FrameView* view = mainFrame()->view();
        DoublePoint oldPosition = view->scrollPositionDouble();
        view->scrollBy(DoubleSize(anchorDelta.width(), anchorDelta.height()), UserScroll);
        DoublePoint newPosition = view->scrollPositionDouble();
        anchorDeltaUnusedByScroll -= toFloatSize(newPosition - oldPosition);
    }

    // Manually bubble any remaining anchor delta up to the visual viewport.
    FloatPoint newLocation(location() + anchorDeltaUnusedByScroll);
    setScaleAndLocation(newPageScale, newLocation);
    return true;
}
Esempio n. 3
0
void TouchEventManager::setAllPropertiesOfTouchInfos(
    HeapVector<TouchInfo>& touchInfos)
{
    for (auto& touchInfo : touchInfos) {
        PlatformTouchPoint::TouchState pointState = touchInfo.point.state();
        Node* touchNode = nullptr;
        String regionID;

        if (pointState == PlatformTouchPoint::TouchReleased
            || pointState == PlatformTouchPoint::TouchCancelled) {
            // The target should be the original target for this touch, so get
            // it from the hashmap. As it's a release or cancel we also remove
            // it from the map.
            touchNode = m_targetForTouchID.take(touchInfo.point.id());
            regionID = m_regionForTouchID.take(touchInfo.point.id());
        } else {
            // No hittest is performed on move or stationary, since the target
            // is not allowed to change anyway.
            touchNode = m_targetForTouchID.get(touchInfo.point.id());
            regionID = m_regionForTouchID.get(touchInfo.point.id());
        }

        LocalFrame* targetFrame = nullptr;
        bool knownTarget = false;
        if (touchNode) {
            Document& doc = touchNode->document();
            // If the target node has moved to a new document while it was being touched,
            // we can't send events to the new document because that could leak nodes
            // from one document to another. See http://crbug.com/394339.
            if (&doc == m_touchSequenceDocument.get()) {
                targetFrame = doc.frame();
                knownTarget = true;
            }
        }
        if (!knownTarget) {
            // If we don't have a target registered for the point it means we've
            // missed our opportunity to do a hit test for it (due to some
            // optimization that prevented blink from ever seeing the
            // touchstart), or that the touch started outside the active touch
            // sequence document. We should still include the touch in the
            // Touches list reported to the application (eg. so it can
            // differentiate between a one and two finger gesture), but we won't
            // actually dispatch any events for it. Set the target to the
            // Document so that there's some valid node here. Perhaps this
            // should really be LocalDOMWindow, but in all other cases the target of
            // a Touch is a Node so using the window could be a breaking change.
            // Since we know there was no handler invoked, the specific target
            // should be completely irrelevant to the application.
            touchNode = m_touchSequenceDocument;
            targetFrame = m_touchSequenceDocument->frame();
        }
        ASSERT(targetFrame);

        // pagePoint should always be in the target element's document coordinates.
        FloatPoint pagePoint = targetFrame->view()->rootFrameToContents(
            touchInfo.point.pos());
        float scaleFactor = 1.0f / targetFrame->pageZoomFactor();

        touchInfo.touchNode = touchNode;
        touchInfo.targetFrame = targetFrame;
        touchInfo.contentPoint = pagePoint.scaledBy(scaleFactor);
        touchInfo.adjustedRadius = touchInfo.point.radius().scaledBy(scaleFactor);
        touchInfo.knownTarget = knownTarget;
        touchInfo.consumed = false;
        touchInfo.region = regionID;
    }
}