LayoutTests:
authorjusting <justing@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 8 Mar 2006 23:07:07 +0000 (23:07 +0000)
committerjusting <justing@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 8 Mar 2006 23:07:07 +0000 (23:07 +0000)
        Reviewed by darin

        <http://bugzilla.opendarwin.org/show_bug.cgi?id=7579>
        TinyMCE: Implement execCommand(insertImage, ...)

        * editing/editing.js:
        * editing/execCommand/insertImage-expected.checksum: Added.
        * editing/execCommand/insertImage-expected.png: Added.
        * editing/execCommand/insertImage-expected.txt: Added.
        * editing/execCommand/insertImage.html: Added.
        * editing/pasteboard/3976872-expected.txt:

WebCore:

        Reviewed by darin

        <http://bugzilla.opendarwin.org/show_bug.cgi?id=7579>
        TinyMCE: Implement execCommand(insertImage, ...)

        Implemented InsertImage and also changed paste to use a single
        rule for when to remove junk that remains after node removal.

        * editing/ReplaceSelectionCommand.cpp:
        (WebCore::ReplaceSelectionCommand::removeNodeAndPruneAncestors):
        (WebCore::ReplaceSelectionCommand::doApply):
        (WebCore::ReplaceSelectionCommand::removeLinePlaceholderIfNeeded):
        * editing/ReplaceSelectionCommand.h:
        * editing/htmlediting.cpp:
        * editing/jsediting.cpp:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@13221 268f45cc-cd09-0410-ab3c-d52691b4dbfc

12 files changed:
LayoutTests/ChangeLog
LayoutTests/editing/editing.js
LayoutTests/editing/execCommand/insertImage-expected.checksum [new file with mode: 0644]
LayoutTests/editing/execCommand/insertImage-expected.png [new file with mode: 0644]
LayoutTests/editing/execCommand/insertImage-expected.txt [new file with mode: 0644]
LayoutTests/editing/execCommand/insertImage.html [new file with mode: 0644]
LayoutTests/editing/pasteboard/3976872-expected.txt
WebCore/ChangeLog
WebCore/editing/ReplaceSelectionCommand.cpp
WebCore/editing/ReplaceSelectionCommand.h
WebCore/editing/htmlediting.cpp
WebCore/editing/jsediting.cpp

index 8c65512..a19b2f0 100644 (file)
@@ -1,3 +1,17 @@
+2006-03-08  Justin Garcia  <justin.garcia@apple.com>
+
+        Reviewed by darin
+        
+        <http://bugzilla.opendarwin.org/show_bug.cgi?id=7579>
+        TinyMCE: Implement execCommand(insertImage, ...)
+
+        * editing/editing.js:
+        * editing/execCommand/insertImage-expected.checksum: Added.
+        * editing/execCommand/insertImage-expected.png: Added.
+        * editing/execCommand/insertImage-expected.txt: Added.
+        * editing/execCommand/insertImage.html: Added.
+        * editing/pasteboard/3976872-expected.txt:
+
 2006-03-08  Rob Buis  <buis@kde.org>
 
         Reviewed by eseidel.
