Commit 6e0111a9 authored by Yoichi Osato's avatar Yoichi Osato Committed by Commit Bot

Let LayoutSelection visit children of display:content element.

We stopped traversal flat tree when Node didn't have a LayoutObject
but Slot elements appear in the tree w/o LayoutObject.
This patch enables LayoutSelection to visit children of
such elements.

Bug: 870734
Cq-Include-Trybots: luci.chromium.try:linux_layout_tests_layout_ng
Change-Id: Id4f7c135fceead131f37485ecb8fa326834d72c3
Reviewed-on: https://chromium-review.googlesource.com/1164724Reviewed-by: default avatarYoshifumi Inoue <yosin@chromium.org>
Commit-Queue: Yoichi Osato <yoichio@chromium.org>
Cr-Commit-Position: refs/heads/master@{#581825}
parent e9599a62
......@@ -22,6 +22,7 @@
#include "third_party/blink/renderer/core/editing/layout_selection.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/editing/editing_utilities.h"
#include "third_party/blink/renderer/core/editing/ephemeral_range.h"
#include "third_party/blink/renderer/core/editing/frame_selection.h"
......@@ -293,19 +294,30 @@ static LayoutTextFragment* FirstLetterPartFor(
return nullptr;
}
static bool IsDisplayContentElement(const Node& node) {
if (!node.IsElementNode())
return false;
const ComputedStyle* const style = node.GetComputedStyle();
return style && style->Display() == EDisplay::kContents;
}
template <typename Visitor>
static void VisitSelectedInclusiveDescendantsOfInternal(const Node& node,
Visitor* visitor) {
LayoutObject* layout_object = node.GetLayoutObject();
if (!layout_object)
return;
if (LayoutTextFragment* first_letter = FirstLetterPartFor(layout_object)) {
if (first_letter->GetSelectionState() != SelectionState::kNone)
visitor->Visit(first_letter);
// Display:content element appears in a flat tree even it doesn't have
// a LayoutObject but we need to visit its children.
if (!IsDisplayContentElement(node)) {
LayoutObject* layout_object = node.GetLayoutObject();
if (!layout_object)
return;
if (LayoutTextFragment* first_letter = FirstLetterPartFor(layout_object)) {
if (first_letter->GetSelectionState() != SelectionState::kNone)
visitor->Visit(first_letter);
}
if (layout_object->GetSelectionState() == SelectionState::kNone)
return;
visitor->Visit(layout_object);
}
if (layout_object->GetSelectionState() == SelectionState::kNone)
return;
visitor->Visit(layout_object);
for (Node& child : FlatTreeTraversal::ChildrenOf(node))
VisitSelectedInclusiveDescendantsOfInternal(child, visitor);
......
......@@ -850,6 +850,35 @@ TEST_F(LayoutSelectionTest, MoveNode) {
DumpSelectionInfo());
}
// http://crbug.com/870734
TEST_F(LayoutSelectionTest, InvalidateSlot) {
Selection().SetSelectionAndEndTyping(
SetSelectionTextToBody("^<div>"
"<template data-mode=open>"
"<slot></slot>"
"</template>"
"foo"
"</div>|"));
UpdateAllLifecyclePhases();
EXPECT_EQ(
"BODY, Contain, NotInvalidate \n"
" DIV, Contain, NotInvalidate \n"
" #shadow-root \n"
" SLOT, <null LayoutObject> \n"
" 'foo', StartAndEnd, NotInvalidate ",
DumpSelectionInfo());
Selection().Clear();
Selection().CommitAppearanceIfNeeded();
EXPECT_EQ(
"BODY, None, NotInvalidate \n"
" DIV, None, NotInvalidate \n"
" #shadow-root \n"
" SLOT, <null LayoutObject> \n"
" 'foo', None, ShouldInvalidate ",
DumpSelectionInfo());
}
static const NGPaintFragment* FindNGPaintFragmentInternal(
const NGPaintFragment* paint,
const LayoutObject* layout_object) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment