Diff
Modified: trunk/LayoutTests/ChangeLog (119883 => 119884)
--- trunk/LayoutTests/ChangeLog 2012-06-09 01:51:27 UTC (rev 119883)
+++ trunk/LayoutTests/ChangeLog 2012-06-09 01:56:42 UTC (rev 119884)
@@ -1,3 +1,17 @@
+2012-06-08 Shezan Baig <[email protected]>
+
+ Caret is not rendered in empty inline contenteditable elements
+ https://bugs.webkit.org/show_bug.cgi?id=85793
+
+ Reviewed by Ryosuke Niwa.
+
+ Add test cases for caret in empty inline.
+
+ * editing/selection/caret-in-empty-inline-1-expected.txt: Added.
+ * editing/selection/caret-in-empty-inline-1.html: Added.
+ * editing/selection/caret-in-empty-inline-2-expected.txt: Added.
+ * editing/selection/caret-in-empty-inline-2.html: Added.
+
2012-06-08 Mike West <[email protected]>
Excluding blob: and filesystem: schemes from the mixed content check.
Added: trunk/LayoutTests/editing/selection/caret-in-empty-inline-1-expected.txt (0 => 119884)
--- trunk/LayoutTests/editing/selection/caret-in-empty-inline-1-expected.txt (rev 0)
+++ trunk/LayoutTests/editing/selection/caret-in-empty-inline-1-expected.txt 2012-06-09 01:56:42 UTC (rev 119884)
@@ -0,0 +1,13 @@
+Bug 85793: Caret is not rendered in empty inline contenteditable elements
+
+This test verifies that an empty inline contenteditable element gets a valid caret rect.
+
+
+PASS caretRect.left is 8
+PASS caretRect.top is 160
+PASS caretRect.width is 1
+PASS caretRect.height is 20
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/editing/selection/caret-in-empty-inline-1.html (0 => 119884)
--- trunk/LayoutTests/editing/selection/caret-in-empty-inline-1.html (rev 0)
+++ trunk/LayoutTests/editing/selection/caret-in-empty-inline-1.html 2012-06-09 01:56:42 UTC (rev 119884)
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="" type="text/_javascript_"></script>
+<style>
+ body {
+ font: 20px Ahem;
+ }
+</style>
+</head>
+<body>
+<p> Bug <a href="" Caret is not rendered in empty inline contenteditable elements</p>
+<p>This test verifies that an empty inline contenteditable element gets a valid caret rect.</p>
+<span id="testInline" CONTENTEDITABLE></span><br>
+<div id="console"></div>
+</body>
+<script>
+ var testInline = document.getElementById("testInline");
+ getSelection().collapse(testInline, 0);
+ if (window.internals) {
+ var caretRect = internals.absoluteCaretBounds(document);
+ shouldBe("caretRect.left", "8");
+ shouldBe("caretRect.top", "160");
+ shouldBe("caretRect.width", "1");
+ shouldBe("caretRect.height", "20");
+ }
+</script>
+<script src="" type="text/_javascript_"></script>
+</html>
Added: trunk/LayoutTests/editing/selection/caret-in-empty-inline-2-expected.txt (0 => 119884)
--- trunk/LayoutTests/editing/selection/caret-in-empty-inline-2-expected.txt (rev 0)
+++ trunk/LayoutTests/editing/selection/caret-in-empty-inline-2-expected.txt 2012-06-09 01:56:42 UTC (rev 119884)
@@ -0,0 +1,13 @@
+Bug 85793: Caret is not rendered in empty inline contenteditable elements
+
+This test verifies that an empty inline contenteditable element, placed after another inline element, gets a valid caret rect.
+
+Previous span
+PASS caretRect.left is 268
+PASS caretRect.top is 180
+PASS caretRect.width is 1
+PASS caretRect.height is 20
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/editing/selection/caret-in-empty-inline-2.html (0 => 119884)
--- trunk/LayoutTests/editing/selection/caret-in-empty-inline-2.html (rev 0)
+++ trunk/LayoutTests/editing/selection/caret-in-empty-inline-2.html 2012-06-09 01:56:42 UTC (rev 119884)
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="" type="text/_javascript_"></script>
+<style>
+ body {
+ font: 20px Ahem;
+ }
+</style>
+</head>
+<body>
+<p> Bug <a href="" Caret is not rendered in empty inline contenteditable elements</p>
+<p>This test verifies that an empty inline contenteditable element, placed after
+another inline element, gets a valid caret rect.</p>
+<span>Previous span</span><span id="testInline" CONTENTEDITABLE></span><br>
+<div id="console"></div>
+</body>
+<script>
+ var testInline = document.getElementById("testInline");
+ getSelection().collapse(testInline, 0);
+ if (window.internals) {
+ var caretRect = internals.absoluteCaretBounds(document);
+ shouldBe("caretRect.left", "268");
+ shouldBe("caretRect.top", "180");
+ shouldBe("caretRect.width", "1");
+ shouldBe("caretRect.height", "20");
+ }
+</script>
+<script src="" type="text/_javascript_"></script>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (119883 => 119884)
--- trunk/Source/WebCore/ChangeLog 2012-06-09 01:51:27 UTC (rev 119883)
+++ trunk/Source/WebCore/ChangeLog 2012-06-09 01:56:42 UTC (rev 119884)
@@ -1,3 +1,36 @@
+2012-06-08 Shezan Baig <[email protected]>
+
+ Caret is not rendered in empty inline contenteditable elements
+ https://bugs.webkit.org/show_bug.cgi?id=85793
+
+ Reviewed by Ryosuke Niwa.
+
+ Override localCaretRect in RenderInline. The implementation was almost
+ identical to localCaretRect in RenderBlock for empty block elements, so
+ I refactored RenderBlock::localCaretRect and moved the logic to a new
+ method 'localCaretRectForEmptyElement' in RenderBoxModelObject. The
+ implementation of 'localCaretRect' in RenderBlock and RenderInline both
+ use this helper method in RenderBoxModelObject.
+
+ Tests: editing/selection/caret-in-empty-inline-1.html
+ editing/selection/caret-in-empty-inline-2.html
+
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::localCaretRect):
+ Modified to use RenderBoxModelObject::localCaretRectForEmptyElement.
+ * rendering/RenderBoxModelObject.cpp:
+ (WebCore::RenderBoxModelObject::localCaretRectForEmptyElement):
+ (WebCore):
+ * rendering/RenderBoxModelObject.h:
+ (RenderBoxModelObject):
+ Add localCaretRectForEmptyElement helper method.
+ * rendering/RenderInline.cpp:
+ (WebCore::RenderInline::localCaretRect):
+ (WebCore):
+ * rendering/RenderInline.h:
+ (RenderInline):
+ Override localCaretRect using localCaretRectForEmptyElement.
+
2012-06-08 Mike West <[email protected]>
Treat blob: and filesystem: URLs generated via secure origins as secure.
Modified: trunk/Source/WebCore/rendering/RenderBlock.cpp (119883 => 119884)
--- trunk/Source/WebCore/rendering/RenderBlock.cpp 2012-06-09 01:51:27 UTC (rev 119883)
+++ trunk/Source/WebCore/rendering/RenderBlock.cpp 2012-06-09 01:56:42 UTC (rev 119884)
@@ -6489,80 +6489,17 @@
if (firstChild())
return RenderBox::localCaretRect(inlineBox, caretOffset, extraWidthToEndOfLine);
- // This is a special case:
- // The element is not an inline element, and it's empty. So we have to
- // calculate a fake position to indicate where objects are to be inserted.
-
- // FIXME: This does not take into account either :first-line or :first-letter
- // However, as soon as some content is entered, the line boxes will be
- // constructed and this kludge is not called any more. So only the caret size
- // of an empty :first-line'd block is wrong. I think we can live with that.
- RenderStyle* currentStyle = firstLineStyle();
- LayoutUnit height = lineHeight(true, currentStyle->isHorizontalWritingMode() ? HorizontalLine : VerticalLine);
+ LayoutRect caretRect = localCaretRectForEmptyElement(width(), textIndentOffset());
- enum CaretAlignment { alignLeft, alignRight, alignCenter };
-
- CaretAlignment alignment = alignLeft;
-
- switch (currentStyle->textAlign()) {
- case TAAUTO:
- case JUSTIFY:
- if (!currentStyle->isLeftToRightDirection())
- alignment = alignRight;
- break;
- case LEFT:
- case WEBKIT_LEFT:
- break;
- case CENTER:
- case WEBKIT_CENTER:
- alignment = alignCenter;
- break;
- case RIGHT:
- case WEBKIT_RIGHT:
- alignment = alignRight;
- break;
- case TASTART:
- if (!currentStyle->isLeftToRightDirection())
- alignment = alignRight;
- break;
- case TAEND:
- if (currentStyle->isLeftToRightDirection())
- alignment = alignRight;
- break;
- }
-
- LayoutUnit x = borderLeft() + paddingLeft();
- LayoutUnit w = width();
-
- switch (alignment) {
- case alignLeft:
- if (currentStyle->isLeftToRightDirection())
- x += textIndentOffset();
- break;
- case alignCenter:
- x = (x + w - (borderRight() + paddingRight())) / 2;
- if (currentStyle->isLeftToRightDirection())
- x += textIndentOffset() / 2;
- else
- x -= textIndentOffset() / 2;
- break;
- case alignRight:
- x = w - (borderRight() + paddingRight()) - caretWidth;
- if (!currentStyle->isLeftToRightDirection())
- x -= textIndentOffset();
- break;
- }
- x = min(x, w - borderRight() - paddingRight() - caretWidth);
-
if (extraWidthToEndOfLine) {
if (isRenderBlock()) {
- *extraWidthToEndOfLine = w - (x + caretWidth);
+ *extraWidthToEndOfLine = width() - caretRect.maxX();
} else {
// FIXME: This code looks wrong.
// myRight and containerRight are set up, but then clobbered.
// So *extraWidthToEndOfLine will always be 0 here.
- LayoutUnit myRight = x + caretWidth;
+ LayoutUnit myRight = caretRect.maxX();
// FIXME: why call localToAbsoluteForContent() twice here, too?
FloatPoint absRightPoint = localToAbsolute(FloatPoint(myRight, 0));
@@ -6573,9 +6510,7 @@
}
}
- LayoutUnit y = paddingTop() + borderTop();
-
- return LayoutRect(x, y, caretWidth, height);
+ return caretRect;
}
void RenderBlock::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint& additionalOffset)
Modified: trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp (119883 => 119884)
--- trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp 2012-06-09 01:51:27 UTC (rev 119883)
+++ trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp 2012-06-09 01:56:42 UTC (rev 119884)
@@ -2650,6 +2650,76 @@
firstLetterRemainingTextMap->remove(this);
}
+LayoutRect RenderBoxModelObject::localCaretRectForEmptyElement(LayoutUnit width, LayoutUnit textIndentOffset)
+{
+ ASSERT(!firstChild());
+
+ // FIXME: This does not take into account either :first-line or :first-letter
+ // However, as soon as some content is entered, the line boxes will be
+ // constructed and this kludge is not called any more. So only the caret size
+ // of an empty :first-line'd block is wrong. I think we can live with that.
+ RenderStyle* currentStyle = firstLineStyle();
+ LayoutUnit height = lineHeight(true, currentStyle->isHorizontalWritingMode() ? HorizontalLine : VerticalLine);
+
+ enum CaretAlignment { alignLeft, alignRight, alignCenter };
+
+ CaretAlignment alignment = alignLeft;
+
+ switch (currentStyle->textAlign()) {
+ case TAAUTO:
+ case JUSTIFY:
+ if (!currentStyle->isLeftToRightDirection())
+ alignment = alignRight;
+ break;
+ case LEFT:
+ case WEBKIT_LEFT:
+ break;
+ case CENTER:
+ case WEBKIT_CENTER:
+ alignment = alignCenter;
+ break;
+ case RIGHT:
+ case WEBKIT_RIGHT:
+ alignment = alignRight;
+ break;
+ case TASTART:
+ if (!currentStyle->isLeftToRightDirection())
+ alignment = alignRight;
+ break;
+ case TAEND:
+ if (currentStyle->isLeftToRightDirection())
+ alignment = alignRight;
+ break;
+ }
+
+ LayoutUnit x = borderLeft() + paddingLeft();
+ LayoutUnit maxX = width - borderRight() - paddingRight();
+
+ switch (alignment) {
+ case alignLeft:
+ if (currentStyle->isLeftToRightDirection())
+ x += textIndentOffset;
+ break;
+ case alignCenter:
+ x = (x + maxX) / 2;
+ if (currentStyle->isLeftToRightDirection())
+ x += textIndentOffset / 2;
+ else
+ x -= textIndentOffset / 2;
+ break;
+ case alignRight:
+ x = maxX - caretWidth;
+ if (!currentStyle->isLeftToRightDirection())
+ x -= textIndentOffset;
+ break;
+ }
+ x = min(x, max(maxX - caretWidth, ZERO_LAYOUT_UNIT));
+
+ LayoutUnit y = paddingTop() + borderTop();
+
+ return LayoutRect(x, y, caretWidth, height);
+}
+
bool RenderBoxModelObject::shouldAntialiasLines(GraphicsContext* context)
{
// FIXME: We may want to not antialias when scaled by an integral value,
Modified: trunk/Source/WebCore/rendering/RenderBoxModelObject.h (119883 => 119884)
--- trunk/Source/WebCore/rendering/RenderBoxModelObject.h 2012-06-09 01:51:27 UTC (rev 119883)
+++ trunk/Source/WebCore/rendering/RenderBoxModelObject.h 2012-06-09 01:56:42 UTC (rev 119884)
@@ -237,6 +237,8 @@
RenderBoxModelObject* continuation() const;
void setContinuation(RenderBoxModelObject*);
+ LayoutRect localCaretRectForEmptyElement(LayoutUnit width, LayoutUnit textIndentOffset);
+
static bool shouldAntialiasLines(GraphicsContext*);
public:
Modified: trunk/Source/WebCore/rendering/RenderInline.cpp (119883 => 119884)
--- trunk/Source/WebCore/rendering/RenderInline.cpp 2012-06-09 01:51:27 UTC (rev 119883)
+++ trunk/Source/WebCore/rendering/RenderInline.cpp 2012-06-09 01:56:42 UTC (rev 119884)
@@ -233,6 +233,30 @@
}
}
+LayoutRect RenderInline::localCaretRect(InlineBox* inlineBox, int, LayoutUnit* extraWidthToEndOfLine)
+{
+ if (firstChild()) {
+ // This condition is possible if the RenderInline is at an editing boundary,
+ // i.e. the VisiblePosition is:
+ // <RenderInline editingBoundary=true>|<RenderText> </RenderText></RenderInline>
+ // FIXME: need to figure out how to make this return a valid rect, note that
+ // there are no line boxes created in the above case.
+ return LayoutRect();
+ }
+
+ ASSERT_UNUSED(inlineBox, !inlineBox);
+
+ if (extraWidthToEndOfLine)
+ *extraWidthToEndOfLine = 0;
+
+ LayoutRect caretRect = localCaretRectForEmptyElement(borderAndPaddingWidth(), 0);
+
+ if (InlineBox* firstBox = firstLineBox())
+ caretRect.moveBy(roundedLayoutPoint(firstBox->topLeft()));
+
+ return caretRect;
+}
+
void RenderInline::addChild(RenderObject* newChild, RenderObject* beforeChild)
{
if (continuation())
Modified: trunk/Source/WebCore/rendering/RenderInline.h (119883 => 119884)
--- trunk/Source/WebCore/rendering/RenderInline.h 2012-06-09 01:51:27 UTC (rev 119883)
+++ trunk/Source/WebCore/rendering/RenderInline.h 2012-06-09 01:56:42 UTC (rev 119884)
@@ -84,6 +84,8 @@
void setAlwaysCreateLineBoxes() { m_alwaysCreateLineBoxes = true; }
void updateAlwaysCreateLineBoxes(bool fullLayout);
+ virtual LayoutRect localCaretRect(InlineBox*, int, LayoutUnit* extraWidthToEndOfLine) OVERRIDE;
+
protected:
virtual void willBeDestroyed();