diff options
author | Ben Murdoch <benm@google.com> | 2011-05-13 16:23:25 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2011-05-16 11:35:02 +0100 |
commit | 65f03d4f644ce73618e5f4f50dd694b26f55ae12 (patch) | |
tree | f478babb801e720de7bfaee23443ffe029f58731 /Source/WebKit/win/WebCoreSupport | |
parent | 47de4a2fb7262c7ebdb9cd133ad2c54c187454d0 (diff) | |
download | external_webkit-65f03d4f644ce73618e5f4f50dd694b26f55ae12.zip external_webkit-65f03d4f644ce73618e5f4f50dd694b26f55ae12.tar.gz external_webkit-65f03d4f644ce73618e5f4f50dd694b26f55ae12.tar.bz2 |
Merge WebKit at r75993: Initial merge by git.
Change-Id: I602bbdc3974787a3b0450456a30a7868286921c3
Diffstat (limited to 'Source/WebKit/win/WebCoreSupport')
26 files changed, 6462 insertions, 0 deletions
diff --git a/Source/WebKit/win/WebCoreSupport/EmbeddedWidget.cpp b/Source/WebKit/win/WebCoreSupport/EmbeddedWidget.cpp new file mode 100644 index 0000000..371ff3a --- /dev/null +++ b/Source/WebKit/win/WebCoreSupport/EmbeddedWidget.cpp @@ -0,0 +1,238 @@ +/* + * 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> + +#include "MemoryStream.h" +#include "WebError.h" +#include "WebURLResponse.h" + +using namespace WebCore; + +PassRefPtr<EmbeddedWidget> EmbeddedWidget::create(IWebEmbeddedView* view, Element* element, HWND parentWindow, const IntSize& size) +{ + RefPtr<EmbeddedWidget> widget = adoptRef(new EmbeddedWidget(view, element)); + + widget->createWindow(parentWindow, size); + return widget.release(); +} + +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() +{ + 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(bool focused) +{ + if (m_window && focused) + SetFocus(m_window); + + Widget::setFocus(focused); +} + +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; +} + +void EmbeddedWidget::didReceiveResponse(const ResourceResponse& response) +{ + ASSERT(m_view); + + COMPtr<IWebURLResponse> urlResponse(AdoptCOM, WebURLResponse::createInstance(response)); + m_view->didReceiveResponse(urlResponse.get()); +} + +void EmbeddedWidget::didReceiveData(const char* data, int length) +{ + COMPtr<MemoryStream> stream = MemoryStream::createInstance(SharedBuffer::create(data, length)); + m_view->didReceiveData(stream.get()); +} + +void EmbeddedWidget::didFinishLoading() +{ + m_view->didFinishLoading(); +} + +void EmbeddedWidget::didFail(const ResourceError& error) +{ + COMPtr<IWebError> webError(AdoptCOM, WebError::createInstance(error)); + m_view->didFail(webError.get()); +} diff --git a/Source/WebKit/win/WebCoreSupport/EmbeddedWidget.h b/Source/WebKit/win/WebCoreSupport/EmbeddedWidget.h new file mode 100644 index 0000000..ccd3451 --- /dev/null +++ b/Source/WebKit/win/WebCoreSupport/EmbeddedWidget.h @@ -0,0 +1,85 @@ +/* + * 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/PluginView.h> + +namespace WebCore { + class Element; + class IntSize; +} + +interface IWebEmbeddedView; + +class EmbeddedWidget : public WebCore::Widget, public WebCore::PluginManualLoader { +public: + static PassRefPtr<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 didReceiveResponse(const WebCore::ResourceResponse&); + virtual void didReceiveData(const char*, int); + virtual void didFinishLoading(); + virtual void didFail(const WebCore::ResourceError&); + + virtual void invalidateRect(const WebCore::IntRect&); + virtual void setFrameRect(const WebCore::IntRect&); + virtual void frameRectsChanged(); + virtual void setFocus(bool); + 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; + + WebCore::IntRect m_clipRect; // The clip rect to apply to an embedded view. + WebCore::IntRect m_windowRect; // Our window rect. +}; + +#endif // EmbeddedWidget_h diff --git a/Source/WebKit/win/WebCoreSupport/WebChromeClient.cpp b/Source/WebKit/win/WebCoreSupport/WebChromeClient.cpp new file mode 100644 index 0000000..6460b4a --- /dev/null +++ b/Source/WebKit/win/WebCoreSupport/WebChromeClient.cpp @@ -0,0 +1,874 @@ +/* + * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + * + * 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 "COMPropertyBag.h" +#include "COMVariantSetter.h" +#include "DOMCoreClasses.h" +#include "WebElementPropertyBag.h" +#include "WebFrame.h" +#include "WebHistory.h" +#include "WebMutableURLRequest.h" +#include "WebDesktopNotificationsDelegate.h" +#include "WebSecurityOrigin.h" +#include "WebView.h" +#include <WebCore/BString.h> +#include <WebCore/Console.h> +#include <WebCore/ContextMenu.h> +#include <WebCore/Cursor.h> +#include <WebCore/FileChooser.h> +#include <WebCore/FloatRect.h> +#include <WebCore/FrameLoadRequest.h> +#include <WebCore/FrameView.h> +#include <WebCore/HTMLNames.h> +#include <WebCore/Icon.h> +#include <WebCore/LocalWindowsContext.h> +#include <WebCore/LocalizedStrings.h> +#include <WebCore/NavigationAction.h> +#include <WebCore/NotImplemented.h> +#include <WebCore/Page.h> +#include <WebCore/SecurityOrigin.h> +#include <WebCore/PopupMenuWin.h> +#include <WebCore/SearchPopupMenuWin.h> +#include <WebCore/WindowFeatures.h> +#include <tchar.h> + +#if USE(ACCELERATED_COMPOSITING) +#include <WebCore/GraphicsLayer.h> +#endif + +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) +#if ENABLE(NOTIFICATIONS) + , m_notificationsDelegate(new WebDesktopNotificationsDelegate(webView)) +#endif +{ +} + +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(); + } +} + +void WebChromeClient::focusedNodeChanged(Node*) +{ +} + +void WebChromeClient::focusedFrameChanged(Frame*) +{ +} + +static COMPtr<IPropertyBag> createWindowFeaturesPropertyBag(const WindowFeatures& features) +{ + HashMap<String, COMVariant> map; + if (features.xSet) + map.set(WebWindowFeaturesXKey, features.x); + if (features.ySet) + map.set(WebWindowFeaturesYKey, features.y); + if (features.widthSet) + map.set(WebWindowFeaturesWidthKey, features.width); + if (features.heightSet) + map.set(WebWindowFeaturesHeightKey, features.height); + map.set(WebWindowFeaturesMenuBarVisibleKey, features.menuBarVisible); + map.set(WebWindowFeaturesStatusBarVisibleKey, features.statusBarVisible); + map.set(WebWindowFeaturesToolBarVisibleKey, features.toolBarVisible); + map.set(WebWindowFeaturesScrollbarsVisibleKey, features.scrollbarsVisible); + map.set(WebWindowFeaturesResizableKey, features.resizable); + map.set(WebWindowFeaturesFullscreenKey, features.fullscreen); + map.set(WebWindowFeaturesDialogKey, features.dialog); + + return COMPtr<IPropertyBag>(AdoptCOM, COMPropertyBag<COMVariant>::adopt(map)); +} + +Page* WebChromeClient::createWindow(Frame*, const FrameLoadRequest&, const WindowFeatures& features, const NavigationAction&) +{ + COMPtr<IWebUIDelegate> delegate = uiDelegate(); + if (!delegate) + return 0; + + // Just create a blank request because createWindow() is only required to create window but not to load URL. + COMPtr<IWebMutableURLRequest> request(AdoptCOM, WebMutableURLRequest::createInstance()); + + COMPtr<IWebUIDelegatePrivate2> delegatePrivate(Query, delegate); + if (delegatePrivate) { + COMPtr<IWebView> newWebView; + HRESULT hr = delegatePrivate->createWebViewWithRequest(m_webView, request.get(), createWindowFeaturesPropertyBag(features).get(), &newWebView); + + if (SUCCEEDED(hr) && newWebView) + return core(newWebView.get()); + + // If the delegate doesn't implement the IWebUIDelegatePrivate2 version of the call, fall back + // to the old versions (even if they support the IWebUIDelegatePrivate2 interface). + if (hr != E_NOTIMPL) + return 0; + } + + COMPtr<IWebView> newWebView; + + if (features.dialog) { + if (FAILED(delegate->createModalDialog(m_webView, request.get(), &newWebView))) + return 0; + } else if (FAILED(delegate->createWebViewWithRequest(m_webView, request.get(), &newWebView))) + return 0; + + return newWebView ? core(newWebView.get()) : 0; +} + +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<IWebUIDelegate> delegate = uiDelegate()) + delegate->canRunModal(m_webView, &result); + return result; +} + +void WebChromeClient::runModal() +{ + if (COMPtr<IWebUIDelegate> delegate = uiDelegate()) + 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<IWebUIDelegate> delegate = uiDelegate(); + if (!delegate) + return; + delegate->setMenuBarVisible(m_webView, visible); +} + +bool WebChromeClient::menubarVisible() +{ + COMPtr<IWebUIDelegate> delegate = uiDelegate(); + 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(MessageSource source, MessageType type, MessageLevel level, 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 +{ + return IntRect(); +} + +void WebChromeClient::invalidateWindow(const IntRect& windowRect, bool immediate) +{ + ASSERT(core(m_webView->topLevelFrame())); + m_webView->repaint(windowRect, false /*contentChanged*/, immediate, false /*repaintContentOnly*/); +} + +void WebChromeClient::invalidateContentsAndWindow(const IntRect& windowRect, bool immediate) +{ + ASSERT(core(m_webView->topLevelFrame())); + m_webView->repaint(windowRect, true /*contentChanged*/, immediate /*immediate*/, false /*repaintContentOnly*/); +} + +void WebChromeClient::invalidateContentsForSlowScroll(const IntRect& windowRect, bool immediate) +{ + ASSERT(core(m_webView->topLevelFrame())); + m_webView->repaint(windowRect, true /*contentChanged*/, immediate, true /*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; +} + +PlatformPageClient WebChromeClient::platformPageClient() const +{ + HWND viewWindow; + if (FAILED(m_webView->viewWindow(reinterpret_cast<OLE_HANDLE*>(&viewWindow)))) + return 0; + return viewWindow; +} + +void WebChromeClient::contentsSizeChanged(Frame*, const IntSize&) const +{ + notImplemented(); +} + +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); +} + +bool WebChromeClient::shouldMissingPluginMessageBeButton() const +{ + COMPtr<IWebUIDelegate> uiDelegate; + if (FAILED(m_webView->uiDelegate(&uiDelegate))) + return false; + + // If the UI delegate implements IWebUIDelegatePrivate3, + // which contains didPressMissingPluginButton, then the message should be a button. + COMPtr<IWebUIDelegatePrivate3> uiDelegatePrivate3(Query, uiDelegate); + return uiDelegatePrivate3; +} + +void WebChromeClient::missingPluginButtonClicked(Element* element) const +{ + COMPtr<IWebUIDelegate> uiDelegate; + if (FAILED(m_webView->uiDelegate(&uiDelegate))) + return; + + COMPtr<IWebUIDelegatePrivate3> uiDelegatePrivate3(Query, uiDelegate); + if (!uiDelegatePrivate3) + return; + + COMPtr<IDOMElement> e(AdoptCOM, DOMElement::createInstance(element)); + uiDelegatePrivate3->didPressMissingPluginButton(e.get()); +} + +void WebChromeClient::setToolTip(const String& toolTip, TextDirection) +{ + m_webView->setToolTip(toolTip); +} + +void WebChromeClient::print(Frame* frame) +{ + COMPtr<IWebUIDelegate> uiDelegate; + if (SUCCEEDED(m_webView->uiDelegate(&uiDelegate))) + uiDelegate->printFrame(m_webView, kit(frame)); +} + +#if ENABLE(DATABASE) +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<IWebUIDelegatePrivate> uiDelegatePrivate(Query, uiDelegate); + if (uiDelegatePrivate) + uiDelegatePrivate->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, WTF_ARRAY_LENGTH(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); + } + } + } +} +#endif + +#if ENABLE(OFFLINE_WEB_APPLICATIONS) +#include "ApplicationCacheStorage.h" +void WebChromeClient::reachedMaxAppCacheSize(int64_t spaceNeeded) +{ + // FIXME: Free some space. + notImplemented(); +} + +void WebChromeClient::reachedApplicationCacheOriginQuota(SecurityOrigin*) +{ + notImplemented(); +} +#endif + +void WebChromeClient::populateVisitedLinks() +{ + COMPtr<IWebHistoryDelegate> historyDelegate; + m_webView->historyDelegate(&historyDelegate); + if (historyDelegate) { + historyDelegate->populateVisitedLinksForWebView(m_webView); + return; + } + + 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<IWebUIDelegate> delegate = uiDelegate(); + 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); + LocalWindowsContext windowsContext(context, webRect); + HRESULT hr = delegate->paintCustomScrollbar(m_webView, windowsContext.hdc(), webRect, webSize, webState, webPressedPart, + vertical, value, proportion, webParts); + return SUCCEEDED(hr); +} + +bool WebChromeClient::paintCustomScrollCorner(GraphicsContext* context, const FloatRect& rect) +{ + if (context->paintingDisabled()) + return false; + + COMPtr<IWebUIDelegate> delegate = uiDelegate(); + if (!delegate) + return false; + + RECT webRect = enclosingIntRect(rect); + LocalWindowsContext windowsContext(context, webRect); + HRESULT hr = delegate->paintCustomScrollCorner(m_webView, windowsContext.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. +} + +void WebChromeClient::chooseIconForFiles(const Vector<WTF::String>& filenames, WebCore::FileChooser* chooser) +{ + chooser->iconLoaded(Icon::createIconForFiles(filenames)); +} + +void WebChromeClient::setCursor(const Cursor& cursor) +{ + HCURSOR platformCursor = cursor.platformCursor()->nativeCursor(); + if (!platformCursor) + return; + + bool shouldSetCursor = true; + if (COMPtr<IWebUIDelegate> delegate = uiDelegate()) { + COMPtr<IWebUIDelegatePrivate> delegatePrivate(Query, delegate); + if (delegatePrivate) { + if (SUCCEEDED(delegatePrivate->webViewSetCursor(m_webView, reinterpret_cast<OLE_HANDLE>(platformCursor)))) + shouldSetCursor = false; + } + } + + if (shouldSetCursor) + ::SetCursor(platformCursor); + + setLastSetCursorToCurrentCursor(); +} + +void WebChromeClient::setLastSetCursorToCurrentCursor() +{ + m_webView->setLastCursor(::GetCursor()); +} + +#if USE(ACCELERATED_COMPOSITING) +void WebChromeClient::attachRootGraphicsLayer(Frame* frame, GraphicsLayer* graphicsLayer) +{ + m_webView->setRootChildLayer(graphicsLayer); +} + +void WebChromeClient::scheduleCompositingLayerSync() +{ + m_webView->scheduleCompositingLayerSync(); +} + +#endif + +COMPtr<IWebUIDelegate> WebChromeClient::uiDelegate() +{ + COMPtr<IWebUIDelegate> delegate; + m_webView->uiDelegate(&delegate); + return delegate; +} + +#if ENABLE(VIDEO) + +bool WebChromeClient::supportsFullscreenForNode(const Node* node) +{ + return node->hasTagName(HTMLNames::videoTag); +} + +void WebChromeClient::enterFullscreenForNode(Node* node) +{ + m_webView->enterFullscreenForNode(node); +} + +void WebChromeClient::exitFullscreenForNode(Node*) +{ + m_webView->exitFullscreen(); +} + +#endif + +bool WebChromeClient::selectItemWritingDirectionIsNatural() +{ + return true; +} + +PassRefPtr<PopupMenu> WebChromeClient::createPopupMenu(PopupMenuClient* client) const +{ + return adoptRef(new PopupMenuWin(client)); +} + +PassRefPtr<SearchPopupMenu> WebChromeClient::createSearchPopupMenu(PopupMenuClient* client) const +{ + return adoptRef(new SearchPopupMenuWin(client)); +} + diff --git a/Source/WebKit/win/WebCoreSupport/WebChromeClient.h b/Source/WebKit/win/WebCoreSupport/WebChromeClient.h new file mode 100644 index 0000000..b6c2525 --- /dev/null +++ b/Source/WebKit/win/WebCoreSupport/WebChromeClient.h @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + * + * 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> +#include <wtf/PassRefPtr.h> + +class WebView; +class WebDesktopNotificationsDelegate; + +interface IWebUIDelegate; + +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 void focusedNodeChanged(WebCore::Node*); + virtual void focusedFrameChanged(WebCore::Frame*); + + virtual WebCore::Page* createWindow(WebCore::Frame*, const WebCore::FrameLoadRequest&, const WebCore::WindowFeatures&, const WebCore::NavigationAction&); + 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(WebCore::MessageSource source, WebCore::MessageType type, WebCore::MessageLevel level, const WTF::String& message, unsigned line, const WTF::String& url); + + virtual bool canRunBeforeUnloadConfirmPanel(); + virtual bool runBeforeUnloadConfirmPanel(const WTF::String& message, WebCore::Frame* frame); + + virtual void closeWindowSoon(); + + virtual void runJavaScriptAlert(WebCore::Frame*, const WTF::String&); + virtual bool runJavaScriptConfirm(WebCore::Frame*, const WTF::String&); + virtual bool runJavaScriptPrompt(WebCore::Frame*, const WTF::String& message, const WTF::String& defaultValue, WTF::String& result); + virtual void setStatusbarText(const WTF::String&); + virtual bool shouldInterruptJavaScript(); + + virtual bool tabsToLinks() const; + virtual WebCore::IntRect windowResizerRect() const; + + virtual void invalidateWindow(const WebCore::IntRect&, bool); + virtual void invalidateContentsAndWindow(const WebCore::IntRect&, bool); + virtual void invalidateContentsForSlowScroll(const WebCore::IntRect&, bool); + 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 PlatformPageClient platformPageClient() const; + virtual void contentsSizeChanged(WebCore::Frame*, const WebCore::IntSize&) const; + + virtual void scrollbarsModeDidChange() const { } + virtual void mouseDidMoveOverElement(const WebCore::HitTestResult&, unsigned modifierFlags); + virtual bool shouldMissingPluginMessageBeButton() const; + virtual void missingPluginButtonClicked(WebCore::Element*) const; + + virtual void setToolTip(const WTF::String&, WebCore::TextDirection); + + virtual void print(WebCore::Frame*); + +#if ENABLE(DATABASE) + virtual void exceededDatabaseQuota(WebCore::Frame*, const WTF::String&); +#endif + +#if ENABLE(OFFLINE_WEB_APPLICATIONS) + virtual void reachedMaxAppCacheSize(int64_t spaceNeeded); + virtual void reachedApplicationCacheOriginQuota(WebCore::SecurityOrigin*); +#endif + +#if ENABLE(CONTEXT_MENUS) + virtual void showContextMenu() { } +#endif + + 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>); + virtual void chooseIconForFiles(const Vector<WTF::String>&, WebCore::FileChooser*); + + virtual void setCursor(const WebCore::Cursor&); + virtual void setLastSetCursorToCurrentCursor(); + + WebView* webView() const { return m_webView; } + + virtual void formStateDidChange(const WebCore::Node*) { } + + virtual PassOwnPtr<WebCore::HTMLParserQuirks> createHTMLParserQuirks() { return 0; } + +#if USE(ACCELERATED_COMPOSITING) + // Pass 0 as the GraphicsLayer to detatch the root layer. + virtual void attachRootGraphicsLayer(WebCore::Frame*, WebCore::GraphicsLayer*); + // Sets a flag to specify that the next time content is drawn to the window, + // the changes appear on the screen in synchrony with updates to GraphicsLayers. + virtual void setNeedsOneShotDrawingSynchronization() { } + // Sets a flag to specify that the view needs to be updated, so we need + // to do an eager layout before the drawing. + virtual void scheduleCompositingLayerSync(); +#endif + + virtual void scrollRectIntoView(const WebCore::IntRect&, const WebCore::ScrollView*) const {} + + // FIXME: Remove once all ports are using client-based geolocation. https://bugs.webkit.org/show_bug.cgi?id=40373 + // For client-based geolocation, these two methods have been moved to WebGeolocationClient. https://bugs.webkit.org/show_bug.cgi?id=50061 + virtual void requestGeolocationPermissionForFrame(WebCore::Frame*, WebCore::Geolocation*) { } + virtual void cancelGeolocationPermissionRequestForFrame(WebCore::Frame*, WebCore::Geolocation*) { } + +#if ENABLE(VIDEO) + virtual bool supportsFullscreenForNode(const WebCore::Node*); + virtual void enterFullscreenForNode(WebCore::Node*); + virtual void exitFullscreenForNode(WebCore::Node*); +#endif + +#if ENABLE(NOTIFICATIONS) + virtual WebCore::NotificationPresenter* notificationPresenter() const { return reinterpret_cast<WebCore::NotificationPresenter*>(m_notificationsDelegate.get()); } +#endif + + virtual bool selectItemWritingDirectionIsNatural(); + virtual PassRefPtr<WebCore::PopupMenu> createPopupMenu(WebCore::PopupMenuClient*) const; + virtual PassRefPtr<WebCore::SearchPopupMenu> createSearchPopupMenu(WebCore::PopupMenuClient*) const; + +private: + COMPtr<IWebUIDelegate> uiDelegate(); + + WebView* m_webView; + +#if ENABLE(NOTIFICATIONS) + OwnPtr<WebDesktopNotificationsDelegate> m_notificationsDelegate; +#endif +}; diff --git a/Source/WebKit/win/WebCoreSupport/WebContextMenuClient.cpp b/Source/WebKit/win/WebCoreSupport/WebContextMenuClient.cpp new file mode 100644 index 0000000..9405fc8 --- /dev/null +++ b/Source/WebKit/win/WebCoreSupport/WebContextMenuClient.cpp @@ -0,0 +1,149 @@ +/* + * 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 "UserGestureIndicator.h" +#include "WebElementPropertyBag.h" +#include "WebLocalizableStrings.h" +#include "WebView.h" + +#include <WebCore/ContextMenu.h> +#include <WebCore/ContextMenuController.h> +#include <WebCore/Event.h> +#include <WebCore/Frame.h> +#include <WebCore/FrameLoader.h> +#include <WebCore/FrameLoadRequest.h> +#include <WebCore/Page.h> +#include <WebCore/ResourceRequest.h> +#include <WebCore/NotImplemented.h> + +#include <tchar.h> + +using namespace WebCore; + +WebContextMenuClient::WebContextMenuClient(WebView* webView) + : m_webView(webView) +{ +} + +void WebContextMenuClient::contextMenuDestroyed() +{ + delete this; +} + +PassOwnPtr<ContextMenu> WebContextMenuClient::customizeMenu(PassOwnPtr<ContextMenu> popMenu) +{ + OwnPtr<ContextMenu> menu = popMenu; + + COMPtr<IWebUIDelegate> uiDelegate; + if (FAILED(m_webView->uiDelegate(&uiDelegate))) + return menu.release(); + + ASSERT(uiDelegate); + + HMENU nativeMenu = menu->nativeMenu(); + COMPtr<WebElementPropertyBag> propertyBag; + propertyBag.adoptRef(WebElementPropertyBag::createInstance(m_webView->page()->contextMenuController()->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)nativeMenu, (OLE_HANDLE*)&nativeMenu))) { + ::DestroyMenu(nativeMenu); + return menu.release(); + } + + OwnPtr<ContextMenu> customizedMenu = adoptPtr(new ContextMenu(nativeMenu)); + ::DestroyMenu(nativeMenu); + + return customizedMenu.release(); +} + +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(m_webView->page()->contextMenuController()->hitTestResult())); + + // This call would leak the MENUITEMINFO's subMenu if it had one, but on Windows, subMenus can't be selected, so there is + // no way we would get to this point. Also, it can't be a separator, because separators cannot be selected. + ASSERT(item->type() != SubmenuType); + ASSERT(item->type() != SeparatorType); + + // ContextMenuItem::nativeMenuItem doesn't set the dwTypeData of the MENUITEMINFO, but no WebKit clients + // use the title in IWebUIDelegate::contextMenuItemSelected, so we don't need to populate it here. + MENUITEMINFO selectedItem = item->nativeMenuItem(); + + uiDelegate->contextMenuItemSelected(m_webView, &selectedItem, propertyBag.get()); +} + +void WebContextMenuClient::downloadURL(const KURL& url) +{ + m_webView->downloadURL(url); +} + +void WebContextMenuClient::searchWithGoogle(const Frame* frame) +{ + String searchString = frame->editor()->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"); + + if (Page* page = frame->page()) { + UserGestureIndicator indicator(DefinitelyProcessingUserGesture); + page->mainFrame()->loader()->urlSelected(KURL(ParsedURLString, url), String(), 0, false, false, SendReferrer); + } +} + +void WebContextMenuClient::lookUpInDictionary(Frame*) +{ + notImplemented(); +} + +void WebContextMenuClient::speak(const String&) +{ + notImplemented(); +} + +void WebContextMenuClient::stopSpeaking() +{ + notImplemented(); +} + +bool WebContextMenuClient::isSpeaking() +{ + notImplemented(); + return false; +} diff --git a/Source/WebKit/win/WebCoreSupport/WebContextMenuClient.h b/Source/WebKit/win/WebCoreSupport/WebContextMenuClient.h new file mode 100644 index 0000000..ed41c59 --- /dev/null +++ b/Source/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/ContextMenu.h> +#include <WebCore/ContextMenuClient.h> +#include <wtf/Forward.h> +#include <wtf/PassOwnPtr.h> + +class WebView; + +class WebContextMenuClient : public WebCore::ContextMenuClient { +public: + WebContextMenuClient(WebView*); + + virtual void contextMenuDestroyed(); + + virtual PassOwnPtr<WebCore::ContextMenu> customizeMenu(PassOwnPtr<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 WTF::String&); + virtual void stopSpeaking(); + virtual bool isSpeaking(); + +private: + WebView* m_webView; +}; diff --git a/Source/WebKit/win/WebCoreSupport/WebDesktopNotificationsDelegate.cpp b/Source/WebKit/win/WebCoreSupport/WebDesktopNotificationsDelegate.cpp new file mode 100644 index 0000000..8c66d0e --- /dev/null +++ b/Source/WebKit/win/WebCoreSupport/WebDesktopNotificationsDelegate.cpp @@ -0,0 +1,206 @@ +/* + * Copyright (C) 2009 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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 "WebDesktopNotificationsDelegate.h" +#include "WebSecurityOrigin.h" +#include "WebView.h" +#include <WebCore/BString.h> +#include <WebCore/Document.h> +#include <WebCore/KURL.h> + +#if ENABLE(NOTIFICATIONS) + +using namespace WebCore; + +class NotificationCOMWrapper : public IWebDesktopNotification { +public: + static NotificationCOMWrapper* create(Notification* inner) { return new NotificationCOMWrapper(inner); } + + // IUnknown + virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject); + virtual ULONG STDMETHODCALLTYPE AddRef(); + virtual ULONG STDMETHODCALLTYPE Release(); + + // IWebDesktopNotification + HRESULT STDMETHODCALLTYPE isHTML(BOOL* result); + HRESULT STDMETHODCALLTYPE contentsURL(BSTR* result); + HRESULT STDMETHODCALLTYPE iconURL(BSTR* result); + HRESULT STDMETHODCALLTYPE title(BSTR* result); + HRESULT STDMETHODCALLTYPE text(BSTR* result); + HRESULT STDMETHODCALLTYPE notifyDisplay(); + HRESULT STDMETHODCALLTYPE notifyError(); + HRESULT STDMETHODCALLTYPE notifyClose(BOOL xplicit); + +private: + NotificationCOMWrapper(Notification* inner) : m_refCount(1), m_inner(inner) {} + + int m_refCount; + Notification* m_inner; +}; + +HRESULT STDMETHODCALLTYPE NotificationCOMWrapper::QueryInterface(REFIID riid, void** ppvObject) +{ + *ppvObject = 0; + if (IsEqualGUID(riid, IID_IUnknown)) + *ppvObject = static_cast<NotificationCOMWrapper*>(this); + else if (IsEqualGUID(riid, IID_IWebDesktopNotification)) + *ppvObject = static_cast<NotificationCOMWrapper*>(this); + else + return E_NOINTERFACE; + + AddRef(); + return S_OK; +} + +ULONG STDMETHODCALLTYPE NotificationCOMWrapper::AddRef() +{ + return ++m_refCount; +} + +ULONG STDMETHODCALLTYPE NotificationCOMWrapper::Release() +{ + ULONG newRef = --m_refCount; + if (!newRef) + delete(this); + return newRef; +} + +HRESULT STDMETHODCALLTYPE NotificationCOMWrapper::isHTML(BOOL* result) +{ + *result = m_inner->isHTML(); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE NotificationCOMWrapper::contentsURL(BSTR* result) +{ + *result = BString(m_inner->url()).release(); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE NotificationCOMWrapper::iconURL(BSTR* result) +{ + *result = BString(m_inner->contents().icon()).release(); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE NotificationCOMWrapper::title(BSTR* result) +{ + *result = BString(m_inner->contents().title()).release(); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE NotificationCOMWrapper::text(BSTR* result) +{ + *result = BString(m_inner->contents().body()).release(); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE NotificationCOMWrapper::notifyDisplay() +{ + m_inner->dispatchDisplayEvent(); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE NotificationCOMWrapper::notifyError() +{ + m_inner->dispatchErrorEvent(); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE NotificationCOMWrapper::notifyClose(BOOL xplicit) +{ + m_inner->dispatchCloseEvent(); + return S_OK; +} + +WebDesktopNotificationsDelegate::WebDesktopNotificationsDelegate(WebView* webView) + : m_webView(webView) +{ +} + +bool WebDesktopNotificationsDelegate::show(Notification* object) +{ + if (hasNotificationDelegate()) + notificationDelegate()->showDesktopNotification(NotificationCOMWrapper::create(object)); + return true; +} + +void WebDesktopNotificationsDelegate::cancel(Notification* object) +{ + if (hasNotificationDelegate()) + notificationDelegate()->cancelDesktopNotification(NotificationCOMWrapper::create(object)); +} + +void WebDesktopNotificationsDelegate::notificationObjectDestroyed(Notification* object) +{ + if (hasNotificationDelegate()) + notificationDelegate()->notificationDestroyed(NotificationCOMWrapper::create(object)); +} + +void WebDesktopNotificationsDelegate::requestPermission(SecurityOrigin* origin, PassRefPtr<VoidCallback> callback) +{ + BString org(origin->toString()); + if (hasNotificationDelegate()) + notificationDelegate()->requestNotificationPermission(org); +} + +NotificationPresenter::Permission WebDesktopNotificationsDelegate::checkPermission(const KURL& url) +{ + int out = 0; + BString org(SecurityOrigin::create(url)->toString()); + if (hasNotificationDelegate()) + notificationDelegate()->checkNotificationPermission(org, &out); + return (NotificationPresenter::Permission) out; +} + +bool WebDesktopNotificationsDelegate::hasNotificationDelegate() +{ + COMPtr<IWebUIDelegate> ui; + m_webView->uiDelegate(&ui); + + COMPtr<IWebUIDelegate2> ui2; + return SUCCEEDED(ui->QueryInterface(IID_IWebUIDelegate2, (void**) &ui2)); +} + +COMPtr<IWebDesktopNotificationsDelegate> WebDesktopNotificationsDelegate::notificationDelegate() +{ + COMPtr<IWebUIDelegate> ui; + m_webView->uiDelegate(&ui); + + COMPtr<IWebUIDelegate2> ui2; + COMPtr<IWebDesktopNotificationsDelegate> delegate; + if (SUCCEEDED(ui->QueryInterface(IID_IWebUIDelegate2, (void**) &ui2))) + ui2->desktopNotificationsDelegate(&delegate); + + return delegate; +} + +#endif // ENABLE(NOTIFICATIONS) diff --git a/Source/WebKit/win/WebCoreSupport/WebDesktopNotificationsDelegate.h b/Source/WebKit/win/WebCoreSupport/WebDesktopNotificationsDelegate.h new file mode 100644 index 0000000..344c95b --- /dev/null +++ b/Source/WebKit/win/WebCoreSupport/WebDesktopNotificationsDelegate.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2009 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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/COMPtr.h> +#include <WebCore/Notification.h> +#include <WebCore/NotificationPresenter.h> + +#if ENABLE(NOTIFICATIONS) + +interface IWebDesktopNotificationPresenter; + +namespace WebCore { +class Document; +class KURL; +} + +class WebDesktopNotificationsDelegate : public WebCore::NotificationPresenter { +public: + WebDesktopNotificationsDelegate(WebView* view); + + /* WebCore::NotificationPresenter interface */ + virtual bool show(WebCore::Notification* object); + virtual void cancel(WebCore::Notification* object); + virtual void notificationObjectDestroyed(WebCore::Notification* object); + virtual void requestPermission(WebCore::SecurityOrigin* origin, PassRefPtr<WebCore::VoidCallback> callback); + virtual WebCore::NotificationPresenter::Permission checkPermission(const KURL& url); + +private: + bool hasNotificationDelegate(); + COMPtr<IWebDesktopNotificationsDelegate> notificationDelegate(); + + WebView* m_webView; +}; + +#endif diff --git a/Source/WebKit/win/WebCoreSupport/WebDragClient.cpp b/Source/WebKit/win/WebCoreSupport/WebDragClient.cpp new file mode 100644 index 0000000..f4d9842 --- /dev/null +++ b/Source/WebKit/win/WebCoreSupport/WebDragClient.cpp @@ -0,0 +1,325 @@ +/* + * 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> + +#pragma warning(push, 0) +#include <WebCore/ClipboardWin.h> +#include <WebCore/DragController.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/Settings.h> +#include <WebCore/StringTruncator.h> +#include <WebCore/WebCoreTextRenderer.h> +#pragma warning(pop) + +namespace WebCore { + HBITMAP allocImage(HDC dc, IntSize size, PlatformGraphicsContext** targetRef); + void deallocContext(PlatformGraphicsContext* target); +} + + +#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; + +static DWORD draggingSourceOperationMaskToDragCursors(DragOperation op) +{ + DWORD result = DROPEFFECT_NONE; + if (op == DragOperationEvery) + return DROPEFFECT_COPY | DROPEFFECT_LINK | DROPEFFECT_MOVE; + if (op & DragOperationCopy) + result |= DROPEFFECT_COPY; + if (op & DragOperationLink) + result |= DROPEFFECT_LINK; + if (op & DragOperationMove) + result |= DROPEFFECT_MOVE; + if (op & DragOperationGeneric) + result |= DROPEFFECT_MOVE; + return result; +} + +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 action, const IntPoint& intPoint, Clipboard* clipboard) +{ + COMPtr<IWebUIDelegate> uiDelegate; + if (!SUCCEEDED(m_webView->uiDelegate(&uiDelegate))) + return; + + POINT point = intPoint; + COMPtr<IDataObject> dataObject = static_cast<ClipboardWin*>(clipboard)->dataObject(); + + COMPtr<IDataObject> newDataObject; + HRESULT result = uiDelegate->willPerformDragSourceAction(m_webView, static_cast<WebDragSourceAction>(action), &point, dataObject.get(), &newDataObject); + if (result == S_OK && newDataObject != dataObject) + static_cast<ClipboardWin*>(clipboard)->setExternalDataObject(newDataObject.get()); +} + +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()); + } + } + + DWORD okEffect = draggingSourceOperationMaskToDragCursors(m_webView->page()->dragController()->sourceDragOperation()); + DWORD effect = DROPEFFECT_NONE; + COMPtr<IWebUIDelegate> ui; + HRESULT hr = E_NOTIMPL; + if (SUCCEEDED(m_webView->uiDelegate(&ui))) { + COMPtr<IWebUIDelegatePrivate> uiPrivate; + if (SUCCEEDED(ui->QueryInterface(IID_IWebUIDelegatePrivate, (void**)&uiPrivate))) + hr = uiPrivate->doDragDrop(m_webView, dataObject.get(), source.get(), okEffect, &effect); + } + if (hr == E_NOTIMPL) + hr = DoDragDrop(dataObject.get(), source.get(), okEffect, &effect); + + DragOperation operation = DragOperationNone; + if (hr == DRAGDROP_S_DROP) { + if (effect & DROPEFFECT_COPY) + operation = DragOperationCopy; + else if (effect & DROPEFFECT_LINK) + operation = DragOperationLink; + else if (effect & DROPEFFECT_MOVE) + operation = DragOperationMove; + } + frame->eventHandler()->dragSourceEndedAt(generateMouseEvent(m_webView, false), operation); + } +} + +static Font dragLabelFont(int size, bool bold, FontRenderingMode renderingMode) +{ + NONCLIENTMETRICS metrics; + metrics.cbSize = sizeof(metrics); + SystemParametersInfo(SPI_GETNONCLIENTMETRICS, metrics.cbSize, &metrics, 0); + FontDescription desc; + desc.setWeight(bold ? FontWeightBold : FontWeightNormal); + FontFamily family; + family.setFamily(metrics.lfSmCaptionFont.lfFaceName); + desc.setFamily(family); + desc.setSpecifiedSize((float)size); + desc.setComputedSize((float)size); + desc.setRenderingMode(renderingMode); + Font result = Font(desc, 0, 0); + result.update(0); + return result; +} + +DragImageRef WebDragClient::createDragImageForLink(KURL& url, const String& inLabel, Frame* frame) +{ + // This is more or less an exact match for the Mac OS X code. + + const Font* labelFont; + const Font* urlFont; + + if (frame->settings() && frame->settings()->fontRenderingMode() == AlternateRenderingMode) { + static const Font alternateRenderingModeLabelFont = dragLabelFont(DRAG_LINK_LABEL_FONT_SIZE, true, AlternateRenderingMode); + static const Font alternateRenderingModeURLFont = dragLabelFont(DRAG_LINK_URL_FONT_SIZE, false, AlternateRenderingMode); + labelFont = &alternateRenderingModeLabelFont; + urlFont = &alternateRenderingModeURLFont; + } else { + static const Font normalRenderingModeLabelFont = dragLabelFont(DRAG_LINK_LABEL_FONT_SIZE, true, NormalRenderingMode); + static const Font normalRenderingModeURLFont = dragLabelFont(DRAG_LINK_URL_FONT_SIZE, false, NormalRenderingMode); + labelFont = &normalRenderingModeLabelFont; + urlFont = &normalRenderingModeURLFont; + } + + 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; + } + + PlatformGraphicsContext* 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); + IntRect rect(0, 0, imageSize.width(), imageSize.height()); + context.fillRoundedRect(rect, radii, radii, radii, radii, backgroundColor, ColorSpaceDeviceRGB); + + // 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); + + deallocContext(contextRef); + DeleteDC(workingDC); + ReleaseDC(0, dc); + return image; +} + +void WebDragClient::dragControllerDestroyed() +{ + delete this; +} diff --git a/Source/WebKit/win/WebCoreSupport/WebDragClient.h b/Source/WebKit/win/WebCoreSupport/WebDragClient.h new file mode 100644 index 0000000..da2d208 --- /dev/null +++ b/Source/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 WTF::String&, WebCore::Frame*); +private: + WebView* m_webView; +}; + diff --git a/Source/WebKit/win/WebCoreSupport/WebEditorClient.cpp b/Source/WebKit/win/WebCoreSupport/WebEditorClient.cpp new file mode 100644 index 0000000..539259b --- /dev/null +++ b/Source/WebKit/win/WebCoreSupport/WebEditorClient.cpp @@ -0,0 +1,790 @@ +/* + * 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 "WebNotification.h" +#include "WebNotificationCenter.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/NotImplemented.h> +#include <WebCore/PlatformKeyboardEvent.h> +#include <WebCore/Range.h> +#include <WebCore/UserTypingGestureIndicator.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(); + + static BSTR webViewDidChangeSelectionNotificationName = SysAllocString(WebViewDidChangeSelectionNotification); + IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal(); + notifyCenter->postNotificationName(webViewDidChangeSelectionNotificationName, static_cast<IWebView*>(m_webView), 0); +} + +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::isSelectTrailingWhitespaceEnabled(void) +{ + BOOL enabled = FALSE; + m_webView->isSelectTrailingWhitespaceEnabled(&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) +{ + if (!UserTypingGestureIndicator::processingUserTypingGesture() || UserTypingGestureIndicator::focusedElementAtGestureStart() != e) + return; + + 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); +} + +String WebEditorClient::getAutoCorrectSuggestionForMisspelledWord(const String& inputWord) +{ + // This method can be implemented using customized algorithms for the particular browser. + // Currently, it computes an empty string. + return String(); +} + +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, const String& context, 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::willSetInputMethodState() +{ +} + +void WebEditorClient::setInputMethodState(bool enabled) +{ + m_webView->setInputMethodState(enabled); +} diff --git a/Source/WebKit/win/WebCoreSupport/WebEditorClient.h b/Source/WebKit/win/WebCoreSupport/WebEditorClient.h new file mode 100644 index 0000000..358a365 --- /dev/null +++ b/Source/WebKit/win/WebCoreSupport/WebEditorClient.h @@ -0,0 +1,121 @@ +/* + * 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 WTF::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(); + bool isSelectTrailingWhitespaceEnabled(); + + 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 WTF::String&); + virtual void learnWord(const WTF::String&); + virtual void checkSpellingOfString(const UChar*, int length, int* misspellingLocation, int* misspellingLength); + virtual WTF::String getAutoCorrectSuggestionForMisspelledWord(const WTF::String&); + virtual void checkGrammarOfString(const UChar*, int length, Vector<WebCore::GrammarDetail>&, int* badGrammarLocation, int* badGrammarLength); + virtual void updateSpellingUIWithGrammarString(const WTF::String&, const WebCore::GrammarDetail& detail); + virtual void updateSpellingUIWithMisspelledWord(const WTF::String&); + virtual void showSpellingUI(bool show); + virtual bool spellingUIIsShowing(); + virtual void getGuessesForWord(const WTF::String& word, const WTF::String& context, WTF::Vector<WTF::String>& guesses); + + virtual void willSetInputMethodState(); + virtual void setInputMethodState(bool); + virtual void requestCheckingOfString(WebCore::SpellChecker*, int, const WTF::String&) {} + +private: + WebView* m_webView; + WebEditorUndoTarget* m_undoTarget; +}; + +#endif // WebEditorClient_H diff --git a/Source/WebKit/win/WebCoreSupport/WebFrameLoaderClient.cpp b/Source/WebKit/win/WebCoreSupport/WebFrameLoaderClient.cpp new file mode 100644 index 0000000..7fd2b98 --- /dev/null +++ b/Source/WebKit/win/WebCoreSupport/WebFrameLoaderClient.cpp @@ -0,0 +1,930 @@ +/* + * Copyright (C) 2006, 2007, 2008, 2009 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 "DOMHTMLClasses.h" +#include "EmbeddedWidget.h" +#include "MarshallingHelpers.h" +#include "NotImplemented.h" +#include "WebCachedFramePlatformData.h" +#include "WebChromeClient.h" +#include "WebDocumentLoader.h" +#include "WebError.h" +#include "WebFrame.h" +#include "WebHistory.h" +#include "WebHistoryItem.h" +#include "WebMutableURLRequest.h" +#include "WebNavigationData.h" +#include "WebNotificationCenter.h" +#include "WebSecurityOrigin.h" +#include "WebURLAuthenticationChallenge.h" +#include "WebURLResponse.h" +#include "WebView.h" +#pragma warning(push, 0) +#include <WebCore/CachedFrame.h> +#include <WebCore/DocumentLoader.h> +#include <WebCore/FrameLoader.h> +#include <WebCore/FrameTree.h> +#include <WebCore/FrameView.h> +#include <WebCore/HTMLAppletElement.h> +#include <WebCore/HTMLFrameElement.h> +#include <WebCore/HTMLFrameOwnerElement.h> +#include <WebCore/HTMLNames.h> +#include <WebCore/HTMLParserIdioms.h> +#include <WebCore/HTMLPlugInElement.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_manualLoader(0) + , m_hasSentResponseToPlugin(false) +{ + ASSERT_ARG(webFrame, webFrame); +} + +WebFrameLoaderClient::~WebFrameLoaderClient() +{ +} + +bool WebFrameLoaderClient::hasWebView() const +{ + return m_webFrame->webView(); +} + +void WebFrameLoaderClient::forceLayout() +{ + Frame* frame = core(m_webFrame); + if (!frame) + return; + + if (frame->document() && frame->document()->inPageCache()) + return; + + FrameView* view = frame->view(); + if (!view) + return; + + view->setNeedsLayout(); + view->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); +} + +bool WebFrameLoaderClient::shouldUseCredentialStorage(DocumentLoader* loader, unsigned long identifier) +{ + WebView* webView = m_webFrame->webView(); + COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate; + if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate))) + return true; + + COMPtr<IWebResourceLoadDelegatePrivate> resourceLoadDelegatePrivate; + if (FAILED(resourceLoadDelegate->QueryInterface(IID_IWebResourceLoadDelegatePrivate, reinterpret_cast<void**>(&resourceLoadDelegatePrivate)))) + return true; + + BOOL shouldUse; + if (SUCCEEDED(resourceLoadDelegatePrivate->shouldUseCredentialStorage(webView, identifier, getWebDataSource(loader), &shouldUse))) + return shouldUse; + + return true; +} + +void WebFrameLoaderClient::dispatchDidReceiveAuthenticationChallenge(DocumentLoader* loader, unsigned long identifier, const AuthenticationChallenge& challenge) +{ +#if USE(CFNETWORK) + ASSERT(challenge.authenticationClient()); + + 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.authenticationClient()->receivedRequestToContinueWithoutCredential(challenge); +#else + notImplemented(); +#endif +} + +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; + + if (!newWebURLRequest) { + request = ResourceRequest(); + 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)); +} + +bool WebFrameLoaderClient::shouldCacheResponse(DocumentLoader* loader, unsigned long identifier, const ResourceResponse& response, const unsigned char* data, const unsigned long long length) +{ + WebView* webView = m_webFrame->webView(); + COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate; + if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate))) + return true; + + COMPtr<IWebResourceLoadDelegatePrivate> resourceLoadDelegatePrivate(Query, resourceLoadDelegate); + if (!resourceLoadDelegatePrivate) + return true; + + COMPtr<IWebURLResponse> urlResponse(AdoptCOM, WebURLResponse::createInstance(response)); + BOOL shouldCache; + if (SUCCEEDED(resourceLoadDelegatePrivate->shouldCacheResponse(webView, identifier, urlResponse.get(), data, length, getWebDataSource(loader), &shouldCache))) + return shouldCache; + + return true; +} + +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::dispatchDidPushStateWithinPage() +{ + WebView* webView = m_webFrame->webView(); + COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv; + if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv) + return; + + COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv); + if (!frameLoadDelegatePriv2) + return; + + frameLoadDelegatePriv2->didPushStateWithinPageForFrame(webView, m_webFrame); +} + +void WebFrameLoaderClient::dispatchDidReplaceStateWithinPage() +{ + WebView* webView = m_webFrame->webView(); + COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv; + if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv) + return; + + COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv); + if (!frameLoadDelegatePriv2) + return; + + frameLoadDelegatePriv2->didReplaceStateWithinPageForFrame(webView, m_webFrame); +} + +void WebFrameLoaderClient::dispatchDidPopStateWithinPage() +{ + WebView* webView = m_webFrame->webView(); + COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv; + if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv) + return; + + COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv); + if (!frameLoadDelegatePriv2) + return; + + frameLoadDelegatePriv2->didPopStateWithinPageForFrame(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::dispatchDidChangeIcons() +{ + WebView* webView = m_webFrame->webView(); + COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv; + if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv) + return; + + COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv); + if (!frameLoadDelegatePriv2) + return; + + frameLoadDelegatePriv2->didChangeIcons(webView, 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); +} + +void WebFrameLoaderClient::dispatchDidFirstVisuallyNonEmptyLayout() +{ + WebView* webView = m_webFrame->webView(); + COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePrivate; + if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePrivate)) && frameLoadDelegatePrivate) + frameLoadDelegatePrivate->didFirstVisuallyNonEmptyLayoutInFrame(webView, m_webFrame); +} + +Frame* WebFrameLoaderClient::dispatchCreatePage(const NavigationAction&) +{ + 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_manualLoader) + return; + + m_manualLoader->didFail(error); + m_manualLoader = 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) +{ + if (!m_manualLoader) + loader->commitData(data, length); + + // If the document is a stand-alone media document, now is the right time to cancel the WebKit load. + // FIXME: This code should be shared across all ports. <http://webkit.org/b/48762>. + Frame* coreFrame = core(m_webFrame); + if (coreFrame->document()->isMediaDocument()) + loader->cancelMainResourceLoad(pluginWillHandleLoadError(loader->response())); + + if (!m_manualLoader) + return; + + if (!m_hasSentResponseToPlugin) { + m_manualLoader->didReceiveResponse(loader->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_manualLoader + // to null + if (!m_manualLoader) + return; + m_hasSentResponseToPlugin = true; + } + m_manualLoader->didReceiveData(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) + committedLoad(loader, 0, 0); + + if (!m_manualLoader) + return; + + m_manualLoader->didFinishLoading(); + m_manualLoader = 0; + m_hasSentResponseToPlugin = false; +} + +void WebFrameLoaderClient::updateGlobalHistory() +{ + DocumentLoader* loader = core(m_webFrame)->loader()->documentLoader(); + WebView* webView = m_webFrame->webView(); + COMPtr<IWebHistoryDelegate> historyDelegate; + webView->historyDelegate(&historyDelegate); + + if (historyDelegate) { + COMPtr<IWebURLResponse> urlResponse(AdoptCOM, WebURLResponse::createInstance(loader->response())); + COMPtr<IWebURLRequest> urlRequest(AdoptCOM, WebMutableURLRequest::createInstance(loader->originalRequestCopy())); + + COMPtr<IWebNavigationData> navigationData(AdoptCOM, WebNavigationData::createInstance( + loader->urlForHistory(), loader->title(), urlRequest.get(), urlResponse.get(), loader->substituteData().isValid(), loader->clientRedirectSourceForHistory())); + + historyDelegate->didNavigateWithNavigationData(webView, navigationData.get(), m_webFrame); + return; + } + + WebHistory* history = WebHistory::sharedHistory(); + if (!history) + return; + + history->visitedURL(loader->urlForHistory(), loader->title(), loader->originalRequestCopy().httpMethod(), loader->urlForHistoryReflectsFailure(), !loader->clientRedirectSourceForHistory()); +} + +void WebFrameLoaderClient::updateGlobalHistoryRedirectLinks() +{ + WebView* webView = m_webFrame->webView(); + COMPtr<IWebHistoryDelegate> historyDelegate; + webView->historyDelegate(&historyDelegate); + + WebHistory* history = WebHistory::sharedHistory(); + + DocumentLoader* loader = core(m_webFrame)->loader()->documentLoader(); + ASSERT(loader->unreachableURL().isEmpty()); + + if (!loader->clientRedirectSourceForHistory().isNull()) { + if (historyDelegate) { + BString sourceURL(loader->clientRedirectSourceForHistory()); + BString destURL(loader->clientRedirectDestinationForHistory()); + historyDelegate->didPerformClientRedirectFromURL(webView, sourceURL, destURL, m_webFrame); + } else { + if (history) { + if (COMPtr<IWebHistoryItem> iWebHistoryItem = history->itemForURLString(loader->clientRedirectSourceForHistory())) { + COMPtr<WebHistoryItem> webHistoryItem(Query, iWebHistoryItem); + webHistoryItem->historyItem()->addRedirectURL(loader->clientRedirectDestinationForHistory()); + } + } + } + } + + if (!loader->serverRedirectSourceForHistory().isNull()) { + if (historyDelegate) { + BString sourceURL(loader->serverRedirectSourceForHistory()); + BString destURL(loader->serverRedirectDestinationForHistory()); + historyDelegate->didPerformServerRedirectFromURL(webView, sourceURL, destURL, m_webFrame); + } else { + if (history) { + if (COMPtr<IWebHistoryItem> iWebHistoryItem = history->itemForURLString(loader->serverRedirectSourceForHistory())) { + COMPtr<WebHistoryItem> webHistoryItem(Query, iWebHistoryItem); + webHistoryItem->historyItem()->addRedirectURL(loader->serverRedirectDestinationForHistory()); + } + } + } + } +} + +bool WebFrameLoaderClient::shouldGoToHistoryItem(HistoryItem*) const +{ + return true; +} + +void WebFrameLoaderClient::dispatchDidAddBackForwardItem(HistoryItem*) const +{ +} + +void WebFrameLoaderClient::dispatchDidRemoveBackForwardItem(HistoryItem*) const +{ +} + +void WebFrameLoaderClient::dispatchDidChangeBackForwardIndex() const +{ +} + +void WebFrameLoaderClient::didDisplayInsecureContent() +{ + WebView* webView = m_webFrame->webView(); + COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv; + if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv) + return; + + COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv); + if (!frameLoadDelegatePriv2) + return; + + frameLoadDelegatePriv2->didDisplayInsecureContent(webView); +} + +void WebFrameLoaderClient::didRunInsecureContent(SecurityOrigin* origin) +{ + COMPtr<IWebSecurityOrigin> webSecurityOrigin = WebSecurityOrigin::createInstance(origin); + + WebView* webView = m_webFrame->webView(); + COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv; + if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv) + return; + + COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv); + if (!frameLoadDelegatePriv2) + return; + + frameLoadDelegatePriv2->didRunInsecureContent(webView, webSecurityOrigin.get()); +} + +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) +{ + WebView* webView = m_webFrame->webView(); + COMPtr<IWebHistoryDelegate> historyDelegate; + webView->historyDelegate(&historyDelegate); + if (historyDelegate) { + BString titleBSTR(title); + BString urlBSTR(url.string()); + historyDelegate->updateHistoryTitle(webView, titleBSTR, urlBSTR); + return; + } + + 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::savePlatformDataToCachedFrame(CachedFrame* cachedFrame) +{ +#if USE(CFNETWORK) + Frame* coreFrame = core(m_webFrame); + if (!coreFrame) + return; + + ASSERT(coreFrame->loader()->documentLoader() == cachedFrame->documentLoader()); + + WebCachedFramePlatformData* webPlatformData = new WebCachedFramePlatformData(static_cast<IWebDataSource*>(getWebDataSource(coreFrame->loader()->documentLoader()))); + cachedFrame->setCachedFramePlatformData(webPlatformData); +#else + notImplemented(); +#endif +} + +void WebFrameLoaderClient::transitionToCommittedFromCachedFrame(CachedFrame*) +{ +} + +void WebFrameLoaderClient::transitionToCommittedForNewPage() +{ + WebView* view = m_webFrame->webView(); + + RECT rect; + view->frameRect(&rect); + bool transparent = view->transparent(); + Color backgroundColor = transparent ? Color::transparent : Color::white; + core(m_webFrame)->createView(IntRect(rect).size(), backgroundColor, transparent, IntSize(), false); +} + +void WebFrameLoaderClient::didSaveToPageCache() +{ +} + +void WebFrameLoaderClient::didRestoreFromPageCache() +{ +} + +void WebFrameLoaderClient::dispatchDidBecomeFrameset(bool) +{ +} + +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(); +} + +void WebFrameLoaderClient::didTransferChildFrameToNewDocument(Page*) +{ + Frame* coreFrame = core(m_webFrame); + ASSERT(coreFrame); + WebView* webView = kit(coreFrame->page()); + if (m_webFrame->webView() != webView) + m_webFrame->setWebView(webView); +} + +void WebFrameLoaderClient::transferLoadingResourceFromPage(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request, Page* oldPage) +{ + assignIdentifierToInitialRequest(identifier, loader, request); + + WebView* oldWebView = kit(oldPage); + if (!oldWebView) + return; + + COMPtr<IWebResourceLoadDelegate> oldResourceLoadDelegate; + if (FAILED(oldWebView->resourceLoadDelegate(&oldResourceLoadDelegate))) + return; + + COMPtr<IWebResourceLoadDelegatePrivate2> oldResourceLoadDelegatePrivate2(Query, oldResourceLoadDelegate); + if (!oldResourceLoadDelegatePrivate2) + return; + oldResourceLoadDelegatePrivate2->removeIdentifierForRequest(oldWebView, identifier); +} + +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); + + childFrame->tree()->setName(name); + coreFrame->tree()->appendChild(childFrame); + childFrame->init(); + + coreFrame->loader()->loadURLIntoChildFrame(URL, referrer, childFrame.get()); + + // The frame's onload handler may have removed it from the document. + if (!childFrame->tree()->parent()) + return 0; + + return childFrame.release(); +} + +void WebFrameLoaderClient::dispatchDidFailToStartPlugin(const PluginView* pluginView) const +{ + WebView* webView = m_webFrame->webView(); + + COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate; + if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate))) + return; + + RetainPtr<CFMutableDictionaryRef> userInfo(AdoptCF, CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); + + Frame* frame = core(m_webFrame); + ASSERT(frame == pluginView->parentFrame()); + + if (!pluginView->pluginsPage().isNull()) { + KURL pluginPageURL = frame->document()->completeURL(stripLeadingAndTrailingHTMLSpaces(pluginView->pluginsPage())); + if (pluginPageURL.protocolInHTTPFamily()) { + static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorPlugInPageURLStringKey); + RetainPtr<CFStringRef> str(AdoptCF, pluginPageURL.string().createCFString()); + CFDictionarySetValue(userInfo.get(), key, str.get()); + } + } + + if (!pluginView->mimeType().isNull()) { + static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorMIMETypeKey); + + RetainPtr<CFStringRef> str(AdoptCF, pluginView->mimeType().createCFString()); + CFDictionarySetValue(userInfo.get(), key, str.get()); + } + + if (pluginView->plugin()) { + String 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 = 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, pluginView->url().string(), String()); + COMPtr<IWebError> error(AdoptCOM, WebError::createInstance(resourceError, userInfoBag.get())); + + resourceLoadDelegate->plugInFailedWithError(webView, error.get(), getWebDataSource(frame->loader()->documentLoader())); +} + +PassRefPtr<Widget> WebFrameLoaderClient::createPlugin(const IntSize& pluginSize, HTMLPlugInElement* 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<IWebUIDelegatePrivate> 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)); + COMPtr<IDOMElement> containingElement(AdoptCOM, DOMElement::createInstance(element)); + + HashMap<String, COMVariant> arguments; + + arguments.set(WebEmbeddedViewAttributesKey, viewArgumentsBag); + arguments.set(WebEmbeddedViewBaseURLKey, url.string()); + arguments.set(WebEmbeddedViewContainingElementKey, containingElement); + arguments.set(WebEmbeddedViewMIMETypeKey, mimeType); + + COMPtr<IPropertyBag> argumentsBag(AdoptCOM, COMPropertyBag<COMVariant>::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); + RefPtr<PluginView> pluginView = PluginView::create(frame, pluginSize, element, url, paramNames, paramValues, mimeType, loadManually); + + if (pluginView->status() == PluginStatusLoadedSuccessfully) + return pluginView; + + dispatchDidFailToStartPlugin(pluginView.get()); + + return 0; +} + +void WebFrameLoaderClient::redirectDataToPlugin(Widget* pluginWidget) +{ + // Ideally, this function shouldn't be necessary, see <rdar://problem/4852889> + + if (pluginWidget->isPluginView()) + m_manualLoader = static_cast<PluginView*>(pluginWidget); + else + m_manualLoader = static_cast<EmbeddedWidget*>(pluginWidget); +} + +WebHistory* WebFrameLoaderClient::webHistory() const +{ + if (m_webFrame != m_webFrame->webView()->topLevelFrame()) + return 0; + + return WebHistory::sharedHistory(); +} + +bool WebFrameLoaderClient::shouldUsePluginDocument(const String& mimeType) const +{ + WebView* webView = m_webFrame->webView(); + if (!webView) + return false; + + return webView->shouldUseEmbeddedView(mimeType); +} diff --git a/Source/WebKit/win/WebCoreSupport/WebFrameLoaderClient.h b/Source/WebKit/win/WebCoreSupport/WebFrameLoaderClient.h new file mode 100644 index 0000000..573b58f --- /dev/null +++ b/Source/WebKit/win/WebCoreSupport/WebFrameLoaderClient.h @@ -0,0 +1,145 @@ +/* + * 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 PluginManualLoader; + 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 bool shouldUseCredentialStorage(WebCore::DocumentLoader*, unsigned long identifier); + 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 bool shouldCacheResponse(WebCore::DocumentLoader*, unsigned long identifier, const WebCore::ResourceResponse&, const unsigned char* data, unsigned long long length); + + virtual void dispatchDidHandleOnloadEvents(); + virtual void dispatchDidReceiveServerRedirectForProvisionalLoad(); + virtual void dispatchDidCancelClientRedirect(); + virtual void dispatchWillPerformClientRedirect(const WebCore::KURL&, double interval, double fireDate); + virtual void dispatchDidChangeLocationWithinPage(); + virtual void dispatchDidPushStateWithinPage(); + virtual void dispatchDidReplaceStateWithinPage(); + virtual void dispatchDidPopStateWithinPage(); + virtual void dispatchWillClose(); + virtual void dispatchDidReceiveIcon(); + virtual void dispatchDidStartProvisionalLoad(); + virtual void dispatchDidReceiveTitle(const WTF::String&); + virtual void dispatchDidChangeIcons(); + virtual void dispatchDidCommitLoad(); + virtual void dispatchDidFinishDocumentLoad(); + virtual void dispatchDidFinishLoad(); + virtual void dispatchDidFirstLayout(); + virtual void dispatchDidFirstVisuallyNonEmptyLayout(); + + virtual WebCore::Frame* dispatchCreatePage(const WebCore::NavigationAction&); + 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(); + virtual void updateGlobalHistoryRedirectLinks(); + virtual bool shouldGoToHistoryItem(WebCore::HistoryItem*) const; + virtual void dispatchDidAddBackForwardItem(WebCore::HistoryItem*) const; + virtual void dispatchDidRemoveBackForwardItem(WebCore::HistoryItem*) const; + virtual void dispatchDidChangeBackForwardIndex() const; + + virtual void didDisplayInsecureContent(); + virtual void didRunInsecureContent(WebCore::SecurityOrigin*); + + virtual PassRefPtr<WebCore::DocumentLoader> createDocumentLoader(const WebCore::ResourceRequest&, const WebCore::SubstituteData&); + virtual void setTitle(const WTF::String& title, const WebCore::KURL&); + + virtual void savePlatformDataToCachedFrame(WebCore::CachedFrame*); + virtual void transitionToCommittedFromCachedFrame(WebCore::CachedFrame*); + virtual void transitionToCommittedForNewPage(); + + virtual void didSaveToPageCache(); + virtual void didRestoreFromPageCache(); + + virtual void dispatchDidBecomeFrameset(bool); + + virtual bool canCachePage() const; + + virtual PassRefPtr<WebCore::Frame> createFrame(const WebCore::KURL& url, const WTF::String& name, WebCore::HTMLFrameOwnerElement* ownerElement, + const WTF::String& referrer, bool allowsScrolling, int marginWidth, int marginHeight); + virtual void didTransferChildFrameToNewDocument(WebCore::Page*); + virtual void transferLoadingResourceFromPage(unsigned long, WebCore::DocumentLoader*, const WebCore::ResourceRequest&, WebCore::Page*); + virtual PassRefPtr<WebCore::Widget> createPlugin(const WebCore::IntSize&, WebCore::HTMLPlugInElement*, const WebCore::KURL&, const Vector<WTF::String>&, const Vector<WTF::String>&, const WTF::String&, bool loadManually); + virtual void redirectDataToPlugin(WebCore::Widget* pluginWidget); + + virtual bool shouldUsePluginDocument(const WTF::String& mimeType) const; + + virtual void dispatchDidFailToStartPlugin(const WebCore::PluginView*) const; + +protected: + WebFrameLoaderClient(WebFrame*); + ~WebFrameLoaderClient(); + +private: + PassRefPtr<WebCore::Frame> createFrame(const WebCore::KURL&, const WTF::String& name, WebCore::HTMLFrameOwnerElement*, const WTF::String& referrer); + WebHistory* webHistory() const; + + WebFrame* m_webFrame; + + // Points to the manual loader that data should be redirected to. + WebCore::PluginManualLoader* m_manualLoader; + + bool m_hasSentResponseToPlugin; +}; + +#endif // WebFrameLoaderClient_h diff --git a/Source/WebKit/win/WebCoreSupport/WebFrameNetworkingContext.cpp b/Source/WebKit/win/WebCoreSupport/WebFrameNetworkingContext.cpp new file mode 100644 index 0000000..b87b6d9 --- /dev/null +++ b/Source/WebKit/win/WebCoreSupport/WebFrameNetworkingContext.cpp @@ -0,0 +1,44 @@ +/* + Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" + +#include "WebFrameNetworkingContext.h" + +using namespace WebCore; + +PassRefPtr<WebFrameNetworkingContext> WebFrameNetworkingContext::create(Frame* frame, const String& userAgent) +{ + return adoptRef(new WebFrameNetworkingContext(frame, userAgent)); +} + +String WebFrameNetworkingContext::userAgent() const +{ + return m_userAgent; +} + +String WebFrameNetworkingContext::referrer() const +{ + return frame()->loader()->referrer(); +} + +WebCore::ResourceError WebFrameNetworkingContext::blockedError(const WebCore::ResourceRequest& request) const +{ + return frame()->loader()->blockedError(request); +} diff --git a/Source/WebKit/win/WebCoreSupport/WebFrameNetworkingContext.h b/Source/WebKit/win/WebCoreSupport/WebFrameNetworkingContext.h new file mode 100644 index 0000000..a237c9a --- /dev/null +++ b/Source/WebKit/win/WebCoreSupport/WebFrameNetworkingContext.h @@ -0,0 +1,44 @@ +/* + Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef WebFrameNetworkingContext_h +#define WebFrameNetworkingContext_h + +#include <WebCore/FrameNetworkingContext.h> +#include <WebCore/ResourceError.h> + +class WebFrameNetworkingContext : public WebCore::FrameNetworkingContext { +public: + static PassRefPtr<WebFrameNetworkingContext> create(WebCore::Frame*, const WTF::String& userAgent); + +private: + WebFrameNetworkingContext(WebCore::Frame* frame, const WTF::String& userAgent) + : WebCore::FrameNetworkingContext(frame) + , m_userAgent(userAgent) + { + } + + virtual WTF::String userAgent() const; + virtual WTF::String referrer() const; + virtual WebCore::ResourceError blockedError(const WebCore::ResourceRequest&) const; + + WTF::String m_userAgent; +}; + +#endif // WebFrameNetworkingContext_h diff --git a/Source/WebKit/win/WebCoreSupport/WebGeolocationClient.cpp b/Source/WebKit/win/WebCoreSupport/WebGeolocationClient.cpp new file mode 100644 index 0000000..b1d83fb --- /dev/null +++ b/Source/WebKit/win/WebCoreSupport/WebGeolocationClient.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2010 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. 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 INC. 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 "WebKitDLL.h" +#include "WebGeolocationClient.h" + +#include "WebFrame.h" +#include "WebGeolocationPolicyListener.h" +#include "WebGeolocationPosition.h" +#include "WebSecurityOrigin.h" +#include "WebView.h" +#include <WebCore/Frame.h> +#include <WebCore/Geolocation.h> +#include <WebCore/SecurityOrigin.h> + +using namespace WebCore; + +WebGeolocationClient::WebGeolocationClient(WebView* webView) + : m_webView(webView) +{ +} + +void WebGeolocationClient::geolocationDestroyed() +{ + delete this; +} + +void WebGeolocationClient::startUpdating() +{ + COMPtr<IWebGeolocationProvider> provider; + if (FAILED(m_webView->geolocationProvider(&provider))) + return; + provider->registerWebView(m_webView.get()); +} + +void WebGeolocationClient::stopUpdating() +{ + COMPtr<IWebGeolocationProvider> provider; + if (FAILED(m_webView->geolocationProvider(&provider))) + return; + provider->unregisterWebView(m_webView.get()); +} + +GeolocationPosition* WebGeolocationClient::lastPosition() +{ +#if ENABLE(CLIENT_BASED_GEOLOCATION) + COMPtr<IWebGeolocationProvider> provider; + if (FAILED(m_webView->geolocationProvider(&provider))) + return 0; + COMPtr<IWebGeolocationPosition> position; + if (FAILED(provider->lastPosition(&position))) + return 0; + return core(position.get()); +#else + return 0; +#endif +} + +void WebGeolocationClient::requestPermission(Geolocation* geolocation) +{ + COMPtr<IWebUIDelegate> uiDelegate; + if (FAILED(m_webView->uiDelegate(&uiDelegate))) { + geolocation->setIsAllowed(false); + return; + } + + COMPtr<IWebUIDelegatePrivate2> uiDelegatePrivate2(Query, uiDelegate); + if (!uiDelegatePrivate2) { + geolocation->setIsAllowed(false); + return; + } + + Frame* frame = geolocation->frame(); + COMPtr<WebSecurityOrigin> origin(AdoptCOM, WebSecurityOrigin::createInstance(frame->document()->securityOrigin())); + COMPtr<WebGeolocationPolicyListener> listener = WebGeolocationPolicyListener::createInstance(geolocation); + HRESULT hr = uiDelegatePrivate2->decidePolicyForGeolocationRequest(m_webView.get(), kit(frame), origin.get(), listener.get()); + if (hr != E_NOTIMPL) + return; + + geolocation->setIsAllowed(false); +} diff --git a/Source/WebKit/win/WebCoreSupport/WebGeolocationClient.h b/Source/WebKit/win/WebCoreSupport/WebGeolocationClient.h new file mode 100644 index 0000000..c5db134 --- /dev/null +++ b/Source/WebKit/win/WebCoreSupport/WebGeolocationClient.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2010 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. 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 INC. 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 WebGeolocationClient_h +#define WebGeolocationClient_h + +#include "COMPtr.h" +#include <WebCore/GeolocationClient.h> + +namespace WebCore { +class Geolocation; +class GeolocationPosition; +} + +class WebView; + +class WebGeolocationClient : public WebCore::GeolocationClient { +public: + WebGeolocationClient(WebView*); + + virtual void geolocationDestroyed(); + virtual void startUpdating(); + virtual void stopUpdating(); + virtual void setEnableHighAccuracy(bool) { } + virtual WebCore::GeolocationPosition* lastPosition(); + + virtual void requestPermission(WebCore::Geolocation*); + virtual void cancelPermissionRequest(WebCore::Geolocation*) { } + +private: + COMPtr<WebView> m_webView; +}; + +#endif // WebGeolocationClient_h diff --git a/Source/WebKit/win/WebCoreSupport/WebInspectorClient.cpp b/Source/WebKit/win/WebCoreSupport/WebInspectorClient.cpp new file mode 100644 index 0000000..76ebc8f --- /dev/null +++ b/Source/WebKit/win/WebCoreSupport/WebInspectorClient.cpp @@ -0,0 +1,537 @@ +/* + * Copyright (C) 2006, 2007, 2008, 2009, 2010 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/NotImplemented.h> +#include <WebCore/Page.h> +#include <WebCore/RenderObject.h> +#include <WebCore/WindowMessageBroadcaster.h> +#pragma warning(pop) + +#include <tchar.h> +#include <wtf/RetainPtr.h> +#include <wtf/text/StringConcatenate.h> + +using namespace WebCore; + +static LPCTSTR kWebInspectorWindowClassName = TEXT("WebInspectorWindowClass"); +static ATOM registerWindowClass(); +static LPCTSTR kWebInspectorPointerProp = TEXT("WebInspectorPointer"); + +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_frontendPage(0) +{ + ASSERT(m_inspectedWebView); + m_inspectedWebView->viewWindow((OLE_HANDLE*)&m_inspectedWebViewHwnd); +} + +WebInspectorClient::~WebInspectorClient() +{ + m_frontendPage = 0; +} + +void WebInspectorClient::inspectorDestroyed() +{ + delete this; +} + +void WebInspectorClient::openInspectorFrontend(InspectorController* inspectorController) +{ + registerWindowClass(); + + HWND frontendHwnd = ::CreateWindowEx(0, kWebInspectorWindowClassName, 0, WS_OVERLAPPEDWINDOW, + defaultWindowRect().x(), defaultWindowRect().y(), defaultWindowRect().width(), defaultWindowRect().height(), + 0, 0, 0, 0); + + if (!frontendHwnd) + return; + + COMPtr<WebView> frontendWebView(AdoptCOM, WebView::createInstance()); + + if (FAILED(frontendWebView->setHostWindow((OLE_HANDLE)(ULONG64)frontendHwnd))) + return; + + RECT rect; + GetClientRect(frontendHwnd, &rect); + if (FAILED(frontendWebView->initWithFrame(rect, 0, 0))) + return; + + COMPtr<WebInspectorDelegate> delegate(AdoptCOM, WebInspectorDelegate::createInstance()); + if (FAILED(frontendWebView->setUIDelegate(delegate.get()))) + return; + + // Keep preferences separate from the rest of the client, making sure we are using expected preference values. + // 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; + COMPtr<WebPreferences> preferences(Query, iPreferences); + if (!preferences) + return; + if (FAILED(preferences->setAutosaves(FALSE))) + return; + if (FAILED(preferences->setLoadsImagesAutomatically(TRUE))) + return; + if (FAILED(preferences->setAuthorAndUserStylesEnabled(TRUE))) + return; + if (FAILED(preferences->setAllowsAnimatedImages(TRUE))) + return; + if (FAILED(preferences->setLoadsImagesAutomatically(TRUE))) + return; + if (FAILED(preferences->setPlugInsEnabled(FALSE))) + return; + if (FAILED(preferences->setJavaEnabled(FALSE))) + return; + if (FAILED(preferences->setUserStyleSheetEnabled(FALSE))) + return; + if (FAILED(preferences->setTabsToLinks(FALSE))) + return; + if (FAILED(preferences->setMinimumFontSize(0))) + return; + if (FAILED(preferences->setMinimumLogicalFontSize(9))) + return; + if (FAILED(preferences->setFixedFontFamily(BString(L"Courier New")))) + return; + if (FAILED(preferences->setDefaultFixedFontSize(13))) + return; + + if (FAILED(frontendWebView->setPreferences(preferences.get()))) + return; + + frontendWebView->setProhibitsMainFrameScrolling(TRUE); + + HWND frontendWebViewHwnd; + if (FAILED(frontendWebView->viewWindow(reinterpret_cast<OLE_HANDLE*>(&frontendWebViewHwnd)))) + return; + + COMPtr<WebMutableURLRequest> request(AdoptCOM, WebMutableURLRequest::createInstance()); + + RetainPtr<CFURLRef> htmlURLRef(AdoptCF, CFBundleCopyResourceURL(getWebKitBundle(), CFSTR("inspector"), CFSTR("html"), CFSTR("inspector"))); + if (!htmlURLRef) + return; + + CFStringRef urlStringRef = ::CFURLGetString(htmlURLRef.get()); + if (FAILED(request->initWithURL(BString(urlStringRef), WebURLRequestUseProtocolCachePolicy, 60))) + return; + + if (FAILED(frontendWebView->topLevelFrame()->loadRequest(request.get()))) + return; + + m_frontendPage = core(frontendWebView.get()); + WebInspectorFrontendClient* frontendClient = new WebInspectorFrontendClient(m_inspectedWebView, m_inspectedWebViewHwnd, frontendHwnd, frontendWebView, frontendWebViewHwnd, this); + m_frontendPage->inspectorController()->setInspectorFrontendClient(frontendClient); + m_frontendHwnd = frontendHwnd; +} + +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_frontendHwnd)) + m_highlight->placeBehindWindow(m_frontendHwnd); +} + +void WebInspectorClient::hideHighlight() +{ + if (m_highlight) + m_highlight->setShowsWhileWebViewIsVisible(false); +} + +void WebInspectorClient::updateHighlight() +{ + if (m_highlight && m_highlight->isShowing()) + m_highlight->update(); +} + +WebInspectorFrontendClient::WebInspectorFrontendClient(WebView* inspectedWebView, HWND inspectedWebViewHwnd, HWND frontendHwnd, const COMPtr<WebView>& frontendWebView, HWND frontendWebViewHwnd, WebInspectorClient* inspectorClient) + : InspectorFrontendClientLocal(inspectedWebView->page()->inspectorController(), core(frontendWebView.get())) + , m_inspectedWebView(inspectedWebView) + , m_inspectedWebViewHwnd(inspectedWebViewHwnd) + , m_inspectorClient(inspectorClient) + , m_frontendHwnd(frontendHwnd) + , m_frontendWebView(frontendWebView) + , m_frontendWebViewHwnd(frontendWebViewHwnd) + , m_attached(false) + , m_destroyingInspectorView(false) +{ + ::SetProp(frontendHwnd, kWebInspectorPointerProp, reinterpret_cast<HANDLE>(this)); + // FIXME: Implement window size/position save/restore +#if 0 + [self setWindowFrameAutosaveName:@"Web Inspector"]; +#endif +} + +WebInspectorFrontendClient::~WebInspectorFrontendClient() +{ + destroyInspectorView(true); +} + +void WebInspectorFrontendClient::frontendLoaded() +{ + InspectorFrontendClientLocal::frontendLoaded(); + + setAttachedWindow(m_attached); +} + +String WebInspectorFrontendClient::localizedStringsURL() +{ + RetainPtr<CFURLRef> url(AdoptCF, CFBundleCopyResourceURL(getWebKitBundle(), CFSTR("localizedStrings"), CFSTR("js"), 0)); + if (!url) + return String(); + + return CFURLGetString(url.get()); +} + +String WebInspectorFrontendClient::hiddenPanels() +{ + // FIXME: implement this + return String(); +} + +void WebInspectorFrontendClient::bringToFront() +{ + showWindowWithoutNotifications(); +} + +void WebInspectorFrontendClient::closeWindow() +{ + destroyInspectorView(true); +} + +void WebInspectorFrontendClient::disconnectFromBackend() +{ + destroyInspectorView(false); +} + +void WebInspectorFrontendClient::attachWindow() +{ + if (m_attached) + return; + + // FIXME: This flag can be saved to the flags storage directly. + m_inspectedWebView->page()->inspectorController()->setInspectorStartsAttached(true); + + closeWindowWithoutNotifications(); + showWindowWithoutNotifications(); +} + +void WebInspectorFrontendClient::detachWindow() +{ + if (!m_attached) + return; + + // FIXME: This flag can be saved to the flags storage directly. + m_inspectedWebView->page()->inspectorController()->setInspectorStartsAttached(false); + + closeWindowWithoutNotifications(); + showWindowWithoutNotifications(); +} + +void WebInspectorFrontendClient::setAttachedWindowHeight(unsigned height) +{ + if (!m_attached) + return; + + HWND hostWindow; + if (!SUCCEEDED(m_inspectedWebView->hostWindow((OLE_HANDLE*)&hostWindow))) + return; + + RECT hostWindowRect; + GetClientRect(hostWindow, &hostWindowRect); + + RECT inspectedRect; + GetClientRect(m_inspectedWebViewHwnd, &inspectedRect); + + int totalHeight = hostWindowRect.bottom - hostWindowRect.top; + int webViewWidth = inspectedRect.right - inspectedRect.left; + + SetWindowPos(m_frontendWebViewHwnd, 0, 0, totalHeight - height, webViewWidth, height, SWP_NOZORDER); + + // We want to set the inspected web view height to the totalHeight, because the height adjustment + // of the inspected web view happens in onWebViewWindowPosChanging, not here. + SetWindowPos(m_inspectedWebViewHwnd, 0, 0, 0, webViewWidth, totalHeight, SWP_NOZORDER); + + RedrawWindow(m_frontendWebViewHwnd, 0, 0, RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_UPDATENOW); + RedrawWindow(m_inspectedWebViewHwnd, 0, 0, RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_UPDATENOW); +} + +void WebInspectorFrontendClient::inspectedURLChanged(const String& newURL) +{ + m_inspectedURL = newURL; + updateWindowTitle(); +} + +void WebInspectorFrontendClient::closeWindowWithoutNotifications() +{ + if (!m_frontendHwnd) + return; + + if (!m_attached) { + ShowWindow(m_frontendHwnd, SW_HIDE); + return; + } + + ASSERT(m_frontendWebView); + ASSERT(m_inspectedWebViewHwnd); + ASSERT(!IsWindowVisible(m_frontendHwnd)); + + // Remove the Inspector's WebView from the inspected WebView's parent window. + WindowMessageBroadcaster::removeListener(m_inspectedWebViewHwnd, this); + + m_attached = false; + + m_frontendWebView->setHostWindow(reinterpret_cast<OLE_HANDLE>(m_frontendHwnd)); + + // Make sure everything has the right size/position. + HWND hostWindow; + if (SUCCEEDED(m_inspectedWebView->hostWindow((OLE_HANDLE*)&hostWindow))) + SendMessage(hostWindow, WM_SIZE, 0, 0); +} + +void WebInspectorFrontendClient::showWindowWithoutNotifications() +{ + if (!m_frontendHwnd) + return; + + ASSERT(m_frontendWebView); + ASSERT(m_inspectedWebViewHwnd); + + bool shouldAttach = false; + if (m_attached) + shouldAttach = true; + else { + // If no preference is set - default to an attached window. This is important for inspector LayoutTests. + // FIXME: This flag can be fetched directly from the flags storage. + shouldAttach = m_inspectedWebView->page()->inspectorController()->inspectorStartsAttached(); + + if (shouldAttach && !canAttachWindow()) + shouldAttach = false; + } + + if (!shouldAttach) { + // Put the Inspector's WebView inside our window and show it. + m_frontendWebView->setHostWindow(reinterpret_cast<OLE_HANDLE>(m_frontendHwnd)); + SendMessage(m_frontendHwnd, WM_SIZE, 0, 0); + updateWindowTitle(); + + SetWindowPos(m_frontendHwnd, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE); + return; + } + + // Put the Inspector's WebView inside the inspected WebView's parent window. + WindowMessageBroadcaster::addListener(m_inspectedWebViewHwnd, this); + + HWND hostWindow; + if (FAILED(m_inspectedWebView->hostWindow(reinterpret_cast<OLE_HANDLE*>(&hostWindow)))) + return; + + m_frontendWebView->setHostWindow(reinterpret_cast<OLE_HANDLE>(hostWindow)); + + // Then hide our own window. + ShowWindow(m_frontendHwnd, SW_HIDE); + + m_attached = true; + + // Make sure everything has the right size/position. + SendMessage(hostWindow, WM_SIZE, 0, 0); + m_inspectorClient->updateHighlight(); +} + +void WebInspectorFrontendClient::destroyInspectorView(bool notifyInspectorController) +{ + if (m_destroyingInspectorView) + return; + m_destroyingInspectorView = true; + + + closeWindowWithoutNotifications(); + + if (notifyInspectorController) { + m_inspectedWebView->page()->inspectorController()->disconnectFrontend(); + m_inspectorClient->updateHighlight(); + m_inspectorClient->frontendClosing(); + } + ::DestroyWindow(m_frontendHwnd); +} + +void WebInspectorFrontendClient::updateWindowTitle() +{ + String title = makeString("Web Inspector ", static_cast<UChar>(0x2014), ' ', m_inspectedURL); + ::SetWindowText(m_frontendHwnd, title.charactersWithNullTermination()); +} + +LRESULT WebInspectorFrontendClient::onGetMinMaxInfo(WPARAM, LPARAM lParam) +{ + MINMAXINFO* info = reinterpret_cast<MINMAXINFO*>(lParam); + POINT size = {400, 400}; + info->ptMinTrackSize = size; + + return 0; +} + +LRESULT WebInspectorFrontendClient::onSize(WPARAM, LPARAM) +{ + RECT rect; + ::GetClientRect(m_frontendHwnd, &rect); + + ::SetWindowPos(m_frontendWebViewHwnd, 0, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER); + + return 0; +} + +LRESULT WebInspectorFrontendClient::onClose(WPARAM, LPARAM) +{ + ::ShowWindow(m_frontendHwnd, SW_HIDE); + m_inspectedWebView->page()->inspectorController()->close(); + + return 0; +} + +LRESULT WebInspectorFrontendClient::onSetFocus() +{ + SetFocus(m_frontendWebViewHwnd); + return 0; +} + +void WebInspectorFrontendClient::onWebViewWindowPosChanging(WPARAM, LPARAM lParam) +{ + ASSERT(m_attached); + + WINDOWPOS* windowPos = reinterpret_cast<WINDOWPOS*>(lParam); + ASSERT_ARG(lParam, windowPos); + + if (windowPos->flags & SWP_NOSIZE) + return; + + RECT inspectorRect; + GetClientRect(m_frontendWebViewHwnd, &inspectorRect); + unsigned inspectorHeight = inspectorRect.bottom - inspectorRect.top; + + windowPos->cy -= inspectorHeight; + + SetWindowPos(m_frontendWebViewHwnd, 0, windowPos->x, windowPos->y + windowPos->cy, windowPos->cx, inspectorHeight, SWP_NOZORDER); +} + +static LRESULT CALLBACK WebInspectorWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + WebInspectorFrontendClient* client = reinterpret_cast<WebInspectorFrontendClient*>(::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 WebInspectorFrontendClient::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/Source/WebKit/win/WebCoreSupport/WebInspectorClient.h b/Source/WebKit/win/WebCoreSupport/WebInspectorClient.h new file mode 100644 index 0000000..0c38247 --- /dev/null +++ b/Source/WebKit/win/WebCoreSupport/WebInspectorClient.h @@ -0,0 +1,138 @@ +/* + * 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/InspectorFrontendClientLocal.h> +#include <WebCore/PlatformString.h> +#include <WebCore/WindowMessageListener.h> +#include <wtf/OwnPtr.h> +#include <windows.h> + +namespace WebCore { + +class Page; + +} + +class WebNodeHighlight; +class WebView; + +class WebInspectorClient : public WebCore::InspectorClient { +public: + WebInspectorClient(WebView*); + + // InspectorClient + virtual void inspectorDestroyed(); + + virtual void openInspectorFrontend(WebCore::InspectorController*); + + virtual void highlight(WebCore::Node*); + virtual void hideHighlight(); + + virtual void populateSetting(const WTF::String& key, WTF::String* value); + virtual void storeSetting(const WTF::String& key, const WTF::String& value); + + virtual bool sendMessageToFrontend(const WTF::String&); + + void updateHighlight(); + void frontendClosing() + { + m_frontendHwnd = 0; + releaseFrontendPage(); + } + + void releaseFrontendPage(); +private: + ~WebInspectorClient(); + + WebView* m_inspectedWebView; + WebCore::Page* m_frontendPage; + HWND m_inspectedWebViewHwnd; + HWND m_frontendHwnd; + + OwnPtr<WebNodeHighlight> m_highlight; +}; + +class WebInspectorFrontendClient : public WebCore::InspectorFrontendClientLocal, WebCore::WindowMessageListener { +public: + WebInspectorFrontendClient(WebView* inspectedWebView, HWND inspectedWebViewHwnd, HWND frontendHwnd, const COMPtr<WebView>& frotnendWebView, HWND frontendWebViewHwnd, WebInspectorClient* inspectorClient); + + virtual void frontendLoaded(); + + virtual WTF::String localizedStringsURL(); + virtual WTF::String hiddenPanels(); + + virtual void bringToFront(); + virtual void closeWindow(); + virtual void disconnectFromBackend(); + + virtual void attachWindow(); + virtual void detachWindow(); + + virtual void setAttachedWindowHeight(unsigned height); + virtual void inspectedURLChanged(const WTF::String& newURL); + +private: + ~WebInspectorFrontendClient(); + + void closeWindowWithoutNotifications(); + void showWindowWithoutNotifications(); + + void destroyInspectorView(bool notifyInspectorController); + + 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_frontendHwnd; + WebInspectorClient* m_inspectorClient; + COMPtr<WebView> m_frontendWebView; + HWND m_frontendWebViewHwnd; + + bool m_attached; + + WTF::String m_inspectedURL; + bool m_destroyingInspectorView; + + static friend LRESULT CALLBACK WebInspectorWndProc(HWND, UINT, WPARAM, LPARAM); +}; + +#endif // !defined(WebInspectorClient_h) diff --git a/Source/WebKit/win/WebCoreSupport/WebInspectorDelegate.cpp b/Source/WebKit/win/WebCoreSupport/WebInspectorDelegate.cpp new file mode 100644 index 0000000..3ed8c9d --- /dev/null +++ b/Source/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/Source/WebKit/win/WebCoreSupport/WebInspectorDelegate.h b/Source/WebKit/win/WebCoreSupport/WebInspectorDelegate.h new file mode 100644 index 0000000..7561d5a --- /dev/null +++ b/Source/WebKit/win/WebCoreSupport/WebInspectorDelegate.h @@ -0,0 +1,336 @@ +/*
+ * 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*,
+ /* [retval][out] */ 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; }
+
+ virtual HRESULT STDMETHODCALLTYPE printFrame(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IWebFrame *frame) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE ftpDirectoryTemplatePath(
+ /* [in] */ IWebView *webView,
+ /* [retval][out] */ BSTR *path) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewHeaderHeight(
+ /* [in] */ IWebView *webView,
+ /* [retval][out] */ float *result) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewFooterHeight(
+ /* [in] */ IWebView *webView,
+ /* [retval][out] */ float *result) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE drawHeaderInRect(
+ /* [in] */ IWebView *webView,
+ /* [in] */ RECT *rect,
+ /* [in] */ OLE_HANDLE drawingContext) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE drawFooterInRect(
+ /* [in] */ IWebView *webView,
+ /* [in] */ RECT *rect,
+ /* [in] */ OLE_HANDLE drawingContext,
+ /* [in] */ UINT pageIndex,
+ /* [in] */ UINT pageCount) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewPrintingMarginRect(
+ /* [in] */ IWebView *webView,
+ /* [retval][out] */ RECT *rect) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE canRunModal(
+ /* [in] */ IWebView *webView,
+ /* [retval][out] */ BOOL *canRunBoolean) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE createModalDialog(
+ /* [in] */ IWebView *sender,
+ /* [in] */ IWebURLRequest *request,
+ /* [retval][out] */ IWebView **newWebView) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE runModal(
+ /* [in] */ IWebView *webView) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE isMenuBarVisible(
+ /* [in] */ IWebView *webView,
+ /* [retval][out] */ BOOL *visible) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE setMenuBarVisible(
+ /* [in] */ IWebView *webView,
+ /* [in] */ BOOL visible) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE runDatabaseSizeLimitPrompt(
+ /* [in] */ IWebView *webView,
+ /* [in] */ BSTR displayName,
+ /* [in] */ IWebFrame *initiatedByFrame,
+ /* [retval][out] */ BOOL *allowed) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE paintCustomScrollbar(
+ /* [in] */ IWebView *webView,
+ /* [in] */ HDC hDC,
+ /* [in] */ RECT rect,
+ /* [in] */ WebScrollBarControlSize size,
+ /* [in] */ WebScrollbarControlState state,
+ /* [in] */ WebScrollbarControlPart pressedPart,
+ /* [in] */ BOOL vertical,
+ /* [in] */ float value,
+ /* [in] */ float proportion,
+ /* [in] */ WebScrollbarControlPartMask parts) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE paintCustomScrollCorner(
+ /* [in] */ IWebView *webView,
+ /* [in] */ HDC hDC,
+ /* [in] */ RECT rect) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE desktopNotificationsDelegate(
+ /* [retval][out] */ IWebDesktopNotificationsDelegate **result) { return E_NOTIMPL; }
+
+private:
+ WebInspectorDelegate();
+
+ ULONG m_refCount;
+};
+
+#endif // WebInspectorDelegate_h
diff --git a/Source/WebKit/win/WebCoreSupport/WebPlatformStrategies.cpp b/Source/WebKit/win/WebCoreSupport/WebPlatformStrategies.cpp new file mode 100644 index 0000000..fe35877 --- /dev/null +++ b/Source/WebKit/win/WebCoreSupport/WebPlatformStrategies.cpp @@ -0,0 +1,661 @@ +/* + * Copyright (C) 2010 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. 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 INC. 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 "WebPlatformStrategies.h" + +#include "WebLocalizableStrings.h" +#include <WebCore/IntSize.h> +#include <WebCore/Page.h> +#include <WebCore/PageGroup.h> +#include <WebCore/PluginDatabase.h> +#include <wtf/MathExtras.h> +#include <wtf/RetainPtr.h> + +using namespace WebCore; + +void WebPlatformStrategies::initialize() +{ + DEFINE_STATIC_LOCAL(WebPlatformStrategies, platformStrategies, ()); +} + +WebPlatformStrategies::WebPlatformStrategies() +{ + setPlatformStrategies(this); +} + +// PluginStrategy + +PluginStrategy* WebPlatformStrategies::createPluginStrategy() +{ + return this; +} + +LocalizationStrategy* WebPlatformStrategies::createLocalizationStrategy() +{ + return this; +} + +VisitedLinkStrategy* WebPlatformStrategies::createVisitedLinkStrategy() +{ + return this; +} + +void WebPlatformStrategies::refreshPlugins() +{ + PluginDatabase::installedPlugins()->refresh(); +} + +void WebPlatformStrategies::getPluginInfo(const WebCore::Page*, Vector<WebCore::PluginInfo>& outPlugins) +{ + const Vector<PluginPackage*>& plugins = PluginDatabase::installedPlugins()->plugins(); + + outPlugins.resize(plugins.size()); + + for (size_t i = 0; i < plugins.size(); ++i) { + PluginPackage* package = plugins[i]; + + PluginInfo info; + info.name = package->name(); + info.file = package->fileName(); + info.desc = package->description(); + + const MIMEToDescriptionsMap& mimeToDescriptions = package->mimeToDescriptions(); + + info.mimes.reserveCapacity(mimeToDescriptions.size()); + + MIMEToDescriptionsMap::const_iterator end = mimeToDescriptions.end(); + for (MIMEToDescriptionsMap::const_iterator it = mimeToDescriptions.begin(); it != end; ++it) { + MimeClassInfo mime; + + mime.type = it->first; + mime.desc = it->second; + mime.extensions = package->mimeToExtensions().get(mime.type); + + info.mimes.append(mime); + } + + outPlugins[i] = info; + } +} + +// LocalizationStrategy + +String WebPlatformStrategies::searchableIndexIntroduction() +{ + return UI_STRING("This is a searchable index. Enter search keywords: ", "text that appears at the start of nearly-obsolete web pages in the form of a 'searchable index'"); +} + +String WebPlatformStrategies::submitButtonDefaultLabel() +{ + return UI_STRING("Submit", "default label for Submit buttons in forms on web pages"); +} + +String WebPlatformStrategies::inputElementAltText() +{ + return UI_STRING_KEY("Submit", "Submit (input element)", "alt text for <input> elements with no alt, title, or value"); +} + +String WebPlatformStrategies::resetButtonDefaultLabel() +{ + return UI_STRING("Reset", "default label for Reset buttons in forms on web pages"); +} + +String WebPlatformStrategies::fileButtonChooseFileLabel() +{ + return UI_STRING("Choose File", "title for file button used in HTML forms"); +} + +String WebPlatformStrategies::fileButtonNoFileSelectedLabel() +{ + return UI_STRING("no file selected", "text to display in file button used in HTML forms when no file is selected"); +} + +String WebPlatformStrategies::contextMenuItemTagOpenLinkInNewWindow() +{ + return UI_STRING("Open Link in New Window", "Open in New Window context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagDownloadLinkToDisk() +{ + return UI_STRING("Download Linked File", "Download Linked File context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagCopyLinkToClipboard() +{ + return UI_STRING("Copy Link", "Copy Link context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagOpenImageInNewWindow() +{ + return UI_STRING("Open Image in New Window", "Open Image in New Window context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagDownloadImageToDisk() +{ + return UI_STRING("Download Image", "Download Image context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagCopyImageToClipboard() +{ + return UI_STRING("Copy Image", "Copy Image context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagOpenVideoInNewWindow() +{ + return UI_STRING("Open Video in New Window", "Open Video in New Window context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagOpenAudioInNewWindow() +{ + return UI_STRING("Open Audio in New Window", "Open Audio in New Window context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagCopyVideoLinkToClipboard() +{ + return UI_STRING("Copy Video Address", "Copy Video Address Location context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagCopyAudioLinkToClipboard() +{ + return UI_STRING("Copy Audio Address", "Copy Audio Address Location context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagToggleMediaControls() +{ + return UI_STRING("Controls", "Media Controls context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagToggleMediaLoop() +{ + return UI_STRING("Loop", "Media Loop context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagEnterVideoFullscreen() +{ + return UI_STRING("Enter Fullscreen", "Video Enter Fullscreen context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagMediaPlay() +{ + return UI_STRING("Play", "Media Play context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagMediaPause() +{ + return UI_STRING("Pause", "Media Pause context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagMediaMute() +{ + return UI_STRING("Mute", "Media Mute context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagOpenFrameInNewWindow() +{ + return UI_STRING("Open Frame in New Window", "Open Frame in New Window context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagCopy() +{ + return UI_STRING("Copy", "Copy context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagGoBack() +{ + return UI_STRING("Back", "Back context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagGoForward() +{ + return UI_STRING("Forward", "Forward context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagStop() +{ + return UI_STRING("Stop", "Stop context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagReload() +{ + return UI_STRING("Reload", "Reload context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagCut() +{ + return UI_STRING("Cut", "Cut context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagPaste() +{ + return UI_STRING("Paste", "Paste context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagNoGuessesFound() +{ + return UI_STRING("No Guesses Found", "No Guesses Found context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagIgnoreSpelling() +{ + return UI_STRING("Ignore Spelling", "Ignore Spelling context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagLearnSpelling() +{ + return UI_STRING("Learn Spelling", "Learn Spelling context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagSearchWeb() +{ + return UI_STRING("Search with Google", "Search in Google context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagLookUpInDictionary() +{ + return UI_STRING("Look Up in Dictionary", "Look Up in Dictionary context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagOpenLink() +{ + return UI_STRING("Open Link", "Open Link context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagIgnoreGrammar() +{ + return UI_STRING("Ignore Grammar", "Ignore Grammar context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagSpellingMenu() +{ + return UI_STRING("Spelling and Grammar", "Spelling and Grammar context sub-menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagCheckSpelling() +{ + return UI_STRING("Check Document Now", "Check spelling context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagCheckSpellingWhileTyping() +{ + return UI_STRING("Check Spelling While Typing", "Check spelling while typing context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagCheckGrammarWithSpelling() +{ + return UI_STRING("Check Grammar With Spelling", "Check grammar with spelling context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagFontMenu() +{ + return UI_STRING("Font", "Font context sub-menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagBold() +{ + return UI_STRING("Bold", "Bold context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagItalic() +{ + return UI_STRING("Italic", "Italic context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagUnderline() +{ + return UI_STRING("Underline", "Underline context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagOutline() +{ + return UI_STRING("Outline", "Outline context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagWritingDirectionMenu() +{ + return UI_STRING("Paragraph Direction", "Paragraph direction context sub-menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagTextDirectionMenu() +{ + return UI_STRING("Selection Direction", "Selection direction context sub-menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagDefaultDirection() +{ + return UI_STRING("Default", "Default writing direction context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagLeftToRight() +{ + return UI_STRING("Left to Right", "Left to Right context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagRightToLeft() +{ + return UI_STRING("Right to Left", "Right to Left context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagShowSpellingPanel(bool show) +{ + if (show) + return UI_STRING("Show Spelling and Grammar", "menu item title"); + return UI_STRING("Hide Spelling and Grammar", "menu item title"); +} + +String WebPlatformStrategies::contextMenuItemTagInspectElement() +{ + return UI_STRING("Inspect Element", "Inspect Element context menu item"); +} + +String WebPlatformStrategies::searchMenuNoRecentSearchesText() +{ + return UI_STRING("No recent searches", "Label for only item in menu that appears when clicking on the search field image, when no searches have been performed"); +} + +String WebPlatformStrategies::searchMenuRecentSearchesText() +{ + return UI_STRING("Recent Searches", "label for first item in the menu that appears when clicking on the search field image, used as embedded menu title"); +} + +String WebPlatformStrategies::searchMenuClearRecentSearchesText() +{ + return UI_STRING("Clear Recent Searches", "menu item in Recent Searches menu that empties menu's contents"); +} + +String WebPlatformStrategies::AXWebAreaText() +{ + return UI_STRING("web area", "accessibility role description for web area"); +} + +String WebPlatformStrategies::AXLinkText() +{ + return UI_STRING("link", "accessibility role description for link"); +} + +String WebPlatformStrategies::AXListMarkerText() +{ + return UI_STRING("list marker", "accessibility role description for list marker"); +} + +String WebPlatformStrategies::AXImageMapText() +{ + return UI_STRING("image map", "accessibility role description for image map"); +} + +String WebPlatformStrategies::AXHeadingText() +{ + return UI_STRING("heading", "accessibility role description for headings"); +} + +String WebPlatformStrategies::AXDefinitionListTermText() +{ + return UI_STRING("term", "term word of a definition"); +} + +String WebPlatformStrategies::AXDefinitionListDefinitionText() +{ + return UI_STRING("definition", "definition phrase"); +} + +String WebPlatformStrategies::AXButtonActionVerb() +{ + return UI_STRING("press", "Verb stating the action that will occur when a button is pressed, as used by accessibility"); +} + +String WebPlatformStrategies::AXRadioButtonActionVerb() +{ + return UI_STRING("select", "Verb stating the action that will occur when a radio button is clicked, as used by accessibility"); +} + +String WebPlatformStrategies::AXTextFieldActionVerb() +{ + return UI_STRING("activate", "Verb stating the action that will occur when a text field is selected, as used by accessibility"); +} + +String WebPlatformStrategies::AXCheckedCheckBoxActionVerb() +{ + return UI_STRING("uncheck", "Verb stating the action that will occur when a checked checkbox is clicked, as used by accessibility"); +} + +String WebPlatformStrategies::AXUncheckedCheckBoxActionVerb() +{ + return UI_STRING("check", "Verb stating the action that will occur when an unchecked checkbox is clicked, as used by accessibility"); +} + +String WebPlatformStrategies::AXLinkActionVerb() +{ + return UI_STRING("jump", "Verb stating the action that will occur when a link is clicked, as used by accessibility"); +} + +String WebPlatformStrategies::AXMenuListActionVerb() +{ + return UI_STRING("open", "Verb stating the action that will occur when a select element is clicked, as used by accessibility"); +} + +String WebPlatformStrategies::AXMenuListPopupActionVerb() +{ + return UI_STRING_KEY("press", "press (select element)", "Verb stating the action that will occur when a select element's popup list is clicked, as used by accessibility"); +} + +String WebPlatformStrategies::unknownFileSizeText() +{ + return UI_STRING("Unknown", "Unknown filesize FTP directory listing item"); +} + +String WebPlatformStrategies::uploadFileText() +{ + return UI_STRING("Upload file", "(Windows) Form submit file upload dialog title"); +} + +String WebPlatformStrategies::allFilesText() +{ + return UI_STRING("All Files", "(Windows) Form submit file upload all files pop-up"); +} + +String WebPlatformStrategies::missingPluginText() +{ + return UI_STRING("Missing Plug-in", "Label text to be used when a plugin is missing"); +} + +String WebPlatformStrategies::crashedPluginText() +{ + return UI_STRING("Plug-in Failure", "Label text to be used if plugin host process has crashed"); +} + +String WebPlatformStrategies::imageTitle(const String& filename, const IntSize& size) +{ + RetainPtr<CFStringRef> filenameCF(AdoptCF, filename.createCFString()); + return RetainPtr<CFStringRef>(AdoptCF, CFStringCreateWithFormat(0, 0, UI_STRING("%@ %d\xC3\x97%d pixels", "window title for a standalone image (uses multiplication symbol, not x)"), filenameCF.get(), size.width(), size.height())).get(); +} + +String WebPlatformStrategies::multipleFileUploadText(unsigned numberOfFiles) +{ + return RetainPtr<CFStringRef>(AdoptCF, CFStringCreateWithFormat(0, 0, UI_STRING("%d files", "Label to describe the number of files selected in a file upload control that allows multiple files"), numberOfFiles)).get(); +} + +String WebPlatformStrategies::mediaElementLoadingStateText() +{ + return UI_STRING("Loading...", "Media controller status message when the media is loading"); +} + +String WebPlatformStrategies::mediaElementLiveBroadcastStateText() +{ + return UI_STRING("Live Broadcast", "Media controller status message when watching a live broadcast"); +} + +String WebPlatformStrategies::localizedMediaControlElementString(const String& name) +{ + if (name == "AudioElement") + return UI_STRING("audio element controller", "accessibility role description for audio element controller"); + if (name == "VideoElement") + return UI_STRING("video element controller", "accessibility role description for video element controller"); + if (name == "MuteButton") + return UI_STRING("mute", "accessibility role description for mute button"); + if (name == "UnMuteButton") + return UI_STRING("unmute", "accessibility role description for turn mute off button"); + if (name == "PlayButton") + return UI_STRING("play", "accessibility role description for play button"); + if (name == "PauseButton") + return UI_STRING("pause", "accessibility role description for pause button"); + if (name == "Slider") + return UI_STRING("movie time", "accessibility role description for timeline slider"); + if (name == "SliderThumb") + return UI_STRING("timeline slider thumb", "accessibility role description for timeline thumb"); + if (name == "RewindButton") + return UI_STRING("back 30 seconds", "accessibility role description for seek back 30 seconds button"); + if (name == "ReturnToRealtimeButton") + return UI_STRING("return to realtime", "accessibility role description for return to real time button"); + if (name == "CurrentTimeDisplay") + return UI_STRING("elapsed time", "accessibility role description for elapsed time display"); + if (name == "TimeRemainingDisplay") + return UI_STRING("remaining time", "accessibility role description for time remaining display"); + if (name == "StatusDisplay") + return UI_STRING("status", "accessibility role description for movie status"); + if (name == "FullscreenButton") + return UI_STRING("fullscreen", "accessibility role description for enter fullscreen button"); + if (name == "SeekForwardButton") + return UI_STRING("fast forward", "accessibility role description for fast forward button"); + if (name == "SeekBackButton") + return UI_STRING("fast reverse", "accessibility role description for fast reverse button"); + if (name == "ShowClosedCaptionsButton") + return UI_STRING("show closed captions", "accessibility role description for show closed captions button"); + if (name == "HideClosedCaptionsButton") + return UI_STRING("hide closed captions", "accessibility role description for hide closed captions button"); + + ASSERT_NOT_REACHED(); + return String(); +} + +String WebPlatformStrategies::localizedMediaControlElementHelpText(const String& name) +{ + if (name == "AudioElement") + return UI_STRING("audio element playback controls and status display", "accessibility role description for audio element controller"); + if (name == "VideoElement") + return UI_STRING("video element playback controls and status display", "accessibility role description for video element controller"); + if (name == "MuteButton") + return UI_STRING("mute audio tracks", "accessibility help text for mute button"); + if (name == "UnMuteButton") + return UI_STRING("unmute audio tracks", "accessibility help text for un mute button"); + if (name == "PlayButton") + return UI_STRING("begin playback", "accessibility help text for play button"); + if (name == "PauseButton") + return UI_STRING("pause playback", "accessibility help text for pause button"); + if (name == "Slider") + return UI_STRING("movie time scrubber", "accessibility help text for timeline slider"); + if (name == "SliderThumb") + return UI_STRING("movie time scrubber thumb", "accessibility help text for timeline slider thumb"); + if (name == "RewindButton") + return UI_STRING("seek movie back 30 seconds", "accessibility help text for jump back 30 seconds button"); + if (name == "ReturnToRealtimeButton") + return UI_STRING("return streaming movie to real time", "accessibility help text for return streaming movie to real time button"); + if (name == "CurrentTimeDisplay") + return UI_STRING("current movie time in seconds", "accessibility help text for elapsed time display"); + if (name == "TimeRemainingDisplay") + return UI_STRING("number of seconds of movie remaining", "accessibility help text for remaining time display"); + if (name == "StatusDisplay") + return UI_STRING("current movie status", "accessibility help text for movie status display"); + if (name == "SeekBackButton") + return UI_STRING("seek quickly back", "accessibility help text for fast rewind button"); + if (name == "SeekForwardButton") + return UI_STRING("seek quickly forward", "accessibility help text for fast forward button"); + if (name == "FullscreenButton") + return UI_STRING("Play movie in fullscreen mode", "accessibility help text for enter fullscreen button"); + if (name == "ShowClosedCaptionsButton") + return UI_STRING("start displaying closed captions", "accessibility help text for show closed captions button"); + if (name == "HideClosedCaptionsButton") + return UI_STRING("stop displaying closed captions", "accessibility help text for hide closed captions button"); + + ASSERT_NOT_REACHED(); + return String(); +} + +String WebPlatformStrategies::localizedMediaTimeDescription(float time) +{ + if (!isfinite(time)) + return UI_STRING("indefinite time", "accessibility help text for an indefinite media controller time value"); + + int seconds = (int)fabsf(time); + int days = seconds / (60 * 60 * 24); + int hours = seconds / (60 * 60); + int minutes = (seconds / 60) % 60; + seconds %= 60; + + if (days) + return RetainPtr<CFStringRef>(AdoptCF, CFStringCreateWithFormat(0, 0, UI_STRING("%1$d days %2$d hours %3$d minutes %4$d seconds", "accessibility help text for media controller time value >= 1 day"), days, hours, minutes, seconds)).get(); + + if (hours) + return RetainPtr<CFStringRef>(AdoptCF, CFStringCreateWithFormat(0, 0, UI_STRING("%1$d hours %2$d minutes %3$d seconds", "accessibility help text for media controller time value >= 60 minutes"), hours, minutes, seconds)).get(); + + if (minutes) + return RetainPtr<CFStringRef>(AdoptCF, CFStringCreateWithFormat(0, 0, UI_STRING("%1$d minutes %2$d seconds", "accessibility help text for media controller time value >= 60 seconds"), minutes, seconds)).get(); + + return RetainPtr<CFStringRef>(AdoptCF, CFStringCreateWithFormat(0, 0, UI_STRING("%1$d seconds", "accessibility help text for media controller time value < 60 seconds"), seconds)).get(); +} + +String WebPlatformStrategies::validationMessageValueMissingText() +{ + return UI_STRING("value missing", "Validation message for required form control elements that have no value"); +} + +String WebPlatformStrategies::validationMessageTypeMismatchText() +{ + return UI_STRING("type mismatch", "Validation message for input form controls with a value not matching type"); +} + +String WebPlatformStrategies::validationMessagePatternMismatchText() +{ + return UI_STRING("pattern mismatch", "Validation message for input form controls requiring a constrained value according to pattern"); +} + +String WebPlatformStrategies::validationMessageTooLongText() +{ + return UI_STRING("too long", "Validation message for form control elements with a value longer than maximum allowed length"); +} + +String WebPlatformStrategies::validationMessageRangeUnderflowText() +{ + return UI_STRING("range underflow", "Validation message for input form controls with value lower than allowed minimum"); +} + +String WebPlatformStrategies::validationMessageRangeOverflowText() +{ + return UI_STRING("range overflow", "Validation message for input form controls with value higher than allowed maximum"); +} + +String WebPlatformStrategies::validationMessageStepMismatchText() +{ + return UI_STRING("step mismatch", "Validation message for input form controls with value not respecting the step attribute"); +} + +bool WebPlatformStrategies::isLinkVisited(Page* page, LinkHash hash) +{ + return page->group().isLinkVisited(hash); +} + +void WebPlatformStrategies::addVisitedLink(Page* page, LinkHash hash) +{ + page->group().addVisitedLinkHash(hash); +} diff --git a/Source/WebKit/win/WebCoreSupport/WebPlatformStrategies.h b/Source/WebKit/win/WebCoreSupport/WebPlatformStrategies.h new file mode 100644 index 0000000..48c2b46 --- /dev/null +++ b/Source/WebKit/win/WebCoreSupport/WebPlatformStrategies.h @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2010 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. 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 INC. 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 WebPlatformStrategies_h +#define WebPlatformStrategies_h + +#include <WebCore/LocalizationStrategy.h> +#include <WebCore/PlatformStrategies.h> +#include <WebCore/PluginStrategy.h> +#include <WebCore/VisitedLinkStrategy.h> + +class WebPlatformStrategies : public WebCore::PlatformStrategies, private WebCore::PluginStrategy, private WebCore::LocalizationStrategy, private WebCore::VisitedLinkStrategy { +public: + static void initialize(); + +private: + WebPlatformStrategies(); + + // WebCore::PlatformStrategies + virtual WebCore::PluginStrategy* createPluginStrategy(); + virtual WebCore::LocalizationStrategy* createLocalizationStrategy(); + virtual WebCore::VisitedLinkStrategy* createVisitedLinkStrategy(); + + // WebCore::PluginStrategy + virtual void refreshPlugins(); + virtual void getPluginInfo(const WebCore::Page*, Vector<WebCore::PluginInfo>&); + + // WebCore::LocalizationStrategy + virtual WTF::String inputElementAltText(); + virtual WTF::String resetButtonDefaultLabel(); + virtual WTF::String searchableIndexIntroduction(); + virtual WTF::String submitButtonDefaultLabel(); + virtual WTF::String fileButtonChooseFileLabel(); + virtual WTF::String fileButtonNoFileSelectedLabel(); +#if ENABLE(CONTEXT_MENUS) + virtual WTF::String contextMenuItemTagOpenLinkInNewWindow(); + virtual WTF::String contextMenuItemTagDownloadLinkToDisk(); + virtual WTF::String contextMenuItemTagCopyLinkToClipboard(); + virtual WTF::String contextMenuItemTagOpenImageInNewWindow(); + virtual WTF::String contextMenuItemTagDownloadImageToDisk(); + virtual WTF::String contextMenuItemTagCopyImageToClipboard(); + virtual WTF::String contextMenuItemTagOpenFrameInNewWindow(); + virtual WTF::String contextMenuItemTagCopy(); + virtual WTF::String contextMenuItemTagGoBack(); + virtual WTF::String contextMenuItemTagGoForward(); + virtual WTF::String contextMenuItemTagStop(); + virtual WTF::String contextMenuItemTagReload(); + virtual WTF::String contextMenuItemTagCut(); + virtual WTF::String contextMenuItemTagPaste(); + virtual WTF::String contextMenuItemTagNoGuessesFound(); + virtual WTF::String contextMenuItemTagIgnoreSpelling(); + virtual WTF::String contextMenuItemTagLearnSpelling(); + virtual WTF::String contextMenuItemTagSearchWeb(); + virtual WTF::String contextMenuItemTagLookUpInDictionary(); + virtual WTF::String contextMenuItemTagOpenLink(); + virtual WTF::String contextMenuItemTagIgnoreGrammar(); + virtual WTF::String contextMenuItemTagSpellingMenu(); + virtual WTF::String contextMenuItemTagShowSpellingPanel(bool show); + virtual WTF::String contextMenuItemTagCheckSpelling(); + virtual WTF::String contextMenuItemTagCheckSpellingWhileTyping(); + virtual WTF::String contextMenuItemTagCheckGrammarWithSpelling(); + virtual WTF::String contextMenuItemTagFontMenu(); + virtual WTF::String contextMenuItemTagBold(); + virtual WTF::String contextMenuItemTagItalic(); + virtual WTF::String contextMenuItemTagUnderline(); + virtual WTF::String contextMenuItemTagOutline(); + virtual WTF::String contextMenuItemTagWritingDirectionMenu(); + virtual WTF::String contextMenuItemTagTextDirectionMenu(); + virtual WTF::String contextMenuItemTagDefaultDirection(); + virtual WTF::String contextMenuItemTagLeftToRight(); + virtual WTF::String contextMenuItemTagRightToLeft(); + virtual WTF::String contextMenuItemTagInspectElement(); + virtual WTF::String contextMenuItemTagOpenVideoInNewWindow(); + virtual WTF::String contextMenuItemTagOpenAudioInNewWindow(); + virtual WTF::String contextMenuItemTagCopyVideoLinkToClipboard(); + virtual WTF::String contextMenuItemTagCopyAudioLinkToClipboard(); + virtual WTF::String contextMenuItemTagToggleMediaControls(); + virtual WTF::String contextMenuItemTagToggleMediaLoop(); + virtual WTF::String contextMenuItemTagEnterVideoFullscreen(); + virtual WTF::String contextMenuItemTagMediaPlay(); + virtual WTF::String contextMenuItemTagMediaPause(); + virtual WTF::String contextMenuItemTagMediaMute(); +#endif // ENABLE(CONTEXT_MENUS) + virtual WTF::String searchMenuNoRecentSearchesText(); + virtual WTF::String searchMenuRecentSearchesText(); + virtual WTF::String searchMenuClearRecentSearchesText(); + virtual WTF::String AXWebAreaText(); + virtual WTF::String AXLinkText(); + virtual WTF::String AXListMarkerText(); + virtual WTF::String AXImageMapText(); + virtual WTF::String AXHeadingText(); + virtual WTF::String AXDefinitionListTermText(); + virtual WTF::String AXDefinitionListDefinitionText(); + virtual WTF::String AXButtonActionVerb(); + virtual WTF::String AXRadioButtonActionVerb(); + virtual WTF::String AXTextFieldActionVerb(); + virtual WTF::String AXCheckedCheckBoxActionVerb(); + virtual WTF::String AXUncheckedCheckBoxActionVerb(); + virtual WTF::String AXMenuListActionVerb(); + virtual WTF::String AXMenuListPopupActionVerb(); + virtual WTF::String AXLinkActionVerb(); + virtual WTF::String missingPluginText(); + virtual WTF::String crashedPluginText(); + virtual WTF::String multipleFileUploadText(unsigned numberOfFiles); + virtual WTF::String unknownFileSizeText(); + virtual WTF::String uploadFileText(); + virtual WTF::String allFilesText(); + virtual WTF::String imageTitle(const WTF::String& filename, const WebCore::IntSize&); + virtual WTF::String mediaElementLoadingStateText(); + virtual WTF::String mediaElementLiveBroadcastStateText(); + virtual WTF::String localizedMediaControlElementString(const WTF::String&); + virtual WTF::String localizedMediaControlElementHelpText(const WTF::String&); + virtual WTF::String localizedMediaTimeDescription(float); + virtual WTF::String validationMessageValueMissingText(); + virtual WTF::String validationMessageTypeMismatchText(); + virtual WTF::String validationMessagePatternMismatchText(); + virtual WTF::String validationMessageTooLongText(); + virtual WTF::String validationMessageRangeUnderflowText(); + virtual WTF::String validationMessageRangeOverflowText(); + virtual WTF::String validationMessageStepMismatchText(); + + // WebCore::VisitedLinkStrategy + virtual bool isLinkVisited(WebCore::Page*, WebCore::LinkHash); + virtual void addVisitedLink(WebCore::Page*, WebCore::LinkHash); +}; + +#endif // WebPlatformStrategies_h diff --git a/Source/WebKit/win/WebCoreSupport/WebPluginHalterClient.cpp b/Source/WebKit/win/WebCoreSupport/WebPluginHalterClient.cpp new file mode 100644 index 0000000..995b05d --- /dev/null +++ b/Source/WebKit/win/WebCoreSupport/WebPluginHalterClient.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2009 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 "WebPluginHalterClient.h" + +#include "DOMCoreClasses.h" +#include "WebView.h" +#include <WebCore/Node.h> +#include <wtf/Assertions.h> + +using namespace WebCore; + +WebPluginHalterClient::WebPluginHalterClient(WebView* webView) + : m_webView(webView) +{ + ASSERT_ARG(webView, webView); +} + +bool WebPluginHalterClient::shouldHaltPlugin(Node* n, bool isWindowed, const String& pluginName) const +{ + ASSERT_ARG(n, n); + + IWebPluginHalterDelegate* d; + if (FAILED(m_webView->pluginHalterDelegate(&d)) || !d) + return false; + + COMPtr<IDOMNode> domNode(AdoptCOM, DOMNode::createInstance(n)); + + BOOL shouldHalt; + if (FAILED(d->shouldHaltPlugin(m_webView, domNode.get(), isWindowed, BString(pluginName), &shouldHalt))) + return false; + + return shouldHalt; +} + +bool WebPluginHalterClient::enabled() const +{ + IWebPluginHalterDelegate* d; + if (FAILED(m_webView->pluginHalterDelegate(&d)) || !d) + return false; + + return true; +} diff --git a/Source/WebKit/win/WebCoreSupport/WebPluginHalterClient.h b/Source/WebKit/win/WebCoreSupport/WebPluginHalterClient.h new file mode 100644 index 0000000..9a4ca01 --- /dev/null +++ b/Source/WebKit/win/WebCoreSupport/WebPluginHalterClient.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2009 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 WebPluginHalterClient_h +#define WebPluginHalterClient_h + +#include <WebCore/PluginHalterClient.h> +#include <wtf/Forward.h> + +namespace WebCore { + class Node; +} + +class WebView; + +class WebPluginHalterClient : public WebCore::PluginHalterClient { +public: + WebPluginHalterClient(WebView* webView); + + virtual bool shouldHaltPlugin(WebCore::Node* n, bool isWindowed, const WTF::String& pluginName) const; + virtual bool enabled() const; + +private: + WebView* m_webView; +}; + +#endif // WebPluginHalterClient_h |