Text insertion cursor disappears after pressing enter
https://bugs.webkit.org/show_bug.cgi?id=169291
<rdar://problem/30899611>
Reviewed by Tim Horton.
Source/WebCore:
Positon upstream/downstream (as the result of VisiblePosition -> canonicalPosition) require
linebox tree. In addition to regular text, we need to bail out of simple line layout on line breaks too.
Test: editing/simple-line-layout-caret-is-gone.html
* dom/Position.cpp:
(WebCore::ensureLineBoxesIfNeeded):
(WebCore::Position::upstream):
(WebCore::Position::downstream):
(WebCore::Position::getInlineBoxAndOffset):
* rendering/RenderLineBreak.cpp:
(WebCore::RenderLineBreak::ensureLineBoxes):
(WebCore::RenderLineBreak::positionForPoint):
(WebCore::RenderLineBreak::setSelectionState):
(WebCore::RenderLineBreak::collectSelectionRects):
(WebCore::ensureLineBoxes): Deleted.
* rendering/RenderLineBreak.h:
LayoutTests:
* editing/simple-line-layout-caret-is-gone-expected.txt: Added.
* editing/simple-line-layout-caret-is-gone.html: Added.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@215094 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 78e21a9..76581ee 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,14 @@
+2017-04-07 Zalan Bujtas <zalan@apple.com>
+
+ Text insertion cursor disappears after pressing enter
+ https://bugs.webkit.org/show_bug.cgi?id=169291
+ <rdar://problem/30899611>
+
+ Reviewed by Tim Horton.
+
+ * editing/simple-line-layout-caret-is-gone-expected.txt: Added.
+ * editing/simple-line-layout-caret-is-gone.html: Added.
+
2017-04-06 Myles C. Maxfield <mmaxfield@apple.com>
Make FontWithFeatures test font pass OTS
diff --git a/LayoutTests/editing/simple-line-layout-caret-is-gone-expected.txt b/LayoutTests/editing/simple-line-layout-caret-is-gone-expected.txt
new file mode 100644
index 0000000..ca48f3d
--- /dev/null
+++ b/LayoutTests/editing/simple-line-layout-caret-is-gone-expected.txt
@@ -0,0 +1 @@
+36 0 1 18
diff --git a/LayoutTests/editing/simple-line-layout-caret-is-gone.html b/LayoutTests/editing/simple-line-layout-caret-is-gone.html
new file mode 100644
index 0000000..783e945
--- /dev/null
+++ b/LayoutTests/editing/simple-line-layout-caret-is-gone.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>This tests that contenteditable returns the correct caret bounds.</title>
+<style>
+body {
+ margin: 0px;
+}
+
+#editable {
+ -webkit-nbsp-mode: normal !important;
+ -webkit-line-break: auto !important;
+ width: 50px;
+ height: 50px;
+}
+</style>
+</head>
+<body>
+<div id=editable contenteditable=true></div>
+<script>
+editable.focus();
+if (window.testRunner)
+ testRunner.dumpAsText();
+if (window.eventSender) {
+ eventSender.keyDown('\n');
+ eventSender.keyDown('\n');
+}
+if (window.internals) {
+ var withTextCaretRect = internals.absoluteCaretBounds();
+ document.body.innerText = withTextCaretRect.top + " " + withTextCaretRect.left + " " + withTextCaretRect.width + " " + withTextCaretRect.height;
+}
+</script>
+</body>
+</html>
diff --git a/LayoutTests/platform/ios/editing/simple-line-layout-caret-is-gone-expected.txt b/LayoutTests/platform/ios/editing/simple-line-layout-caret-is-gone-expected.txt
new file mode 100644
index 0000000..13620c0
--- /dev/null
+++ b/LayoutTests/platform/ios/editing/simple-line-layout-caret-is-gone-expected.txt
@@ -0,0 +1 @@
+0 0 2 20
diff --git a/LayoutTests/platform/mac/editing/pasteboard/5761530-1-expected.txt b/LayoutTests/platform/mac/editing/pasteboard/5761530-1-expected.txt
index e61026e..90085db 100644
--- a/LayoutTests/platform/mac/editing/pasteboard/5761530-1-expected.txt
+++ b/LayoutTests/platform/mac/editing/pasteboard/5761530-1-expected.txt
@@ -1,3 +1,3 @@
This tests to see that tabs are put into tab spans when they are copied individually. The pasted tab should be inside of a tab span, not a style span. To run the test manually, paste and then inspect the editable region, and ensure that there is a tab span at the beginning of the editable div.
-<span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space:pre;"> </span>xxx
+<span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space:pre;"> </span>xxx
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index e0d43b1..13fffc3 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,29 @@
+2017-04-07 Zalan Bujtas <zalan@apple.com>
+
+ Text insertion cursor disappears after pressing enter
+ https://bugs.webkit.org/show_bug.cgi?id=169291
+ <rdar://problem/30899611>
+
+ Reviewed by Tim Horton.
+
+ Positon upstream/downstream (as the result of VisiblePosition -> canonicalPosition) require
+ linebox tree. In addition to regular text, we need to bail out of simple line layout on line breaks too.
+
+ Test: editing/simple-line-layout-caret-is-gone.html
+
+ * dom/Position.cpp:
+ (WebCore::ensureLineBoxesIfNeeded):
+ (WebCore::Position::upstream):
+ (WebCore::Position::downstream):
+ (WebCore::Position::getInlineBoxAndOffset):
+ * rendering/RenderLineBreak.cpp:
+ (WebCore::RenderLineBreak::ensureLineBoxes):
+ (WebCore::RenderLineBreak::positionForPoint):
+ (WebCore::RenderLineBreak::setSelectionState):
+ (WebCore::RenderLineBreak::collectSelectionRects):
+ (WebCore::ensureLineBoxes): Deleted.
+ * rendering/RenderLineBreak.h:
+
2017-04-07 Xan Lopez <xlopez@igalia.com>
[GTK] Fix codec name in OWR ASSERT
diff --git a/Source/WebCore/dom/Position.cpp b/Source/WebCore/dom/Position.cpp
index e0c6338..b6f5575 100644
--- a/Source/WebCore/dom/Position.cpp
+++ b/Source/WebCore/dom/Position.cpp
@@ -634,6 +634,13 @@
return pos.atStartOfNode();
}
+static void ensureLineBoxesIfNeeded(RenderObject& renderer)
+{
+ if (!is<RenderText>(renderer) && !is<RenderLineBreak>(renderer))
+ return;
+ is<RenderText>(renderer) ? downcast<RenderText>(renderer).ensureLineBoxes() : downcast<RenderLineBreak>(renderer).ensureLineBoxes();
+}
+
// This function and downstream() are used for moving back and forth between visually equivalent candidates.
// For example, for the text node "foo bar" where whitespace is collapsible, there are two candidates
// that map to the VisiblePosition between 'b' and the space. This function will return the left candidate
@@ -679,7 +686,7 @@
RenderObject* renderer = currentNode.renderer();
if (!renderer || renderer->style().visibility() != VISIBLE)
continue;
-
+ ensureLineBoxesIfNeeded(*renderer);
if (rule == CanCrossEditingBoundary && boundaryCrossed) {
lastVisible = currentPosition;
break;
@@ -704,8 +711,6 @@
// return current position if it is in rendered text
if (is<RenderText>(*renderer)) {
auto& textRenderer = downcast<RenderText>(*renderer);
- textRenderer.ensureLineBoxes();
-
if (!textRenderer.firstTextBox())
continue;
if (¤tNode != startNode) {
@@ -816,7 +821,7 @@
auto* renderer = currentNode.renderer();
if (!renderer || renderer->style().visibility() != VISIBLE)
continue;
-
+ ensureLineBoxesIfNeeded(*renderer);
if (rule == CanCrossEditingBoundary && boundaryCrossed) {
lastVisible = currentPosition;
break;
@@ -836,8 +841,6 @@
// return current position if it is in rendered text
if (is<RenderText>(*renderer)) {
auto& textRenderer = downcast<RenderText>(*renderer);
- textRenderer.ensureLineBoxes();
-
if (!textRenderer.firstTextBox())
continue;
if (¤tNode != startNode) {
@@ -1230,9 +1233,11 @@
caretOffset = deprecatedEditingOffset();
RenderObject* renderer = deprecatedNode()->renderer();
- if (renderer->isBR())
- inlineBox = !caretOffset ? downcast<RenderLineBreak>(*renderer).inlineBoxWrapper() : nullptr;
- else if (is<RenderText>(*renderer)) {
+ if (renderer->isBR()) {
+ auto& lineBreakRenderer = downcast<RenderLineBreak>(*renderer);
+ lineBreakRenderer.ensureLineBoxes();
+ inlineBox = !caretOffset ? lineBreakRenderer.inlineBoxWrapper() : nullptr;
+ } else if (is<RenderText>(*renderer)) {
auto& textRenderer = downcast<RenderText>(*renderer);
textRenderer.ensureLineBoxes();
diff --git a/Source/WebCore/rendering/RenderLineBreak.cpp b/Source/WebCore/rendering/RenderLineBreak.cpp
index b819980..dced326 100644
--- a/Source/WebCore/rendering/RenderLineBreak.cpp
+++ b/Source/WebCore/rendering/RenderLineBreak.cpp
@@ -48,13 +48,6 @@
return downcast<RenderBlockFlow>(*renderer.parent()).simpleLineLayout();
}
-static void ensureLineBoxes(const RenderLineBreak& renderer)
-{
- if (!is<RenderBlockFlow>(*renderer.parent()))
- return;
- downcast<RenderBlockFlow>(*renderer.parent()).ensureLineBoxes();
-}
-
RenderLineBreak::RenderLineBreak(HTMLElement& element, RenderStyle&& style)
: RenderBoxModelObject(element, WTFMove(style), 0)
, m_inlineBoxWrapper(nullptr)
@@ -129,6 +122,13 @@
m_inlineBoxWrapper->dirtyLineBoxes();
}
+void RenderLineBreak::ensureLineBoxes()
+{
+ if (!is<RenderBlockFlow>(*parent()))
+ return;
+ downcast<RenderBlockFlow>(*parent()).ensureLineBoxes();
+}
+
void RenderLineBreak::deleteLineBoxesBeforeSimpleLineLayout()
{
delete m_inlineBoxWrapper;
@@ -152,14 +152,14 @@
VisiblePosition RenderLineBreak::positionForPoint(const LayoutPoint&, const RenderRegion*)
{
- ensureLineBoxes(*this);
+ ensureLineBoxes();
return createVisiblePosition(0, DOWNSTREAM);
}
void RenderLineBreak::setSelectionState(SelectionState state)
{
if (state != SelectionNone)
- ensureLineBoxes(*this);
+ ensureLineBoxes();
RenderBoxModelObject::setSelectionState(state);
if (!m_inlineBoxWrapper)
return;
@@ -228,7 +228,7 @@
#if PLATFORM(IOS)
void RenderLineBreak::collectSelectionRects(Vector<SelectionRect>& rects, unsigned, unsigned)
{
- ensureLineBoxes(*this);
+ ensureLineBoxes();
InlineElementBox* box = m_inlineBoxWrapper;
if (!box)
return;
diff --git a/Source/WebCore/rendering/RenderLineBreak.h b/Source/WebCore/rendering/RenderLineBreak.h
index 26883a8..dd79c41 100644
--- a/Source/WebCore/rendering/RenderLineBreak.h
+++ b/Source/WebCore/rendering/RenderLineBreak.h
@@ -54,6 +54,7 @@
#if PLATFORM(IOS)
void collectSelectionRects(Vector<SelectionRect>&, unsigned startOffset = 0, unsigned endOffset = std::numeric_limits<unsigned>::max()) override;
#endif
+ void ensureLineBoxes();
private:
void node() const = delete;