コード例 #1
0
FloatSize AutoscrollController::calculateAutoscrollDelta() {
  LocalFrame* frame = m_autoscrollLayoutObject->frame();
  if (!frame)
    return FloatSize();

  IntPoint lastKnownMousePosition =
      frame->eventHandler().lastKnownMousePosition();

  // We need to check if the last known mouse position is out of the window.
  // When the mouse is out of the window, the position is incoherent
  static IntPoint previousMousePosition;
  if (lastKnownMousePosition.x() < 0 || lastKnownMousePosition.y() < 0)
    lastKnownMousePosition = previousMousePosition;
  else
    previousMousePosition = lastKnownMousePosition;

  IntSize delta = lastKnownMousePosition - m_middleClickAutoscrollStartPos;

  // at the center we let the space for the icon.
  if (abs(delta.width()) <= noMiddleClickAutoscrollRadius)
    delta.setWidth(0);
  if (abs(delta.height()) <= noMiddleClickAutoscrollRadius)
    delta.setHeight(0);
  return FloatSize(adjustedScrollDelta(delta));
}
コード例 #2
0
void RenderLayerScrollableArea::setScrollOffset(const IntPoint& newScrollOffset)
{
    // Ensure that the dimensions will be computed if they need to be (for overflow:hidden blocks).
    if (m_scrollDimensionsDirty)
        computeScrollDimensions();

    if (scrollOffset() == toIntSize(newScrollOffset))
        return;

    setScrollOffset(toIntSize(newScrollOffset));

    LocalFrame* frame = box().frame();
    ASSERT(frame);

    RefPtr<FrameView> frameView = box().frameView();

    TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "ScrollLayer", "data", InspectorScrollLayerEvent::data(&box()));

    const RenderLayerModelObject* paintInvalidationContainer = box().containerForPaintInvalidation();

    // Update the positions of our child layers (if needed as only fixed layers should be impacted by a scroll).
    // We don't update compositing layers, because we need to do a deep update from the compositing ancestor.
    if (!frameView->isInPerformLayout()) {
        // If we're in the middle of layout, we'll just update layers once layout has finished.
        layer()->clipper().clearClipRectsIncludingDescendants();
        box().setPreviousPaintInvalidationRect(box().boundsRectForPaintInvalidation(paintInvalidationContainer));
        updateCompositingLayersAfterScroll();
    }

    // The caret rect needs to be invalidated after scrolling
    frame->selection().setCaretRectNeedsUpdate();

    FloatQuad quadForFakeMouseMoveEvent = FloatQuad(layer()->renderer()->previousPaintInvalidationRect());

    quadForFakeMouseMoveEvent = paintInvalidationContainer->localToAbsoluteQuad(quadForFakeMouseMoveEvent);
    frame->eventHandler().dispatchFakeMouseMoveEventSoonInQuad(quadForFakeMouseMoveEvent);

    // For querying RenderLayer::compositingState()
    // This code appears correct, since scrolling outside of layout happens during activities that do not dirty compositing state.
    DisableCompositingQueryAsserts disabler;
    if (box().frameView()->isInPerformLayout())
        box().setShouldDoFullPaintInvalidation(true);
    else
        box().invalidatePaintUsingContainer(paintInvalidationContainer, layer()->renderer()->previousPaintInvalidationRect(), InvalidationScroll);

    // Schedule the scroll DOM event.
    if (box().node())
        box().node()->document().enqueueScrollEventForNode(box().node());
}
コード例 #3
0
// Used to insert/replace text during composition update and confirm
// composition.
// Procedure:
//   1. Fire 'beforeinput' event for (TODO(chongz): deleted composed text) and
//      inserted text
//   2. Fire 'compositionupdate' event
//   3. Fire TextEvent and modify DOM
//   TODO(chongz): 4. Fire 'input' event
void insertTextDuringCompositionWithEvents(
    LocalFrame& frame,
    const String& text,
    TypingCommand::Options options,
    TypingCommand::TextCompositionType compositionType) {
  DCHECK(compositionType ==
             TypingCommand::TextCompositionType::TextCompositionUpdate ||
         compositionType ==
             TypingCommand::TextCompositionType::TextCompositionConfirm)
      << "compositionType should be TextCompositionUpdate or "
         "TextCompositionConfirm, but got "
      << static_cast<int>(compositionType);
  if (!frame.document())
    return;

  Element* target = frame.document()->focusedElement();
  if (!target)
    return;

  // TODO(chongz): Fire 'beforeinput' for the composed text being
  // replaced/deleted.

  // Only the last confirmed text is cancelable.
  InputEvent::EventCancelable beforeInputCancelable =
      (compositionType ==
       TypingCommand::TextCompositionType::TextCompositionUpdate)
          ? InputEvent::EventCancelable::NotCancelable
          : InputEvent::EventCancelable::IsCancelable;
  DispatchEventResult result = dispatchBeforeInputFromComposition(
      target, InputEvent::InputType::InsertText, text, beforeInputCancelable);

  if (beforeInputCancelable == InputEvent::EventCancelable::IsCancelable &&
      result != DispatchEventResult::NotCanceled)
    return;

  // 'beforeinput' event handler may destroy document.
  if (!frame.document())
    return;

  dispatchCompositionUpdateEvent(frame, text);
  // 'compositionupdate' event handler may destroy document.
  if (!frame.document())
    return;

  switch (compositionType) {
    case TypingCommand::TextCompositionType::TextCompositionUpdate:
      TypingCommand::insertText(*frame.document(), text, options,
                                compositionType);
      break;
    case TypingCommand::TextCompositionType::TextCompositionConfirm:
      // TODO(chongz): Use TypingCommand::insertText after TextEvent was
      // removed. (Removed from spec since 2012)
      // See TextEvent.idl.
      frame.eventHandler().handleTextInputEvent(text, 0,
                                                TextEventInputComposition);
      break;
    default:
      NOTREACHED();
  }
  // TODO(chongz): Fire 'input' event.
}
コード例 #4
0
static bool executeInsertNewline(LocalFrame& frame, Event* event, EditorCommandSource, const String&)
{
    LocalFrame* targetFrame = blink::targetFrame(frame, event);
    return targetFrame->eventHandler().handleTextInputEvent("\n", event, targetFrame->editor().canEditRichly() ? TextEventInputKeyboard : TextEventInputLineBreak);
}
コード例 #5
0
ファイル: TouchActionTest.cpp プロジェクト: mirror/chromium
void TouchActionTest::runTestOnTree(ContainerNode* root,
                                    WebView* webView,
                                    TouchActionTrackingWebViewClient& client) {
  // Find all elements to test the touch-action of in the document.
  TrackExceptionState es;

  // Oilpan: see runTouchActionTest() comment why these are persistent
  // references.
  Persistent<StaticElementList> elements =
      root->querySelectorAll("[expected-action]", es);
  ASSERT_FALSE(es.hadException());

  for (unsigned index = 0; index < elements->length(); index++) {
    Element* element = elements->item(index);
    element->scrollIntoViewIfNeeded();

    std::string failureContext("Test case: ");
    if (element->hasID()) {
      failureContext.append(element->getIdAttribute().ascii().data());
    } else if (element->firstChild()) {
      failureContext.append("\"");
      failureContext.append(element->firstChild()
                                ->textContent(false)
                                .stripWhiteSpace()
                                .ascii()
                                .data());
      failureContext.append("\"");
    } else {
      failureContext += "<missing ID>";
    }

    // Run each test three times at different positions in the element.
    // Note that we don't want the bounding box because our tests sometimes have
    // elements with multiple border boxes with other elements in between. Use
    // the first border box (which we can easily visualize in a browser for
    // debugging).
    Persistent<ClientRectList> rects = element->getClientRects();
    ASSERT_GE(rects->length(), 0u) << failureContext;
    Persistent<ClientRect> r = rects->item(0);
    FloatRect clientFloatRect =
        FloatRect(r->left(), r->top(), r->width(), r->height());
    IntRect clientRect = enclosedIntRect(clientFloatRect);
    for (int locIdx = 0; locIdx < 3; locIdx++) {
      IntPoint framePoint;
      std::stringstream contextStream;
      contextStream << failureContext << " (";
      switch (locIdx) {
        case 0:
          framePoint = clientRect.center();
          contextStream << "center";
          break;
        case 1:
          framePoint = clientRect.location();
          contextStream << "top-left";
          break;
        case 2:
          framePoint = clientRect.maxXMaxYCorner();
          framePoint.move(-1, -1);
          contextStream << "bottom-right";
          break;
        default:
          FAIL() << "Invalid location index.";
      }

      IntPoint windowPoint =
          root->document().frame()->view()->convertToRootFrame(framePoint);
      contextStream << "=" << windowPoint.x() << "," << windowPoint.y() << ").";
      std::string failureContextPos = contextStream.str();

      LocalFrame* mainFrame =
          static_cast<LocalFrame*>(webView->mainFrame()->toImplBase()->frame());
      FrameView* mainFrameView = mainFrame->view();
      IntRect visibleRect = windowClipRect(*mainFrameView);
      ASSERT_TRUE(visibleRect.contains(windowPoint))
          << failureContextPos
          << " Test point not contained in visible area: " << visibleRect.x()
          << "," << visibleRect.y() << "-" << visibleRect.maxX() << ","
          << visibleRect.maxY();

      // First validate that a hit test at this point will really hit the
      // element we intended. This is the easiest way for a test to be broken,
      // but has nothing really to do with touch action.  Note that we can't use
      // WebView's hit test API because it doesn't look into shadow DOM.
      IntPoint docPoint(mainFrameView->frameToContents(windowPoint));
      HitTestResult result = mainFrame->eventHandler().hitTestResultAtPoint(
          docPoint, HitTestRequest::ReadOnly | HitTestRequest::Active);
      ASSERT_EQ(element, result.innerElement())
          << "Unexpected hit test result " << failureContextPos
          << "  Got element: \""
          << result.innerElement()
                 ->outerHTML()
                 .stripWhiteSpace()
                 .left(80)
                 .ascii()
                 .data()
          << "\"" << std::endl
          << "Document render tree:" << std::endl
          << externalRepresentation(root->document().frame()).utf8().data();

      // Now send the touch event and check any touch action result.
      sendTouchEvent(webView, WebInputEvent::TouchStart, windowPoint);

      AtomicString expectedAction = element->getAttribute("expected-action");
      if (expectedAction == "auto") {
        // Auto is the default - no action set.
        EXPECT_EQ(0, client.touchActionSetCount()) << failureContextPos;
        EXPECT_EQ(WebTouchActionAuto, client.lastTouchAction())
            << failureContextPos;
      } else {
        // Should have received exactly one touch action.
        EXPECT_EQ(1, client.touchActionSetCount()) << failureContextPos;
        if (client.touchActionSetCount()) {
          if (expectedAction == "none") {
            EXPECT_EQ(WebTouchActionNone, client.lastTouchAction())
                << failureContextPos;
          } else if (expectedAction == "pan-x") {
            EXPECT_EQ(WebTouchActionPanX, client.lastTouchAction())
                << failureContextPos;
          } else if (expectedAction == "pan-y") {
            EXPECT_EQ(WebTouchActionPanY, client.lastTouchAction())
                << failureContextPos;
          } else if (expectedAction == "pan-x-y") {
            EXPECT_EQ((WebTouchActionPan), client.lastTouchAction())
                << failureContextPos;
          } else if (expectedAction == "manipulation") {
            EXPECT_EQ((WebTouchActionManipulation), client.lastTouchAction())
                << failureContextPos;
          } else {
            FAIL() << "Unrecognized expected-action \""
                   << expectedAction.ascii().data() << "\" "
                   << failureContextPos;
          }
        }
      }

      // Reset webview touch state.
      client.reset();
      sendTouchEvent(webView, WebInputEvent::TouchCancel, windowPoint);
      EXPECT_EQ(0, client.touchActionSetCount());
    }
  }
}
コード例 #6
0
bool PageWidgetEventHandler::handleTouchEvent(LocalFrame& mainFrame, const WebTouchEvent& event)
{
    return mainFrame.eventHandler().handleTouchEvent(PlatformTouchEventBuilder(mainFrame.view(), event));
}
コード例 #7
0
bool PageWidgetEventHandler::handleMouseWheel(LocalFrame& mainFrame, const WebMouseWheelEvent& event)
{
    return mainFrame.eventHandler().handleWheelEvent(PlatformWheelEventBuilder(mainFrame.view(), event));
}
コード例 #8
0
void PageWidgetEventHandler::handleMouseUp(LocalFrame& mainFrame, const WebMouseEvent& event)
{
    mainFrame.eventHandler().handleMouseReleaseEvent(PlatformMouseEventBuilder(mainFrame.view(), event));
}