summaryrefslogtreecommitdiffstats
path: root/WebKit/win/WebCoreSupport
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2008-12-17 18:05:15 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2008-12-17 18:05:15 -0800
commit1cbdecfa9fc428ac2d8aca0fa91c9580b3d57353 (patch)
tree4457a7306ea5acb43fe05bfe0973b1f7faf97ba2 /WebKit/win/WebCoreSupport
parent9364f22aed35e1a1e9d07c121510f80be3ab0502 (diff)
downloadexternal_webkit-1cbdecfa9fc428ac2d8aca0fa91c9580b3d57353.zip
external_webkit-1cbdecfa9fc428ac2d8aca0fa91c9580b3d57353.tar.gz
external_webkit-1cbdecfa9fc428ac2d8aca0fa91c9580b3d57353.tar.bz2
Code drop from //branches/cupcake/...@124589
Diffstat (limited to 'WebKit/win/WebCoreSupport')
-rw-r--r--WebKit/win/WebCoreSupport/EmbeddedWidget.cpp209
-rw-r--r--WebKit/win/WebCoreSupport/EmbeddedWidget.h80
-rw-r--r--WebKit/win/WebCoreSupport/WebChromeClient.cpp709
-rw-r--r--WebKit/win/WebCoreSupport/WebChromeClient.h127
-rw-r--r--WebKit/win/WebCoreSupport/WebContextMenuClient.cpp179
-rw-r--r--WebKit/win/WebCoreSupport/WebContextMenuClient.h51
-rw-r--r--WebKit/win/WebCoreSupport/WebDragClient.cpp269
-rw-r--r--WebKit/win/WebCoreSupport/WebDragClient.h46
-rw-r--r--WebKit/win/WebCoreSupport/WebEditorClient.cpp762
-rw-r--r--WebKit/win/WebCoreSupport/WebEditorClient.h117
-rw-r--r--WebKit/win/WebCoreSupport/WebFrameLoaderClient.cpp706
-rw-r--r--WebKit/win/WebCoreSupport/WebFrameLoaderClient.h120
-rw-r--r--WebKit/win/WebCoreSupport/WebInspectorClient.cpp426
-rw-r--r--WebKit/win/WebCoreSupport/WebInspectorClient.h100
-rw-r--r--WebKit/win/WebCoreSupport/WebInspectorDelegate.cpp66
-rw-r--r--WebKit/win/WebCoreSupport/WebInspectorDelegate.h257
16 files changed, 4224 insertions, 0 deletions
diff --git a/WebKit/win/WebCoreSupport/EmbeddedWidget.cpp b/WebKit/win/WebCoreSupport/EmbeddedWidget.cpp
new file mode 100644
index 0000000..b18022b
--- /dev/null
+++ b/WebKit/win/WebCoreSupport/EmbeddedWidget.cpp
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "EmbeddedWidget.h"
+
+#include <WebCore/Document.h>
+#include <WebCore/Element.h>
+#include <WebCore/FrameView.h>
+#include <WebCore/RenderObject.h>
+
+using namespace WebCore;
+
+EmbeddedWidget* EmbeddedWidget::create(IWebEmbeddedView* view, Element* element, HWND parentWindow, const IntSize& size)
+{
+ EmbeddedWidget* widget = new EmbeddedWidget(view, element);
+
+ widget->createWindow(parentWindow, size);
+ return widget;
+}
+
+EmbeddedWidget::~EmbeddedWidget()
+{
+ if (m_window)
+ DestroyWindow(m_window);
+}
+
+bool EmbeddedWidget::createWindow(HWND parentWindow, const IntSize& size)
+{
+ ASSERT(!m_window);
+
+ HWND window;
+
+ SIZE pluginSize(size);
+
+ HRESULT hr = m_view->createViewWindow((OLE_HANDLE)parentWindow, &pluginSize, (OLE_HANDLE*)&window);
+
+ if (FAILED(hr) || !window)
+ return false;
+
+ m_window = window;
+ return true;
+}
+
+void EmbeddedWidget::invalidateRect(const IntRect& rect)
+{
+ if (!m_window)
+ return;
+
+ RECT r = rect;
+ ::InvalidateRect(m_window, &r, false);
+}
+
+void EmbeddedWidget::setFrameRect(const IntRect& rect)
+{
+ if (m_element->document()->printing())
+ return;
+
+ if (rect != frameRect())
+ Widget::setFrameRect(rect);
+
+ frameRectsChanged();
+}
+
+void EmbeddedWidget::frameRectsChanged() const
+{
+ if (!parent())
+ return;
+
+ ASSERT(parent()->isFrameView());
+ FrameView* frameView = static_cast<FrameView*>(parent());
+
+ IntRect oldWindowRect = m_windowRect;
+ IntRect oldClipRect = m_clipRect;
+
+ m_windowRect = IntRect(frameView->contentsToWindow(frameRect().location()), frameRect().size());
+ m_clipRect = windowClipRect();
+ m_clipRect.move(-m_windowRect.x(), -m_windowRect.y());
+
+ if (!m_window)
+ return;
+
+ if (m_windowRect == oldWindowRect && m_clipRect == oldClipRect)
+ return;
+
+ HRGN rgn;
+
+ // To prevent flashes while scrolling, we disable drawing during the window
+ // update process by clipping the window to the zero rect.
+
+ bool clipToZeroRect = true;
+
+ if (clipToZeroRect) {
+ rgn = ::CreateRectRgn(0, 0, 0, 0);
+ ::SetWindowRgn(m_window, rgn, FALSE);
+ } else {
+ rgn = ::CreateRectRgn(m_clipRect.x(), m_clipRect.y(), m_clipRect.right(), m_clipRect.bottom());
+ ::SetWindowRgn(m_window, rgn, TRUE);
+ }
+
+ if (m_windowRect != oldWindowRect)
+ ::MoveWindow(m_window, m_windowRect.x(), m_windowRect.y(), m_windowRect.width(), m_windowRect.height(), TRUE);
+
+ if (clipToZeroRect) {
+ rgn = ::CreateRectRgn(m_clipRect.x(), m_clipRect.y(), m_clipRect.right(), m_clipRect.bottom());
+ ::SetWindowRgn(m_window, rgn, TRUE);
+ }
+}
+
+void EmbeddedWidget::setFocus()
+{
+ if (m_window)
+ SetFocus(m_window);
+
+ Widget::setFocus();
+}
+
+void EmbeddedWidget::show()
+{
+ m_isVisible = true;
+
+ if (m_attachedToWindow && m_window)
+ ShowWindow(m_window, SW_SHOWNA);
+
+ Widget::show();
+}
+
+void EmbeddedWidget::hide()
+{
+ m_isVisible = false;
+
+ if (m_attachedToWindow && m_window)
+ ShowWindow(m_window, SW_HIDE);
+
+ Widget::hide();
+}
+
+IntRect EmbeddedWidget::windowClipRect() const
+{
+ // Start by clipping to our bounds.
+ IntRect clipRect(m_windowRect);
+
+ // Take our element and get the clip rect from the enclosing layer and frame view.
+ RenderLayer* layer = m_element->renderer()->enclosingLayer();
+ FrameView* parentView = m_element->document()->view();
+ clipRect.intersect(parentView->windowClipRectForLayer(layer, true));
+
+ return clipRect;
+}
+
+void EmbeddedWidget::setParent(ScrollView* parent)
+{
+ Widget::setParent(parent);
+
+ if (!m_window)
+ return;
+
+ if (parent)
+ return;
+
+ // If the embedded window or one of its children have the focus, we need to
+ // clear it to prevent the web view window from being focused because that can
+ // trigger a layout while the plugin element is being detached.
+ HWND focusedWindow = ::GetFocus();
+ if (m_window == focusedWindow || ::IsChild(m_window, focusedWindow))
+ ::SetFocus(0);
+}
+
+void EmbeddedWidget::attachToWindow()
+{
+ if (m_attachedToWindow)
+ return;
+
+ m_attachedToWindow = true;
+ if (m_isVisible && m_window)
+ ShowWindow(m_window, SW_SHOWNA);
+}
+
+void EmbeddedWidget::detachFromWindow()
+{
+ if (!m_attachedToWindow)
+ return;
+
+ if (m_isVisible && m_window)
+ ShowWindow(m_window, SW_HIDE);
+ m_attachedToWindow = false;
+}
diff --git a/WebKit/win/WebCoreSupport/EmbeddedWidget.h b/WebKit/win/WebCoreSupport/EmbeddedWidget.h
new file mode 100644
index 0000000..ed7c025
--- /dev/null
+++ b/WebKit/win/WebCoreSupport/EmbeddedWidget.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef EmbeddedWidget_h
+#define EmbeddedWidget_h
+
+#include <WebCore/COMPtr.h>
+#include <WebCore/IntRect.h>
+#include <WebCore/Widget.h>
+
+namespace WebCore {
+ class Element;
+ class IntSize;
+}
+
+interface IWebEmbeddedView;
+
+class EmbeddedWidget : public WebCore::Widget {
+public:
+ static EmbeddedWidget* create(IWebEmbeddedView*, WebCore::Element* element, HWND parentWindow, const WebCore::IntSize&);
+ ~EmbeddedWidget();
+
+private:
+ EmbeddedWidget(IWebEmbeddedView* view, WebCore::Element* element)
+ : m_view(view)
+ , m_element(element)
+ , m_window(0)
+ , m_isVisible(false)
+ , m_attachedToWindow(false)
+ {
+ }
+
+ bool createWindow(HWND parentWindow, const WebCore::IntSize& size);
+
+ virtual void invalidateRect(const WebCore::IntRect&);
+ virtual void setFrameRect(const WebCore::IntRect&);
+ virtual void frameRectsChanged() const;
+ virtual void setFocus();
+ virtual void show();
+ virtual void hide();
+ virtual WebCore::IntRect windowClipRect() const;
+ virtual void setParent(WebCore::ScrollView*);
+
+ virtual void attachToWindow();
+ virtual void detachFromWindow();
+
+ COMPtr<IWebEmbeddedView> m_view;
+ WebCore::Element* m_element;
+ HWND m_window;
+
+ bool m_isVisible;
+ bool m_attachedToWindow;
+
+ mutable WebCore::IntRect m_clipRect; // The clip rect to apply to an embedded view.
+ mutable WebCore::IntRect m_windowRect; // Our window rect.
+};
+
+#endif // EmbeddedWidget_h
diff --git a/WebKit/win/WebCoreSupport/WebChromeClient.cpp b/WebKit/win/WebCoreSupport/WebChromeClient.cpp
new file mode 100644
index 0000000..dba87e5
--- /dev/null
+++ b/WebKit/win/WebCoreSupport/WebChromeClient.cpp
@@ -0,0 +1,709 @@
+/*
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebChromeClient.h"
+
+#include "WebElementPropertyBag.h"
+#include "WebFrame.h"
+#include "WebHistory.h"
+#include "WebMutableURLRequest.h"
+#include "WebSecurityOrigin.h"
+#include "WebView.h"
+#pragma warning(push, 0)
+#include <WebCore/BString.h>
+#include <WebCore/ContextMenu.h>
+#include <WebCore/FileChooser.h>
+#include <WebCore/FloatRect.h>
+#include <WebCore/FrameLoadRequest.h>
+#include <WebCore/FrameView.h>
+#include <WebCore/LocalizedStrings.h>
+#include <WebCore/Page.h>
+#include <WebCore/WindowFeatures.h>
+#pragma warning(pop)
+
+#include <tchar.h>
+
+using namespace WebCore;
+
+// When you call GetOpenFileName, if the size of the buffer is too small,
+// MSDN says that the first two bytes of the buffer contain the required size for the file selection, in bytes or characters
+// So we can assume the required size can't be more than the maximum value for a short.
+static const size_t maxFilePathsListSize = USHRT_MAX;
+
+WebChromeClient::WebChromeClient(WebView* webView)
+ : m_webView(webView)
+{
+}
+
+void WebChromeClient::chromeDestroyed()
+{
+ delete this;
+}
+
+void WebChromeClient::setWindowRect(const FloatRect& r)
+{
+ IWebUIDelegate* uiDelegate = 0;
+ if (SUCCEEDED(m_webView->uiDelegate(&uiDelegate))) {
+ RECT rect = IntRect(r);
+ uiDelegate->setFrame(m_webView, &rect);
+ uiDelegate->Release();
+ }
+}
+
+FloatRect WebChromeClient::windowRect()
+{
+ IWebUIDelegate* uiDelegate = 0;
+ if (SUCCEEDED(m_webView->uiDelegate(&uiDelegate))) {
+ RECT rect;
+ HRESULT retval = uiDelegate->webViewFrame(m_webView, &rect);
+
+ uiDelegate->Release();
+
+ if (SUCCEEDED(retval))
+ return rect;
+ }
+
+ return FloatRect();
+}
+
+FloatRect WebChromeClient::pageRect()
+{
+ RECT rect;
+ m_webView->frameRect(&rect);
+ return rect;
+}
+
+float WebChromeClient::scaleFactor()
+{
+ // Windows doesn't support UI scaling.
+ return 1.0;
+}
+
+void WebChromeClient::focus()
+{
+ IWebUIDelegate* uiDelegate = 0;
+ if (SUCCEEDED(m_webView->uiDelegate(&uiDelegate))) {
+ uiDelegate->webViewFocus(m_webView);
+ uiDelegate->Release();
+ }
+ // Normally this would happen on a timer, but JS might need to know this earlier, so we'll update here.
+ m_webView->updateActiveState();
+}
+
+void WebChromeClient::unfocus()
+{
+ IWebUIDelegate* uiDelegate = 0;
+ if (SUCCEEDED(m_webView->uiDelegate(&uiDelegate))) {
+ uiDelegate->webViewUnfocus(m_webView);
+ uiDelegate->Release();
+ }
+ // Normally this would happen on a timer, but JS might need to know this earlier, so we'll update here.
+ m_webView->updateActiveState();
+}
+
+bool WebChromeClient::canTakeFocus(FocusDirection direction)
+{
+ IWebUIDelegate* uiDelegate = 0;
+ BOOL bForward = (direction == FocusDirectionForward) ? TRUE : FALSE;
+ BOOL result = FALSE;
+ if (SUCCEEDED(m_webView->uiDelegate(&uiDelegate))) {
+ uiDelegate->canTakeFocus(m_webView, bForward, &result);
+ uiDelegate->Release();
+ }
+
+ return !!result;
+}
+
+void WebChromeClient::takeFocus(FocusDirection direction)
+{
+ IWebUIDelegate* uiDelegate = 0;
+ BOOL bForward = (direction == FocusDirectionForward) ? TRUE : FALSE;
+ if (SUCCEEDED(m_webView->uiDelegate(&uiDelegate))) {
+ uiDelegate->takeFocus(m_webView, bForward);
+ uiDelegate->Release();
+ }
+}
+
+Page* WebChromeClient::createWindow(Frame*, const FrameLoadRequest& frameLoadRequest, const WindowFeatures& features)
+{
+ if (features.dialog) {
+ COMPtr<IWebUIDelegate3> delegate = uiDelegate3();
+ if (!delegate)
+ return 0;
+ COMPtr<IWebMutableURLRequest> request(AdoptCOM, WebMutableURLRequest::createInstance(frameLoadRequest.resourceRequest()));
+ COMPtr<IWebView> dialog;
+ if (FAILED(delegate->createModalDialog(m_webView, request.get(), &dialog)))
+ return 0;
+ return core(dialog.get());
+ }
+
+ Page* page = 0;
+ IWebUIDelegate* uiDelegate = 0;
+ IWebMutableURLRequest* request = WebMutableURLRequest::createInstance(frameLoadRequest.resourceRequest());
+
+ if (SUCCEEDED(m_webView->uiDelegate(&uiDelegate))) {
+ IWebView* webView = 0;
+ if (SUCCEEDED(uiDelegate->createWebViewWithRequest(m_webView, request, &webView))) {
+ page = core(webView);
+ webView->Release();
+ }
+
+ uiDelegate->Release();
+ }
+
+ request->Release();
+ return page;
+}
+
+void WebChromeClient::show()
+{
+ IWebUIDelegate* uiDelegate = 0;
+ if (SUCCEEDED(m_webView->uiDelegate(&uiDelegate))) {
+ uiDelegate->webViewShow(m_webView);
+ uiDelegate->Release();
+ }
+}
+
+bool WebChromeClient::canRunModal()
+{
+ BOOL result = FALSE;
+ if (COMPtr<IWebUIDelegate3> delegate = uiDelegate3())
+ delegate->canRunModal(m_webView, &result);
+ return result;
+}
+
+void WebChromeClient::runModal()
+{
+ if (COMPtr<IWebUIDelegate3> delegate = uiDelegate3())
+ delegate->runModal(m_webView);
+}
+
+void WebChromeClient::setToolbarsVisible(bool visible)
+{
+ IWebUIDelegate* uiDelegate = 0;
+ if (SUCCEEDED(m_webView->uiDelegate(&uiDelegate))) {
+ uiDelegate->setToolbarsVisible(m_webView, visible);
+ uiDelegate->Release();
+ }
+}
+
+bool WebChromeClient::toolbarsVisible()
+{
+ BOOL result = false;
+ IWebUIDelegate* uiDelegate = 0;
+ if (SUCCEEDED(m_webView->uiDelegate(&uiDelegate))) {
+ uiDelegate->webViewAreToolbarsVisible(m_webView, &result);
+ uiDelegate->Release();
+ }
+ return result != false;
+}
+
+void WebChromeClient::setStatusbarVisible(bool visible)
+{
+ IWebUIDelegate* uiDelegate = 0;
+ if (SUCCEEDED(m_webView->uiDelegate(&uiDelegate))) {
+ uiDelegate->setStatusBarVisible(m_webView, visible);
+ uiDelegate->Release();
+ }
+}
+
+bool WebChromeClient::statusbarVisible()
+{
+ BOOL result = false;
+ IWebUIDelegate* uiDelegate = 0;
+ if (SUCCEEDED(m_webView->uiDelegate(&uiDelegate))) {
+ uiDelegate->webViewIsStatusBarVisible(m_webView, &result);
+ uiDelegate->Release();
+ }
+ return result != false;
+}
+
+void WebChromeClient::setScrollbarsVisible(bool b)
+{
+ WebFrame* webFrame = m_webView->topLevelFrame();
+ if (webFrame)
+ webFrame->setAllowsScrolling(b);
+}
+
+bool WebChromeClient::scrollbarsVisible()
+{
+ WebFrame* webFrame = m_webView->topLevelFrame();
+ BOOL b = false;
+ if (webFrame)
+ webFrame->allowsScrolling(&b);
+
+ return !!b;
+}
+
+void WebChromeClient::setMenubarVisible(bool visible)
+{
+ COMPtr<IWebUIDelegate3> delegate = uiDelegate3();
+ if (!delegate)
+ return;
+ delegate->setMenuBarVisible(m_webView, visible);
+}
+
+bool WebChromeClient::menubarVisible()
+{
+ COMPtr<IWebUIDelegate3> delegate = uiDelegate3();
+ if (!delegate)
+ return true;
+ BOOL result = true;
+ delegate->isMenuBarVisible(m_webView, &result);
+ return result;
+}
+
+void WebChromeClient::setResizable(bool resizable)
+{
+ IWebUIDelegate* uiDelegate = 0;
+ if (SUCCEEDED(m_webView->uiDelegate(&uiDelegate))) {
+ uiDelegate->setResizable(m_webView, resizable);
+ uiDelegate->Release();
+ }
+}
+
+void WebChromeClient::addMessageToConsole(const String& message, unsigned line, const String& url)
+{
+ COMPtr<IWebUIDelegate> uiDelegate;
+ if (SUCCEEDED(m_webView->uiDelegate(&uiDelegate))) {
+ COMPtr<IWebUIDelegatePrivate> uiPrivate;
+ if (SUCCEEDED(uiDelegate->QueryInterface(IID_IWebUIDelegatePrivate, (void**)&uiPrivate)))
+ uiPrivate->webViewAddMessageToConsole(m_webView, BString(message), line, BString(url), true);
+ }
+}
+
+bool WebChromeClient::canRunBeforeUnloadConfirmPanel()
+{
+ IWebUIDelegate* ui;
+ if (SUCCEEDED(m_webView->uiDelegate(&ui)) && ui) {
+ ui->Release();
+ return true;
+ }
+ return false;
+}
+
+bool WebChromeClient::runBeforeUnloadConfirmPanel(const String& message, Frame* frame)
+{
+ BOOL result = TRUE;
+ IWebUIDelegate* ui;
+ if (SUCCEEDED(m_webView->uiDelegate(&ui)) && ui) {
+ WebFrame* webFrame = kit(frame);
+ ui->runBeforeUnloadConfirmPanelWithMessage(m_webView, BString(message), webFrame, &result);
+ ui->Release();
+ }
+ return !!result;
+}
+
+void WebChromeClient::closeWindowSoon()
+{
+ // We need to remove the parent WebView from WebViewSets here, before it actually
+ // closes, to make sure that JavaScript code that executes before it closes
+ // can't find it. Otherwise, window.open will select a closed WebView instead of
+ // opening a new one <rdar://problem/3572585>.
+
+ // We also need to stop the load to prevent further parsing or JavaScript execution
+ // after the window has torn down <rdar://problem/4161660>.
+
+ // FIXME: This code assumes that the UI delegate will respond to a webViewClose
+ // message by actually closing the WebView. Safari guarantees this behavior, but other apps might not.
+ // This approach is an inherent limitation of not making a close execute immediately
+ // after a call to window.close.
+
+ m_webView->setGroupName(0);
+ m_webView->stopLoading(0);
+ m_webView->closeWindowSoon();
+}
+
+void WebChromeClient::runJavaScriptAlert(Frame*, const String& message)
+{
+ COMPtr<IWebUIDelegate> ui;
+ if (SUCCEEDED(m_webView->uiDelegate(&ui)))
+ ui->runJavaScriptAlertPanelWithMessage(m_webView, BString(message));
+}
+
+bool WebChromeClient::runJavaScriptConfirm(Frame*, const String& message)
+{
+ BOOL result = FALSE;
+ COMPtr<IWebUIDelegate> ui;
+ if (SUCCEEDED(m_webView->uiDelegate(&ui)))
+ ui->runJavaScriptConfirmPanelWithMessage(m_webView, BString(message), &result);
+ return !!result;
+}
+
+bool WebChromeClient::runJavaScriptPrompt(Frame*, const String& message, const String& defaultValue, String& result)
+{
+ COMPtr<IWebUIDelegate> ui;
+ if (FAILED(m_webView->uiDelegate(&ui)))
+ return false;
+
+ TimerBase::fireTimersInNestedEventLoop();
+
+ BSTR resultBSTR = 0;
+ if (FAILED(ui->runJavaScriptTextInputPanelWithPrompt(m_webView, BString(message), BString(defaultValue), &resultBSTR)))
+ return false;
+
+ if (resultBSTR) {
+ result = String(resultBSTR, SysStringLen(resultBSTR));
+ SysFreeString(resultBSTR);
+ return true;
+ }
+
+ return false;
+}
+
+void WebChromeClient::setStatusbarText(const String& statusText)
+{
+ COMPtr<IWebUIDelegate> uiDelegate;
+ if (SUCCEEDED(m_webView->uiDelegate(&uiDelegate))) {
+ uiDelegate->setStatusText(m_webView, BString(statusText));
+ }
+}
+
+bool WebChromeClient::shouldInterruptJavaScript()
+{
+ COMPtr<IWebUIDelegate> uiDelegate;
+ if (SUCCEEDED(m_webView->uiDelegate(&uiDelegate))) {
+ COMPtr<IWebUIDelegatePrivate> uiPrivate;
+ if (SUCCEEDED(uiDelegate->QueryInterface(IID_IWebUIDelegatePrivate, (void**)&uiPrivate))) {
+ BOOL result;
+ if (SUCCEEDED(uiPrivate->webViewShouldInterruptJavaScript(m_webView, &result)))
+ return !!result;
+ }
+ }
+ return false;
+}
+
+bool WebChromeClient::tabsToLinks() const
+{
+ BOOL enabled = FALSE;
+ IWebPreferences* preferences;
+ if (SUCCEEDED(m_webView->preferences(&preferences)))
+ preferences->tabsToLinks(&enabled);
+
+ return !!enabled;
+}
+
+IntRect WebChromeClient::windowResizerRect() const
+{
+ IntRect intRect;
+
+ IWebUIDelegate* ui;
+ if (SUCCEEDED(m_webView->uiDelegate(&ui)) && ui) {
+ IWebUIDelegatePrivate* uiPrivate;
+ if (SUCCEEDED(ui->QueryInterface(IID_IWebUIDelegatePrivate, (void**)&uiPrivate))) {
+ RECT r;
+ if (SUCCEEDED(uiPrivate->webViewResizerRect(m_webView, &r)))
+ intRect = IntRect(r.left, r.top, r.right-r.left, r.bottom-r.top);
+ uiPrivate->Release();
+ }
+ ui->Release();
+ }
+ return intRect;
+}
+
+void WebChromeClient::repaint(const IntRect& windowRect, bool contentChanged, bool immediate, bool repaintContentOnly)
+{
+ ASSERT(core(m_webView->topLevelFrame()));
+ m_webView->repaint(windowRect, contentChanged, immediate, repaintContentOnly);
+}
+
+void WebChromeClient::scroll(const IntSize& delta, const IntRect& scrollViewRect, const IntRect& clipRect)
+{
+ ASSERT(core(m_webView->topLevelFrame()));
+
+ m_webView->scrollBackingStore(core(m_webView->topLevelFrame())->view(), delta.width(), delta.height(), scrollViewRect, clipRect);
+}
+
+IntRect WebChromeClient::windowToScreen(const IntRect& rect) const
+{
+ HWND viewWindow;
+ if (FAILED(m_webView->viewWindow(reinterpret_cast<OLE_HANDLE*>(&viewWindow))))
+ return rect;
+
+ // Find the top left corner of the Widget's containing window in screen coords,
+ // and adjust the result rect's position by this amount.
+ POINT topLeft = {0, 0};
+ IntRect result = rect;
+ ::ClientToScreen(viewWindow, &topLeft);
+ result.move(topLeft.x, topLeft.y);
+
+ return result;
+}
+
+IntPoint WebChromeClient::screenToWindow(const IntPoint& point) const
+{
+ POINT result = point;
+
+ HWND viewWindow;
+ if (FAILED(m_webView->viewWindow(reinterpret_cast<OLE_HANDLE*>(&viewWindow))))
+ return point;
+
+ ::ScreenToClient(viewWindow, &result);
+
+ return result;
+}
+
+PlatformWidget WebChromeClient::platformWindow() const
+{
+ HWND viewWindow;
+ if (FAILED(m_webView->viewWindow(reinterpret_cast<OLE_HANDLE*>(&viewWindow))))
+ return 0;
+ return viewWindow;
+}
+
+void WebChromeClient::mouseDidMoveOverElement(const HitTestResult& result, unsigned modifierFlags)
+{
+ COMPtr<IWebUIDelegate> uiDelegate;
+ if (FAILED(m_webView->uiDelegate(&uiDelegate)))
+ return;
+
+ COMPtr<WebElementPropertyBag> element;
+ element.adoptRef(WebElementPropertyBag::createInstance(result));
+
+ uiDelegate->mouseDidMoveOverElement(m_webView, element.get(), modifierFlags);
+}
+
+void WebChromeClient::setToolTip(const String& toolTip)
+{
+ m_webView->setToolTip(toolTip);
+}
+
+void WebChromeClient::print(Frame* frame)
+{
+ COMPtr<IWebUIDelegate> uiDelegate;
+ COMPtr<IWebUIDelegate2> uiDelegate2;
+ if (SUCCEEDED(m_webView->uiDelegate(&uiDelegate)))
+ if (SUCCEEDED(uiDelegate->QueryInterface(IID_IWebUIDelegate2, (void**)&uiDelegate2)))
+ uiDelegate2->printFrame(m_webView, kit(frame));
+}
+
+void WebChromeClient::exceededDatabaseQuota(Frame* frame, const String& databaseIdentifier)
+{
+ COMPtr<WebSecurityOrigin> origin(AdoptCOM, WebSecurityOrigin::createInstance(frame->document()->securityOrigin()));
+ COMPtr<IWebUIDelegate> uiDelegate;
+ if (SUCCEEDED(m_webView->uiDelegate(&uiDelegate))) {
+ COMPtr<IWebUIDelegatePrivate3> uiDelegatePrivate3(Query, uiDelegate);
+ if (uiDelegatePrivate3)
+ uiDelegatePrivate3->exceededDatabaseQuota(m_webView, kit(frame), origin.get(), BString(databaseIdentifier));
+ else {
+ // FIXME: remove this workaround once shipping Safari has the necessary delegate implemented.
+ TCHAR path[MAX_PATH];
+ HMODULE safariHandle = GetModuleHandle(TEXT("Safari.exe"));
+ if (!safariHandle)
+ return;
+ GetModuleFileName(safariHandle, path, ARRAYSIZE(path));
+ DWORD handle;
+ DWORD versionSize = GetFileVersionInfoSize(path, &handle);
+ if (!versionSize)
+ return;
+ Vector<char> data(versionSize);
+ if (!GetFileVersionInfo(path, 0, versionSize, data.data()))
+ return;
+
+ LPCTSTR productVersion;
+ UINT productVersionLength;
+ if (!VerQueryValue(data.data(), TEXT("\\StringFileInfo\\040904b0\\ProductVersion"), (void**)&productVersion, &productVersionLength))
+ return;
+ if (_tcsncmp(TEXT("3.1"), productVersion, productVersionLength) > 0) {
+ const unsigned long long defaultQuota = 5 * 1024 * 1024; // 5 megabytes should hopefully be enough to test storage support.
+ origin->setQuota(defaultQuota);
+ }
+ }
+ }
+}
+
+void WebChromeClient::populateVisitedLinks()
+{
+ WebHistory* history = WebHistory::sharedHistory();
+ if (!history)
+ return;
+ history->addVisitedLinksToPageGroup(m_webView->page()->group());
+}
+
+bool WebChromeClient::paintCustomScrollbar(GraphicsContext* context, const FloatRect& rect, ScrollbarControlSize size,
+ ScrollbarControlState state, ScrollbarPart pressedPart, bool vertical,
+ float value, float proportion, ScrollbarControlPartMask parts)
+{
+ if (context->paintingDisabled())
+ return false;
+
+ COMPtr<IWebUIDelegate4> delegate = uiDelegate4();
+ if (!delegate)
+ return false;
+
+ WebScrollbarControlPartMask webParts = WebNoScrollPart;
+ if (parts & BackButtonStartPart) // FIXME: Hyatt, what about BackButtonEndPart?
+ webParts |= WebBackButtonPart;
+ if (parts & BackTrackPart)
+ webParts |= WebBackTrackPart;
+ if (parts & ThumbPart)
+ webParts |= WebThumbPart;
+ if (parts & ForwardTrackPart)
+ webParts |= WebForwardTrackPart;
+ if (parts & ForwardButtonStartPart) // FIXME: Hyatt, what about ForwardButtonEndPart?
+ webParts |= WebForwardButtonPart;
+
+ WebScrollbarControlPart webPressedPart = WebNoScrollPart;
+ switch (pressedPart) {
+ case BackButtonStartPart: // FIXME: Hyatt, what about BackButtonEndPart?
+ webPressedPart = WebBackButtonPart;
+ break;
+ case BackTrackPart:
+ webPressedPart = WebBackTrackPart;
+ break;
+ case ThumbPart:
+ webPressedPart = WebThumbPart;
+ break;
+ case ForwardTrackPart:
+ webPressedPart = WebForwardTrackPart;
+ break;
+ case ForwardButtonStartPart: // FIXME: Hyatt, what about ForwardButtonEndPart?
+ webPressedPart = WebForwardButtonPart;
+ break;
+ default:
+ break;
+ }
+
+ WebScrollBarControlSize webSize;
+ switch (size) {
+ case SmallScrollbar:
+ webSize = WebSmallScrollbar;
+ break;
+ case RegularScrollbar:
+ default:
+ webSize = WebRegularScrollbar;
+ }
+ WebScrollbarControlState webState = 0;
+ if (state & ActiveScrollbarState)
+ webState |= WebActiveScrollbarState;
+ if (state & EnabledScrollbarState)
+ webState |= WebEnabledScrollbarState;
+ if (state & PressedScrollbarState)
+ webState |= WebPressedScrollbarState;
+
+ RECT webRect = enclosingIntRect(rect);
+ HDC hDC = context->getWindowsContext(webRect);
+ HRESULT hr = delegate->paintCustomScrollbar(m_webView, hDC, webRect, webSize, webState, webPressedPart,
+ vertical, value, proportion, webParts);
+ context->releaseWindowsContext(hDC, webRect);
+ return SUCCEEDED(hr);
+}
+
+bool WebChromeClient::paintCustomScrollCorner(GraphicsContext* context, const FloatRect& rect)
+{
+ if (context->paintingDisabled())
+ return false;
+
+ COMPtr<IWebUIDelegate4> delegate = uiDelegate4();
+ if (!delegate)
+ return false;
+
+ RECT webRect = enclosingIntRect(rect);
+ HDC hDC = context->getWindowsContext(webRect);
+ HRESULT hr = delegate->paintCustomScrollCorner(m_webView, hDC, webRect);
+ context->releaseWindowsContext(hDC, webRect);
+ return SUCCEEDED(hr);
+}
+
+void WebChromeClient::runOpenPanel(Frame*, PassRefPtr<FileChooser> prpFileChooser)
+{
+ RefPtr<FileChooser> fileChooser = prpFileChooser;
+
+ HWND viewWindow;
+ if (FAILED(m_webView->viewWindow(reinterpret_cast<OLE_HANDLE*>(&viewWindow))))
+ return;
+
+ bool multiFile = fileChooser->allowsMultipleFiles();
+ Vector<TCHAR> fileBuf(multiFile ? maxFilePathsListSize : MAX_PATH);
+
+ OPENFILENAME ofn;
+
+ memset(&ofn, 0, sizeof(ofn));
+
+ // Need to zero out the first char of fileBuf so GetOpenFileName doesn't think it's an initialization string
+ fileBuf[0] = '\0';
+
+ ofn.lStructSize = sizeof(ofn);
+ ofn.hwndOwner = viewWindow;
+ String allFiles = allFilesText();
+ allFiles.append(TEXT("\0*.*\0\0"), 6);
+ ofn.lpstrFilter = allFiles.charactersWithNullTermination();
+ ofn.lpstrFile = fileBuf.data();
+ ofn.nMaxFile = fileBuf.size();
+ String dialogTitle = uploadFileText();
+ ofn.lpstrTitle = dialogTitle.charactersWithNullTermination();
+ ofn.Flags = OFN_ENABLESIZING | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_EXPLORER;
+ if (multiFile)
+ ofn.Flags = ofn.Flags | OFN_ALLOWMULTISELECT;
+
+ if (GetOpenFileName(&ofn)) {
+ TCHAR* files = fileBuf.data();
+ Vector<String> fileList;
+ String file(files);
+ if (multiFile) {
+ while (!file.isEmpty()) {
+ // When using the OFN_EXPLORER flag, the file list is null delimited.
+ // When you create a String from a ptr to this list, it will use strlen to look for the null character.
+ // Then we find the next file path string by using the length of the string we just created.
+ TCHAR* nextFilePtr = files + file.length() + 1;
+ String nextFile(nextFilePtr);
+ // If multiple files are selected, there will be a directory name first, which we don't want to add to the vector.
+ // We know a single file was selected if there is only one filename in the list.
+ // In that case, we don't want to skip adding the first (and only) name.
+ if (files != fileBuf.data() || nextFile.isEmpty())
+ fileList.append(file);
+ files = nextFilePtr;
+ file = nextFile;
+ }
+ } else
+ fileList.append(file);
+ ASSERT(fileList.size());
+ fileChooser->chooseFiles(fileList);
+ }
+ // FIXME: Show some sort of error if too many files are selected and the buffer is too small. For now, this will fail silently.
+}
+
+COMPtr<IWebUIDelegate> WebChromeClient::uiDelegate()
+{
+ COMPtr<IWebUIDelegate> delegate;
+ m_webView->uiDelegate(&delegate);
+ return delegate;
+}
+
+COMPtr<IWebUIDelegate2> WebChromeClient::uiDelegate2()
+{
+ return COMPtr<IWebUIDelegate2>(Query, uiDelegate());
+}
+
+COMPtr<IWebUIDelegate3> WebChromeClient::uiDelegate3()
+{
+ return COMPtr<IWebUIDelegate3>(Query, uiDelegate());
+}
+
+COMPtr<IWebUIDelegate4> WebChromeClient::uiDelegate4()
+{
+ return COMPtr<IWebUIDelegate4>(Query, uiDelegate());
+}
diff --git a/WebKit/win/WebCoreSupport/WebChromeClient.h b/WebKit/win/WebCoreSupport/WebChromeClient.h
new file mode 100644
index 0000000..83c5a70
--- /dev/null
+++ b/WebKit/win/WebCoreSupport/WebChromeClient.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <WebCore/ChromeClient.h>
+#include <WebCore/COMPtr.h>
+#include <WebCore/GraphicsContext.h>
+#include <WebCore/FocusDirection.h>
+#include <WebCore/ScrollTypes.h>
+#include <wtf/Forward.h>
+
+class WebView;
+
+interface IWebUIDelegate;
+interface IWebUIDelegate2;
+interface IWebUIDelegate3;
+interface IWebUIDelegate4;
+
+class WebChromeClient : public WebCore::ChromeClient {
+public:
+ WebChromeClient(WebView*);
+
+ virtual void chromeDestroyed();
+
+ virtual void setWindowRect(const WebCore::FloatRect&);
+ virtual WebCore::FloatRect windowRect();
+
+ virtual WebCore::FloatRect pageRect();
+
+ virtual float scaleFactor();
+
+ virtual void focus();
+ virtual void unfocus();
+
+ virtual bool canTakeFocus(WebCore::FocusDirection);
+ virtual void takeFocus(WebCore::FocusDirection);
+
+ virtual WebCore::Page* createWindow(WebCore::Frame*, const WebCore::FrameLoadRequest&, const WebCore::WindowFeatures&);
+ virtual void show();
+
+ virtual bool canRunModal();
+ virtual void runModal();
+
+ virtual void setToolbarsVisible(bool);
+ virtual bool toolbarsVisible();
+
+ virtual void setStatusbarVisible(bool);
+ virtual bool statusbarVisible();
+
+ virtual void setScrollbarsVisible(bool);
+ virtual bool scrollbarsVisible();
+
+ virtual void setMenubarVisible(bool);
+ virtual bool menubarVisible();
+
+ virtual void setResizable(bool);
+
+ virtual void addMessageToConsole(const WebCore::String& message, unsigned line, const WebCore::String& url);
+
+ virtual bool canRunBeforeUnloadConfirmPanel();
+ virtual bool runBeforeUnloadConfirmPanel(const WebCore::String& message, WebCore::Frame* frame);
+
+ virtual void closeWindowSoon();
+
+ virtual void runJavaScriptAlert(WebCore::Frame*, const WebCore::String&);
+ virtual bool runJavaScriptConfirm(WebCore::Frame*, const WebCore::String&);
+ virtual bool runJavaScriptPrompt(WebCore::Frame*, const WebCore::String& message, const WebCore::String& defaultValue, WebCore::String& result);
+ virtual void setStatusbarText(const WebCore::String&);
+ virtual bool shouldInterruptJavaScript();
+
+ virtual bool tabsToLinks() const;
+ virtual WebCore::IntRect windowResizerRect() const;
+
+ virtual void repaint(const WebCore::IntRect&, bool contentChanged, bool immediate = false, bool repaintContentOnly = false);
+ virtual void scroll(const WebCore::IntSize& scrollDelta, const WebCore::IntRect& rectToScroll, const WebCore::IntRect& clipRect);
+ virtual WebCore::IntPoint screenToWindow(const WebCore::IntPoint& p) const;
+ virtual WebCore::IntRect windowToScreen(const WebCore::IntRect& r) const;
+ virtual PlatformWidget platformWindow() const;
+
+ virtual void mouseDidMoveOverElement(const WebCore::HitTestResult&, unsigned modifierFlags);
+
+ virtual void setToolTip(const WebCore::String&);
+
+ virtual void print(WebCore::Frame*);
+
+ virtual void exceededDatabaseQuota(WebCore::Frame*, const WebCore::String&);
+
+ virtual void populateVisitedLinks();
+
+ virtual bool paintCustomScrollbar(WebCore::GraphicsContext*, const WebCore::FloatRect&, WebCore::ScrollbarControlSize,
+ WebCore::ScrollbarControlState, WebCore::ScrollbarPart pressedPart, bool vertical,
+ float value, float proportion, WebCore::ScrollbarControlPartMask);
+ virtual bool paintCustomScrollCorner(WebCore::GraphicsContext*, const WebCore::FloatRect&);
+
+ virtual void runOpenPanel(WebCore::Frame*, PassRefPtr<WebCore::FileChooser>);
+
+ WebView* webView() const { return m_webView; }
+
+private:
+ COMPtr<IWebUIDelegate> uiDelegate();
+ COMPtr<IWebUIDelegate2> uiDelegate2();
+ COMPtr<IWebUIDelegate3> uiDelegate3();
+ COMPtr<IWebUIDelegate4> uiDelegate4();
+
+ WebView* m_webView;
+};
diff --git a/WebKit/win/WebCoreSupport/WebContextMenuClient.cpp b/WebKit/win/WebCoreSupport/WebContextMenuClient.cpp
new file mode 100644
index 0000000..be7b483
--- /dev/null
+++ b/WebKit/win/WebCoreSupport/WebContextMenuClient.cpp
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebContextMenuClient.h"
+
+#include "WebDownload.h"
+#include "WebElementPropertyBag.h"
+#include "WebLocalizableStrings.h"
+#include "WebView.h"
+
+#pragma warning(push, 0)
+#include <WebCore/ContextMenu.h>
+#include <WebCore/FrameLoader.h>
+#include <WebCore/FrameLoadRequest.h>
+#include <WebCore/Page.h>
+#include <WebCore/ResourceRequest.h>
+#include <WebCore/NotImplemented.h>
+#pragma warning(pop)
+
+#include <tchar.h>
+
+using namespace WebCore;
+
+WebContextMenuClient::WebContextMenuClient(WebView* webView)
+ : m_webView(webView)
+{
+}
+
+void WebContextMenuClient::contextMenuDestroyed()
+{
+ delete this;
+}
+
+static bool isPreInspectElementTagSafari(IWebUIDelegate* uiDelegate)
+{
+ if (!uiDelegate)
+ return false;
+
+ // We assume anyone who implements IWebUIDelegate2 also knows about the Inspect Element item.
+ COMPtr<IWebUIDelegate2> uiDelegate2;
+ if (SUCCEEDED(uiDelegate->QueryInterface(IID_IWebUIDelegate2, (void**)&uiDelegate2)))
+ return false;
+
+ TCHAR modulePath[MAX_PATH];
+ DWORD length = ::GetModuleFileName(0, modulePath, _countof(modulePath));
+ if (!length)
+ return false;
+
+ return String(modulePath, length).endsWith("Safari.exe", false);
+}
+
+static HMENU fixMenuReceivedFromOldSafari(IWebUIDelegate* uiDelegate, ContextMenu* originalMenu, HMENU menuFromClient)
+{
+ ASSERT_ARG(originalMenu, originalMenu);
+ if (!isPreInspectElementTagSafari(uiDelegate))
+ return menuFromClient;
+
+ int count = ::GetMenuItemCount(originalMenu->platformDescription());
+ if (count < 1)
+ return menuFromClient;
+
+ if (::GetMenuItemID(originalMenu->platformDescription(), count - 1) != WebMenuItemTagInspectElement)
+ return menuFromClient;
+
+ count = ::GetMenuItemCount(menuFromClient);
+ if (count < 1)
+ return menuFromClient;
+
+ if (::GetMenuItemID(menuFromClient, count - 1) == WebMenuItemTagInspectElement)
+ return menuFromClient;
+
+ originalMenu->setPlatformDescription(menuFromClient);
+ originalMenu->addInspectElementItem();
+ return originalMenu->platformDescription();
+}
+
+HMENU WebContextMenuClient::getCustomMenuFromDefaultItems(ContextMenu* menu)
+{
+ COMPtr<IWebUIDelegate> uiDelegate;
+ if (FAILED(m_webView->uiDelegate(&uiDelegate)))
+ return menu->platformDescription();
+
+ ASSERT(uiDelegate);
+
+ HMENU newMenu = 0;
+ COMPtr<WebElementPropertyBag> propertyBag;
+ propertyBag.adoptRef(WebElementPropertyBag::createInstance(menu->hitTestResult()));
+ // FIXME: We need to decide whether to do the default before calling this delegate method
+ if (FAILED(uiDelegate->contextMenuItemsForElement(m_webView, propertyBag.get(), (OLE_HANDLE)(ULONG64)menu->platformDescription(), (OLE_HANDLE*)&newMenu)))
+ return menu->platformDescription();
+ return fixMenuReceivedFromOldSafari(uiDelegate.get(), menu, newMenu);
+}
+
+void WebContextMenuClient::contextMenuItemSelected(ContextMenuItem* item, const ContextMenu* parentMenu)
+{
+ ASSERT(item->type() == ActionType || item->type() == CheckableActionType);
+
+ COMPtr<IWebUIDelegate> uiDelegate;
+ if (FAILED(m_webView->uiDelegate(&uiDelegate)))
+ return;
+
+ ASSERT(uiDelegate);
+
+ COMPtr<WebElementPropertyBag> propertyBag;
+ propertyBag.adoptRef(WebElementPropertyBag::createInstance(parentMenu->hitTestResult()));
+
+ uiDelegate->contextMenuItemSelected(m_webView, item->releasePlatformDescription(), propertyBag.get());
+}
+
+void WebContextMenuClient::downloadURL(const KURL& url)
+{
+ COMPtr<IWebDownloadDelegate> downloadDelegate;
+ if (FAILED(m_webView->downloadDelegate(&downloadDelegate))) {
+ // If the WebView doesn't successfully provide a download delegate we'll pass a null one
+ // into the WebDownload - which may or may not decide to use a DefaultDownloadDelegate
+ LOG_ERROR("Failed to get downloadDelegate from WebView");
+ downloadDelegate = 0;
+ }
+
+ // Its the delegate's job to ref the WebDownload to keep it alive - otherwise it will be destroyed
+ // when this method returns
+ COMPtr<WebDownload> download;
+ download.adoptRef(WebDownload::createInstance(url, downloadDelegate.get()));
+ download->start();
+}
+
+void WebContextMenuClient::searchWithGoogle(const Frame* frame)
+{
+ String searchString = frame->selectedText();
+ searchString.stripWhiteSpace();
+ String encoded = encodeWithURLEscapeSequences(searchString);
+ encoded.replace("%20", "+");
+
+ String url("http://www.google.com/search?q=");
+ url.append(encoded);
+ url.append("&ie=UTF-8&oe=UTF-8");
+
+ ResourceRequest request = ResourceRequest(url);
+ if (Page* page = frame->page())
+ page->mainFrame()->loader()->urlSelected(FrameLoadRequest(request), 0, false);
+}
+
+void WebContextMenuClient::lookUpInDictionary(Frame*)
+{
+ notImplemented();
+}
+
+void WebContextMenuClient::speak(const String&)
+{
+ notImplemented();
+}
+
+void WebContextMenuClient::stopSpeaking()
+{
+ notImplemented();
+}
diff --git a/WebKit/win/WebCoreSupport/WebContextMenuClient.h b/WebKit/win/WebCoreSupport/WebContextMenuClient.h
new file mode 100644
index 0000000..a981f4e
--- /dev/null
+++ b/WebKit/win/WebCoreSupport/WebContextMenuClient.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <WebCore/ContextMenuClient.h>
+#include <wtf/Forward.h>
+
+namespace WebCore {
+ class String;
+}
+class WebView;
+
+class WebContextMenuClient : public WebCore::ContextMenuClient {
+public:
+ WebContextMenuClient(WebView*);
+
+ virtual void contextMenuDestroyed();
+
+ virtual HMENU getCustomMenuFromDefaultItems(WebCore::ContextMenu*);
+ virtual void contextMenuItemSelected(WebCore::ContextMenuItem*, const WebCore::ContextMenu*);
+
+ virtual void downloadURL(const WebCore::KURL&);
+ virtual void searchWithGoogle(const WebCore::Frame*);
+ virtual void lookUpInDictionary(WebCore::Frame*);
+ virtual void speak(const WebCore::String&);
+ virtual void stopSpeaking();
+
+private:
+ WebView* m_webView;
+};
diff --git a/WebKit/win/WebCoreSupport/WebDragClient.cpp b/WebKit/win/WebCoreSupport/WebDragClient.cpp
new file mode 100644
index 0000000..c35991f
--- /dev/null
+++ b/WebKit/win/WebCoreSupport/WebDragClient.cpp
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebDragClient.h"
+#include "WebDropSource.h"
+#include "WebKitGraphics.h"
+#include "WebView.h"
+
+#include <shlobj.h>
+#include <CoreGraphics/CoreGraphics.h>
+
+#pragma warning(push, 0)
+#include <WebCore/ClipboardWin.h>
+#include <WebCore/DragData.h>
+#include <WebCore/Font.h>
+#include <WebCore/FontDescription.h>
+#include <WebCore/FontSelector.h>
+#include <WebCore/FrameView.h>
+#include <WebCore/GraphicsContext.h>
+#include <WebCore/Page.h>
+#include <WebCore/StringTruncator.h>
+#include <WebCore/WebCoreTextRenderer.h>
+#pragma warning(pop)
+
+namespace WebCore {
+ HBITMAP allocImage(HDC dc, IntSize size, CGContextRef *targetRef);
+}
+
+
+#define DRAG_LABEL_BORDER_X 4
+// Keep border_y in synch with DragController::LinkDragBorderInset
+#define DRAG_LABEL_BORDER_Y 2
+#define DRAG_LABEL_RADIUS 5
+#define DRAG_LABEL_BORDER_Y_OFFSET 2
+
+#define MIN_DRAG_LABEL_WIDTH_BEFORE_CLIP 120
+
+// Observation says max size is 200x200
+#define MAX_DRAG_LABEL_WIDTH 200
+#define MAX_DRAG_LABEL_STRING_WIDTH (MAX_DRAG_LABEL_WIDTH - 2 * DRAG_LABEL_BORDER_X)
+
+#define DRAG_LINK_LABEL_FONT_SIZE 11
+#define DRAG_LINK_URL_FONT_SIZE 10
+
+using namespace WebCore;
+
+WebDragClient::WebDragClient(WebView* webView)
+ : m_webView(webView)
+{
+ ASSERT(webView);
+}
+
+DragDestinationAction WebDragClient::actionMaskForDrag(DragData* dragData)
+{
+ COMPtr<IWebUIDelegate> delegateRef = 0;
+ //Default behaviour (eg. no delegate, or callback not implemented) is to allow
+ //any action
+ WebDragDestinationAction mask = WebDragDestinationActionAny;
+ if (SUCCEEDED(m_webView->uiDelegate(&delegateRef)))
+ delegateRef->dragDestinationActionMaskForDraggingInfo(m_webView, dragData->platformData(), &mask);
+
+ return (DragDestinationAction)mask;
+}
+
+void WebDragClient::willPerformDragDestinationAction(DragDestinationAction action, DragData* dragData)
+{
+ //Default delegate for willPerformDragDestinationAction has no side effects
+ //so we just call the delegate, and don't worry about whether it's implemented
+ COMPtr<IWebUIDelegate> delegateRef = 0;
+ if (SUCCEEDED(m_webView->uiDelegate(&delegateRef)))
+ delegateRef->willPerformDragDestinationAction(m_webView, (WebDragDestinationAction)action, dragData->platformData());
+}
+
+DragSourceAction WebDragClient::dragSourceActionMaskForPoint(const IntPoint& windowPoint)
+{
+ COMPtr<IWebUIDelegate> delegateRef = 0;
+ WebDragSourceAction action = WebDragSourceActionAny;
+ POINT localpt = core(m_webView)->mainFrame()->view()->windowToContents(windowPoint);
+ if (SUCCEEDED(m_webView->uiDelegate(&delegateRef)))
+ delegateRef->dragSourceActionMaskForPoint(m_webView, &localpt, &action);
+ return (DragSourceAction)action;
+}
+
+void WebDragClient::willPerformDragSourceAction(DragSourceAction, const IntPoint&, Clipboard*)
+{
+}
+
+void WebDragClient::startDrag(DragImageRef image, const IntPoint& imageOrigin, const IntPoint& dragPoint, Clipboard* clipboard, Frame* frame, bool isLink)
+{
+ //FIXME: Allow UIDelegate to override behaviour <rdar://problem/5015953>
+
+ //We liberally protect everything, to protect against a load occurring mid-drag
+ RefPtr<Frame> frameProtector = frame;
+ COMPtr<IDragSourceHelper> helper;
+ COMPtr<IDataObject> dataObject;
+ COMPtr<WebView> viewProtector = m_webView;
+ COMPtr<IDropSource> source;
+ if (FAILED(WebDropSource::createInstance(m_webView, &source)))
+ return;
+
+ dataObject = static_cast<ClipboardWin*>(clipboard)->dataObject();
+ if (source && (image || dataObject)) {
+ if (image) {
+ if(SUCCEEDED(CoCreateInstance(CLSID_DragDropHelper, 0, CLSCTX_INPROC_SERVER,
+ IID_IDragSourceHelper,(LPVOID*)&helper))) {
+ BITMAP b;
+ GetObject(image, sizeof(BITMAP), &b);
+ SHDRAGIMAGE sdi;
+ sdi.sizeDragImage.cx = b.bmWidth;
+ sdi.sizeDragImage.cy = b.bmHeight;
+ sdi.crColorKey = 0xffffffff;
+ sdi.hbmpDragImage = image;
+ sdi.ptOffset.x = dragPoint.x() - imageOrigin.x();
+ sdi.ptOffset.y = dragPoint.y() - imageOrigin.y();
+ if (isLink)
+ sdi.ptOffset.y = b.bmHeight - sdi.ptOffset.y;
+
+ helper->InitializeFromBitmap(&sdi, dataObject.get());
+ }
+ }
+
+ //FIXME: Ensure correct drag ops are available <rdar://problem/5015957>
+ DWORD okEffect = DROPEFFECT_COPY | DROPEFFECT_LINK | DROPEFFECT_MOVE;
+ DWORD effect;
+ COMPtr<IWebUIDelegate> ui;
+ if (SUCCEEDED(m_webView->uiDelegate(&ui))) {
+ COMPtr<IWebUIDelegatePrivate> uiPrivate;
+ if (SUCCEEDED(ui->QueryInterface(IID_IWebUIDelegatePrivate, (void**)&uiPrivate)))
+ if (SUCCEEDED(uiPrivate->doDragDrop(m_webView, dataObject.get(), source.get(), okEffect, &effect)))
+ return;
+ }
+
+ DoDragDrop(dataObject.get(), source.get(), okEffect, &effect);
+ }
+}
+
+static Font dragLabelFont(int size, bool bold)
+{
+ FontDescription desc;
+ desc.setWeight(bold ? FontWeightBold : FontWeightNormal);
+ FontFamily family;
+ family.setFamily("Lucida Grande");
+ desc.setFamily(family);
+ desc.setSpecifiedSize((float)size);
+ desc.setComputedSize((float)size);
+ Font result = Font(desc, 0, 0);
+ result.update(0);
+ return result;
+}
+
+DragImageRef WebDragClient::createDragImageForLink(KURL& url, const String& inLabel, Frame*)
+{
+ //This is more or less an exact match for the MacOS code
+ static const Font labelFont = dragLabelFont(DRAG_LINK_LABEL_FONT_SIZE, true);
+ static const Font urlFont = dragLabelFont(DRAG_LINK_URL_FONT_SIZE, false);
+ bool drawURLString = true;
+ bool clipURLString = false;
+ bool clipLabelString = false;
+
+ String urlString = url.string();
+ String label = inLabel;
+ if (label.isEmpty()) {
+ drawURLString = false;
+ label = urlString;
+ }
+
+ //First step in drawing the link drag image width
+ TextRun labelRun(label.impl());
+ TextRun urlRun(urlString.impl());
+ IntSize labelSize(labelFont.width(labelRun), labelFont.ascent() + labelFont.descent());
+
+ if (labelSize.width() > MAX_DRAG_LABEL_STRING_WIDTH){
+ labelSize.setWidth(MAX_DRAG_LABEL_STRING_WIDTH);
+ clipLabelString = true;
+ }
+
+ IntSize urlStringSize;
+ IntSize imageSize(labelSize.width() + DRAG_LABEL_BORDER_X * 2,
+ labelSize.height() + DRAG_LABEL_BORDER_Y * 2);
+
+ if (drawURLString) {
+ urlStringSize.setWidth(urlFont.width(urlRun));
+ urlStringSize.setHeight(urlFont.ascent() + urlFont.descent());
+ imageSize.setHeight(imageSize.height() + urlStringSize.height());
+ if (urlStringSize.width() > MAX_DRAG_LABEL_STRING_WIDTH) {
+ imageSize.setWidth(MAX_DRAG_LABEL_WIDTH);
+ clipURLString = true;
+ } else {
+ imageSize.setWidth(std::max(labelSize.width(), urlStringSize.width()) + DRAG_LABEL_BORDER_X * 2);
+ }
+ }
+
+ // We now know how big the image needs to be, so we create and
+ // fill the background
+ HBITMAP image = 0;
+ HDC dc = GetDC(0);
+ HDC workingDC = CreateCompatibleDC(dc);
+ if (!workingDC) {
+ ReleaseDC(0, dc);
+ return 0;
+ }
+
+ CGContextRef contextRef;
+ image = allocImage(workingDC, imageSize, &contextRef);
+ if (!image) {
+ DeleteDC(workingDC);
+ ReleaseDC(0, dc);
+ return 0;
+ }
+
+ ::SelectObject(workingDC, image);
+ GraphicsContext context(contextRef);
+ // On Mac alpha is {0.7, 0.7, 0.7, 0.8}, however we can't control alpha
+ // for drag images on win, so we use 1
+ static const Color backgroundColor(140, 140, 140);
+ static const IntSize radii(DRAG_LABEL_RADIUS, DRAG_LABEL_RADIUS);
+ context.setFont(labelFont);
+ IntRect rect(0, 0, imageSize.width(), imageSize.height());
+ context.fillRoundedRect(rect, radii, radii, radii, radii, backgroundColor);
+
+ // Draw the text
+ static const Color topColor(0, 0, 0, 255); //original alpha = 0.75
+ static const Color bottomColor(255, 255, 255, 127); //original alpha = 0.5
+ if (drawURLString) {
+ if (clipURLString)
+ urlString = StringTruncator::rightTruncate(urlString, imageSize.width() - (DRAG_LABEL_BORDER_X * 2.0f), urlFont, false);
+ IntPoint textPos(DRAG_LABEL_BORDER_X, imageSize.height() - (DRAG_LABEL_BORDER_Y_OFFSET + urlFont.descent()));
+ WebCoreDrawDoubledTextAtPoint(context, urlString, textPos, urlFont, topColor, bottomColor);
+ }
+
+ if (clipLabelString)
+ label = StringTruncator::rightTruncate(label, imageSize.width() - (DRAG_LABEL_BORDER_X * 2.0f), labelFont, false);
+
+ IntPoint textPos(DRAG_LABEL_BORDER_X, DRAG_LABEL_BORDER_Y + labelFont.pixelSize());
+ WebCoreDrawDoubledTextAtPoint(context, label, textPos, labelFont, topColor, bottomColor);
+
+ CGContextRelease(contextRef);
+ DeleteDC(workingDC);
+ ReleaseDC(0, dc);
+ return image;
+}
+
+void WebDragClient::dragControllerDestroyed()
+{
+ delete this;
+}
diff --git a/WebKit/win/WebCoreSupport/WebDragClient.h b/WebKit/win/WebCoreSupport/WebDragClient.h
new file mode 100644
index 0000000..f7ca139
--- /dev/null
+++ b/WebKit/win/WebCoreSupport/WebDragClient.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <WebCore/DragClient.h>
+
+class WebView;
+
+class WebDragClient : public WebCore::DragClient {
+public:
+ WebDragClient(WebView*);
+ virtual WebCore::DragDestinationAction actionMaskForDrag(WebCore::DragData*);
+ virtual void willPerformDragDestinationAction(WebCore::DragDestinationAction, WebCore::DragData*);
+ virtual void dragControllerDestroyed();
+ virtual WebCore::DragSourceAction dragSourceActionMaskForPoint(const WebCore::IntPoint&);
+ virtual void willPerformDragSourceAction(WebCore::DragSourceAction, const WebCore::IntPoint&, WebCore::Clipboard*);
+ virtual void startDrag(WebCore::DragImageRef, const WebCore::IntPoint&, const WebCore::IntPoint&, WebCore::Clipboard*, WebCore::Frame*, bool);
+ virtual WebCore::DragImageRef createDragImageForLink(WebCore::KURL&, const WebCore::String&, WebCore::Frame*);
+private:
+ WebView* m_webView;
+};
+
diff --git a/WebKit/win/WebCoreSupport/WebEditorClient.cpp b/WebKit/win/WebCoreSupport/WebEditorClient.cpp
new file mode 100644
index 0000000..e38cd0d
--- /dev/null
+++ b/WebKit/win/WebCoreSupport/WebEditorClient.cpp
@@ -0,0 +1,762 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebKitDLL.h"
+#include "WebEditorClient.h"
+
+#include "WebKit.h"
+#include "WebLocalizableStrings.h"
+#include "WebView.h"
+#include "DOMCoreClasses.h"
+#pragma warning(push, 0)
+#include <WebCore/BString.h>
+#include <WebCore/Document.h>
+#include <WebCore/EditCommand.h>
+#include <WebCore/HTMLElement.h>
+#include <WebCore/HTMLInputElement.h>
+#include <WebCore/HTMLNames.h>
+#include <WebCore/KeyboardEvent.h>
+#include <WebCore/PlatformKeyboardEvent.h>
+#include <WebCore/NotImplemented.h>
+#include <WebCore/Range.h>
+#pragma warning(pop)
+
+using namespace WebCore;
+using namespace HTMLNames;
+
+// {09A11D2B-FAFB-4ca0-A6F7-791EE8932C88}
+static const GUID IID_IWebUndoCommand =
+{ 0x9a11d2b, 0xfafb, 0x4ca0, { 0xa6, 0xf7, 0x79, 0x1e, 0xe8, 0x93, 0x2c, 0x88 } };
+
+class IWebUndoCommand : public IUnknown {
+public:
+ virtual void execute() = 0;
+};
+
+// WebEditorUndoTarget -------------------------------------------------------------
+
+class WebEditorUndoTarget : public IWebUndoTarget
+{
+public:
+ WebEditorUndoTarget();
+
+ // IUnknown
+ virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject);
+ virtual ULONG STDMETHODCALLTYPE AddRef(void);
+ virtual ULONG STDMETHODCALLTYPE Release(void);
+
+ // IWebUndoTarget
+ virtual HRESULT STDMETHODCALLTYPE invoke(
+ /* [in] */ BSTR actionName,
+ /* [in] */ IUnknown *obj);
+
+private:
+ ULONG m_refCount;
+};
+
+WebEditorUndoTarget::WebEditorUndoTarget()
+: m_refCount(1)
+{
+}
+
+HRESULT STDMETHODCALLTYPE WebEditorUndoTarget::QueryInterface(REFIID riid, void** ppvObject)
+{
+ *ppvObject = 0;
+ if (IsEqualGUID(riid, IID_IUnknown))
+ *ppvObject = static_cast<IWebUndoTarget*>(this);
+ else if (IsEqualGUID(riid, IID_IWebUndoTarget))
+ *ppvObject = static_cast<IWebUndoTarget*>(this);
+ else
+ return E_NOINTERFACE;
+
+ AddRef();
+ return S_OK;
+}
+
+ULONG STDMETHODCALLTYPE WebEditorUndoTarget::AddRef(void)
+{
+ return ++m_refCount;
+}
+
+ULONG STDMETHODCALLTYPE WebEditorUndoTarget::Release(void)
+{
+ ULONG newRef = --m_refCount;
+ if (!newRef)
+ delete(this);
+
+ return newRef;
+}
+
+HRESULT STDMETHODCALLTYPE WebEditorUndoTarget::invoke(
+ /* [in] */ BSTR /*actionName*/,
+ /* [in] */ IUnknown *obj)
+{
+ IWebUndoCommand* undoCommand = 0;
+ if (SUCCEEDED(obj->QueryInterface(IID_IWebUndoCommand, (void**)&undoCommand))) {
+ undoCommand->execute();
+ undoCommand->Release();
+ }
+ return S_OK;
+}
+
+// WebEditorClient ------------------------------------------------------------------
+
+WebEditorClient::WebEditorClient(WebView* webView)
+ : m_webView(webView)
+ , m_undoTarget(0)
+{
+ m_undoTarget = new WebEditorUndoTarget();
+}
+
+WebEditorClient::~WebEditorClient()
+{
+ if (m_undoTarget)
+ m_undoTarget->Release();
+}
+
+void WebEditorClient::pageDestroyed()
+{
+ delete this;
+}
+
+bool WebEditorClient::isContinuousSpellCheckingEnabled()
+{
+ BOOL enabled;
+ if (FAILED(m_webView->isContinuousSpellCheckingEnabled(&enabled)))
+ return false;
+ return !!enabled;
+}
+
+void WebEditorClient::toggleContinuousSpellChecking()
+{
+ m_webView->toggleContinuousSpellChecking(0);
+}
+
+bool WebEditorClient::isGrammarCheckingEnabled()
+{
+ BOOL enabled;
+ if (FAILED(m_webView->isGrammarCheckingEnabled(&enabled)))
+ return false;
+ return !!enabled;
+}
+
+void WebEditorClient::toggleGrammarChecking()
+{
+ m_webView->toggleGrammarChecking(0);
+}
+
+static void initViewSpecificSpelling(IWebViewEditing* viewEditing)
+{
+ // we just use this as a flag to indicate that we've spell checked the document
+ // and need to close the spell checker out when the view closes.
+ int tag;
+ viewEditing->spellCheckerDocumentTag(&tag);
+}
+
+int WebEditorClient::spellCheckerDocumentTag()
+{
+ // we don't use the concept of spelling tags
+ notImplemented();
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+bool WebEditorClient::shouldBeginEditing(Range*)
+{
+ notImplemented();
+ return true;
+}
+
+bool WebEditorClient::shouldEndEditing(Range*)
+{
+ notImplemented();
+ return true;
+}
+
+void WebEditorClient::didBeginEditing()
+{
+ notImplemented();
+}
+
+void WebEditorClient::respondToChangedContents()
+{
+ notImplemented();
+}
+
+void WebEditorClient::respondToChangedSelection()
+{
+ m_webView->selectionChanged();
+}
+
+void WebEditorClient::didEndEditing()
+{
+ notImplemented();
+}
+
+void WebEditorClient::didWriteSelectionToPasteboard()
+{
+ notImplemented();
+}
+
+void WebEditorClient::didSetSelectionTypesForPasteboard()
+{
+ notImplemented();
+}
+
+bool WebEditorClient::shouldDeleteRange(Range* /*range*/)
+{
+ notImplemented();
+ 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);
+ //if (SUCCEEDED(m_webView->editingDelegate(&editingDelegate))) {
+ // editingDelegate->shouldDeleteDOMRange(m_webView, domRange, &result);
+ // editingDelegate->Release();
+ //}
+ //return !!result;
+}
+
+bool WebEditorClient::shouldInsertNode(Node* /*node*/, Range* /*replacingRange*/, EditorInsertAction /*givenAction*/)
+{
+ notImplemented();
+ return true;
+}
+
+bool WebEditorClient::shouldInsertText(const String& /*str*/, Range* /* replacingRange */, EditorInsertAction /*givenAction*/)
+{
+ notImplemented();
+ 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;
+}
+
+//bool WebEditorClient::shouldChangeSelectedRange(Range *currentRange, Range *toProposedRange, SelectionAffinity selectionAffinity, bool stillSelecting)
+//{ notImplemented(); return false; }
+
+bool WebEditorClient::shouldApplyStyle(CSSStyleDeclaration* /*style*/, Range* /*toElementsInDOMRange*/)
+{ notImplemented(); return true; }
+
+bool WebEditorClient::shouldMoveRangeAfterDelete(Range* /*range*/, Range* /*rangeToBeReplaced*/)
+{ notImplemented(); return true; }
+
+bool WebEditorClient::shouldChangeTypingStyle(CSSStyleDeclaration* /*currentStyle*/, CSSStyleDeclaration* /*toProposedStyle*/)
+{ notImplemented(); return false; }
+
+void WebEditorClient::webViewDidChangeTypingStyle(WebNotification* /*notification*/)
+{ notImplemented(); }
+
+void WebEditorClient::webViewDidChangeSelection(WebNotification* /*notification*/)
+{ notImplemented(); }
+
+bool WebEditorClient::shouldShowDeleteInterface(HTMLElement* /*element*/)
+{ notImplemented(); return false; }
+
+bool WebEditorClient::smartInsertDeleteEnabled(void)
+{
+ BOOL enabled = FALSE;
+ m_webView->smartInsertDeleteEnabled(&enabled);
+ return !!enabled;
+}
+
+bool WebEditorClient::shouldChangeSelectedRange(WebCore::Range*, WebCore::Range*, WebCore::EAffinity, bool)
+{ notImplemented(); return true; }
+
+void WebEditorClient::textFieldDidBeginEditing(Element* e)
+{
+ IWebFormDelegate* formDelegate;
+ if (SUCCEEDED(m_webView->formDelegate(&formDelegate)) && formDelegate) {
+ IDOMElement* domElement = DOMElement::createInstance(e);
+ if (domElement) {
+ IDOMHTMLInputElement* domInputElement;
+ if (SUCCEEDED(domElement->QueryInterface(IID_IDOMHTMLInputElement, (void**)&domInputElement))) {
+ formDelegate->textFieldDidBeginEditing(domInputElement, kit(e->document()->frame()));
+ domInputElement->Release();
+ }
+ domElement->Release();
+ }
+ formDelegate->Release();
+ }
+}
+
+void WebEditorClient::textFieldDidEndEditing(Element* e)
+{
+ IWebFormDelegate* formDelegate;
+ if (SUCCEEDED(m_webView->formDelegate(&formDelegate)) && formDelegate) {
+ IDOMElement* domElement = DOMElement::createInstance(e);
+ if (domElement) {
+ IDOMHTMLInputElement* domInputElement;
+ if (SUCCEEDED(domElement->QueryInterface(IID_IDOMHTMLInputElement, (void**)&domInputElement))) {
+ formDelegate->textFieldDidEndEditing(domInputElement, kit(e->document()->frame()));
+ domInputElement->Release();
+ }
+ domElement->Release();
+ }
+ formDelegate->Release();
+ }
+}
+
+void WebEditorClient::textDidChangeInTextField(Element* e)
+{
+ IWebFormDelegate* formDelegate;
+ if (SUCCEEDED(m_webView->formDelegate(&formDelegate)) && formDelegate) {
+ IDOMElement* domElement = DOMElement::createInstance(e);
+ if (domElement) {
+ IDOMHTMLInputElement* domInputElement;
+ if (SUCCEEDED(domElement->QueryInterface(IID_IDOMHTMLInputElement, (void**)&domInputElement))) {
+ formDelegate->textDidChangeInTextField(domInputElement, kit(e->document()->frame()));
+ domInputElement->Release();
+ }
+ domElement->Release();
+ }
+ formDelegate->Release();
+ }
+}
+
+bool WebEditorClient::doTextFieldCommandFromEvent(Element* e, KeyboardEvent* ke)
+{
+ BOOL result = FALSE;
+ IWebFormDelegate* formDelegate;
+ if (SUCCEEDED(m_webView->formDelegate(&formDelegate)) && formDelegate) {
+ IDOMElement* domElement = DOMElement::createInstance(e);
+ if (domElement) {
+ IDOMHTMLInputElement* domInputElement;
+ if (SUCCEEDED(domElement->QueryInterface(IID_IDOMHTMLInputElement, (void**)&domInputElement))) {
+ String command = m_webView->interpretKeyEvent(ke);
+ // We allow empty commands here because the app code actually depends on this being called for all key presses.
+ // We may want to revisit this later because it doesn't really make sense to send an empty command.
+ formDelegate->doPlatformCommand(domInputElement, BString(command), kit(e->document()->frame()), &result);
+ domInputElement->Release();
+ }
+ domElement->Release();
+ }
+ formDelegate->Release();
+ }
+ return !!result;
+}
+
+void WebEditorClient::textWillBeDeletedInTextField(Element* e)
+{
+ // We're using the deleteBackward command for all deletion operations since the autofill code treats all deletions the same way.
+ IWebFormDelegate* formDelegate;
+ if (SUCCEEDED(m_webView->formDelegate(&formDelegate)) && formDelegate) {
+ IDOMElement* domElement = DOMElement::createInstance(e);
+ if (domElement) {
+ IDOMHTMLInputElement* domInputElement;
+ if (SUCCEEDED(domElement->QueryInterface(IID_IDOMHTMLInputElement, (void**)&domInputElement))) {
+ BOOL result;
+ formDelegate->doPlatformCommand(domInputElement, BString(L"DeleteBackward"), kit(e->document()->frame()), &result);
+ domInputElement->Release();
+ }
+ domElement->Release();
+ }
+ formDelegate->Release();
+ }
+}
+
+void WebEditorClient::textDidChangeInTextArea(Element* e)
+{
+ IWebFormDelegate* formDelegate;
+ if (SUCCEEDED(m_webView->formDelegate(&formDelegate)) && formDelegate) {
+ IDOMElement* domElement = DOMElement::createInstance(e);
+ if (domElement) {
+ IDOMHTMLTextAreaElement* domTextAreaElement;
+ if (SUCCEEDED(domElement->QueryInterface(IID_IDOMHTMLTextAreaElement, (void**)&domTextAreaElement))) {
+ formDelegate->textDidChangeInTextArea(domTextAreaElement, kit(e->document()->frame()));
+ domTextAreaElement->Release();
+ }
+ domElement->Release();
+ }
+ formDelegate->Release();
+ }
+}
+
+class WebEditorUndoCommand : public IWebUndoCommand
+{
+public:
+ WebEditorUndoCommand(PassRefPtr<EditCommand> editCommand, bool isUndo);
+ void execute();
+
+ // IUnknown
+ virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject);
+ virtual ULONG STDMETHODCALLTYPE AddRef(void);
+ virtual ULONG STDMETHODCALLTYPE Release(void);
+
+private:
+ ULONG m_refCount;
+ RefPtr<EditCommand> m_editCommand;
+ bool m_isUndo;
+};
+
+WebEditorUndoCommand::WebEditorUndoCommand(PassRefPtr<EditCommand> editCommand, bool isUndo)
+ : m_editCommand(editCommand)
+ , m_isUndo(isUndo)
+ , m_refCount(1)
+{
+}
+
+void WebEditorUndoCommand::execute()
+{
+ if (m_isUndo)
+ m_editCommand->unapply();
+ else
+ m_editCommand->reapply();
+}
+
+HRESULT STDMETHODCALLTYPE WebEditorUndoCommand::QueryInterface(REFIID riid, void** ppvObject)
+{
+ *ppvObject = 0;
+ if (IsEqualGUID(riid, IID_IUnknown))
+ *ppvObject = static_cast<IWebUndoCommand*>(this);
+ else if (IsEqualGUID(riid, IID_IWebUndoCommand))
+ *ppvObject = static_cast<IWebUndoCommand*>(this);
+ else
+ return E_NOINTERFACE;
+
+ AddRef();
+ return S_OK;
+}
+
+ULONG STDMETHODCALLTYPE WebEditorUndoCommand::AddRef(void)
+{
+ return ++m_refCount;
+}
+
+ULONG STDMETHODCALLTYPE WebEditorUndoCommand::Release(void)
+{
+ ULONG newRef = --m_refCount;
+ if (!newRef)
+ delete(this);
+
+ return newRef;
+}
+
+static LPCTSTR undoNameForEditAction(EditAction editAction)
+{
+ switch (editAction) {
+ case EditActionUnspecified: return 0;
+ case EditActionSetColor: return LPCTSTR_UI_STRING_KEY("Set Color", "Set Color (Undo action name)", "Undo action name");
+ case EditActionSetBackgroundColor: return LPCTSTR_UI_STRING_KEY("Set Background Color", "Set Background Color (Undo action name)", "Undo action name");
+ case EditActionTurnOffKerning: return LPCTSTR_UI_STRING_KEY("Turn Off Kerning", "Turn Off Kerning (Undo action name)", "Undo action name");
+ case EditActionTightenKerning: return LPCTSTR_UI_STRING_KEY("Tighten Kerning", "Tighten Kerning (Undo action name)", "Undo action name");
+ case EditActionLoosenKerning: return LPCTSTR_UI_STRING_KEY("Loosen Kerning", "Loosen Kerning (Undo action name)", "Undo action name");
+ case EditActionUseStandardKerning: return LPCTSTR_UI_STRING_KEY("Use Standard Kerning", "Use Standard Kerning (Undo action name)", "Undo action name");
+ case EditActionTurnOffLigatures: return LPCTSTR_UI_STRING_KEY("Turn Off Ligatures", "Turn Off Ligatures (Undo action name)", "Undo action name");
+ case EditActionUseStandardLigatures: return LPCTSTR_UI_STRING_KEY("Use Standard Ligatures", "Use Standard Ligatures (Undo action name)", "Undo action name");
+ case EditActionUseAllLigatures: return LPCTSTR_UI_STRING_KEY("Use All Ligatures", "Use All Ligatures (Undo action name)", "Undo action name");
+ case EditActionRaiseBaseline: return LPCTSTR_UI_STRING_KEY("Raise Baseline", "Raise Baseline (Undo action name)", "Undo action name");
+ case EditActionLowerBaseline: return LPCTSTR_UI_STRING_KEY("Lower Baseline", "Lower Baseline (Undo action name)", "Undo action name");
+ case EditActionSetTraditionalCharacterShape: return LPCTSTR_UI_STRING_KEY("Set Traditional Character Shape", "Set Traditional Character Shape (Undo action name)", "Undo action name");
+ case EditActionSetFont: return LPCTSTR_UI_STRING_KEY("Set Font", "Set Font (Undo action name)", "Undo action name");
+ case EditActionChangeAttributes: return LPCTSTR_UI_STRING_KEY("Change Attributes", "Change Attributes (Undo action name)", "Undo action name");
+ case EditActionAlignLeft: return LPCTSTR_UI_STRING_KEY("Align Left", "Align Left (Undo action name)", "Undo action name");
+ case EditActionAlignRight: return LPCTSTR_UI_STRING_KEY("Align Right", "Align Right (Undo action name)", "Undo action name");
+ case EditActionCenter: return LPCTSTR_UI_STRING_KEY("Center", "Center (Undo action name)", "Undo action name");
+ case EditActionJustify: return LPCTSTR_UI_STRING_KEY("Justify", "Justify (Undo action name)", "Undo action name");
+ case EditActionSetWritingDirection: return LPCTSTR_UI_STRING_KEY("Set Writing Direction", "Set Writing Direction (Undo action name)", "Undo action name");
+ case EditActionSubscript: return LPCTSTR_UI_STRING_KEY("Subscript", "Subscript (Undo action name)", "Undo action name");
+ case EditActionSuperscript: return LPCTSTR_UI_STRING_KEY("Superscript", "Superscript (Undo action name)", "Undo action name");
+ case EditActionUnderline: return LPCTSTR_UI_STRING_KEY("Underline", "Underline (Undo action name)", "Undo action name");
+ case EditActionOutline: return LPCTSTR_UI_STRING_KEY("Outline", "Outline (Undo action name)", "Undo action name");
+ case EditActionUnscript: return LPCTSTR_UI_STRING_KEY("Unscript", "Unscript (Undo action name)", "Undo action name");
+ case EditActionDrag: return LPCTSTR_UI_STRING_KEY("Drag", "Drag (Undo action name)", "Undo action name");
+ case EditActionCut: return LPCTSTR_UI_STRING_KEY("Cut", "Cut (Undo action name)", "Undo action name");
+ case EditActionPaste: return LPCTSTR_UI_STRING_KEY("Paste", "Paste (Undo action name)", "Undo action name");
+ case EditActionPasteFont: return LPCTSTR_UI_STRING_KEY("Paste Font", "Paste Font (Undo action name)", "Undo action name");
+ case EditActionPasteRuler: return LPCTSTR_UI_STRING_KEY("Paste Ruler", "Paste Ruler (Undo action name)", "Undo action name");
+ case EditActionTyping: return LPCTSTR_UI_STRING_KEY("Typing", "Typing (Undo action name)", "Undo action name");
+ case EditActionCreateLink: return LPCTSTR_UI_STRING_KEY("Create Link", "Create Link (Undo action name)", "Undo action name");
+ case EditActionUnlink: return LPCTSTR_UI_STRING_KEY("Unlink", "Unlink (Undo action name)", "Undo action name");
+ case EditActionInsertList: return LPCTSTR_UI_STRING_KEY("Insert List", "Insert List (Undo action name)", "Undo action name");
+ case EditActionFormatBlock: return LPCTSTR_UI_STRING_KEY("Formatting", "Format Block (Undo action name)", "Undo action name");
+ case EditActionIndent: return LPCTSTR_UI_STRING_KEY("Indent", "Indent (Undo action name)", "Undo action name");
+ case EditActionOutdent: return LPCTSTR_UI_STRING_KEY("Outdent", "Outdent (Undo action name)", "Undo action name");
+ }
+ return 0;
+}
+
+void WebEditorClient::registerCommandForUndo(PassRefPtr<EditCommand> command)
+{
+ IWebUIDelegate* uiDelegate = 0;
+ if (SUCCEEDED(m_webView->uiDelegate(&uiDelegate))) {
+ LPCTSTR actionName = undoNameForEditAction(command->editingAction());
+ WebEditorUndoCommand* undoCommand = new WebEditorUndoCommand(command, true);
+ if (!undoCommand)
+ return;
+ uiDelegate->registerUndoWithTarget(m_undoTarget, 0, undoCommand);
+ undoCommand->Release(); // the undo manager owns the reference
+ BSTR actionNameBSTR = SysAllocString(actionName);
+ if (actionNameBSTR) {
+ uiDelegate->setActionTitle(actionNameBSTR);
+ SysFreeString(actionNameBSTR);
+ }
+ uiDelegate->Release();
+ }
+}
+
+void WebEditorClient::registerCommandForRedo(PassRefPtr<EditCommand> command)
+{
+ IWebUIDelegate* uiDelegate = 0;
+ if (SUCCEEDED(m_webView->uiDelegate(&uiDelegate))) {
+ WebEditorUndoCommand* undoCommand = new WebEditorUndoCommand(command, false);
+ if (!undoCommand)
+ return;
+ uiDelegate->registerUndoWithTarget(m_undoTarget, 0, undoCommand);
+ undoCommand->Release(); // the undo manager owns the reference
+ uiDelegate->Release();
+ }
+}
+
+void WebEditorClient::clearUndoRedoOperations()
+{
+ IWebUIDelegate* uiDelegate = 0;
+ if (SUCCEEDED(m_webView->uiDelegate(&uiDelegate))) {
+ uiDelegate->removeAllActionsWithTarget(m_undoTarget);
+ uiDelegate->Release();
+ }
+}
+
+bool WebEditorClient::canUndo() const
+{
+ BOOL result = FALSE;
+ IWebUIDelegate* uiDelegate = 0;
+ if (SUCCEEDED(m_webView->uiDelegate(&uiDelegate))) {
+ uiDelegate->canUndo(&result);
+ uiDelegate->Release();
+ }
+ return !!result;
+}
+
+bool WebEditorClient::canRedo() const
+{
+ BOOL result = FALSE;
+ IWebUIDelegate* uiDelegate = 0;
+ if (SUCCEEDED(m_webView->uiDelegate(&uiDelegate))) {
+ uiDelegate->canRedo(&result);
+ uiDelegate->Release();
+ }
+ return !!result;
+}
+
+void WebEditorClient::undo()
+{
+ IWebUIDelegate* uiDelegate = 0;
+ if (SUCCEEDED(m_webView->uiDelegate(&uiDelegate))) {
+ uiDelegate->undo();
+ uiDelegate->Release();
+ }
+}
+
+void WebEditorClient::redo()
+{
+ IWebUIDelegate* uiDelegate = 0;
+ if (SUCCEEDED(m_webView->uiDelegate(&uiDelegate))) {
+ uiDelegate->redo();
+ uiDelegate->Release();
+ }
+}
+
+void WebEditorClient::handleKeyboardEvent(KeyboardEvent* evt)
+{
+ if (m_webView->handleEditingKeyboardEvent(evt))
+ evt->setDefaultHandled();
+}
+
+void WebEditorClient::handleInputMethodKeydown(KeyboardEvent* )
+{
+}
+
+bool WebEditorClient::isEditable()
+{
+ return false;
+}
+
+void WebEditorClient::ignoreWordInSpellDocument(const String& word)
+{
+ COMPtr<IWebEditingDelegate> ed;
+ if (FAILED(m_webView->editingDelegate(&ed)) || !ed.get())
+ return;
+
+ initViewSpecificSpelling(m_webView);
+ ed->ignoreWordInSpellDocument(m_webView, BString(word));
+}
+
+void WebEditorClient::learnWord(const String& word)
+{
+ COMPtr<IWebEditingDelegate> ed;
+ if (FAILED(m_webView->editingDelegate(&ed)) || !ed.get())
+ return;
+
+ ed->learnWord(BString(word));
+}
+
+void WebEditorClient::checkSpellingOfString(const UChar* text, int length, int* misspellingLocation, int* misspellingLength)
+{
+ *misspellingLocation = -1;
+ *misspellingLength = 0;
+
+ COMPtr<IWebEditingDelegate> ed;
+ if (FAILED(m_webView->editingDelegate(&ed)) || !ed.get())
+ return;
+
+ initViewSpecificSpelling(m_webView);
+ ed->checkSpellingOfString(m_webView, text, length, misspellingLocation, misspellingLength);
+}
+
+void WebEditorClient::checkGrammarOfString(const UChar* text, int length, Vector<GrammarDetail>& details, int* badGrammarLocation, int* badGrammarLength)
+{
+ details.clear();
+ *badGrammarLocation = -1;
+ *badGrammarLength = 0;
+
+ COMPtr<IWebEditingDelegate> ed;
+ if (FAILED(m_webView->editingDelegate(&ed)) || !ed.get())
+ return;
+
+ initViewSpecificSpelling(m_webView);
+ COMPtr<IEnumWebGrammarDetails> enumDetailsObj;
+ if (FAILED(ed->checkGrammarOfString(m_webView, text, length, &enumDetailsObj, badGrammarLocation, badGrammarLength)))
+ return;
+
+ while (true) {
+ ULONG fetched;
+ COMPtr<IWebGrammarDetail> detailObj;
+ if (enumDetailsObj->Next(1, &detailObj, &fetched) != S_OK)
+ break;
+
+ GrammarDetail detail;
+ if (FAILED(detailObj->length(&detail.length)))
+ continue;
+ if (FAILED(detailObj->location(&detail.location)))
+ continue;
+ BSTR userDesc;
+ if (FAILED(detailObj->userDescription(&userDesc)))
+ continue;
+ detail.userDescription = String(userDesc, SysStringLen(userDesc));
+ SysFreeString(userDesc);
+
+ COMPtr<IEnumSpellingGuesses> enumGuessesObj;
+ if (FAILED(detailObj->guesses(&enumGuessesObj)))
+ continue;
+ while (true) {
+ BSTR guess;
+ if (enumGuessesObj->Next(1, &guess, &fetched) != S_OK)
+ break;
+ detail.guesses.append(String(guess, SysStringLen(guess)));
+ SysFreeString(guess);
+ }
+
+ details.append(detail);
+ }
+}
+
+void WebEditorClient::updateSpellingUIWithGrammarString(const String& string, const WebCore::GrammarDetail& detail)
+{
+ COMPtr<IWebEditingDelegate> ed;
+ if (FAILED(m_webView->editingDelegate(&ed)) || !ed.get())
+ return;
+
+ Vector<BSTR> guessesBSTRs;
+ for (unsigned i = 0; i < detail.guesses.size(); i++) {
+ BString guess(detail.guesses[i]);
+ guessesBSTRs.append(guess.release());
+ }
+ BString userDescriptionBSTR(detail.userDescription);
+ ed->updateSpellingUIWithGrammarString(BString(string), detail.location, detail.length, userDescriptionBSTR, guessesBSTRs.data(), (int)guessesBSTRs.size());
+ for (unsigned i = 0; i < guessesBSTRs.size(); i++)
+ SysFreeString(guessesBSTRs[i]);
+}
+
+void WebEditorClient::updateSpellingUIWithMisspelledWord(const String& word)
+{
+ COMPtr<IWebEditingDelegate> ed;
+ if (FAILED(m_webView->editingDelegate(&ed)) || !ed.get())
+ return;
+
+ ed->updateSpellingUIWithMisspelledWord(BString(word));
+}
+
+void WebEditorClient::showSpellingUI(bool show)
+{
+ COMPtr<IWebEditingDelegate> ed;
+ if (FAILED(m_webView->editingDelegate(&ed)) || !ed.get())
+ return;
+
+ ed->showSpellingUI(show);
+}
+
+bool WebEditorClient::spellingUIIsShowing()
+{
+ COMPtr<IWebEditingDelegate> ed;
+ if (FAILED(m_webView->editingDelegate(&ed)) || !ed.get())
+ return false;
+
+ BOOL showing;
+ if (FAILED(ed->spellingUIIsShowing(&showing)))
+ return false;
+
+ return !!showing;
+}
+
+void WebEditorClient::getGuessesForWord(const String& word, Vector<String>& guesses)
+{
+ guesses.clear();
+
+ COMPtr<IWebEditingDelegate> ed;
+ if (FAILED(m_webView->editingDelegate(&ed)) || !ed.get())
+ return;
+
+ COMPtr<IEnumSpellingGuesses> enumGuessesObj;
+ if (FAILED(ed->guessesForWord(BString(word), &enumGuessesObj)))
+ return;
+
+ while (true) {
+ ULONG fetched;
+ BSTR guess;
+ if (enumGuessesObj->Next(1, &guess, &fetched) != S_OK)
+ break;
+ guesses.append(String(guess, SysStringLen(guess)));
+ SysFreeString(guess);
+ }
+}
+
+void WebEditorClient::setInputMethodState(bool enabled)
+{
+ m_webView->setInputMethodState(enabled);
+}
diff --git a/WebKit/win/WebCoreSupport/WebEditorClient.h b/WebKit/win/WebCoreSupport/WebEditorClient.h
new file mode 100644
index 0000000..8c603f2
--- /dev/null
+++ b/WebKit/win/WebCoreSupport/WebEditorClient.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebEditorClient_H
+#define WebEditorClient_H
+
+#include "WebKit.h"
+#pragma warning(push, 0)
+#include <WebCore/EditorClient.h>
+#include <wtf/OwnPtr.h>
+#pragma warning(pop)
+
+class WebView;
+class WebNotification;
+class WebEditorUndoTarget;
+
+class WebEditorClient : public WebCore::EditorClient {
+public:
+ WebEditorClient(WebView*);
+ ~WebEditorClient();
+
+ virtual void pageDestroyed();
+
+ virtual bool isContinuousSpellCheckingEnabled();
+ virtual void toggleGrammarChecking();
+ virtual bool isGrammarCheckingEnabled();
+ virtual void toggleContinuousSpellChecking();
+ virtual int spellCheckerDocumentTag();
+
+ virtual bool isEditable();
+
+ virtual bool shouldBeginEditing(WebCore::Range*);
+ virtual bool shouldEndEditing(WebCore::Range*);
+ virtual bool shouldInsertText(const WebCore::String&, WebCore::Range*, WebCore::EditorInsertAction);
+
+ virtual void didBeginEditing();
+ virtual void didEndEditing();
+ virtual void didWriteSelectionToPasteboard();
+ virtual void didSetSelectionTypesForPasteboard();
+
+ virtual void respondToChangedContents();
+ virtual void respondToChangedSelection();
+
+ bool shouldShowDeleteInterface(WebCore::HTMLElement*);
+ bool shouldDeleteRange(WebCore::Range*);
+
+ bool shouldInsertNode(WebCore::Node*, WebCore::Range* replacingRange, WebCore::EditorInsertAction);
+ bool shouldApplyStyle(WebCore::CSSStyleDeclaration*, WebCore::Range*);
+ bool shouldMoveRangeAfterDelete(WebCore::Range*, WebCore::Range*);
+ bool shouldChangeTypingStyle(WebCore::CSSStyleDeclaration* currentStyle, WebCore::CSSStyleDeclaration* toProposedStyle);
+
+ void webViewDidChangeTypingStyle(WebNotification*);
+ void webViewDidChangeSelection(WebNotification*);
+
+ bool smartInsertDeleteEnabled();
+
+ void registerCommandForUndo(PassRefPtr<WebCore::EditCommand>);
+ void registerCommandForRedo(PassRefPtr<WebCore::EditCommand>);
+ void clearUndoRedoOperations();
+
+ bool canUndo() const;
+ bool canRedo() const;
+
+ void undo();
+ void redo();
+
+ virtual bool shouldChangeSelectedRange(WebCore::Range* fromRange, WebCore::Range* toRange, WebCore::EAffinity, bool stillSelecting);
+ virtual void textFieldDidBeginEditing(WebCore::Element*);
+ virtual void textFieldDidEndEditing(WebCore::Element*);
+ virtual void textDidChangeInTextField(WebCore::Element*);
+ virtual bool doTextFieldCommandFromEvent(WebCore::Element*, WebCore::KeyboardEvent*);
+ virtual void textWillBeDeletedInTextField(WebCore::Element* input);
+ virtual void textDidChangeInTextArea(WebCore::Element*);
+
+ void handleKeyboardEvent(WebCore::KeyboardEvent*);
+ void handleInputMethodKeydown(WebCore::KeyboardEvent*);
+
+ virtual void ignoreWordInSpellDocument(const WebCore::String&);
+ virtual void learnWord(const WebCore::String&);
+ virtual void checkSpellingOfString(const UChar*, int length, int* misspellingLocation, int* misspellingLength);
+ virtual void checkGrammarOfString(const UChar*, int length, Vector<WebCore::GrammarDetail>&, int* badGrammarLocation, int* badGrammarLength);
+ virtual void updateSpellingUIWithGrammarString(const WebCore::String&, const WebCore::GrammarDetail& detail);
+ virtual void updateSpellingUIWithMisspelledWord(const WebCore::String&);
+ virtual void showSpellingUI(bool show);
+ virtual bool spellingUIIsShowing();
+ virtual void getGuessesForWord(const WebCore::String&, Vector<WebCore::String>& guesses);
+
+ virtual void setInputMethodState(bool);
+
+private:
+ WebView* m_webView;
+ WebEditorUndoTarget* m_undoTarget;
+};
+
+#endif // WebEditorClient_H
diff --git a/WebKit/win/WebCoreSupport/WebFrameLoaderClient.cpp b/WebKit/win/WebCoreSupport/WebFrameLoaderClient.cpp
new file mode 100644
index 0000000..17bee47
--- /dev/null
+++ b/WebKit/win/WebCoreSupport/WebFrameLoaderClient.cpp
@@ -0,0 +1,706 @@
+/*
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebFrameLoaderClient.h"
+
+#include "CFDictionaryPropertyBag.h"
+#include "COMPropertyBag.h"
+#include "EmbeddedWidget.h"
+#include "MarshallingHelpers.h"
+#include "WebCachedPagePlatformData.h"
+#include "WebChromeClient.h"
+#include "WebDocumentLoader.h"
+#include "WebError.h"
+#include "WebFrame.h"
+#include "WebHistory.h"
+#include "WebMutableURLRequest.h"
+#include "WebNotificationCenter.h"
+#include "WebScriptDebugServer.h"
+#include "WebURLAuthenticationChallenge.h"
+#include "WebURLResponse.h"
+#include "WebView.h"
+#pragma warning(push, 0)
+#include <WebCore/DocumentLoader.h>
+#include <WebCore/FrameLoader.h>
+#include <WebCore/FrameTree.h>
+#include <WebCore/FrameView.h>
+#include <WebCore/HTMLFrameElement.h>
+#include <WebCore/HTMLFrameOwnerElement.h>
+#include <WebCore/HTMLNames.h>
+#include <WebCore/HistoryItem.h>
+#include <WebCore/Page.h>
+#include <WebCore/PluginPackage.h>
+#include <WebCore/PluginView.h>
+#include <WebCore/RenderPart.h>
+#include <WebCore/ResourceHandle.h>
+#pragma warning(pop)
+
+using namespace WebCore;
+using namespace HTMLNames;
+
+static WebDataSource* getWebDataSource(DocumentLoader* loader)
+{
+ return loader ? static_cast<WebDocumentLoader*>(loader)->dataSource() : 0;
+}
+
+WebFrameLoaderClient::WebFrameLoaderClient(WebFrame* webFrame)
+ : m_webFrame(webFrame)
+ , m_pluginView(0)
+ , m_hasSentResponseToPlugin(false)
+{
+ ASSERT_ARG(webFrame, webFrame);
+}
+
+WebFrameLoaderClient::~WebFrameLoaderClient()
+{
+}
+
+bool WebFrameLoaderClient::hasWebView() const
+{
+ return m_webFrame->webView();
+}
+
+void WebFrameLoaderClient::forceLayout()
+{
+ core(m_webFrame)->forceLayout(true);
+}
+
+void WebFrameLoaderClient::assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request)
+{
+ WebView* webView = m_webFrame->webView();
+ COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
+ if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
+ return;
+
+ COMPtr<WebMutableURLRequest> webURLRequest(AdoptCOM, WebMutableURLRequest::createInstance(request));
+ resourceLoadDelegate->identifierForInitialRequest(webView, webURLRequest.get(), getWebDataSource(loader), identifier);
+}
+
+void WebFrameLoaderClient::dispatchDidReceiveAuthenticationChallenge(DocumentLoader* loader, unsigned long identifier, const AuthenticationChallenge& challenge)
+{
+ ASSERT(challenge.sourceHandle());
+
+ WebView* webView = m_webFrame->webView();
+ COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
+ if (SUCCEEDED(webView->resourceLoadDelegate(&resourceLoadDelegate))) {
+ COMPtr<WebURLAuthenticationChallenge> webChallenge(AdoptCOM, WebURLAuthenticationChallenge::createInstance(challenge));
+ if (SUCCEEDED(resourceLoadDelegate->didReceiveAuthenticationChallenge(webView, identifier, webChallenge.get(), getWebDataSource(loader))))
+ return;
+ }
+
+ // If the ResourceLoadDelegate doesn't exist or fails to handle the call, we tell the ResourceHandle
+ // to continue without credential - this is the best approximation of Mac behavior
+ challenge.sourceHandle()->receivedRequestToContinueWithoutCredential(challenge);
+}
+
+void WebFrameLoaderClient::dispatchDidCancelAuthenticationChallenge(DocumentLoader* loader, unsigned long identifier, const AuthenticationChallenge& challenge)
+{
+ WebView* webView = m_webFrame->webView();
+ COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
+ if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
+ return;
+
+ COMPtr<WebURLAuthenticationChallenge> webChallenge(AdoptCOM, WebURLAuthenticationChallenge::createInstance(challenge));
+ resourceLoadDelegate->didCancelAuthenticationChallenge(webView, identifier, webChallenge.get(), getWebDataSource(loader));
+}
+
+void WebFrameLoaderClient::dispatchWillSendRequest(DocumentLoader* loader, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse)
+{
+ WebView* webView = m_webFrame->webView();
+ COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
+ if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
+ return;
+
+ COMPtr<WebMutableURLRequest> webURLRequest(AdoptCOM, WebMutableURLRequest::createInstance(request));
+ COMPtr<WebURLResponse> webURLRedirectResponse(AdoptCOM, WebURLResponse::createInstance(redirectResponse));
+
+ COMPtr<IWebURLRequest> newWebURLRequest;
+ if (FAILED(resourceLoadDelegate->willSendRequest(webView, identifier, webURLRequest.get(), webURLRedirectResponse.get(), getWebDataSource(loader), &newWebURLRequest)))
+ return;
+
+ if (webURLRequest == newWebURLRequest)
+ return;
+
+ COMPtr<WebMutableURLRequest> newWebURLRequestImpl(Query, newWebURLRequest);
+ if (!newWebURLRequestImpl)
+ return;
+
+ request = newWebURLRequestImpl->resourceRequest();
+}
+
+void WebFrameLoaderClient::dispatchDidReceiveResponse(DocumentLoader* loader, unsigned long identifier, const ResourceResponse& response)
+{
+ WebView* webView = m_webFrame->webView();
+ COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
+ if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
+ return;
+
+ COMPtr<WebURLResponse> webURLResponse(AdoptCOM, WebURLResponse::createInstance(response));
+ resourceLoadDelegate->didReceiveResponse(webView, identifier, webURLResponse.get(), getWebDataSource(loader));
+}
+
+void WebFrameLoaderClient::dispatchDidReceiveContentLength(DocumentLoader* loader, unsigned long identifier, int length)
+{
+ WebView* webView = m_webFrame->webView();
+ COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
+ if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
+ return;
+
+ resourceLoadDelegate->didReceiveContentLength(webView, identifier, length, getWebDataSource(loader));
+}
+
+void WebFrameLoaderClient::dispatchDidFinishLoading(DocumentLoader* loader, unsigned long identifier)
+{
+ WebView* webView = m_webFrame->webView();
+ COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
+ if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
+ return;
+
+ resourceLoadDelegate->didFinishLoadingFromDataSource(webView, identifier, getWebDataSource(loader));
+}
+
+void WebFrameLoaderClient::dispatchDidFailLoading(DocumentLoader* loader, unsigned long identifier, const ResourceError& error)
+{
+ WebView* webView = m_webFrame->webView();
+ COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
+ if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
+ return;
+
+ COMPtr<WebError> webError(AdoptCOM, WebError::createInstance(error));
+ resourceLoadDelegate->didFailLoadingWithError(webView, identifier, webError.get(), getWebDataSource(loader));
+}
+
+void WebFrameLoaderClient::dispatchDidHandleOnloadEvents()
+{
+ WebView* webView = m_webFrame->webView();
+ COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
+ if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) && frameLoadDelegatePriv)
+ frameLoadDelegatePriv->didHandleOnloadEventsForFrame(webView, m_webFrame);
+}
+
+void WebFrameLoaderClient::dispatchDidReceiveServerRedirectForProvisionalLoad()
+{
+ WebView* webView = m_webFrame->webView();
+ COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
+ if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
+ frameLoadDelegate->didReceiveServerRedirectForProvisionalLoadForFrame(webView, m_webFrame);
+}
+
+void WebFrameLoaderClient::dispatchDidCancelClientRedirect()
+{
+ WebView* webView = m_webFrame->webView();
+ COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
+ if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
+ frameLoadDelegate->didCancelClientRedirectForFrame(webView, m_webFrame);
+}
+
+void WebFrameLoaderClient::dispatchWillPerformClientRedirect(const KURL& url, double delay, double fireDate)
+{
+ WebView* webView = m_webFrame->webView();
+ COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
+ if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
+ frameLoadDelegate->willPerformClientRedirectToURL(webView, BString(url.string()), delay, MarshallingHelpers::CFAbsoluteTimeToDATE(fireDate), m_webFrame);
+}
+
+void WebFrameLoaderClient::dispatchDidChangeLocationWithinPage()
+{
+ WebView* webView = m_webFrame->webView();
+ COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
+ if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
+ frameLoadDelegate->didChangeLocationWithinPageForFrame(webView, m_webFrame);
+}
+
+void WebFrameLoaderClient::dispatchWillClose()
+{
+ WebView* webView = m_webFrame->webView();
+ COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
+ if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
+ frameLoadDelegate->willCloseFrame(webView, m_webFrame);
+}
+
+void WebFrameLoaderClient::dispatchDidReceiveIcon()
+{
+ m_webFrame->webView()->dispatchDidReceiveIconFromWebFrame(m_webFrame);
+}
+
+void WebFrameLoaderClient::dispatchDidStartProvisionalLoad()
+{
+ WebView* webView = m_webFrame->webView();
+ COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
+ if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
+ frameLoadDelegate->didStartProvisionalLoadForFrame(webView, m_webFrame);
+}
+
+void WebFrameLoaderClient::dispatchDidReceiveTitle(const String& title)
+{
+ WebView* webView = m_webFrame->webView();
+ COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
+ if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
+ frameLoadDelegate->didReceiveTitle(webView, BString(title), m_webFrame);
+}
+
+void WebFrameLoaderClient::dispatchDidCommitLoad()
+{
+ WebView* webView = m_webFrame->webView();
+ COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
+ if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
+ frameLoadDelegate->didCommitLoadForFrame(webView, m_webFrame);
+}
+
+void WebFrameLoaderClient::dispatchDidFinishDocumentLoad()
+{
+ WebView* webView = m_webFrame->webView();
+ COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
+ if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) && frameLoadDelegatePriv)
+ frameLoadDelegatePriv->didFinishDocumentLoadForFrame(webView, m_webFrame);
+}
+
+void WebFrameLoaderClient::dispatchDidFinishLoad()
+{
+ WebView* webView = m_webFrame->webView();
+ COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
+ if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
+ frameLoadDelegate->didFinishLoadForFrame(webView, m_webFrame);
+}
+
+void WebFrameLoaderClient::dispatchDidFirstLayout()
+{
+ WebView* webView = m_webFrame->webView();
+ COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
+ if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) && frameLoadDelegatePriv)
+ frameLoadDelegatePriv->didFirstLayoutInFrame(webView, m_webFrame);
+}
+
+Frame* WebFrameLoaderClient::dispatchCreatePage()
+{
+ WebView* webView = m_webFrame->webView();
+
+ COMPtr<IWebUIDelegate> ui;
+ if (FAILED(webView->uiDelegate(&ui)))
+ return 0;
+
+ COMPtr<IWebView> newWebView;
+ if (FAILED(ui->createWebViewWithRequest(webView, 0, &newWebView)))
+ return 0;
+
+ COMPtr<IWebFrame> mainFrame;
+ if (FAILED(newWebView->mainFrame(&mainFrame)))
+ return 0;
+
+ COMPtr<WebFrame> mainFrameImpl(Query, mainFrame);
+ return core(mainFrameImpl.get());
+}
+
+void WebFrameLoaderClient::dispatchShow()
+{
+ WebView* webView = m_webFrame->webView();
+ COMPtr<IWebUIDelegate> ui;
+ if (SUCCEEDED(webView->uiDelegate(&ui)))
+ ui->webViewShow(webView);
+}
+
+void WebFrameLoaderClient::dispatchDidLoadMainResource(DocumentLoader*)
+{
+}
+
+void WebFrameLoaderClient::setMainDocumentError(DocumentLoader*, const ResourceError& error)
+{
+ if (!m_pluginView)
+ return;
+
+ if (m_pluginView->status() == PluginStatusLoadedSuccessfully)
+ m_pluginView->didFail(error);
+ m_pluginView = 0;
+ m_hasSentResponseToPlugin = false;
+}
+
+void WebFrameLoaderClient::postProgressStartedNotification()
+{
+ static BSTR progressStartedName = SysAllocString(WebViewProgressStartedNotification);
+ IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
+ notifyCenter->postNotificationName(progressStartedName, static_cast<IWebView*>(m_webFrame->webView()), 0);
+}
+
+void WebFrameLoaderClient::postProgressEstimateChangedNotification()
+{
+ static BSTR progressEstimateChangedName = SysAllocString(WebViewProgressEstimateChangedNotification);
+ IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
+ notifyCenter->postNotificationName(progressEstimateChangedName, static_cast<IWebView*>(m_webFrame->webView()), 0);
+}
+
+void WebFrameLoaderClient::postProgressFinishedNotification()
+{
+ static BSTR progressFinishedName = SysAllocString(WebViewProgressFinishedNotification);
+ IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
+ notifyCenter->postNotificationName(progressFinishedName, static_cast<IWebView*>(m_webFrame->webView()), 0);
+}
+
+void WebFrameLoaderClient::committedLoad(DocumentLoader* loader, const char* data, int length)
+{
+ // FIXME: This should probably go through the data source.
+ const String& textEncoding = loader->response().textEncodingName();
+
+ if (!m_pluginView)
+ receivedData(data, length, textEncoding);
+
+ if (!m_pluginView || m_pluginView->status() != PluginStatusLoadedSuccessfully)
+ return;
+
+ if (!m_hasSentResponseToPlugin) {
+ m_pluginView->didReceiveResponse(core(m_webFrame)->loader()->documentLoader()->response());
+ // didReceiveResponse sets up a new stream to the plug-in. on a full-page plug-in, a failure in
+ // setting up this stream can cause the main document load to be cancelled, setting m_pluginView
+ // to null
+ if (!m_pluginView)
+ return;
+ m_hasSentResponseToPlugin = true;
+ }
+ m_pluginView->didReceiveData(data, length);
+}
+
+void WebFrameLoaderClient::receivedData(const char* data, int length, const String& textEncoding)
+{
+ Frame* coreFrame = core(m_webFrame);
+ if (!coreFrame)
+ return;
+
+ // Set the encoding. This only needs to be done once, but it's harmless to do it again later.
+ String encoding = coreFrame->loader()->documentLoader()->overrideEncoding();
+ bool userChosen = !encoding.isNull();
+ if (encoding.isNull())
+ encoding = textEncoding;
+ coreFrame->loader()->setEncoding(encoding, userChosen);
+
+ coreFrame->loader()->addData(data, length);
+}
+
+void WebFrameLoaderClient::finishedLoading(DocumentLoader* loader)
+{
+ // Telling the frame we received some data and passing 0 as the data is our
+ // way to get work done that is normally done when the first bit of data is
+ // received, even for the case of a document with no data (like about:blank)
+ if (!m_pluginView) {
+ committedLoad(loader, 0, 0);
+ return;
+ }
+
+ if (m_pluginView->status() == PluginStatusLoadedSuccessfully)
+ m_pluginView->didFinishLoading();
+ m_pluginView = 0;
+ m_hasSentResponseToPlugin = false;
+}
+
+void WebFrameLoaderClient::updateGlobalHistory(const KURL& url)
+{
+ WebHistory* history = WebHistory::sharedHistory();
+ if (!history)
+ return;
+ history->addItem(url, core(m_webFrame)->loader()->documentLoader()->title());
+}
+
+bool WebFrameLoaderClient::shouldGoToHistoryItem(HistoryItem*) const
+{
+ return true;
+}
+
+PassRefPtr<DocumentLoader> WebFrameLoaderClient::createDocumentLoader(const ResourceRequest& request, const SubstituteData& substituteData)
+{
+ RefPtr<WebDocumentLoader> loader = WebDocumentLoader::create(request, substituteData);
+
+ COMPtr<WebDataSource> dataSource(AdoptCOM, WebDataSource::createInstance(loader.get()));
+
+ loader->setDataSource(dataSource.get());
+ return loader.release();
+}
+
+void WebFrameLoaderClient::setTitle(const String& title, const KURL& url)
+{
+ BOOL privateBrowsingEnabled = FALSE;
+ COMPtr<IWebPreferences> preferences;
+ if (SUCCEEDED(m_webFrame->webView()->preferences(&preferences)))
+ preferences->privateBrowsingEnabled(&privateBrowsingEnabled);
+ if (privateBrowsingEnabled)
+ return;
+
+ // update title in global history
+ COMPtr<WebHistory> history = webHistory();
+ if (!history)
+ return;
+
+ COMPtr<IWebHistoryItem> item;
+ if (FAILED(history->itemForURL(BString(url.string()), &item)))
+ return;
+
+ COMPtr<IWebHistoryItemPrivate> itemPrivate(Query, item);
+ if (!itemPrivate)
+ return;
+
+ itemPrivate->setTitle(BString(title));
+}
+
+void WebFrameLoaderClient::savePlatformDataToCachedPage(CachedPage* cachedPage)
+{
+ Frame* coreFrame = core(m_webFrame);
+ if (!coreFrame)
+ return;
+
+ ASSERT(coreFrame->loader()->documentLoader() == cachedPage->documentLoader());
+
+ WebCachedPagePlatformData* webPlatformData = new WebCachedPagePlatformData(static_cast<IWebDataSource*>(getWebDataSource(coreFrame->loader()->documentLoader())));
+ cachedPage->setCachedPagePlatformData(webPlatformData);
+}
+
+void WebFrameLoaderClient::transitionToCommittedForNewPage()
+{
+ Frame* frame = core(m_webFrame);
+ ASSERT(frame);
+
+ Page* page = frame->page();
+ ASSERT(page);
+
+ bool isMainFrame = frame == page->mainFrame();
+
+ if (isMainFrame && frame->view())
+ frame->view()->setParentVisible(false);
+
+ frame->setView(0);
+
+ WebView* webView = m_webFrame->webView();
+
+ FrameView* frameView;
+ if (isMainFrame) {
+ RECT rect;
+ webView->frameRect(&rect);
+ frameView = new FrameView(frame, IntRect(rect).size());
+ } else
+ frameView = new FrameView(frame);
+
+ frame->setView(frameView);
+ frameView->deref(); // FrameViews are created with a ref count of 1. Release this ref since we've assigned it to frame.
+
+ m_webFrame->updateBackground();
+
+ if (isMainFrame)
+ frameView->setParentVisible(true);
+
+ if (frame->ownerRenderer())
+ frame->ownerRenderer()->setWidget(frameView);
+
+ if (HTMLFrameOwnerElement* owner = frame->ownerElement())
+ frame->view()->setCanHaveScrollbars(owner->scrollingMode() != ScrollbarAlwaysOff);
+}
+
+bool WebFrameLoaderClient::canCachePage() const
+{
+ return true;
+}
+
+PassRefPtr<Frame> WebFrameLoaderClient::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement,
+ const String& referrer, bool /*allowsScrolling*/, int /*marginWidth*/, int /*marginHeight*/)
+{
+ RefPtr<Frame> result = createFrame(url, name, ownerElement, referrer);
+ if (!result)
+ return 0;
+ return result.release();
+}
+
+PassRefPtr<Frame> WebFrameLoaderClient::createFrame(const KURL& URL, const String& name, HTMLFrameOwnerElement* ownerElement, const String& referrer)
+{
+ Frame* coreFrame = core(m_webFrame);
+ ASSERT(coreFrame);
+
+ COMPtr<WebFrame> webFrame(AdoptCOM, WebFrame::createInstance());
+
+ RefPtr<Frame> childFrame = webFrame->init(m_webFrame->webView(), coreFrame->page(), ownerElement);
+
+ coreFrame->tree()->appendChild(childFrame);
+ childFrame->tree()->setName(name);
+ childFrame->init();
+
+ loadURLIntoChild(URL, referrer, webFrame.get());
+
+ // The frame's onload handler may have removed it from the document.
+ if (!childFrame->tree()->parent())
+ return 0;
+
+ return childFrame.release();
+}
+
+void WebFrameLoaderClient::loadURLIntoChild(const KURL& originalURL, const String& referrer, WebFrame* childFrame)
+{
+ ASSERT(childFrame);
+ ASSERT(core(childFrame));
+
+ Frame* coreFrame = core(m_webFrame);
+ ASSERT(coreFrame);
+
+ HistoryItem* parentItem = coreFrame->loader()->currentHistoryItem();
+ FrameLoadType loadType = coreFrame->loader()->loadType();
+ FrameLoadType childLoadType = FrameLoadTypeRedirectWithLockedHistory;
+
+ KURL url = originalURL;
+
+ // If we're moving in the backforward list, we might want to replace the content
+ // of this child frame with whatever was there at that point.
+ // Reload will maintain the frame contents, LoadSame will not.
+ if (parentItem && parentItem->children().size() &&
+ (isBackForwardLoadType(loadType)
+ || loadType == FrameLoadTypeReload
+ || loadType == FrameLoadTypeReloadAllowingStaleData))
+ {
+ if (HistoryItem* childItem = parentItem->childItemWithName(core(childFrame)->tree()->name())) {
+ // Use the original URL to ensure we get all the side-effects, such as
+ // onLoad handlers, of any redirects that happened. An example of where
+ // this is needed is Radar 3213556.
+ url = childItem->originalURL();
+ // These behaviors implied by these loadTypes should apply to the child frames
+ childLoadType = loadType;
+
+ if (isBackForwardLoadType(loadType))
+ // For back/forward, remember this item so we can traverse any child items as child frames load
+ core(childFrame)->loader()->setProvisionalHistoryItem(childItem);
+ else
+ // For reload, just reinstall the current item, since a new child frame was created but we won't be creating a new BF item
+ core(childFrame)->loader()->setCurrentHistoryItem(childItem);
+ }
+ }
+
+ // FIXME: Handle loading WebArchives here
+ String frameName = core(childFrame)->tree()->name();
+ core(childFrame)->loader()->loadURL(url, referrer, frameName, childLoadType, 0, 0);
+}
+
+Widget* WebFrameLoaderClient::createPlugin(const IntSize& pluginSize, Element* element, const KURL& url, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually)
+{
+ WebView* webView = m_webFrame->webView();
+
+ COMPtr<IWebUIDelegate> ui;
+ if (SUCCEEDED(webView->uiDelegate(&ui)) && ui) {
+ COMPtr<IWebUIDelegatePrivate4> uiPrivate(Query, ui);
+
+ if (uiPrivate) {
+ // Assemble the view arguments in a property bag.
+ HashMap<String, String> viewArguments;
+ for (unsigned i = 0; i < paramNames.size(); i++)
+ viewArguments.set(paramNames[i], paramValues[i]);
+ COMPtr<IPropertyBag> viewArgumentsBag(AdoptCOM, COMPropertyBag<String>::adopt(viewArguments));
+
+ // Now create a new property bag where the view arguments is the only property.
+ HashMap<String, COMPtr<IUnknown> > arguments;
+ arguments.set(WebEmbeddedViewAttributesKey, COMPtr<IUnknown>(AdoptCOM, viewArgumentsBag.releaseRef()));
+ COMPtr<IPropertyBag> argumentsBag(AdoptCOM, COMPropertyBag<COMPtr<IUnknown> >::adopt(arguments));
+
+ COMPtr<IWebEmbeddedView> view;
+ HRESULT result = uiPrivate->embeddedViewWithArguments(webView, m_webFrame, argumentsBag.get(), &view);
+ if (SUCCEEDED(result)) {
+ HWND parentWindow;
+ HRESULT hr = webView->viewWindow((OLE_HANDLE*)&parentWindow);
+ ASSERT(SUCCEEDED(hr));
+
+ return EmbeddedWidget::create(view.get(), element, parentWindow, pluginSize);
+ }
+ }
+ }
+
+ Frame* frame = core(m_webFrame);
+ PluginView* pluginView = PluginView::create(frame, pluginSize, element, url, paramNames, paramValues, mimeType, loadManually);
+
+ if (pluginView->status() == PluginStatusLoadedSuccessfully)
+ return pluginView;
+
+ COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
+
+ if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
+ return pluginView;
+
+ RetainPtr<CFMutableDictionaryRef> userInfo(AdoptCF, CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+
+ unsigned count = (unsigned)paramNames.size();
+ for (unsigned i = 0; i < count; i++) {
+ if (paramNames[i] == "pluginspage") {
+ static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorPlugInPageURLStringKey);
+ RetainPtr<CFStringRef> str(AdoptCF, paramValues[i].createCFString());
+ CFDictionarySetValue(userInfo.get(), key, str.get());
+ break;
+ }
+ }
+
+ if (!mimeType.isNull()) {
+ static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorMIMETypeKey);
+
+ RetainPtr<CFStringRef> str(AdoptCF, mimeType.createCFString());
+ CFDictionarySetValue(userInfo.get(), key, str.get());
+ }
+
+ String pluginName;
+ if (pluginView->plugin())
+ pluginName = pluginView->plugin()->name();
+ if (!pluginName.isNull()) {
+ static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorPlugInNameKey);
+ RetainPtr<CFStringRef> str(AdoptCF, pluginName.createCFString());
+ CFDictionarySetValue(userInfo.get(), key, str.get());
+ }
+
+ COMPtr<CFDictionaryPropertyBag> userInfoBag(AdoptCOM, CFDictionaryPropertyBag::createInstance());
+ userInfoBag->setDictionary(userInfo.get());
+
+ int errorCode = 0;
+ switch (pluginView->status()) {
+ case PluginStatusCanNotFindPlugin:
+ errorCode = WebKitErrorCannotFindPlugIn;
+ break;
+ case PluginStatusCanNotLoadPlugin:
+ errorCode = WebKitErrorCannotLoadPlugIn;
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+
+ ResourceError resourceError(String(WebKitErrorDomain), errorCode, url.string(), String());
+ COMPtr<IWebError> error(AdoptCOM, WebError::createInstance(resourceError, userInfoBag.get()));
+
+ resourceLoadDelegate->plugInFailedWithError(webView, error.get(), getWebDataSource(frame->loader()->documentLoader()));
+
+ return pluginView;
+}
+
+void WebFrameLoaderClient::redirectDataToPlugin(Widget* pluginWidget)
+{
+ // Ideally, this function shouldn't be necessary, see <rdar://problem/4852889>
+
+ m_pluginView = static_cast<PluginView*>(pluginWidget);
+}
+
+WebHistory* WebFrameLoaderClient::webHistory() const
+{
+ if (m_webFrame != m_webFrame->webView()->topLevelFrame())
+ return 0;
+
+ return WebHistory::sharedHistory();
+}
diff --git a/WebKit/win/WebCoreSupport/WebFrameLoaderClient.h b/WebKit/win/WebCoreSupport/WebFrameLoaderClient.h
new file mode 100644
index 0000000..b9fd027
--- /dev/null
+++ b/WebKit/win/WebCoreSupport/WebFrameLoaderClient.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebFrameLoaderClient_h
+#define WebFrameLoaderClient_h
+
+#pragma warning(push, 0)
+#include <WebCore/FrameLoaderClient.h>
+#pragma warning(pop)
+
+namespace WebCore {
+ class PluginView;
+}
+
+template <typename T> class COMPtr;
+class WebFrame;
+
+class WebFrameLoaderClient : public WebCore::FrameLoaderClient {
+public:
+ virtual bool hasWebView() const;
+
+ virtual void forceLayout();
+
+ virtual void assignIdentifierToInitialRequest(unsigned long identifier, WebCore::DocumentLoader*, const WebCore::ResourceRequest&);
+
+ virtual void dispatchWillSendRequest(WebCore::DocumentLoader*, unsigned long identifier, WebCore::ResourceRequest&, const WebCore::ResourceResponse& redirectResponse);
+ virtual void dispatchDidReceiveAuthenticationChallenge(WebCore::DocumentLoader*, unsigned long identifier, const WebCore::AuthenticationChallenge&);
+ virtual void dispatchDidCancelAuthenticationChallenge(WebCore::DocumentLoader*, unsigned long identifier, const WebCore::AuthenticationChallenge&);
+ virtual void dispatchDidReceiveResponse(WebCore::DocumentLoader*, unsigned long identifier, const WebCore::ResourceResponse&);
+ virtual void dispatchDidReceiveContentLength(WebCore::DocumentLoader*, unsigned long identifier, int lengthReceived);
+ virtual void dispatchDidFinishLoading(WebCore::DocumentLoader*, unsigned long identifier);
+ virtual void dispatchDidFailLoading(WebCore::DocumentLoader*, unsigned long identifier, const WebCore::ResourceError&);
+
+ virtual void dispatchDidHandleOnloadEvents();
+ virtual void dispatchDidReceiveServerRedirectForProvisionalLoad();
+ virtual void dispatchDidCancelClientRedirect();
+ virtual void dispatchWillPerformClientRedirect(const WebCore::KURL&, double interval, double fireDate);
+ virtual void dispatchDidChangeLocationWithinPage();
+ virtual void dispatchWillClose();
+ virtual void dispatchDidReceiveIcon();
+ virtual void dispatchDidStartProvisionalLoad();
+ virtual void dispatchDidReceiveTitle(const WebCore::String&);
+ virtual void dispatchDidCommitLoad();
+ virtual void dispatchDidFinishDocumentLoad();
+ virtual void dispatchDidFinishLoad();
+ virtual void dispatchDidFirstLayout();
+
+ virtual WebCore::Frame* dispatchCreatePage();
+ virtual void dispatchShow();
+
+ virtual void dispatchDidLoadMainResource(WebCore::DocumentLoader*);
+ virtual void setMainDocumentError(WebCore::DocumentLoader*, const WebCore::ResourceError&);
+
+ virtual void postProgressStartedNotification();
+ virtual void postProgressEstimateChangedNotification();
+ virtual void postProgressFinishedNotification();
+
+ virtual void committedLoad(WebCore::DocumentLoader*, const char*, int);
+ virtual void finishedLoading(WebCore::DocumentLoader*);
+
+ virtual void updateGlobalHistory(const WebCore::KURL&);
+ virtual bool shouldGoToHistoryItem(WebCore::HistoryItem*) const;
+
+ virtual PassRefPtr<WebCore::DocumentLoader> createDocumentLoader(const WebCore::ResourceRequest&, const WebCore::SubstituteData&);
+ virtual void setTitle(const WebCore::String& title, const WebCore::KURL&);
+
+ virtual void savePlatformDataToCachedPage(WebCore::CachedPage*);
+ virtual void transitionToCommittedForNewPage();
+
+ virtual bool canCachePage() const;
+
+ virtual PassRefPtr<WebCore::Frame> createFrame(const WebCore::KURL& url, const WebCore::String& name, WebCore::HTMLFrameOwnerElement* ownerElement,
+ const WebCore::String& referrer, bool allowsScrolling, int marginWidth, int marginHeight);
+ virtual WebCore::Widget* createPlugin(const WebCore::IntSize&, WebCore::Element*, const WebCore::KURL&, const Vector<WebCore::String>&, const Vector<WebCore::String>&, const WebCore::String&, bool loadManually);
+ virtual void redirectDataToPlugin(WebCore::Widget* pluginWidget);
+
+protected:
+ WebFrameLoaderClient(WebFrame*);
+ ~WebFrameLoaderClient();
+
+private:
+ PassRefPtr<WebCore::Frame> createFrame(const WebCore::KURL&, const WebCore::String& name, WebCore::HTMLFrameOwnerElement*, const WebCore::String& referrer);
+ void loadURLIntoChild(const WebCore::KURL&, const WebCore::String& referrer, WebFrame* childFrame);
+ void receivedData(const char*, int, const WebCore::String&);
+ WebHistory* webHistory() const;
+
+ WebFrame* m_webFrame;
+
+ // Points to the plugin view that data should be redirected to.
+ WebCore::PluginView* m_pluginView;
+
+ bool m_hasSentResponseToPlugin;
+};
+
+#endif // WebFrameLoaderClient_h
diff --git a/WebKit/win/WebCoreSupport/WebInspectorClient.cpp b/WebKit/win/WebCoreSupport/WebInspectorClient.cpp
new file mode 100644
index 0000000..bfbf858
--- /dev/null
+++ b/WebKit/win/WebCoreSupport/WebInspectorClient.cpp
@@ -0,0 +1,426 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebInspectorClient.h"
+
+#include "WebInspectorDelegate.h"
+#include "WebKit.h"
+#include "WebMutableURLRequest.h"
+#include "WebNodeHighlight.h"
+#include "WebView.h"
+
+#pragma warning(push, 0)
+#include <WebCore/BString.h>
+#include <WebCore/Element.h>
+#include <WebCore/FloatRect.h>
+#include <WebCore/FrameView.h>
+#include <WebCore/InspectorController.h>
+#include <WebCore/Page.h>
+#include <WebCore/RenderObject.h>
+#include <WebCore/WindowMessageBroadcaster.h>
+#pragma warning(pop)
+
+#include <tchar.h>
+#include <wtf/RetainPtr.h>
+
+using namespace WebCore;
+
+static LPCTSTR kWebInspectorWindowClassName = TEXT("WebInspectorWindowClass");
+static ATOM registerWindowClass();
+static LPCTSTR kWebInspectorPointerProp = TEXT("WebInspectorPointer");
+
+static const unsigned defaultAttachedHeight = 300;
+
+static const IntRect& defaultWindowRect()
+{
+ static IntRect rect(60, 200, 750, 650);
+ return rect;
+}
+
+static CFBundleRef getWebKitBundle()
+{
+ return CFBundleGetBundleWithIdentifier(CFSTR("com.apple.WebKit"));
+}
+
+WebInspectorClient::WebInspectorClient(WebView* webView)
+ : m_inspectedWebView(webView)
+ , m_hwnd(0)
+ , m_webViewHwnd(0)
+ , m_attached(false)
+{
+ ASSERT(m_inspectedWebView);
+
+ m_inspectedWebView->viewWindow((OLE_HANDLE*)&m_inspectedWebViewHwnd);
+
+ // FIXME: Implement window size/position save/restore
+#if 0
+ [self setWindowFrameAutosaveName:@"Web Inspector"];
+#endif
+}
+
+WebInspectorClient::~WebInspectorClient()
+{
+ if (m_hwnd)
+ ::DestroyWindow(m_hwnd);
+}
+
+void WebInspectorClient::inspectorDestroyed()
+{
+ delete this;
+}
+
+Page* WebInspectorClient::createPage()
+{
+ if (m_webView)
+ return core(m_webView.get());
+
+ ASSERT(!m_hwnd);
+
+ registerWindowClass();
+
+ m_hwnd = ::CreateWindowEx(0, kWebInspectorWindowClassName, 0, WS_OVERLAPPEDWINDOW,
+ defaultWindowRect().x(), defaultWindowRect().y(), defaultWindowRect().width(), defaultWindowRect().height(),
+ 0, 0, 0, 0);
+
+ if (!m_hwnd)
+ return 0;
+
+ ::SetProp(m_hwnd, kWebInspectorPointerProp, reinterpret_cast<HANDLE>(this));
+
+ m_webView.adoptRef(WebView::createInstance());
+
+ if (FAILED(m_webView->setHostWindow((OLE_HANDLE)(ULONG64)m_hwnd)))
+ return 0;
+
+ RECT rect;
+ GetClientRect(m_hwnd, &rect);
+ if (FAILED(m_webView->initWithFrame(rect, 0, 0)))
+ return 0;
+
+ COMPtr<WebInspectorDelegate> delegate(AdoptCOM, WebInspectorDelegate::createInstance());
+ if (FAILED(m_webView->setUIDelegate(delegate.get())))
+ return 0;
+
+ // Keep preferences separate from the rest of the client, making sure we are using expected preference values.
+ // One reason this is good is that it keeps the inspector out of history via "private browsing".
+ // FIXME: It's crazy that we have to do this song and dance to end up with
+ // a private WebPreferences object, even within WebKit. We should make this
+ // process simpler, and consider whether we can make it simpler for WebKit
+ // clients as well.
+ COMPtr<WebPreferences> tempPreferences(AdoptCOM, WebPreferences::createInstance());
+ COMPtr<IWebPreferences> iPreferences;
+ if (FAILED(tempPreferences->initWithIdentifier(BString(L"WebInspectorPreferences"), &iPreferences)))
+ return 0;
+ COMPtr<WebPreferences> preferences(Query, iPreferences);
+ if (!preferences)
+ return 0;
+ if (FAILED(preferences->setAutosaves(FALSE)))
+ return 0;
+ if (FAILED(preferences->setPrivateBrowsingEnabled(TRUE)))
+ return 0;
+ if (FAILED(preferences->setLoadsImagesAutomatically(TRUE)))
+ return 0;
+ if (FAILED(preferences->setAuthorAndUserStylesEnabled(TRUE)))
+ return 0;
+ if (FAILED(preferences->setAllowsAnimatedImages(TRUE)))
+ return 0;
+ if (FAILED(preferences->setLoadsImagesAutomatically(TRUE)))
+ return 0;
+ if (FAILED(preferences->setPlugInsEnabled(FALSE)))
+ return 0;
+ if (FAILED(preferences->setJavaEnabled(FALSE)))
+ return 0;
+ if (FAILED(preferences->setUserStyleSheetEnabled(FALSE)))
+ return 0;
+ if (FAILED(preferences->setTabsToLinks(FALSE)))
+ return 0;
+ if (FAILED(preferences->setMinimumFontSize(0)))
+ return 0;
+ if (FAILED(preferences->setMinimumLogicalFontSize(9)))
+ return 0;
+
+ if (FAILED(m_webView->setPreferences(preferences.get())))
+ return 0;
+
+ m_webView->setProhibitsMainFrameScrolling(TRUE);
+
+ if (FAILED(m_webView->viewWindow(reinterpret_cast<OLE_HANDLE*>(&m_webViewHwnd))))
+ return 0;
+
+ COMPtr<WebMutableURLRequest> request;
+ request.adoptRef(WebMutableURLRequest::createInstance());
+
+ RetainPtr<CFURLRef> htmlURLRef(AdoptCF, CFBundleCopyResourceURL(getWebKitBundle(), CFSTR("inspector"), CFSTR("html"), CFSTR("inspector")));
+ if (!htmlURLRef)
+ return 0;
+
+ CFStringRef urlStringRef = ::CFURLGetString(htmlURLRef.get());
+ if (FAILED(request->initWithURL(BString(urlStringRef), WebURLRequestUseProtocolCachePolicy, 60)))
+ return 0;
+
+ if (FAILED(m_webView->topLevelFrame()->loadRequest(request.get())))
+ return 0;
+
+ return core(m_webView.get());
+}
+
+
+String WebInspectorClient::localizedStringsURL()
+{
+ RetainPtr<CFURLRef> url(AdoptCF, CFBundleCopyResourceURL(getWebKitBundle(), CFSTR("localizedStrings"), CFSTR("js"), 0));
+ if (!url)
+ return String();
+
+ return CFURLGetString(url.get());
+}
+
+void WebInspectorClient::showWindow()
+{
+ if (!m_hwnd)
+ return;
+
+ updateWindowTitle();
+ ::SetWindowPos(m_hwnd, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
+ m_inspectedWebView->page()->inspectorController()->setWindowVisible(true);
+}
+
+void WebInspectorClient::closeWindow()
+{
+ if (!m_webView)
+ return;
+
+ ::ShowWindow(m_hwnd, SW_HIDE);
+ m_inspectedWebView->page()->inspectorController()->setWindowVisible(false);
+}
+
+bool WebInspectorClient::windowVisible()
+{
+ return !!::IsWindowVisible(m_hwnd);
+}
+
+void WebInspectorClient::attachWindow()
+{
+ ASSERT(m_hwnd);
+ ASSERT(m_webView);
+ ASSERT(m_inspectedWebViewHwnd);
+
+ if (m_attached)
+ return;
+
+ WindowMessageBroadcaster::addListener(m_inspectedWebViewHwnd, this);
+
+ HWND hostWindow;
+ if (FAILED(m_inspectedWebView->hostWindow((OLE_HANDLE*)&hostWindow)))
+ return;
+
+ m_webView->setHostWindow((OLE_HANDLE)(ULONG64)hostWindow);
+ ::ShowWindow(m_hwnd, SW_HIDE);
+ m_attached = true;
+
+ ::SendMessage(hostWindow, WM_SIZE, 0, 0);
+
+ if (m_highlight && m_highlight->isShowing())
+ m_highlight->update();
+}
+
+void WebInspectorClient::detachWindow()
+{
+ if (!m_attached)
+ return;
+
+ WindowMessageBroadcaster::removeListener(m_inspectedWebViewHwnd, this);
+
+ m_attached = false;
+
+ m_webView->setHostWindow((OLE_HANDLE)(ULONG64)m_hwnd);
+ ::ShowWindow(m_hwnd, SW_SHOW);
+ ::SendMessage(m_hwnd, WM_SIZE, 0, 0);
+
+ HWND hostWindow;
+ if (SUCCEEDED(m_inspectedWebView->hostWindow((OLE_HANDLE*)&hostWindow)))
+ ::SendMessage(hostWindow, WM_SIZE, 0, 0);
+
+ if (m_highlight && m_highlight->isShowing())
+ m_highlight->update();
+}
+
+void WebInspectorClient::setAttachedWindowHeight(unsigned height)
+{
+ // FIXME: implement this.
+}
+
+void WebInspectorClient::highlight(Node*)
+{
+ bool creatingHighlight = !m_highlight;
+
+ if (creatingHighlight)
+ m_highlight.set(new WebNodeHighlight(m_inspectedWebView));
+
+ if (m_highlight->isShowing())
+ m_highlight->update();
+ else
+ m_highlight->setShowsWhileWebViewIsVisible(true);
+
+ if (creatingHighlight && IsWindowVisible(m_hwnd))
+ m_highlight->placeBehindWindow(m_hwnd);
+}
+
+void WebInspectorClient::hideHighlight()
+{
+ if (m_highlight)
+ m_highlight->setShowsWhileWebViewIsVisible(false);
+}
+
+void WebInspectorClient::inspectedURLChanged(const String& newURL)
+{
+ m_inspectedURL = newURL;
+ updateWindowTitle();
+}
+
+void WebInspectorClient::updateWindowTitle()
+{
+ // FIXME: The series of appends should be replaced with a call to String::format()
+ // when it can be figured out how to get the unicode em-dash to show up.
+ String title = "Web Inspector ";
+ title.append((UChar)0x2014); // em-dash
+ title.append(' ');
+ title.append(m_inspectedURL);
+ ::SetWindowText(m_hwnd, title.charactersWithNullTermination());
+}
+
+LRESULT WebInspectorClient::onGetMinMaxInfo(WPARAM, LPARAM lParam)
+{
+ MINMAXINFO* info = reinterpret_cast<MINMAXINFO*>(lParam);
+ POINT size = {400, 400};
+ info->ptMinTrackSize = size;
+
+ return 0;
+}
+
+LRESULT WebInspectorClient::onSize(WPARAM, LPARAM)
+{
+ RECT rect;
+ ::GetClientRect(m_hwnd, &rect);
+
+ ::SetWindowPos(m_webViewHwnd, 0, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER);
+
+ return 0;
+}
+
+LRESULT WebInspectorClient::onClose(WPARAM, LPARAM)
+{
+ ::ShowWindow(m_hwnd, SW_HIDE);
+ m_inspectedWebView->page()->inspectorController()->setWindowVisible(false);
+
+ hideHighlight();
+
+ return 0;
+}
+
+LRESULT WebInspectorClient::onSetFocus()
+{
+ SetFocus(m_webViewHwnd);
+ return 0;
+}
+
+void WebInspectorClient::onWebViewWindowPosChanging(WPARAM, LPARAM lParam)
+{
+ ASSERT(m_attached);
+
+ WINDOWPOS* windowPos = reinterpret_cast<WINDOWPOS*>(lParam);
+ ASSERT_ARG(lParam, windowPos);
+
+ if (windowPos->flags & SWP_NOSIZE)
+ return;
+
+ windowPos->cy -= defaultAttachedHeight;
+
+ ::SetWindowPos(m_webViewHwnd, 0, windowPos->x, windowPos->y + windowPos->cy, windowPos->cx, defaultAttachedHeight, SWP_NOZORDER);
+}
+
+static LRESULT CALLBACK WebInspectorWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ WebInspectorClient* client = reinterpret_cast<WebInspectorClient*>(::GetProp(hwnd, kWebInspectorPointerProp));
+ if (!client)
+ return ::DefWindowProc(hwnd, msg, wParam, lParam);
+
+ switch (msg) {
+ case WM_GETMINMAXINFO:
+ return client->onGetMinMaxInfo(wParam, lParam);
+ case WM_SIZE:
+ return client->onSize(wParam, lParam);
+ case WM_CLOSE:
+ return client->onClose(wParam, lParam);
+ case WM_SETFOCUS:
+ return client->onSetFocus();
+ default:
+ break;
+ }
+
+ return ::DefWindowProc(hwnd, msg, wParam, lParam);
+}
+
+void WebInspectorClient::windowReceivedMessage(HWND, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_WINDOWPOSCHANGING:
+ onWebViewWindowPosChanging(wParam, lParam);
+ break;
+ default:
+ break;
+ }
+}
+
+static ATOM registerWindowClass()
+{
+ static bool haveRegisteredWindowClass = false;
+
+ if (haveRegisteredWindowClass)
+ return true;
+
+ WNDCLASSEX wcex;
+
+ wcex.cbSize = sizeof(WNDCLASSEX);
+
+ wcex.style = 0;
+ wcex.lpfnWndProc = WebInspectorWndProc;
+ wcex.cbClsExtra = 0;
+ wcex.cbWndExtra = 0;
+ wcex.hInstance = 0;
+ wcex.hIcon = 0;
+ wcex.hCursor = LoadCursor(0, IDC_ARROW);
+ wcex.hbrBackground = 0;
+ wcex.lpszMenuName = 0;
+ wcex.lpszClassName = kWebInspectorWindowClassName;
+ wcex.hIconSm = 0;
+
+ haveRegisteredWindowClass = true;
+
+ return ::RegisterClassEx(&wcex);
+}
diff --git a/WebKit/win/WebCoreSupport/WebInspectorClient.h b/WebKit/win/WebCoreSupport/WebInspectorClient.h
new file mode 100644
index 0000000..a28507a
--- /dev/null
+++ b/WebKit/win/WebCoreSupport/WebInspectorClient.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebInspectorClient_h
+#define WebInspectorClient_h
+
+#include <WebCore/COMPtr.h>
+#include <WebCore/InspectorClient.h>
+#include <WebCore/PlatformString.h>
+#include <WebCore/WindowMessageListener.h>
+#include <wtf/OwnPtr.h>
+#include <windows.h>
+
+class WebNodeHighlight;
+class WebView;
+
+class WebInspectorClient : public WebCore::InspectorClient, WebCore::WindowMessageListener {
+public:
+ WebInspectorClient(WebView*);
+
+ // InspectorClient
+ virtual void inspectorDestroyed();
+
+ virtual WebCore::Page* createPage();
+
+ virtual WebCore::String localizedStringsURL();
+
+ virtual void showWindow();
+ virtual void closeWindow();
+ virtual bool windowVisible();
+
+ virtual void attachWindow();
+ virtual void detachWindow();
+
+ virtual void setAttachedWindowHeight(unsigned height);
+
+ virtual void highlight(WebCore::Node*);
+ virtual void hideHighlight();
+
+ virtual void inspectedURLChanged(const WebCore::String& newURL);
+
+ virtual void populateSetting(const WebCore::String& key, WebCore::InspectorController::Setting&);
+ virtual void storeSetting(const WebCore::String& key, const WebCore::InspectorController::Setting&);
+ virtual void removeSetting(const WebCore::String& key);
+
+private:
+ ~WebInspectorClient();
+
+ void updateWindowTitle();
+
+ LRESULT onGetMinMaxInfo(WPARAM, LPARAM);
+ LRESULT onSize(WPARAM, LPARAM);
+ LRESULT onClose(WPARAM, LPARAM);
+ LRESULT onSetFocus();
+
+ virtual void windowReceivedMessage(HWND, UINT message, WPARAM, LPARAM);
+
+ void onWebViewWindowPosChanging(WPARAM, LPARAM);
+
+ WebView* m_inspectedWebView;
+ HWND m_inspectedWebViewHwnd;
+ HWND m_hwnd;
+ COMPtr<WebView> m_webView;
+ HWND m_webViewHwnd;
+
+ bool m_attached;
+
+ OwnPtr<WebNodeHighlight> m_highlight;
+
+ WebCore::String m_inspectedURL;
+
+ static friend LRESULT CALLBACK WebInspectorWndProc(HWND, UINT, WPARAM, LPARAM);
+};
+
+#endif // !defined(WebInspectorClient_h)
diff --git a/WebKit/win/WebCoreSupport/WebInspectorDelegate.cpp b/WebKit/win/WebCoreSupport/WebInspectorDelegate.cpp
new file mode 100644
index 0000000..3ed8c9d
--- /dev/null
+++ b/WebKit/win/WebCoreSupport/WebInspectorDelegate.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebInspectorDelegate.h"
+
+WebInspectorDelegate::WebInspectorDelegate()
+ :m_refCount(0)
+{
+}
+
+WebInspectorDelegate* WebInspectorDelegate::createInstance()
+{
+ WebInspectorDelegate* instance = new WebInspectorDelegate;
+ instance->AddRef();
+ return instance;
+}
+
+ULONG STDMETHODCALLTYPE WebInspectorDelegate::AddRef()
+{
+ return ++m_refCount;
+}
+
+ULONG STDMETHODCALLTYPE WebInspectorDelegate::Release()
+{
+ ULONG newRef = --m_refCount;
+ if (!newRef)
+ delete(this);
+
+ return newRef;
+}
+
+HRESULT STDMETHODCALLTYPE WebInspectorDelegate::dragDestinationActionMaskForDraggingInfo(
+ /* [in] */ IWebView*,
+ /* [in] */ IDataObject*,
+ /* [retval][out] */ WebDragDestinationAction* action)
+{
+ *action = WebDragDestinationActionNone;
+
+ return S_OK;
+}
diff --git a/WebKit/win/WebCoreSupport/WebInspectorDelegate.h b/WebKit/win/WebCoreSupport/WebInspectorDelegate.h
new file mode 100644
index 0000000..a14c5fc
--- /dev/null
+++ b/WebKit/win/WebCoreSupport/WebInspectorDelegate.h
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebInspectorDelegate_h
+#define WebInspectorDelegate_h
+
+struct IDataObject;
+struct IPropertyBag;
+struct IWebView;
+struct IWebFrame;
+struct IWebError;
+struct IWebURLRequest;
+struct IWebOpenPanelResultListener;
+
+class WebInspectorDelegate : public IWebUIDelegate {
+public:
+ static WebInspectorDelegate* createInstance();
+
+ // IUnknown
+ virtual ULONG STDMETHODCALLTYPE AddRef();
+ virtual ULONG STDMETHODCALLTYPE Release();
+ virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID, void**) { return E_NOTIMPL; };
+
+ // IWebUIDelegate
+ virtual HRESULT STDMETHODCALLTYPE dragDestinationActionMaskForDraggingInfo(
+ /* [in] */ IWebView*,
+ /* [in] */ IDataObject*,
+ /* [retval][out] */ WebDragDestinationAction* action);
+
+ // Not implemented
+ virtual HRESULT STDMETHODCALLTYPE createWebViewWithRequest(
+ /* [in] */ IWebView*,
+ /* [in] */ IWebURLRequest*,
+ /* [retval][out] */ IWebView**) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewShow(
+ /* [in] */ IWebView*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewClose(
+ /* [in] */ IWebView*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewFocus(
+ /* [in] */ IWebView*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewUnfocus(
+ /* [in] */ IWebView*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewFirstResponder(
+ /* [in] */ IWebView*,
+ /* [retval][out] */ OLE_HANDLE*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE makeFirstResponder(
+ /* [in] */ IWebView*,
+ /* [in] */ OLE_HANDLE) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE setStatusText(
+ /* [in] */ IWebView*,
+ /* [in] */ BSTR) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewStatusText(
+ /* [in] */ IWebView*,
+ /* [retval][out] */ BSTR*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewAreToolbarsVisible(
+ /* [in] */ IWebView*,
+ /* [retval][out] */ BOOL*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE setToolbarsVisible(
+ /* [in] */ IWebView*,
+ /* [in] */ BOOL) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewIsStatusBarVisible(
+ /* [in] */ IWebView*,
+ /* [retval][out] */ BOOL*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE setStatusBarVisible(
+ /* [in] */ IWebView*,
+ /* [in] */ BOOL) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewIsResizable(
+ /* [in] */ IWebView*,
+ /* [retval][out] */ BOOL*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE setResizable(
+ /* [in] */ IWebView*,
+ /* [in] */ BOOL) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE setFrame(
+ /* [in] */ IWebView*,
+ /* [in] */ RECT*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewFrame(
+ /* [in] */ IWebView*,
+ /* [retval][out] */ RECT*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE setContentRect(
+ /* [in] */ IWebView*,
+ /* [in] */ RECT*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewContentRect(
+ /* [in] */ IWebView*,
+ /* [retval][out] */ RECT*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE runJavaScriptAlertPanelWithMessage(
+ /* [in] */ IWebView*,
+ /* [in] */ BSTR) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE runJavaScriptConfirmPanelWithMessage(
+ /* [in] */ IWebView*,
+ /* [in] */ BSTR,
+ /* [retval][out] */ BOOL*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE runJavaScriptTextInputPanelWithPrompt(
+ /* [in] */ IWebView*,
+ /* [in] */ BSTR /*message*/,
+ /* [in] */ BSTR /*defaultText*/,
+ /* [retval][out] */ BSTR*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE runBeforeUnloadConfirmPanelWithMessage(
+ /* [in] */ IWebView*,
+ /* [in] */ BSTR /*message*/,
+ /* [in] */ IWebFrame* /*initiatedByFrame*/,
+ /* [retval][out] */ BOOL*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE runOpenPanelForFileButtonWithResultListener(
+ /* [in] */ IWebView*,
+ /* [in] */ IWebOpenPanelResultListener*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE mouseDidMoveOverElement(
+ /* [in] */ IWebView*,
+ /* [in] */ IPropertyBag*,
+ /* [in] */ UINT /*modifierFlags*/) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE contextMenuItemsForElement(
+ /* [in] */ IWebView*,
+ /* [in] */ IPropertyBag*,
+ /* [in] */ OLE_HANDLE,
+ /* [retval][out] */ OLE_HANDLE*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE validateUserInterfaceItem(
+ /* [in] */ IWebView*,
+ /* [in] */ UINT,
+ /* [in] */ BOOL,
+ /* [retval][out] */ BOOL*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE shouldPerformAction(
+ /* [in] */ IWebView*,
+ /* [in] */ UINT /*itemCommandID*/,
+ /* [in] */ UINT /*sender*/) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE willPerformDragDestinationAction(
+ /* [in] */ IWebView*,
+ /* [in] */ WebDragDestinationAction,
+ /* [in] */ IDataObject*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE dragSourceActionMaskForPoint(
+ /* [in] */ IWebView*,
+ /* [in] */ LPPOINT,
+ /* [retval][out] */ WebDragSourceAction*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE willPerformDragSourceAction(
+ /* [in] */ IWebView*,
+ /* [in] */ WebDragSourceAction,
+ /* [in] */ LPPOINT,
+ /* [in] */ IDataObject*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE contextMenuItemSelected(
+ /* [in] */ IWebView*,
+ /* [in] */ void* /*item*/,
+ /* [in] */ IPropertyBag*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE hasCustomMenuImplementation(
+ /* [retval][out] */ BOOL*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE trackCustomPopupMenu(
+ /* [in] */ IWebView*,
+ /* [in] */ OLE_HANDLE,
+ /* [in] */ LPPOINT) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE measureCustomMenuItem(
+ /* [in] */ IWebView*,
+ /* [in] */ void* /*measureItem*/) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE drawCustomMenuItem(
+ /* [in] */ IWebView*,
+ /* [in] */ void* /*drawItem*/) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE addCustomMenuDrawingData(
+ /* [in] */ IWebView*,
+ /* [in] */ OLE_HANDLE) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE cleanUpCustomMenuDrawingData(
+ /* [in] */ IWebView*,
+ /* [in] */ OLE_HANDLE) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE canTakeFocus(
+ /* [in] */ IWebView*,
+ /* [in] */ BOOL /*forward*/,
+ /* [out] */ BOOL*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE takeFocus(
+ /* [in] */ IWebView*,
+ /* [in] */ BOOL /*forward*/) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE registerUndoWithTarget(
+ /* [in] */ IWebUndoTarget*,
+ /* [in] */ BSTR /*actionName*/,
+ /* [in] */ IUnknown* /*actionArg*/) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE removeAllActionsWithTarget(
+ /* [in] */ IWebUndoTarget*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE setActionTitle(
+ /* [in] */ BSTR) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE undo() { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE redo() { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE canUndo(
+ /* [retval][out] */ BOOL*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE canRedo(
+ /* [retval][out] */ BOOL*) { return E_NOTIMPL; }
+
+private:
+ WebInspectorDelegate();
+
+ ULONG m_refCount;
+};
+
+#endif // WebInspectorDelegate_h