WebCore:
[WebKit-https.git] / WebCore / editing / FormatBlockCommand.cpp
index 9bd8efc..06a527d 100644 (file)
@@ -72,12 +72,25 @@ void FormatBlockCommand::doApply()
 {
     if (endingSelection().isNone())
         return;
-
-    if (endingSelection().isRange() && modifyRange())
-        return;
     
     if (!endingSelection().rootEditableElement())
         return;
+
+    VisiblePosition visibleEnd = endingSelection().visibleEnd();
+    VisiblePosition visibleStart = endingSelection().visibleStart();
+    // When a selection ends at the start of a paragraph, we rarely paint 
+    // the selection gap before that paragraph, because there often is no gap.  
+    // In a case like this, it's not obvious to the user that the selection 
+    // ends "inside" that paragraph, so it would be confusing if FormatBlock
+    // operated on that paragraph.
+    // FIXME: We paint the gap before some paragraphs that are indented with left 
+    // margin/padding, but not others.  We should make the gap painting more consistent and 
+    // then use a left margin/padding rule here.
+    if (visibleEnd != visibleStart && isStartOfParagraph(visibleEnd))
+        setEndingSelection(Selection(visibleStart, visibleEnd.previous(true)));
+
+    if (endingSelection().isRange() && modifyRange())
+        return;
     
     String localName, prefix;
     if (!Document::parseQualifiedName(m_tagName, prefix, localName))
@@ -97,19 +110,24 @@ void FormatBlockCommand::doApply()
     RefPtr<Node> placeholder = createBreakElement(document());
     
     Node* root = endingSelection().start().node()->rootEditableElement();
-    if (refNode == root || root->isAncestor(refNode))
-        refNode = paragraphStart.deepEquivalent().node();
-    
-    Position upstreamStart = paragraphStart.deepEquivalent().upstream();
-    if ((validBlockTag(refNode->nodeName().lower()) && paragraphStart == blockStart && paragraphEnd == blockEnd) ||
-        !upstreamStart.node()->isAncestor(root))
+    if (validBlockTag(refNode->nodeName().lower()) && 
+        paragraphStart == blockStart && paragraphEnd == blockEnd && 
+        refNode != root && !root->isDescendantOf(refNode))
         // Already in a valid block tag that only contains the current paragraph, so we can swap with the new tag
         insertNodeBefore(blockNode.get(), refNode);
     else {
-        insertNodeAt(blockNode.get(), upstreamStart.node(), upstreamStart.offset());
+        // Avoid inserting inside inline elements that surround paragraphStart with upstream().
+        // This is only to avoid creating bloated markup.
+        insertNodeAt(blockNode.get(), paragraphStart.deepEquivalent().upstream());
     }
     appendNode(placeholder.get(), blockNode.get());
-    moveParagraph(paragraphStart, paragraphEnd, VisiblePosition(Position(placeholder.get(), 0)), true, false);
+    
+    VisiblePosition destination(Position(placeholder.get(), 0));
+    if (paragraphStart == paragraphEnd) {
+        setEndingSelection(destination);
+        return;
+    }
+    moveParagraph(paragraphStart, paragraphEnd, destination, true, false);
 }
 
 }