index 06022b2..446463d 100644 (file)
@@ -361,6 +361,21 @@ function insertHTMLCommand(html) {
 
 //-------------------------------------------------------------------------------------------------------
 
+function execInsertImageCommand(imgSrc) {
+    document.execCommand("InsertImage", false, imgSrc);
+}
+function insertImageCommand(imgSrc) {
+    if (commandDelay > 0) {
+        window.setTimeout(execInsertImageCommand, commandCount * commandDelay, imgSrc);
+        commandCount++;
+    }
+    else {
+        execInsertImageCommand(imgSrc);
+    }
+}
+
+//-------------------------------------------------------------------------------------------------------
+
 function execInsertLineBreakCommand() {
     document.execCommand("InsertLineBreak");
 }
diff --git a/LayoutTests/editing/execCommand/insertImage-expected.checksum b/LayoutTests/editing/execCommand/insertImage-expected.checksum
new file mode 100644 (file)
index 0000000..ea79ce7
--- /dev/null
@@ -0,0 +1 @@
+ec572a085fd0b7e8481c99c102a4a9d1
\ No newline at end of file
diff --git a/LayoutTests/editing/execCommand/insertImage-expected.png b/LayoutTests/editing/execCommand/insertImage-expected.png
new file mode 100644 (file)
index 0000000..d0046c3
Binary files /dev/null and b/LayoutTests/editing/execCommand/insertImage-expected.png differ
diff --git a/LayoutTests/editing/execCommand/insertImage-expected.txt b/LayoutTests/editing/execCommand/insertImage-expected.txt
new file mode 100644 (file)
index 0000000..874fcf8
--- /dev/null
@@ -0,0 +1,24 @@
+EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of DIV > BODY > HTML > #document to 0 of DIV > BODY > HTML > #document
+EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of DIV > BODY > HTML > #document to 0 of DIV > BODY > HTML > #document toDOMRange:range from 1 of DIV > BODY > HTML > #document to 1 of DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 1 of DIV > BODY > HTML > #document to 1 of DIV > BODY > HTML > #document toDOMRange:range from 2 of DIV > BODY > HTML > #document to 2 of DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
+layer at (0,0) size 800x600
+  RenderCanvas at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x576
+      RenderBlock {P} at (0,0) size 784x36
+        RenderText {TEXT} at (0,0) size 748x36
+          text run at (0,0) width 306: "This is a test of execCommand(InsertImage, ...). "
+          text run at (306,0) width 442: "The first test passes execCommand a path to a valid image, the second"
+          text run at (0,18) width 369: "passes execCommand a path where no image should exist."
+      RenderBlock {DIV} at (0,52) size 784x103
+        RenderImage {IMG} at (0,0) size 76x103
+        RenderImage {IMG} at (76,83) size 20x20
+      RenderBlock {UL} at (0,171) size 784x0
+caret: position 1 of child 1 {IMG} of child 3 {DIV} of child 1 {BODY} of child 0 {HTML} of document
diff --git a/LayoutTests/editing/execCommand/insertImage.html b/LayoutTests/editing/execCommand/insertImage.html
new file mode 100644 (file)
index 0000000..cccd65a
--- /dev/null
@@ -0,0 +1,31 @@
+<html>
+<head>
+<script src=../editing.js language="JavaScript" type="text/JavaScript"></script>
+<script>
+function log(message) {
+    var console = document.getElementById("console");
+    var li = document.createElement("li");
+    var text = document.createTextNode(message);
+    li.appendChild(text);
+    console.appendChild(li);
+}
+
+function editingTest() {
+    insertImageCommand("../resources/abe.jpg");
+    insertImageCommand("../resources/do-not-name-an-image-this.jpg");
+}
+</script>
+</head>
+
+<body>
+<p>This is a test of execCommand(InsertImage, ...).  The first test passes execCommand a path to a valid image, the second passes execCommand a path where no image should exist.</p>
+
+<div id="test" contenteditable="true"></div>
+<ul id="console"></ul>
+<script>
+runEditingTest();
+</script>
+
+</body>
+
+</html>
\ No newline at end of file
index f66cc5a..9a446f2 100644 (file)
@@ -31,7 +31,6 @@ layer at (0,0) size 800x600
           RenderInline {B} at (0,0) size 187x18
             RenderText {TEXT} at (1,1) size 187x18
               text run at (1,1) width 187: "this text should end up bold"
-          RenderInline {B} at (0,0) size 0x18
         RenderBlock {DIV} at (0,20) size 784x20 [border: (1px solid #FF0000)]
           RenderInline {B} at (0,0) size 187x18
             RenderText {TEXT} at (1,1) size 187x18
index e31f79a..6a679ee 100644 (file)
@@ -1,3 +1,21 @@
+2006-03-08  Justin Garcia  <justin.garcia@apple.com>
+
+        Reviewed by darin
+        
+        <http://bugzilla.opendarwin.org/show_bug.cgi?id=7579>
+        TinyMCE: Implement execCommand(insertImage, ...)
+        
+        Implemented InsertImage and also changed paste to use a single 
+        rule for when to remove junk that remains after node removal. 
+
+        * editing/ReplaceSelectionCommand.cpp:
+        (WebCore::ReplaceSelectionCommand::removeNodeAndPruneAncestors):
+        (WebCore::ReplaceSelectionCommand::doApply):
+        (WebCore::ReplaceSelectionCommand::removeLinePlaceholderIfNeeded):
+        * editing/ReplaceSelectionCommand.h:
+        * editing/htmlediting.cpp:
+        * editing/jsediting.cpp:
+
 2006-03-08  Eric Seidel  <eseidel@apple.com>
 
         Reviewed by hyatt.
index 534ff40..c5c33ba 100644 (file)
@@ -296,6 +296,21 @@ static DOMString &matchNearestBlockquoteColorString()
     return matchNearestBlockquoteColorString;
 }
 
+// FIXME: Move this somewhere so that the other editing operations can use it to clean up after themselves.
+void ReplaceSelectionCommand::removeNodeAndPruneAncestors(NodeImpl* node)
+{
+    NodeImpl* parent = node->parentNode();
+    removeNode(node);
+    while (parent) {
+        NodeImpl* nextParent = parent->parentNode();
+        // If you change this rule you may have to add an updateLayout() here.
+        if (parent->renderer() && parent->renderer()->firstChild())
+            return;
+        removeNode(parent);
+        parent = nextParent;
+    }
+}
+
 void ReplaceSelectionCommand::fixupNodeStyles(const QValueList<NodeDesiredStyle> &list)
 {
     // This function uses the mapped "desired style" to apply the additional style needed, if any,
@@ -791,17 +806,16 @@ void ReplaceSelectionCommand::doApply()
         if (beyondEndNode) {
             updateLayout();
             QValueList<NodeDesiredStyle> styles;
-            QPtrList<NodeImpl> blocks;
-            NodeImpl *node = beyondEndNode->enclosingInlineElement();
-            NodeImpl *refNode = m_lastNodeInserted.get();
+            NodeImpl* node = beyondEndNode->enclosingInlineElement();
+            NodeImpl* refNode = m_lastNodeInserted.get();
+            
             while (node) {
                 if (node->isBlockFlowOrBlockTable())
                     break;
                     
                 NodeImpl *next = node->nextSibling();
-                blocks.append(node->enclosingBlockFlowElement());
                 computeAndStoreNodeDesiredStyle(node, styles);
-                removeNode(node);
+                removeNodeAndPruneAncestors(node);
                 // No need to update inserted node variables.
                 insertNodeAfter(node, refNode);
                 refNode = node;
@@ -810,18 +824,6 @@ void ReplaceSelectionCommand::doApply()
                     break;
                 node = next;
             }
-            updateLayout();
-            for (QPtrListIterator<NodeImpl> it(blocks); it.current(); ++it) {
-                NodeImpl *blockToRemove = it.current();
-                if (!blockToRemove->inDocument())
-                    continue;
-                if (!blockToRemove->renderer() || !blockToRemove->renderer()->firstChild()) {
-                    if (blockToRemove->parentNode())
-                        blocks.append(blockToRemove->parentNode()->enclosingBlockFlowElement());
-                    removeNode(blockToRemove);
-                    updateLayout();
-                }
-            }
 
             fixupNodeStyles(styles);
         }
@@ -845,11 +847,8 @@ void ReplaceSelectionCommand::removeLinePlaceholderIfNeeded(NodeImpl *linePlaceh
         VisiblePosition placeholderPos(linePlaceholder, linePlaceholder->renderer()->caretMinOffset(), DOWNSTREAM);
         if (placeholderPos.next().isNull() ||
             !(isStartOfLine(placeholderPos) && isEndOfLine(placeholderPos))) {
-            NodeImpl *block = linePlaceholder->enclosingBlockFlowElement();
-            removeNode(linePlaceholder);
-            updateLayout();
-            if (!block->renderer() || block->renderer()->height() == 0)
-                removeNode(block);
+            
+            removeNodeAndPruneAncestors(linePlaceholder);
         }
     }
 }
index 5b5d627..4fedf34 100644 (file)
@@ -122,6 +122,7 @@ private:
     void updateNodesInserted(NodeImpl *);
     void fixupNodeStyles(const QValueList<NodeDesiredStyle> &);
     void removeLinePlaceholderIfNeeded(NodeImpl *);
+    void removeNodeAndPruneAncestors(NodeImpl*);
 
     ReplacementFragment m_fragment;
     RefPtr<NodeImpl> m_firstNodeInserted;
index 64afee3..1675e2b 100644 (file)
@@ -192,7 +192,7 @@ const String& nonBreakingSpaceString()
     return nonBreakingSpaceString;
 }
 
-// FIXME: Why use this instead of maxDeepOffset???
+// FIXME: Why use this instead of maxDeepOffset?
 static int maxRangeOffset(NodeImpl *n)
 {
     if (n->offsetInCharacters())
index e6aaad3..03ec506 100644 (file)
@@ -32,6 +32,8 @@
 #include "css_valueimpl.h"
 #include "cssproperties.h"
 #include "htmlediting.h"
+#include "htmlnames.h"
+#include "html_imageimpl.h"
 #include "markup.h"
 #include "ReplaceSelectionCommand.h"
 #include "TypingCommand.h"
@@ -41,6 +43,8 @@ namespace WebCore {
 
 class DocumentImpl;
 
+using namespace HTMLNames;
+
 namespace {
 
 bool supportsPasteCommand = false;
@@ -244,6 +248,24 @@ bool execInsertHTML(Frame* frame, bool userInterface, const String& value)
     return true;
 }
 
+bool execInsertImage(Frame* frame, bool userInterface, const String& value)
+{
+    // FIXME: If userInterface is true, we should display a dialog box and let the user choose a local image.
+    if (userInterface)
+        LOG_ERROR("A dialog box for image insertion is not yet implemented.\n");
+    
+    RefPtr<HTMLImageElementImpl> image = new HTMLImageElementImpl(imgTag, frame->document());
+    image->setSrc(value);
+    RefPtr<DocumentFragmentImpl> fragment = new DocumentFragmentImpl(frame->document());
+    ExceptionCode ec = 0;
+    fragment->appendChild(image, ec);
+    if (ec)
+        return false;
+    
+    EditCommandPtr(new ReplaceSelectionCommand(frame->document(), fragment.get(), false)).apply();
+    return true;
+}
+
 bool execIndent(Frame *frame, bool userInterface, const DOMString &value)
 {
     // FIXME: Implement.
@@ -529,6 +551,7 @@ CommandMap *createCommandDictionary()
         { "ForwardDelete", { execForwardDelete, enabledAnySelection, stateNone, valueNull } },
         { "Indent", { execIndent, enabledAnySelection, stateNone, valueNull } },
         { "InsertHTML", { execInsertHTML, enabledAnySelection, stateNone, valueNull } },
+        { "InsertImage", { execInsertImage, enabledAnySelection, stateNone, valueNull } },
         { "InsertLineBreak", { execInsertLineBreak, enabledAnySelection, stateNone, valueNull } },
         { "InsertParagraph", { execInsertParagraph, enabledAnySelection, stateNone, valueNull } },
         { "InsertNewlineInQuotedContent", { execInsertNewlineInQuotedContent, enabledAnySelection, stateNone, valueNull } },
@@ -576,7 +599,6 @@ CommandMap *createCommandDictionary()
         // InsertFieldSet (not supported)
         // InsertHorizontalRule (not supported)
         // InsertIFrame (not supported)
-        // InsertImage (not supported)
         // InsertInputButton (not supported)
         // InsertInputCheckbox (not supported)
         // InsertInputFileUpload (not supported)