[Win] Expose missing editing features through WebView interface
[WebKit-https.git] / Source / WebKit / win / WebCoreSupport / WebEditorClient.cpp
index 6a8f6f2..c79334b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006, 2007, 2011 Apple Inc.  All rights reserved.
+ * Copyright (C) 2006, 2007, 2011, 2014 Apple Inc.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -31,6 +31,7 @@
 #include "WebNotificationCenter.h"
 #include "WebView.h"
 #include "DOMCoreClasses.h"
+#include <comutil.h>
 #include <WebCore/BString.h>
 #include <WebCore/Document.h>
 #include <WebCore/HTMLElement.h>
@@ -188,35 +189,57 @@ int WebEditorClient::spellCheckerDocumentTag()
     return 0;
 }
 
-bool WebEditorClient::shouldBeginEditing(Range*)
+bool WebEditorClient::shouldBeginEditing(WebCore::Range* range)
 {
-    notImplemented();
-    return true;
+    COMPtr<IWebEditingDelegate> ed;
+    if (FAILED(m_webView->editingDelegate(&ed)) || !ed.get())
+        return true;
+
+    COMPtr<IDOMRange> currentRange(AdoptCOM, DOMRange::createInstance(range));
+
+    BOOL shouldBegin = FALSE;
+    if (FAILED(ed->shouldBeginEditingInDOMRange(m_webView, currentRange.get(), &shouldBegin)))
+        return true;
+
+    return shouldBegin;
 }
 
-bool WebEditorClient::shouldEndEditing(Range*)
+bool WebEditorClient::shouldEndEditing(Range* range)
 {
-    notImplemented();
-    return true;
+    COMPtr<IWebEditingDelegate> ed;
+    if (FAILED(m_webView->editingDelegate(&ed)) || !ed.get())
+        return true;
+
+    COMPtr<IDOMRange> currentRange(AdoptCOM, DOMRange::createInstance(range));
+
+    BOOL shouldEnd = FALSE;
+    if (FAILED(ed->shouldEndEditingInDOMRange(m_webView, currentRange.get(), &shouldEnd)))
+        return true;
+
+    return shouldEnd;
 }
 
 void WebEditorClient::didBeginEditing()
 {
-    notImplemented();
+    static _bstr_t webViewDidBeginEditingNotificationName(WebViewDidBeginEditingNotification);
+    IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
+    notifyCenter->postNotificationName(webViewDidBeginEditingNotificationName.GetBSTR(), static_cast<IWebView*>(m_webView), nullptr);
 }
 
 void WebEditorClient::respondToChangedContents()
 {
-    notImplemented();
+    static _bstr_t webViewDidChangeNotificationName(WebViewDidChangeNotification);
+    IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
+    notifyCenter->postNotificationName(webViewDidChangeNotificationName.GetBSTR(), static_cast<IWebView*>(m_webView), 0);
 }
 
 void WebEditorClient::respondToChangedSelection(Frame*)
 {
     m_webView->selectionChanged();
 
-    static BSTR webViewDidChangeSelectionNotificationName = SysAllocString(WebViewDidChangeSelectionNotification);
+    static _bstr_t webViewDidChangeSelectionNotificationName(WebViewDidChangeSelectionNotification);
     IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
-    notifyCenter->postNotificationName(webViewDidChangeSelectionNotificationName, static_cast<IWebView*>(m_webView), 0);
+    notifyCenter->postNotificationName(webViewDidChangeSelectionNotificationName.GetBSTR(), static_cast<IWebView*>(m_webView), 0);
 }
 
 void WebEditorClient::discardedComposition(Frame*)
@@ -226,7 +249,9 @@ void WebEditorClient::discardedComposition(Frame*)
 
 void WebEditorClient::didEndEditing()
 {
-    notImplemented();
+    static _bstr_t webViewDidEndEditingNotificationName(WebViewDidEndEditingNotification);
+    IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
+    notifyCenter->postNotificationName(webViewDidEndEditingNotificationName.GetBSTR(), static_cast<IWebView*>(m_webView), nullptr);
 }
 
 void WebEditorClient::didWriteSelectionToPasteboard()
@@ -244,49 +269,75 @@ void WebEditorClient::getClientPasteboardDataForRange(WebCore::Range*, Vector<St
     notImplemented();
 }
 
-bool WebEditorClient::shouldDeleteRange(Range* /*range*/)
+bool WebEditorClient::shouldDeleteRange(Range* range)
 {
-    notImplemented(); 
-    return true; 
+    COMPtr<IWebEditingDelegate> ed;
+    if (FAILED(m_webView->editingDelegate(&ed)) || !ed.get())
+        return true;
+
+    COMPtr<IDOMRange> currentRange(AdoptCOM, DOMRange::createInstance(range));
 
-    // FIXME: calling m_webView->editingDelegate() will cause an assertion failure so we don't want to enable this code until that's implemented. 
-    //BOOL result = false;
-    //IWebViewEditingDelegate* editingDelegate;
-    //// FIXME: DOMRange needs to be implemented before anything meaningful can be done here
-    //IDOMRange* domRange(0);
-    //if (SUCCEEDED(m_webView->editingDelegate(&editingDelegate))) {
-    //    editingDelegate->shouldDeleteDOMRange(m_webView, domRange, &result);
-    //    editingDelegate->Release();
-    //}
-    //return !!result;
+    BOOL shouldDelete = FALSE;
+    if (FAILED(ed->shouldDeleteDOMRange(m_webView, currentRange.get(), &shouldDelete)))
+        return true;
+
+    return shouldDelete;
 }
 
