Exemple #1
0
// This test checks score calculations are correct.
TEST_F(DocumentStatisticsCollectorTest, CountScore) {
  setHtmlInnerHTML(
      "<p class='menu' id='article'>1</p>"  // textContentLength = 1
      "<ul><li><p>12</p></li></ul>"  // textContentLength = 2, skipped because
                                     // under li
      "<p class='menu'>123</p>"      // textContentLength = 3, skipped because
                                     // unlikelyCandidates
      "<p>"
      "12345678901234567890123456789012345678901234567890"
      "12345678901234567890123456789012345678901234567890"
      "12345678901234567890123456789012345678901234"
      "</p>"                               // textContentLength = 144
      "<p style='display:none'>12345</p>"  // textContentLength = 5, skipped
                                           // because invisible
      "<div style='display:none'><p>123456</p></div>"  // textContentLength = 6,
                                                       // skipped because
                                                       // invisible
      "<div style='visibility:hidden'><p>1234567</p></div>"  // textContentLength
                                                             // = 7, skipped
                                                             // because
                                                             // invisible
      "<p style='opacity:0'>12345678</p>"  // textContentLength = 8, skipped
                                           // because invisible
      "<p><a href='#'>1234 </a>6 <b> 9</b></p>"  // textContentLength = 9
      "<ul><li></li><p>123456789012</p></ul>"    // textContentLength = 12
      );
  WebDistillabilityFeatures features =
      DocumentStatisticsCollector::collectStatistics(document());

  EXPECT_DOUBLE_EQ(features.mozScore, sqrt(144 - kParagraphLengthThreshold));
  EXPECT_DOUBLE_EQ(features.mozScoreAllSqrt,
                   1 + sqrt(144) + sqrt(9) + sqrt(12));
  EXPECT_DOUBLE_EQ(features.mozScoreAllLinear, 1 + 144 + 9 + 12);
}
TEST_F(EventHandlerTest, multiClickSelectionFromTap)
{
    setHtmlInnerHTML("<style> body { margin: 0px; } .line { display: block; width: 300px; height: 30px; } </style>"
        "<body contenteditable='true'><span class='line' id='line'>One Two Three</span></body>");

    FrameSelection& selection = document().frame()->selection();
    Node* line = document().getElementById("line")->firstChild();

    TapEventBuilder singleTapEvent(IntPoint(0, 0), 1);
    document().frame()->eventHandler().handleGestureEvent(singleTapEvent);
    ASSERT_TRUE(selection.isCaret());
    EXPECT_EQ(Position(line, 0), selection.start());

    // Multi-tap events on editable elements should trigger selection, just
    // like multi-click events.
    TapEventBuilder doubleTapEvent(IntPoint(0, 0), 2);
    document().frame()->eventHandler().handleGestureEvent(doubleTapEvent);
    ASSERT_TRUE(selection.isRange());
    EXPECT_EQ(Position(line, 0), selection.start());
    if (document().frame()->editor().isSelectTrailingWhitespaceEnabled()) {
        EXPECT_EQ(Position(line, 4), selection.end());
        EXPECT_EQ("One ", WebString(selection.selectedText()).utf8());
    } else {
        EXPECT_EQ(Position(line, 3), selection.end());
        EXPECT_EQ("One", WebString(selection.selectedText()).utf8());
    }

    TapEventBuilder tripleTapEvent(IntPoint(0, 0), 3);
    document().frame()->eventHandler().handleGestureEvent(tripleTapEvent);
    ASSERT_TRUE(selection.isRange());
    EXPECT_EQ(Position(line, 0), selection.start());
    EXPECT_EQ(Position(line, 13), selection.end());
    EXPECT_EQ("One Two Three", WebString(selection.selectedText()).utf8());
}
// This tests that we properly resize and re-layout pages for printing in the presence of
// media queries effecting elements in a subtree layout boundary
TEST_F(DocumentTest, PrintRelayout)
{
    setHtmlInnerHTML(
        "<style>"
        "    div {"
        "        width: 100px;"
        "        height: 100px;"
        "        overflow: hidden;"
        "    }"
        "    span {"
        "        width: 50px;"
        "        height: 50px;"
        "    }"
        "    @media screen {"
        "        span {"
        "            width: 20px;"
        "        }"
        "    }"
        "</style>"
        "<p><div><span></span></div></p>");
    FloatSize pageSize(400, 400);
    float maximumShrinkRatio = 1.6;

    document().frame()->setPrinting(true, pageSize, pageSize, maximumShrinkRatio);
    EXPECT_EQ(document().documentElement()->offsetWidth(), 400);
    document().frame()->setPrinting(false, FloatSize(), FloatSize(), 0);
    EXPECT_EQ(document().documentElement()->offsetWidth(), 800);

}
TEST_F(LayoutThemeTest, ChangeFocusRingColor)
{
    setHtmlInnerHTML("<span id=span tabIndex=0>Span</span>");

    Element* span = document().getElementById(AtomicString("span"));
    EXPECT_NE(nullptr, span);
    EXPECT_NE(nullptr, span->layoutObject());

    Color customColor = makeRGB(123, 145, 167);

    // Checking unfocused style.
    EXPECT_EQ(BNONE, outlineStyle(span));
    EXPECT_NE(customColor, outlineColor(span));

    // Do focus.
    document().page()->focusController().setActive(true);
    document().page()->focusController().setFocused(true);
    span->focus();
    document().view()->updateAllLifecyclePhases();

    // Checking focused style.
    EXPECT_NE(BNONE, outlineStyle(span));
    EXPECT_NE(customColor, outlineColor(span));

    // Change focus ring color.
    LayoutTheme::theme().setCustomFocusRingColor(customColor);
    Page::platformColorsChanged();
    document().view()->updateAllLifecyclePhases();

    // Check that the focus ring color is updated.
    EXPECT_NE(BNONE, outlineStyle(span));
    EXPECT_EQ(customColor, outlineColor(span));
}
TEST_F(DocumentTest, StyleVersion)
{
    setHtmlInnerHTML(
        "<style>"
        "    .a * { color: green }"
        "    .b .c { color: green }"
        "</style>"
        "<div id='x'><span class='c'></span></div>");

    Element* element = document().getElementById("x");
    EXPECT_TRUE(element);

    uint64_t previousStyleVersion = document().styleVersion();
    element->setAttribute(blink::HTMLNames::classAttr, "notfound");
    EXPECT_EQ(previousStyleVersion, document().styleVersion());

    document().view()->updateAllLifecyclePhases();

    previousStyleVersion = document().styleVersion();
    element->setAttribute(blink::HTMLNames::classAttr, "a");
    EXPECT_NE(previousStyleVersion, document().styleVersion());

    document().view()->updateAllLifecyclePhases();

    previousStyleVersion = document().styleVersion();
    element->setAttribute(blink::HTMLNames::classAttr, "a b");
    EXPECT_NE(previousStyleVersion, document().styleVersion());
}
TEST_F(EventHandlerTest, draggedSVGImagePositionTest)
{
    setHtmlInnerHTML(
        "<style>"
        "body { margin: 0px; }"
        "[draggable] {"
        "-webkit-user-select: none; user-select: none; -webkit-user-drag: element; }"
        "</style>"
        "<div style='width: 300px; height: 100px;'>"
        "<svg width='500' height='500'>"
        "<rect x='100' y='100' width='100px' height='100px' fill='blue' draggable='true'/>"
        "</svg>"
        "</div>");
    PlatformMouseEvent mouseDownEvent(
        IntPoint(145, 144),
        IntPoint(212, 282),
        LeftButton,
        PlatformEvent::MousePressed,
        1,
        PlatformEvent::Modifiers::LeftButtonDown,
        WTF::monotonicallyIncreasingTime());
    document().frame()->eventHandler().handleMousePressEvent(mouseDownEvent);

    PlatformMouseEvent mouseMoveEvent(
        IntPoint(618, 298),
        IntPoint(685, 436),
        LeftButton,
        PlatformEvent::MouseMoved,
        1,
        PlatformEvent::Modifiers::LeftButtonDown,
        WTF::monotonicallyIncreasingTime());
    document().frame()->eventHandler().handleMouseMoveEvent(mouseMoveEvent);

    EXPECT_EQ(IntPoint(45, 44), document().frame()->eventHandler().dragDataTransferLocationForTesting());
}
TEST_F(EventHandlerTest, draggedInlinePositionTest)
{
    setHtmlInnerHTML(
        "<style>"
        "body { margin: 0px; }"
        ".line { font-family: sans-serif; background: blue; width: 300px; height: 30px; font-size: 40px; margin-left: 250px; }"
        "</style>"
        "<div style='width: 300px; height: 100px;'>"
        "<span class='line' draggable='true'>abcd</span>"
        "</div>");
    PlatformMouseEvent mouseDownEvent(
        IntPoint(262, 29),
        IntPoint(329, 67),
        LeftButton,
        PlatformEvent::MousePressed,
        1,
        PlatformEvent::Modifiers::LeftButtonDown,
        WTF::monotonicallyIncreasingTime());
    document().frame()->eventHandler().handleMousePressEvent(mouseDownEvent);

    PlatformMouseEvent mouseMoveEvent(
        IntPoint(618, 298),
        IntPoint(685, 436),
        LeftButton,
        PlatformEvent::MouseMoved,
        1,
        PlatformEvent::Modifiers::LeftButtonDown,
        WTF::monotonicallyIncreasingTime());
    document().frame()->eventHandler().handleMouseMoveEvent(mouseMoveEvent);

    EXPECT_EQ(IntPoint(12, 29), document().frame()->eventHandler().dragDataTransferLocationForTesting());
}
Exemple #8
0
TEST_F(EventHandlerTest, multiClickSelectionFromTapDisabledIfNotEditable) {
  setHtmlInnerHTML(
      "<style> body { margin: 0px; } .line { display: block; width: 300px; "
      "height: 30px; } </style>"
      "<span class='line' id='line'>One Two Three</span>");

  FrameSelection& selection = document().frame()->selection();
  Node* line = document().getElementById("line")->firstChild();

  TapEventBuilder singleTapEvent(IntPoint(0, 0), 1);
  document().frame()->eventHandler().handleGestureEvent(singleTapEvent);
  ASSERT_TRUE(selection.isCaret());
  EXPECT_EQ(Position(line, 0), selection.start());

  // As the text is readonly, multi-tap events should not trigger selection.
  TapEventBuilder doubleTapEvent(IntPoint(0, 0), 2);
  document().frame()->eventHandler().handleGestureEvent(doubleTapEvent);
  ASSERT_TRUE(selection.isCaret());
  EXPECT_EQ(Position(line, 0), selection.start());

  TapEventBuilder tripleTapEvent(IntPoint(0, 0), 3);
  document().frame()->eventHandler().handleGestureEvent(tripleTapEvent);
  ASSERT_TRUE(selection.isCaret());
  EXPECT_EQ(Position(line, 0), selection.start());
}
Exemple #9
0
// This test checks non-existence of open graph articles can be recognized.
TEST_F(DocumentStatisticsCollectorTest, NoOpenGraphArticle) {
  setHtmlInnerHTML(
      "<head>"
      "    <meta property='og:type' content='movie' />"
      "</head>");
  WebDistillabilityFeatures features =
      DocumentStatisticsCollector::collectStatistics(document());

  EXPECT_FALSE(features.openGraph);
}
Exemple #10
0
// This test checks open graph articles can be recognized.
TEST_F(DocumentStatisticsCollectorTest, HasOpenGraphArticle) {
  setHtmlInnerHTML(
      "<head>"
      // Note the case-insensitive matching of the word "article".
      "    <meta property='og:type' content='arTiclE' />"
      "</head>");
  WebDistillabilityFeatures features =
      DocumentStatisticsCollector::collectStatistics(document());

  EXPECT_TRUE(features.openGraph);
}
TEST_F(EventHandlerTest, dragSelectionAfterScroll)
{
    setHtmlInnerHTML("<style> body { margin: 0px; } .upper { width: 300px; height: 400px; }"
        ".lower { margin: 0px; width: 300px; height: 400px; } .line { display: block; width: 300px; height: 30px; } </style>"
        "<div class='upper'></div>"
        "<div class='lower'>"
        "<span class='line'>Line 1</span><span class='line'>Line 2</span><span class='line'>Line 3</span><span class='line'>Line 4</span><span class='line'>Line 5</span>"
        "<span class='line'>Line 6</span><span class='line'>Line 7</span><span class='line'>Line 8</span><span class='line'>Line 9</span><span class='line'>Line 10</span>"
        "</div>");

    FrameView* frameView = document().view();
    frameView->scrollTo(DoublePoint(0, 400));

    PlatformMouseEvent mouseDownEvent(
        IntPoint(0, 0),
        IntPoint(100, 200),
        LeftButton,
        PlatformEvent::MousePressed,
        1,
        static_cast<PlatformEvent::Modifiers>(0),
        WTF::currentTime());
    document().frame()->eventHandler().handleMousePressEvent(mouseDownEvent);

    PlatformMouseEvent mouseMoveEvent(
        IntPoint(100, 50),
        IntPoint(200, 250),
        LeftButton,
        PlatformEvent::MouseMoved,
        1,
        static_cast<PlatformEvent::Modifiers>(0),
        WTF::currentTime());
    document().frame()->eventHandler().handleMouseMoveEvent(mouseMoveEvent);

    page().autoscrollController().animate(WTF::currentTime());
    page().animator().serviceScriptedAnimations(WTF::currentTime());

    PlatformMouseEvent mouseUpEvent(
        IntPoint(100, 50),
        IntPoint(200, 250),
        LeftButton,
        PlatformEvent::MouseReleased,
        1,
        static_cast<PlatformEvent::Modifiers>(0),
        WTF::currentTime());
    document().frame()->eventHandler().handleMouseReleaseEvent(mouseUpEvent);

    FrameSelection& selection = document().frame()->selection();
    ASSERT_TRUE(selection.isRange());
    RefPtrWillBeRawPtr<Range> range = createRange(selection.selection().toNormalizedEphemeralRange());
    ASSERT_TRUE(range.get());
    EXPECT_EQ("Line 1\nLine 2", range->text());
}
Exemple #12
0
TEST_F(EventHandlerTest, dragSelectionAfterScroll) {
  setHtmlInnerHTML(
      "<style> body { margin: 0px; } .upper { width: 300px; height: 400px; }"
      ".lower { margin: 0px; width: 300px; height: 400px; } .line { display: "
      "block; width: 300px; height: 30px; } </style>"
      "<div class='upper'></div>"
      "<div class='lower'>"
      "<span class='line'>Line 1</span><span class='line'>Line 2</span><span "
      "class='line'>Line 3</span><span class='line'>Line 4</span><span "
      "class='line'>Line 5</span>"
      "<span class='line'>Line 6</span><span class='line'>Line 7</span><span "
      "class='line'>Line 8</span><span class='line'>Line 9</span><span "
      "class='line'>Line 10</span>"
      "</div>");

  FrameView* frameView = document().view();
  frameView->layoutViewportScrollableArea()->setScrollOffset(
      ScrollOffset(0, 400), ProgrammaticScroll);

  PlatformMouseEvent mouseDownEvent(
      IntPoint(0, 0), IntPoint(100, 200), WebPointerProperties::Button::Left,
      PlatformEvent::MousePressed, 1, PlatformEvent::Modifiers::LeftButtonDown,
      WTF::monotonicallyIncreasingTime());
  document().frame()->eventHandler().handleMousePressEvent(mouseDownEvent);

  PlatformMouseEvent mouseMoveEvent(
      IntPoint(100, 50), IntPoint(200, 250), WebPointerProperties::Button::Left,
      PlatformEvent::MouseMoved, 1, PlatformEvent::Modifiers::LeftButtonDown,
      WTF::monotonicallyIncreasingTime());
  document().frame()->eventHandler().handleMouseMoveEvent(
      mouseMoveEvent, Vector<PlatformMouseEvent>());

  page().autoscrollController().animate(WTF::monotonicallyIncreasingTime());
  page().animator().serviceScriptedAnimations(
      WTF::monotonicallyIncreasingTime());

  PlatformMouseEvent mouseUpEvent(
      IntPoint(100, 50), IntPoint(200, 250), WebPointerProperties::Button::Left,
      PlatformEvent::MouseReleased, 1, static_cast<PlatformEvent::Modifiers>(0),
      WTF::monotonicallyIncreasingTime());
  document().frame()->eventHandler().handleMouseReleaseEvent(mouseUpEvent);

  FrameSelection& selection = document().frame()->selection();
  ASSERT_TRUE(selection.isRange());
  Range* range =
      createRange(selection.selection().toNormalizedEphemeralRange());
  ASSERT_TRUE(range);
  EXPECT_EQ("Line 1\nLine 2", range->text());
}
Exemple #13
0
// This test checks element counts are correct.
TEST_F(DocumentStatisticsCollectorTest, CountElements) {
  setHtmlInnerHTML(
      "<form>"
      "    <input type='text'>"
      "    <input type='password'>"
      "</form>"
      "<pre></pre>"
      "<p><a>    </a></p>"
      "<ul><li><p><a>    </a></p></li></ul>");
  WebDistillabilityFeatures features =
      DocumentStatisticsCollector::collectStatistics(document());

  EXPECT_FALSE(features.openGraph);

  EXPECT_EQ(10u, features.elementCount);
  EXPECT_EQ(2u, features.anchorCount);
  EXPECT_EQ(1u, features.formCount);
  EXPECT_EQ(1u, features.textInputCount);
  EXPECT_EQ(1u, features.passwordInputCount);
  EXPECT_EQ(2u, features.pCount);
  EXPECT_EQ(1u, features.preCount);
}
Exemple #14
0
// This test checks saturation of score calculations is correct.
TEST_F(DocumentStatisticsCollectorTest, CountScoreSaturation) {
  StringBuilder html;
  for (int i = 0; i < 10; i++) {
    html.append("<p>");
    for (int j = 0; j < 1000; j++) {
      html.append("0123456789");
    }
    html.append("</p>");
  }
  setHtmlInnerHTML(html.toString());
  WebDistillabilityFeatures features =
      DocumentStatisticsCollector::collectStatistics(document());

  double error = 1e-5;
  EXPECT_NEAR(features.mozScore, 6 * sqrt(kTextContentLengthSaturation -
                                          kParagraphLengthThreshold),
              error);
  EXPECT_NEAR(features.mozScoreAllSqrt, 6 * sqrt(kTextContentLengthSaturation),
              error);
  EXPECT_NEAR(features.mozScoreAllLinear, 6 * kTextContentLengthSaturation,
              error);
}
// This tests that we mark Frame Timing requests as dirty correctly when we
// update style.
TEST_F(DocumentTest, FrameTimingRelayout)
{
    setHtmlInnerHTML(
        "<style>"
        "    #div1 {"
        "        width: 100px;"
        "        height: 100px;"
        "    }"
        "</style>"
        "<p><div id='div1'><span>test</span></div></p>");

    EXPECT_FALSE(document().view()->frameTimingRequestsDirty());

    // Just calling update should have no effect.
    document().updateLayoutTreeIfNeeded();
    EXPECT_FALSE(document().view()->frameTimingRequestsDirty());

    // Calling update with a style change should flag Frame Timing as dirty.
    document().setChildNeedsStyleRecalc();
    document().updateLayoutTreeIfNeeded();
    EXPECT_TRUE(document().view()->frameTimingRequestsDirty());
}
Exemple #16
0
// Regression test for http://crbug.com/641403 to verify we use up-to-date
// layout tree for dispatching "contextmenu" event.
TEST_F(EventHandlerTest, sendContextMenuEventWithHover) {
  setHtmlInnerHTML(
      "<style>*:hover { color: red; }</style>"
      "<div>foo</div>");
  document().settings()->setScriptEnabled(true);
  Element* script = document().createElement("script");
  script->setInnerHTML(
      "document.addEventListener('contextmenu', event => "
      "event.preventDefault());");
  document().body()->appendChild(script);
  document().updateStyleAndLayout();
  document().frame()->selection().setSelection(
      SelectionInDOMTree::Builder()
          .collapse(Position(document().body(), 0))
          .build());
  PlatformMouseEvent mouseDownEvent(
      IntPoint(0, 0), IntPoint(100, 200), WebPointerProperties::Button::Right,
      PlatformEvent::MousePressed, 1, PlatformEvent::Modifiers::RightButtonDown,
      WTF::monotonicallyIncreasingTime());
  EXPECT_EQ(
      WebInputEventResult::HandledApplication,
      document().frame()->eventHandler().sendContextMenuEvent(mouseDownEvent));
}