Reviewed by Mitz Pettel.
authorggaren <ggaren@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 29 Nov 2006 21:58:41 +0000 (21:58 +0000)
committerggaren <ggaren@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 29 Nov 2006 21:58:41 +0000 (21:58 +0000)
        Fixed http://bugs.webkit.org/show_bug.cgi?id=11710
        REGRESSION (r17906): Crash in WebCore::FrameMac

        Added null checks for EditorClient, since it can be NULL when the page
        has been destroyed. Removed external access to EditorClient, since it's
        an implementation detail of the Editor.

        No test case because this crash depends on window tear-down. Layout tests
        pass.

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

WebCore/ChangeLog
WebCore/bridge/EditorClient.h
WebCore/bridge/mac/FrameMac.mm
WebCore/dom/Document.cpp
WebCore/dom/Document.h
WebCore/editing/Editor.cpp
WebCore/editing/Editor.h
WebCore/editing/JSEditor.cpp
WebCore/loader/FrameLoader.cpp
WebCore/rendering/RenderTextControl.cpp

index 462da8b..f12ad24 100644 (file)
@@ -1,3 +1,17 @@
+2006-11-29  Geoffrey Garen  <ggaren@apple.com>
+
+        Reviewed by Mitz Pettel.
+        
+        Fixed http://bugs.webkit.org/show_bug.cgi?id=11710
+        REGRESSION (r17906): Crash in WebCore::FrameMac
+
+        Added null checks for EditorClient, since it can be NULL when the page
+        has been destroyed. Removed external access to EditorClient, since it's
+        an implementation detail of the Editor.
+
+        No test case because this crash depends on window tear-down. Layout tests
+        pass.
+        
 2006-11-29  Anders Carlsson  <acarlsson@apple.com>
 
         Fix build.
index e7b0a22..6e2417e 100644 (file)
@@ -87,7 +87,9 @@ public:
     virtual void redo() = 0;
 
 #if PLATFORM(MAC)
+    // FIXME: This should become SelectionController::toWebArchive()
     virtual NSData* dataForArchivedSelection(Frame*) = 0; 
+
     virtual NSString* _web_userVisibleString(NSURL*) = 0;
 #endif
 
index 20ee068..8dc716d 100644 (file)
@@ -504,7 +504,7 @@ void FrameMac::advanceToNextMisspelling(bool startBeforeSelection)
                 it.advance();
             else {
                 NSString *chunk = [[NSString alloc] initWithCharactersNoCopy:const_cast<UChar*>(chars) length:len freeWhenDone:NO];
-                NSRange misspellingNSRange = [checker checkSpellingOfString:chunk startingAt:0 language:nil wrap:NO inSpellDocumentWithTag:editor()->client()->spellCheckerDocumentTag() wordCount:NULL];
+                NSRange misspellingNSRange = [checker checkSpellingOfString:chunk startingAt:0 language:nil wrap:NO inSpellDocumentWithTag:editor()->spellCheckerDocumentTag() wordCount:NULL];
 
 #if !defined(NDEBUG) || !defined(BUILDING_ON_TIGER)
                 NSDictionary *grammarDetail = nil;
@@ -1072,7 +1072,7 @@ void FrameMac::ignoreSpelling()
     String text = selectedText();
     ASSERT(text.length() != 0);
     [[NSSpellChecker sharedSpellChecker] ignoreWord:text 
-        inSpellDocumentWithTag:editor()->client()->spellCheckerDocumentTag()];
+        inSpellDocumentWithTag:editor()->spellCheckerDocumentTag()];
 }
 
 void FrameMac::learnSpelling()
@@ -1092,7 +1092,7 @@ bool FrameMac::isSelectionMisspelled()
                                                                     startingAt:0
                                                                       language:nil
                                                                           wrap:NO 
-                                                        inSpellDocumentWithTag:editor()->client()->spellCheckerDocumentTag() 
+                                                        inSpellDocumentWithTag:editor()->spellCheckerDocumentTag() 
                                                                      wordCount:NULL];
     return range.length == length;
 }
@@ -1119,7 +1119,7 @@ Vector<String> FrameMac::guessesForMisspelledSelection()
 
 void FrameMac::markMisspellingsInAdjacentWords(const VisiblePosition &p)
 {
-    if (!editor()->client()->isContinuousSpellCheckingEnabled())
+    if (!editor()->isContinuousSpellCheckingEnabled())
         return;
     markMisspellings(Selection(startOfWord(p, LeftWordIfOnBoundary), endOfWord(p, RightWordIfOnBoundary)));
 }
@@ -1129,7 +1129,7 @@ void FrameMac::markMisspellings(const Selection& selection)
     // This function is called with a selection already expanded to word boundaries.
     // Might be nice to assert that here.
 