-bool WebEditorClient::shouldInsertNode(Node* /*node*/, Range* /*replacingRange*/, EditorInsertAction /*givenAction*/)
+bool WebEditorClient::shouldInsertNode(Node* node, Range* insertingRange, EditorInsertAction givenAction)
 { 
-    notImplemented(); 
-    return true; 
+    COMPtr<IWebEditingDelegate> editingDelegate;
+    if (FAILED(m_webView->editingDelegate(&editingDelegate)) || !editingDelegate.get())
+        return true;
+
+    COMPtr<IDOMRange> insertingDOMRange(AdoptCOM, DOMRange::createInstance(insertingRange));
+    if (!insertingDOMRange)
+        return true;
+
+    COMPtr<IDOMNode> insertDOMNode(AdoptCOM, DOMNode::createInstance(node));
+    if (!insertDOMNode)
+        return true;
+
+    BOOL shouldInsert = FALSE;
+    if (FAILED(editingDelegate->shouldInsertNode(m_webView, insertDOMNode.get(), insertingDOMRange.get(), static_cast<WebViewInsertAction>(givenAction), &shouldInsert)))
+        return true;
+
+    return shouldInsert;
 }
 
-bool WebEditorClient::shouldInsertText(const String& /*str*/, Range* /* replacingRange */, EditorInsertAction /*givenAction*/)
-{     
-    notImplemented(); 
-    return true; 
+bool WebEditorClient::shouldInsertText(const String& str, Range* insertingRange, EditorInsertAction givenAction)
+{
+    COMPtr<IWebEditingDelegate> editingDelegate;
+    if (FAILED(m_webView->editingDelegate(&editingDelegate)) || !editingDelegate.get())
+        return true;
+
+    COMPtr<IDOMRange> insertingDOMRange(AdoptCOM, DOMRange::createInstance(insertingRange));
+    if (!insertingDOMRange)
+        return true;
+
+    BString text(str);
+    BOOL shouldInsert = FALSE;
+    if (FAILED(editingDelegate->shouldInsertText(m_webView, text, insertingDOMRange.get(), static_cast<WebViewInsertAction>(givenAction), &shouldInsert)))
+        return true;
 
-    // FIXME: calling m_webView->editingDelegate() will cause an assertion failure so we don't want to enable this code until that's implemented. 
-    //BOOL result = false;
-    //IWebViewEditingDelegate* editingDelegate;
-    //// FIXME: DOMRange needs to be implemented before anything meaningful can be done here
-    //IDOMRange* domRange(0); // make a DOMRange from replacingRange
-    //BString text(str);
-    //if (SUCCEEDED(m_webView->editingDelegate(&editingDelegate))) {
-    //    editingDelegate->shouldInsertText(m_webView, text, domRange, (WebViewInsertAction) givenAction, &result);
-    //    editingDelegate->Release();
-    //}
-    //return !!result;
+    return shouldInsert;
 }
 
-//bool WebEditorClient::shouldChangeSelectedRange(Range *currentRange, Range *toProposedRange, SelectionAffinity selectionAffinity, bool stillSelecting)
-//{ notImplemented(); return false; }
+bool WebEditorClient::shouldChangeSelectedRange(WebCore::Range* currentRange, WebCore::Range* proposedRange, WebCore::EAffinity selectionAffinity, bool flag)
+{
+    COMPtr<IWebEditingDelegate> ed;
+    if (FAILED(m_webView->editingDelegate(&ed)) || !ed.get())
+        return true;
+
+    COMPtr<IDOMRange> currentIDOMRange(AdoptCOM, DOMRange::createInstance(currentRange));
+    COMPtr<IDOMRange> proposedIDOMRange(AdoptCOM, DOMRange::createInstance(proposedRange));
+
+    BOOL shouldChange = FALSE;
+    if (FAILED(ed->shouldChangeSelectedDOMRange(m_webView, currentIDOMRange.get(), proposedIDOMRange.get(), static_cast<WebSelectionAffinity>(selectionAffinity), flag, &shouldChange)))
+        return true;
+
+    return shouldChange;
+}
 
 bool WebEditorClient::shouldApplyStyle(StyleProperties* /*style*/, Range* /*toElementsInDOMRange*/)
 { notImplemented(); return true; }
@@ -298,10 +349,14 @@ bool WebEditorClient::shouldChangeTypingStyle(StyleProperties* /*currentStyle*/,
 { notImplemented(); return false; }
 
 void WebEditorClient::webViewDidChangeTypingStyle(WebNotification* /*notification*/)
-{  notImplemented(); }
+{
+    notImplemented();
+}
 
 void WebEditorClient::webViewDidChangeSelection(WebNotification* /*notification*/)
-{  notImplemented(); }
+{
+    notImplemented();
+}
 
 bool WebEditorClient::smartInsertDeleteEnabled(void)
 {
@@ -319,9 +374,6 @@ bool WebEditorClient::isSelectTrailingWhitespaceEnabled(void)
     return page->settings().selectTrailingWhitespaceEnabled();
 }
 
-bool WebEditorClient::shouldChangeSelectedRange(WebCore::Range*, WebCore::Range*, WebCore::EAffinity, bool)
-{ notImplemented(); return true; }
-
 void WebEditorClient::textFieldDidBeginEditing(Element* e)
 {
     IWebFormDelegate* formDelegate;