Reviewed by Harrison.
<rdar://problem/
4889598> Problems with moveDown: and moveUp: in Notes with ToDos
* editing/selection/
4889598-expected.checksum: Added.
* editing/selection/
4889598-expected.png: Added.
* editing/selection/
4889598-expected.txt: Added.
* editing/selection/
4889598.html: Added.
WebCore:
Reviewed by Harrison.
<rdar://problem/
4889598> Problems with moveDown: and moveUp: in Notes with ToDos
The caret would disappear when moving from content above or below
a ToDo if that ToDo doesn't have any content in it with the same
x position as the caret. That's because closestLeafChildForXPos
would return non-editable leaves, and which turn into non-editable
VisiblePositions, which are invisible.
* editing/visible_units.cpp:
(WebCore::previousLinePosition): Ask closestLeafForXPos to only
return editable leaves.
(WebCore::nextLinePosition): Ditto.
* rendering/RootInlineBox.cpp:
(WebCore::isEditableLeaf): Added.
(WebCore::RootInlineBox::closestLeafChildForXPos): If requested,
return the closest editable leaf. Removed an early return if the
position is before the first leaf, it's not really much of an
optimization.
* rendering/RootInlineBox.h:
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@22037
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2007-06-06 Justin Garcia <justin.garcia@apple.com>
+
+ Reviewed by Harrison.
+
+ <rdar://problem/4889598> Problems with moveDown: and moveUp: in Notes with ToDos
+
+ * editing/selection/4889598-expected.checksum: Added.
+ * editing/selection/4889598-expected.png: Added.
+ * editing/selection/4889598-expected.txt: Added.
+ * editing/selection/4889598.html: Added.
+
2007-06-06 Sam Weinig <sam@webkit.org>
Reviewed by Hyatt.
--- /dev/null
+327bce76bc950ef78dab1e48513b5b0c
\ No newline at end of file
--- /dev/null
+EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of DIV > BODY > HTML > #document to 7 of DIV > BODY > HTML > #document
+EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: shouldEndEditingInDOMRange:range from 0 of DIV > BODY > HTML > #document to 7 of DIV > BODY > HTML > #document
+EDITING DELEGATE: webViewDidEndEditing:WebViewDidEndEditingNotification
+EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of SPAN > TD > TR > TBODY > TABLE > DIV > BODY > HTML > #document to 1 of SPAN > TD > TR > TBODY > TABLE > DIV > BODY > HTML > #document
+EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: shouldEndEditingInDOMRange:range from 0 of SPAN > TD > TR > TBODY > TABLE > DIV > BODY > HTML > #document to 1 of SPAN > TD > TR > TBODY > TABLE > DIV > BODY > HTML > #document
+EDITING DELEGATE: webViewDidEndEditing:WebViewDidEndEditingNotification
+EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of DIV > BODY > HTML > #document to 7 of DIV > BODY > HTML > #document
+EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: shouldEndEditingInDOMRange:range from 0 of DIV > BODY > HTML > #document to 7 of DIV > BODY > HTML > #document
+EDITING DELEGATE: webViewDidEndEditing:WebViewDidEndEditingNotification
+EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of SPAN > TD > TR > TBODY > TABLE > DIV > BODY > HTML > #document to 1 of SPAN > TD > TR > TBODY > TABLE > DIV > BODY > HTML > #document
+EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: shouldEndEditingInDOMRange:range from 0 of SPAN > TD > TR > TBODY > TABLE > DIV > BODY > HTML > #document to 1 of SPAN > TD > TR > TBODY > TABLE > DIV > BODY > HTML > #document
+EDITING DELEGATE: webViewDidEndEditing:WebViewDidEndEditingNotification
+EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of DIV > BODY > HTML > #document to 7 of DIV > BODY > HTML > #document
+EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: shouldEndEditingInDOMRange:range from 0 of DIV > BODY > HTML > #document to 7 of DIV > BODY > HTML > #document
+EDITING DELEGATE: webViewDidEndEditing:WebViewDidEndEditingNotification
+EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of SPAN > TD > TR > TBODY > TABLE > DIV > BODY > HTML > #document to 1 of SPAN > TD > TR > TBODY > TABLE > DIV > BODY > HTML > #document
+EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: shouldEndEditingInDOMRange:range from 0 of SPAN > TD > TR > TBODY > TABLE > DIV > BODY > HTML > #document to 1 of SPAN > TD > TR > TBODY > TABLE > DIV > BODY > HTML > #document
+EDITING DELEGATE: webViewDidEndEditing:WebViewDidEndEditingNotification
+EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of DIV > BODY > HTML > #document to 7 of DIV > BODY > HTML > #document
+EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: shouldEndEditingInDOMRange:range from 0 of DIV > BODY > HTML > #document to 7 of DIV > BODY > HTML > #document
+EDITING DELEGATE: webViewDidEndEditing:WebViewDidEndEditingNotification
+EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of SPAN > TD > TR > TBODY > TABLE > DIV > BODY > HTML > #document to 1 of SPAN > TD > TR > TBODY > TABLE > DIV > BODY > HTML > #document
+EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+layer at (0,0) size 800x600
+ RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+ RenderBlock {HTML} at (0,0) size 800x600
+ RenderBody {BODY} at (8,8) size 784x584
+ RenderBlock {P} at (0,0) size 784x18
+ RenderText {#text} at (0,0) size 784x18
+ text run at (0,0) width 784: "This tests for a bug moving down by a line from a line just above a ToDo, and moving up by a line from just below a ToDo."
+ RenderBlock {DIV} at (0,34) size 784x64
+ RenderBlock {DIV} at (0,0) size 784x18
+ RenderText {#text} at (0,0) size 279x18
+ text run at (0,0) width 279: "Click anywhere in this line and move down."
+ RenderTable {TABLE} at (0,18) size 335x28 [border: (1px outset #808080)]
+ RenderTableSection {TBODY} at (1,1) size 333x26
+ RenderTableRow {TR} at (0,2) size 333x22
+ RenderTableCell {TD} at (2,2) size 329x22 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=1]
+ RenderText {#text} at (2,2) size 63x18
+ text run at (2,2) width 63: "The caret "
+ RenderInline {SPAN} at (0,0) size 42x18 [color=#0000FF]
+ RenderText {#text} at (65,2) size 42x18
+ text run at (65,2) width 42: "should"
+ RenderText {#text} at (107,2) size 220x18
+ text run at (107,2) width 220: " always go into the editable region."
+ RenderBlock {DIV} at (0,46) size 784x18
+ RenderText {#text} at (0,0) size 259x18
+ text run at (0,0) width 259: "Click anywhere in this line and move up."
+caret: position 6 of child 0 {#text} of child 1 {SPAN} of child 0 {TD} of child 0 {TR} of child 0 {TBODY} of child 3 {TABLE} of child 2 {DIV} of child 0 {BODY} of child 0 {HTML} of document
--- /dev/null
+<p>This tests for a bug moving down by a line from a line just above a ToDo, and moving up by a line from just below a ToDo.</p>
+<div id="div" contenteditable="true">
+<div id="above">Click anywhere in this line and move down.</div>
+<table border="1" contenteditable="false"><tr><td>The caret <span style="color: blue;" contenteditable="true">should</span> always go into the editable region.</td></tr></table>
+<div id="below">Click anywhere in this line and move up.</div>
+</div>
+
+<script>
+if (window.layoutTestController)
+ window.layoutTestController.dumpEditingCallbacks();
+var selection = window.getSelection();
+var above = document.getElementById("above").firstChild;
+selection.setPosition(above, 0);
+selection.modify("move", "forward", "line");
+selection.setPosition(above, above.length);
+selection.modify("move", "forward", "line");
+var below = document.getElementById("below").firstChild;
+selection.setPosition(below, 0);
+selection.modify("move", "backward", "line");
+selection.setPosition(below, below.length);
+selection.modify("move", "backward", "line");
+</script>
+2007-06-06 Justin Garcia <justin.garcia@apple.com>
+
+ Reviewed by Harrison.
+
+ <rdar://problem/4889598> Problems with moveDown: and moveUp: in Notes with ToDos
+
+ The caret would disappear when moving from content above or below
+ a ToDo if that ToDo doesn't have any content in it with the same
+ x position as the caret. That's because closestLeafChildForXPos
+ would return non-editable leaves, and which turn into non-editable
+ VisiblePositions, which are invisible.
+
+ * editing/visible_units.cpp:
+ (WebCore::previousLinePosition): Ask closestLeafForXPos to only
+ return editable leaves.
+ (WebCore::nextLinePosition): Ditto.
+ * rendering/RootInlineBox.cpp:
+ (WebCore::isEditableLeaf): Added.
+ (WebCore::RootInlineBox::closestLeafChildForXPos): If requested,
+ return the closest editable leaf. Removed an early return if the
+ position is before the first leaf, it's not really much of an
+ optimization.
+ * rendering/RootInlineBox.h:
+
2007-06-06 Sam Weinig <sam@webkit.org>
Reviewed by Anders.
containingBlock->absolutePositionForContent(absx, absy);
if (containingBlock->hasOverflowClip())
containingBlock->layer()->subtractScrollOffset(absx, absy);
- RenderObject *renderer = root->closestLeafChildForXPos(x - absx)->object();
+ RenderObject *renderer = root->closestLeafChildForXPos(x - absx, isEditablePosition(p))->object();
Node* node = renderer->element();
if (editingIgnoresContent(node))
return Position(node->parent(), node->nodeIndex());
containingBlock->absolutePositionForContent(absx, absy);
if (containingBlock->hasOverflowClip())
containingBlock->layer()->subtractScrollOffset(absx, absy);
- RenderObject *renderer = root->closestLeafChildForXPos(x - absx)->object();
+ RenderObject *renderer = root->closestLeafChildForXPos(x - absx, isEditablePosition(p))->object();
Node* node = renderer->element();
if (editingIgnoresContent(node))
return Position(node->parent(), node->nodeIndex());
return static_cast<RenderBlock*>(m_object);
}
-InlineBox* RootInlineBox::closestLeafChildForXPos(int x)
+bool isEditableLeaf(InlineBox* leaf)
+{
+ return leaf && leaf->object() && leaf->object()->element() && leaf->object()->element()->isContentEditable();
+}
+
+InlineBox* RootInlineBox::closestLeafChildForXPos(int x, bool onlyEditableLeaves)
{
InlineBox* firstLeaf = firstLeafChildAfterBox();
InlineBox* lastLeaf = lastLeafChildBeforeBox();
- if (firstLeaf == lastLeaf)
+ if (firstLeaf == lastLeaf && (!onlyEditableLeaves || isEditableLeaf(firstLeaf)))
return firstLeaf;
// Avoid returning a list marker when possible.
- if (x <= firstLeaf->m_x && !firstLeaf->object()->isListMarker())
+ if (x <= firstLeaf->m_x && !firstLeaf->object()->isListMarker() && (!onlyEditableLeaves || isEditableLeaf(firstLeaf)))
// The x coordinate is less or equal to left edge of the firstLeaf.
// Return it.
return firstLeaf;
- if (x >= lastLeaf->m_x + lastLeaf->m_width && !lastLeaf->object()->isListMarker())
+ if (x >= lastLeaf->m_x + lastLeaf->m_width && !lastLeaf->object()->isListMarker() && (!onlyEditableLeaves || isEditableLeaf(lastLeaf)))
// The x coordinate is greater or equal to right edge of the lastLeaf.
// Return it.
return lastLeaf;
+ InlineBox* closestLeaf = lastLeaf;
for (InlineBox* leaf = firstLeaf; leaf && leaf != lastLeaf; leaf = leaf->nextLeafChild()) {
- if (!leaf->object()->isListMarker()) {
+ if (!leaf->object()->isListMarker() && (!onlyEditableLeaves || isEditableLeaf(leaf))) {
int leafX = leaf->m_x;
+ closestLeaf = leaf;
if (x < leafX + leaf->m_width)
// The x coordinate is less than the right edge of the box.
// Return it.
}
}
- return lastLeaf;
+ return closestLeaf;
}
void RootInlineBox::setLineBreakInfo(RenderObject* obj, unsigned breakPos, BidiStatus* status, BidiContext* context)
int selectionBottom() { return m_overflow ? m_overflow->m_selectionBottom : m_y + m_height; }
int selectionHeight() { return max(0, selectionBottom() - selectionTop()); }
- InlineBox* closestLeafChildForXPos(int x);
+ InlineBox* closestLeafChildForXPos(int x, bool onlyEditableLeaves = false);
protected:
// Normally we are only as tall as the style on our block dictates, but we might have content