-    if (!editor()->client()->isContinuousSpellCheckingEnabled())
+    if (!editor()->isContinuousSpellCheckingEnabled())
         return;
 
     RefPtr<Range> searchRange(selection.toRange());
@@ -1161,7 +1161,7 @@ void FrameMac::markMisspellings(const Selection& selection)
             int startIndex = 0;
             // Loop over the chunk to find each misspelled word or instance of questionable grammar in it.
             while (startIndex < len) {
-                NSRange misspellingNSRange = [checker checkSpellingOfString:chunk startingAt:startIndex language:nil wrap:NO inSpellDocumentWithTag:editor()->client()->spellCheckerDocumentTag() wordCount:NULL];
+                NSRange misspellingNSRange = [checker checkSpellingOfString:chunk startingAt:startIndex language:nil wrap:NO inSpellDocumentWithTag:editor()->spellCheckerDocumentTag() wordCount:NULL];
 
 #if !defined(NDEBUG) || !defined(BUILDING_ON_TIGER)
                 NSDictionary *grammarDetail = nil;
@@ -1242,7 +1242,7 @@ void FrameMac::markMisspellings(const Selection& selection)
 void FrameMac::respondToChangedSelection(const Selection &oldSelection, bool closeTyping)
 {
     if (document()) {
-        if (editor()->client()->isContinuousSpellCheckingEnabled()) {
+        if (editor()->isContinuousSpellCheckingEnabled()) {
             Selection oldAdjacentWords;
             
             // If this is a change in selection resulting from a delete operation, oldSelection may no longer
index 8fd612a..596aeae 100644 (file)
@@ -1999,7 +1999,7 @@ bool Document::relinquishesEditingFocus(Node *node)
     if (!frame() || !root)
         return false;
 
-    return frame()->editor()->client()->shouldEndEditing(rangeOfContents(root).get());
+    return frame()->editor()->shouldEndEditing(rangeOfContents(root).get());
 }
 
 bool Document::acceptsEditingFocus(Node *node)
@@ -2011,23 +2011,7 @@ bool Document::acceptsEditingFocus(Node *node)
     if (!frame() || !root)
         return false;
 
-    return frame()->editor()->client()->shouldBeginEditing(rangeOfContents(root).get());
-}
-
-void Document::didBeginEditing()
-{
-    if (!frame())
-        return;
-    
-    frame()->editor()->client()->didBeginEditing();
-}
-
-void Document::didEndEditing()
-{
-    if (!frame())
-        return;
-    
-    frame()->editor()->client()->didEndEditing();
+    return frame()->editor()->shouldBeginEditing(rangeOfContents(root).get());
 }
 
 #if PLATFORM(MAC)
@@ -2105,7 +2089,7 @@ bool Document::setFocusNode(PassRefPtr<Node> newFocusNode)
             return true;
             
         if (oldFocusNode.get() == oldFocusNode->rootEditableElement())
-            didEndEditing();
+            frame()->editor()->didEndEditing();
     }
 
     if (newFocusNode) {
@@ -2134,7 +2118,7 @@ bool Document::setFocusNode(PassRefPtr<Node> newFocusNode)
         m_focusNode->setFocus();
         
         if (m_focusNode.get() == m_focusNode->rootEditableElement())
-            didBeginEditing();
+            frame()->editor()->didBeginEditing();
         
         // eww, I suck. set the qt focus correctly
         // ### find a better place in the code for this
index d178d5f..a6c2a6b 100644 (file)
@@ -784,8 +784,6 @@ private:
     JSEditor* m_jsEditor;
     bool relinquishesEditingFocus(Node*);
     bool acceptsEditingFocus(Node*);
-    void didBeginEditing();
-    void didEndEditing();
 
     mutable String m_domain;
     RenderObject* m_savedRenderer;
index bc16692..19c8c70 100644 (file)
@@ -190,8 +190,8 @@ bool Editor::canSmartReplaceWithPasteboard(Pasteboard* pasteboard)
 
 bool Editor::shouldInsertFragment(PassRefPtr<DocumentFragment> fragment, PassRefPtr<Range> replacingDOMRange, EditorInsertAction givenAction)
 {
-    Node *child = fragment->firstChild();
     if (client()) {
+        Node *child = fragment->firstChild();
         if (fragment->lastChild() == child && child->isCharacterDataNode())
             return client()->shouldInsertText(((CharacterData *)child)->data(), replacingDOMRange.get(), givenAction);
         return client()->shouldInsertNode(fragment.get(), replacingDOMRange.get(), givenAction);
@@ -860,13 +860,13 @@ static bool execToggleItalic(Frame* frame)
 
 static bool execRedo(Frame* frame)
 {
-    frame->editor()->client()->redo();
+    frame->editor()->redo();
     return true;
 }
 
 static bool execUndo(Frame* frame)
 {
-    frame->editor()->client()->undo();
+    frame->editor()->undo();
     return true;
 }
 
@@ -904,12 +904,12 @@ static bool hasRichlyEditableSelection(Frame* frame)
 
 static bool canRedo(Frame* frame)
 {
-    return frame->editor()->client()->canRedo();
+    return frame->editor()->canRedo();
 }
 
 static bool canUndo(Frame* frame)
 {
-    return frame->editor()->client()->canUndo();
+    return frame->editor()->canUndo();
 }
 
 struct Command {
@@ -1064,4 +1064,85 @@ void Editor::performDelete()
     deleteSelection();
 }
 
+bool Editor::isContinuousSpellCheckingEnabled()
+{
+    if (client())
+        return client()->isContinuousSpellCheckingEnabled();
+    return false;
+}
+
+int Editor::spellCheckerDocumentTag()
+{
+    if (client())
+        return client()->spellCheckerDocumentTag();
+    return 0;
+}
+
+bool Editor::shouldEndEditing(Range* range)
+{
+    if (client())
+        return client()->shouldEndEditing(range);
+    return false;
+}
+
+bool Editor::shouldBeginEditing(Range* range)
+{
+    if (client())
+        return client()->shouldBeginEditing(range);
+    return false;
+}
+
+void Editor::clearUndoRedoOperations()
+{
+    if (client())
+        client()->clearUndoRedoOperations();
+}
+
+bool Editor::canUndo()
+{
+    if (client())
+        return client()->canUndo();
+    return false;
+}
+
+void Editor::undo()
+{
+    if (client())
+        client()->undo();
+}
+
+bool Editor::canRedo()
+{
+    if (client())
+        return client()->canRedo();
+    return false;
+}
+
+void Editor::redo()
+{
+    if (client())
+        client()->redo();
+}
+
+void Editor::didBeginEditing()
+{
+    if (client())
+        client()->didBeginEditing();
+}
+
+void Editor::didEndEditing()
+{
+    if (client())
+        client()->didEndEditing();
+}
+
+#if PLATFORM(MAC)
+NSString* Editor::_web_userVisibleString(NSURL* nsURL)
+{
+    if (client())
+        return client()->_web_userVisibleString(nsURL);
+    return nil;
+}
+#endif
+
 } // namespace WebCore
index 6548668..5d07f94 100644 (file)
@@ -115,6 +115,26 @@ public:
     bool clientIsEditable() const;
     
     bool execCommand(const String&);
+    
+    bool isContinuousSpellCheckingEnabled();
+    int spellCheckerDocumentTag();
+
+    bool shouldBeginEditing(Range* range);
+    bool shouldEndEditing(Range* range);
+
+    void clearUndoRedoOperations();
+    bool canUndo();
+    void undo();
+    bool canRedo();
+    void redo();
+
+    void didBeginEditing();
+    void didEndEditing();
+
+#if PLATFORM(MAC)
+    NSString* _web_userVisibleString(NSURL* nsURL);
+#endif
+
 private:
     Frame* m_frame;
     OwnPtr<DeleteButtonController> m_deleteButtonController;
index 10cdc8b..df677da 100644 (file)
@@ -408,7 +408,7 @@ bool execPrint(Frame* frame, bool, const String&)
 
 bool execRedo(Frame* frame, bool, const String&)
 {
-    frame->editor()->client()->redo();
+    frame->editor()->redo();
     return true;
 }
 
@@ -454,7 +454,7 @@ bool execUnderline(Frame* frame, bool, const String&)
 
 bool execUndo(Frame* frame, bool, const String&)
 {
-    frame->editor()->client()->undo();
+    frame->editor()->undo();
     return true;
 }
 
@@ -532,12 +532,12 @@ bool enabledAnyRichlyEditableRangeSelection(Frame* frame)
 
 bool enabledRedo(Frame* frame)
 {
-    return frame->editor()->client()->canRedo();
+    return frame->editor()->canRedo();
 }
 
 bool enabledUndo(Frame* frame)
 {
-    return frame->editor()->client()->canUndo();
+    return frame->editor()->canUndo();
 }
 
 // =============================================================================================
index 34977ff..56ac976 100644 (file)
@@ -578,7 +578,7 @@ bool FrameLoader::closeURL()
 {
     saveDocumentState();
     stopLoading(true);
-    m_frame->editor()->client()->clearUndoRedoOperations();
+    m_frame->editor()->clearUndoRedoOperations();
     return true;
 }
 
index 698922b..8aa5e86 100644 (file)
@@ -163,7 +163,7 @@ void RenderTextControl::updateFromElement()
             if (value.endsWith("\n") || value.endsWith("\r"))
                 m_div->appendChild(new HTMLBRElement(document()), ec);
             if (document()->frame())
-                document()->frame()->editor()->client()->clearUndoRedoOperations();
+                document()->frame()->editor()->clearUndoRedoOperations();
             setEdited(false);
         }
         element->setValueMatchesRenderer();