- Revision
- 116192
- Author
- [email protected]
- Date
- 2012-05-04 16:55:40 -0700 (Fri, 04 May 2012)
Log Message
REGRESSION: Cursor jumps to the first line after deleting the last word.
https://bugs.webkit.org/show_bug.cgi?id=85334
<rdar://problem/11210059>
Reviewed by Ryosuke Niwa.
Source/WebCore:
This regression was introduced with the work to remove redundant divs.
When we decide to remove a DIV, we need to adjust the selection, if it is
expressed in terms of the node being removed. The new position was computed
using updatePositionForNodeRemoval that was not designed for the case where we
remove preserving children.
This patch adds a new method to CompositeEditCommand to do this properly.
Test: editing/deleting/delete-word-from-unstyled-div.html
* editing/CompositeEditCommand.cpp:
(WebCore::CompositeEditCommand::isRemovableBlock): Code clenup.
(WebCore::CompositeEditCommand::updatePositionForNodeRemovalPreservingChildren): Added.
* editing/CompositeEditCommand.h:
* editing/DeleteSelectionCommand.cpp:
(WebCore::DeleteSelectionCommand::removeRedundantBlocks): Uses updatePositionForNodeRemovalPreservingChildren.
LayoutTests:
* editing/deleting/delete-word-from-unstyled-div-expected.txt: Added.
* editing/deleting/delete-word-from-unstyled-div.html: Added.
Modified Paths
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (116191 => 116192)
--- trunk/LayoutTests/ChangeLog 2012-05-04 23:42:56 UTC (rev 116191)
+++ trunk/LayoutTests/ChangeLog 2012-05-04 23:55:40 UTC (rev 116192)
@@ -1,3 +1,14 @@
+2012-05-04 Enrica Casucci <[email protected]>
+
+ REGRESSION: Cursor jumps to the first line after deleting the last word.
+ https://bugs.webkit.org/show_bug.cgi?id=85334
+ <rdar://problem/11210059>
+
+ Reviewed by Ryosuke Niwa.
+
+ * editing/deleting/delete-word-from-unstyled-div-expected.txt: Added.
+ * editing/deleting/delete-word-from-unstyled-div.html: Added.
+
2012-05-04 Jeffrey Pfau <[email protected]>
Prevent early EventListener deletion
@@ -1713,7 +1724,6 @@
* fast/writing-mode/flipped-blocks-inline-map-local-to-container.html:
->>>>>>> .r116007
2012-05-03 Andreas Kling <[email protected]>
REGRESSION(r111387): CSSOM representation of 'background-image' values should be CSSPrimitiveValue.
Added: trunk/LayoutTests/editing/deleting/delete-word-from-unstyled-div-expected.txt (0 => 116192)
--- trunk/LayoutTests/editing/deleting/delete-word-from-unstyled-div-expected.txt (rev 0)
+++ trunk/LayoutTests/editing/deleting/delete-word-from-unstyled-div-expected.txt 2012-05-04 23:55:40 UTC (rev 116192)
@@ -0,0 +1,4 @@
+This test that the deletion of the last row of an unstyled DIV leaves a BR element and that the selection is where the BR element is.
+| "one"
+| <br>
+| <br>
Added: trunk/LayoutTests/editing/deleting/delete-word-from-unstyled-div.html (0 => 116192)
--- trunk/LayoutTests/editing/deleting/delete-word-from-unstyled-div.html (rev 0)
+++ trunk/LayoutTests/editing/deleting/delete-word-from-unstyled-div.html 2012-05-04 23:55:40 UTC (rev 116192)
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<head>
+
+<style>
+.editing {
+ border: 2px solid red;
+ padding: 12px;
+ font-size: 24px;
+}
+</style>
+<title>Editing Test</title>
+</head>
+<body contenteditable _onload_="runTest()">
+ <div id="test"><div>one<br>two</div></div>
+</body>"
+<script src=""
+<script>
+function runTest() {
+ Markup.description('This test that the deletion of the last row of an unstyled DIV leaves a BR element and that the selection is where the BR element is.');
+ var element = document.getElementById("test").firstElementChild;
+ getSelection().setBaseAndExtent(element, 2, element, 3);
+ document.execCommand('delete');
+ Markup.dump('test');
+}
+</script>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (116191 => 116192)
--- trunk/Source/WebCore/ChangeLog 2012-05-04 23:42:56 UTC (rev 116191)
+++ trunk/Source/WebCore/ChangeLog 2012-05-04 23:55:40 UTC (rev 116192)
@@ -1,3 +1,27 @@
+2012-05-04 Enrica Casucci <[email protected]>
+
+ REGRESSION: Cursor jumps to the first line after deleting the last word.
+ https://bugs.webkit.org/show_bug.cgi?id=85334
+ <rdar://problem/11210059>
+
+ Reviewed by Ryosuke Niwa.
+
+ This regression was introduced with the work to remove redundant divs.
+ When we decide to remove a DIV, we need to adjust the selection, if it is
+ expressed in terms of the node being removed. The new position was computed
+ using updatePositionForNodeRemoval that was not designed for the case where we
+ remove preserving children.
+ This patch adds a new method to CompositeEditCommand to do this properly.
+
+ Test: editing/deleting/delete-word-from-unstyled-div.html
+
+ * editing/CompositeEditCommand.cpp:
+ (WebCore::CompositeEditCommand::isRemovableBlock): Code clenup.
+ (WebCore::CompositeEditCommand::updatePositionForNodeRemovalPreservingChildren): Added.
+ * editing/CompositeEditCommand.h:
+ * editing/DeleteSelectionCommand.cpp:
+ (WebCore::DeleteSelectionCommand::removeRedundantBlocks): Uses updatePositionForNodeRemovalPreservingChildren.
+
2012-05-04 Jeffrey Pfau <[email protected]>
Prevent early EventListener deletion
Modified: trunk/Source/WebCore/editing/CompositeEditCommand.cpp (116191 => 116192)
--- trunk/Source/WebCore/editing/CompositeEditCommand.cpp 2012-05-04 23:42:56 UTC (rev 116191)
+++ trunk/Source/WebCore/editing/CompositeEditCommand.cpp 2012-05-04 23:55:40 UTC (rev 116192)
@@ -304,11 +304,14 @@
bool CompositeEditCommand::isRemovableBlock(const Node* node)
{
+ if (!node->hasTagName(divTag))
+ return false;
+
Node* parentNode = node->parentNode();
- if ((parentNode && parentNode->firstChild() != parentNode->lastChild()) || !node->hasTagName(divTag))
+ if (parentNode && parentNode->firstChild() != parentNode->lastChild())
return false;
- if (!node->isElementNode() || !toElement(node)->hasAttributes())
+ if (!toElement(node)->hasAttributes())
return true;
return false;
@@ -403,6 +406,14 @@
prune(parent.release());
}
+void CompositeEditCommand::updatePositionForNodeRemovalPreservingChildren(Position& position, Node* node)
+{
+ int offset = (position.anchorType() == Position::PositionIsOffsetInAnchor) ? position.offsetInContainerNode() : 0;
+ updatePositionForNodeRemoval(position, node);
+ if (offset)
+ position.moveToOffset(offset);
+}
+
HTMLElement* CompositeEditCommand::replaceElementWithSpanPreservingChildrenAndAttributes(PassRefPtr<HTMLElement> node)
{
// It would also be possible to implement all of ReplaceNodeWithSpanCommand
Modified: trunk/Source/WebCore/editing/CompositeEditCommand.h (116191 => 116192)
--- trunk/Source/WebCore/editing/CompositeEditCommand.h 2012-05-04 23:42:56 UTC (rev 116191)
+++ trunk/Source/WebCore/editing/CompositeEditCommand.h 2012-05-04 23:55:40 UTC (rev 116192)
@@ -126,6 +126,7 @@
HTMLElement* replaceElementWithSpanPreservingChildrenAndAttributes(PassRefPtr<HTMLElement>);
void removeNodePreservingChildren(PassRefPtr<Node>);
void removeNodeAndPruneAncestors(PassRefPtr<Node>);
+ void updatePositionForNodeRemovalPreservingChildren(Position&, Node*);
void prune(PassRefPtr<Node>);
void replaceTextInNode(PassRefPtr<Text>, unsigned offset, unsigned count, const String& replacementText);
Position replaceSelectedTextInNode(const String&);
Modified: trunk/Source/WebCore/editing/DeleteSelectionCommand.cpp (116191 => 116192)
--- trunk/Source/WebCore/editing/DeleteSelectionCommand.cpp 2012-05-04 23:42:56 UTC (rev 116191)
+++ trunk/Source/WebCore/editing/DeleteSelectionCommand.cpp 2012-05-04 23:55:40 UTC (rev 116192)
@@ -740,7 +740,7 @@
while (node != rootNode) {
if (isRemovableBlock(node)) {
if (node == m_endingPosition.anchorNode())
- updatePositionForNodeRemoval(m_endingPosition, node);
+ updatePositionForNodeRemovalPreservingChildren(m_endingPosition, node);
CompositeEditCommand::removeNodePreservingChildren(node);
node = m_endingPosition.anchorNode();