summaryrefslogtreecommitdiff
path: root/Source/WebKit/chromium/src/WebPagePopupImpl.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-05-07 11:21:11 +0200
committerSimon Hausmann <simon.hausmann@nokia.com>2012-05-07 11:21:11 +0200
commit2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47 (patch)
tree988e8c5b116dd0466244ae2fe5af8ee9be926d76 /Source/WebKit/chromium/src/WebPagePopupImpl.cpp
parentdd91e772430dc294e3bf478c119ef8d43c0a3358 (diff)
downloadqtwebkit-2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47.tar.gz
Imported WebKit commit 7e538425aa020340619e927792f3d895061fb54b (http://svn.webkit.org/repository/webkit/trunk@116286)
Diffstat (limited to 'Source/WebKit/chromium/src/WebPagePopupImpl.cpp')
-rw-r--r--Source/WebKit/chromium/src/WebPagePopupImpl.cpp286
1 files changed, 282 insertions, 4 deletions
diff --git a/Source/WebKit/chromium/src/WebPagePopupImpl.cpp b/Source/WebKit/chromium/src/WebPagePopupImpl.cpp
index bc810c7b1..1ad417bad 100644
--- a/Source/WebKit/chromium/src/WebPagePopupImpl.cpp
+++ b/Source/WebKit/chromium/src/WebPagePopupImpl.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2012 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
@@ -29,21 +29,299 @@
*/
#include "config.h"
+#include "WebPagePopupImpl.h"
+#include "Chrome.h"
+#include "EmptyClients.h"
+#include "FileChooser.h"
+#include "FocusController.h"
+#include "FormState.h"
+#include "FrameView.h"
+#include "HTMLFormElement.h"
+#include "Page.h"
+#include "PagePopupClient.h"
+#include "PageWidgetDelegate.h"
+#include "Settings.h"
+#include "WebInputEvent.h"
+#include "WebInputEventConversion.h"
#include "WebPagePopup.h"
+#include "WebViewImpl.h"
+#include "WebWidgetClient.h"
+
+using namespace WebCore;
+using namespace std;
namespace WebKit {
+#if ENABLE(PAGE_POPUP)
+
+class PagePopupChromeClient : public EmptyChromeClient {
+ WTF_MAKE_NONCOPYABLE(PagePopupChromeClient);
+ WTF_MAKE_FAST_ALLOCATED;
+
+public:
+ explicit PagePopupChromeClient(WebPagePopupImpl* popup)
+ : m_popup(popup)
+ {
+ ASSERT(m_popup->widgetClient());
+ }
+
+private:
+ virtual void closeWindowSoon() OVERRIDE
+ {
+ m_popup->closePopup();
+ }
+
+ virtual FloatRect windowRect() OVERRIDE
+ {
+ return FloatRect(m_popup->m_windowRectInScreen.x, m_popup->m_windowRectInScreen.y, m_popup->m_windowRectInScreen.width, m_popup->m_windowRectInScreen.height);
+ }
+
+ virtual void setWindowRect(const FloatRect& rect) OVERRIDE
+ {
+ IntRect intRect(rect);
+ const WebRect currentRect = m_popup->m_windowRectInScreen;
+ if (intRect.x() == currentRect.x && intRect.y() == currentRect.y && m_popup->m_isPutAboveOrigin)
+ intRect.setY(currentRect.y + currentRect.height - intRect.height());
+ m_popup->m_windowRectInScreen = intRect;
+ m_popup->widgetClient()->setWindowRect(m_popup->m_windowRectInScreen);
+ }
+
+ virtual void addMessageToConsole(MessageSource, MessageType, MessageLevel, const String& message, unsigned int lineNumber, const String&) OVERRIDE
+ {
+#ifndef NDEBUG
+ fprintf(stderr, "CONSOLE MESSSAGE:%u: %s\n", lineNumber, message.utf8().data());
+#else
+ UNUSED_PARAM(message);
+ UNUSED_PARAM(lineNumber);
+#endif
+ }
+
+ virtual void invalidateContentsAndRootView(const IntRect& paintRect, bool) OVERRIDE
+ {
+ if (paintRect.isEmpty())
+ return;
+ m_popup->widgetClient()->didInvalidateRect(paintRect);
+ }
+
+ virtual void scroll(const IntSize& scrollDelta, const IntRect& scrollRect, const IntRect& clipRect) OVERRIDE
+ {
+ m_popup->widgetClient()->didScrollRect(scrollDelta.width(), scrollDelta.height(), intersection(scrollRect, clipRect));
+ }
+
+ virtual void invalidateContentsForSlowScroll(const IntRect& updateRect, bool immediate) OVERRIDE
+ {
+ invalidateContentsAndRootView(updateRect, immediate);
+ }
+
+ virtual void scheduleAnimation() OVERRIDE
+ {
+ m_popup->widgetClient()->scheduleAnimation();
+ }
+
+ virtual void* webView() const OVERRIDE
+ {
+ return m_popup->m_webView;
+ }
+
+ WebPagePopupImpl* m_popup;
+};
+
// WebPagePopupImpl ----------------------------------------------------------------
-// FIXME: WebPagePopupImpl implementation will be written here.
+WebPagePopupImpl::WebPagePopupImpl(WebWidgetClient* client)
+ : m_widgetClient(client)
+ , m_isPutAboveOrigin(false)
+{
+ ASSERT(client);
+}
+
+WebPagePopupImpl::~WebPagePopupImpl()
+{
+ ASSERT(!m_page);
+}
+
+bool WebPagePopupImpl::init(WebViewImpl* webView, PagePopupClient* popupClient, const IntRect& originBoundsInRootView)
+{
+ ASSERT(webView);
+ ASSERT(popupClient);
+ m_webView = webView;
+ m_popupClient = popupClient;
+
+ WebSize rootViewSize = webView->size();
+ IntSize popupSize = popupClient->contentSize();
+ IntRect popupBoundsInRootView(IntPoint(max(0, originBoundsInRootView.x()), max(0, originBoundsInRootView.maxY())), popupSize);
+ if (popupBoundsInRootView.maxY() > rootViewSize.height) {
+ popupBoundsInRootView.setY(max(0, originBoundsInRootView.y() - popupSize.height()));
+ m_isPutAboveOrigin = true;
+ }
+ if (popupBoundsInRootView.maxX() > rootViewSize.width)
+ popupBoundsInRootView.setX(max(0, rootViewSize.width - popupSize.width()));
+ IntRect boundsInScreen = webView->page()->chrome()->rootViewToScreen(popupBoundsInRootView);
+
+ m_widgetClient->setWindowRect(boundsInScreen);
+ m_windowRectInScreen = boundsInScreen;
+ if (!initPage())
+ return false;
+ m_widgetClient->show(WebNavigationPolicy());
+
+ setFocus(true);
+
+ return true;
+}
+
+bool WebPagePopupImpl::initPage()
+{
+ Page::PageClients pageClients;
+ fillWithEmptyClients(pageClients);
+ m_chromeClient = adoptPtr(new PagePopupChromeClient(this));
+ pageClients.chromeClient = m_chromeClient.get();
+
+ m_page = adoptPtr(new Page(pageClients));
+ m_page->settings()->setScriptEnabled(true);
+ m_page->settings()->setAllowScriptsToCloseWindows(true);
+
+ static FrameLoaderClient* emptyFrameLoaderClient = new EmptyFrameLoaderClient;
+ RefPtr<Frame> frame = Frame::create(m_page.get(), 0, emptyFrameLoaderClient);
+ frame->setView(FrameView::create(frame.get()));
+ frame->init();
+ frame->view()->resize(m_popupClient->contentSize());
+ frame->view()->setTransparent(false);
+
+ DocumentWriter* writer = frame->loader()->activeDocumentLoader()->writer();
+ writer->setMIMEType("text/html");
+ writer->setEncoding("UTF-8", false);
+ writer->begin();
+ m_popupClient->writeDocument(*writer);
+ writer->end();
+
+ frame->script()->installFunctionsForPagePopup(frame.get(), m_popupClient);
+ return true;
+}
+
+WebSize WebPagePopupImpl::size()
+{
+ return m_popupClient->contentSize();
+}
+
+void WebPagePopupImpl::animate(double)
+{
+ PageWidgetDelegate::animate(m_page.get(), monotonicallyIncreasingTime());
+}
+
+void WebPagePopupImpl::setCompositorSurfaceReady()
+{
+}
+
+void WebPagePopupImpl::composite(bool)
+{
+}
+
+void WebPagePopupImpl::layout()
+{
+ PageWidgetDelegate::layout(m_page.get());
+}
+
+void WebPagePopupImpl::paint(WebCanvas* canvas, const WebRect& rect)
+{
+ PageWidgetDelegate::paint(m_page.get(), 0, canvas, rect);
+}
+
+void WebPagePopupImpl::resize(const WebSize& newSize)
+{
+ if (m_page)
+ m_page->mainFrame()->view()->resize(newSize);
+ m_widgetClient->didInvalidateRect(WebRect(0, 0, newSize.width, newSize.height));
+}
+
+bool WebPagePopupImpl::handleKeyEvent(const WebKeyboardEvent&)
+{
+ // The main WebView receives key events and forward them to this via handleKeyEvent().
+ ASSERT_NOT_REACHED();
+ return false;
+}
+
+bool WebPagePopupImpl::handleCharEvent(const WebKeyboardEvent&)
+{
+ // The main WebView receives key events and forward them to this via handleKeyEvent().
+ ASSERT_NOT_REACHED();
+ return false;
+}
+
+#if ENABLE(GESTURE_EVENTS)
+bool WebPagePopupImpl::handleGestureEvent(const WebGestureEvent& event)
+{
+ if (!m_page || !m_page->mainFrame() || !m_page->mainFrame()->view())
+ return false;
+ Frame& frame = *m_page->mainFrame();
+ return frame.eventHandler()->handleGestureEvent(PlatformGestureEventBuilder(frame.view(), event));
+}
+#endif
+
+bool WebPagePopupImpl::handleInputEvent(const WebInputEvent& event)
+{
+ return PageWidgetDelegate::handleInputEvent(m_page.get(), *this, event);
+}
+
+bool WebPagePopupImpl::handleKeyEvent(const PlatformKeyboardEvent& event)
+{
+ if (!m_page->mainFrame() || !m_page->mainFrame()->view())
+ return false;
+ return m_page->mainFrame()->eventHandler()->keyEvent(event);
+}
+
+void WebPagePopupImpl::setFocus(bool enable)
+{
+ if (!m_page)
+ return;
+ m_page->focusController()->setFocused(enable);
+ if (enable)
+ m_page->focusController()->setActive(true);
+}
+
+void WebPagePopupImpl::close()
+{
+ m_page.clear();
+ m_widgetClient = 0;
+ deref();
+}
+
+void WebPagePopupImpl::closePopup()
+{
+ if (m_page) {
+ m_page->setGroupName(String());
+ m_page->mainFrame()->loader()->stopAllLoaders();
+ m_page->mainFrame()->loader()->stopLoading(UnloadEventPolicyNone);
+ }
+ // m_widgetClient might be 0 because this widget might be already closed.
+ if (m_widgetClient) {
+ // closeWidgetSoon() will call this->close() later.
+ m_widgetClient->closeWidgetSoon();
+ }
+
+ m_popupClient->didClosePopup();
+}
+
+#endif // ENABLE(PAGE_POPUP)
// WebPagePopup ----------------------------------------------------------------
-WebPagePopup* WebPagePopup::create(WebWidgetClient*)
+WebPagePopup* WebPagePopup::create(WebWidgetClient* client)
{
- // FIXME: Returns a WebPagePopupImpl object.
+#if ENABLE(PAGE_POPUP)
+ if (!client)
+ CRASH();
+ // A WebPagePopupImpl instance usually has two references.
+ // - One owned by the instance itself. It represents the visible widget.
+ // - One owned by a WebViewImpl. It's released when the WebViewImpl ask the
+ // WebPagePopupImpl to close.
+ // We need them because the closing operation is asynchronous and the widget
+ // can be closed while the WebViewImpl is unaware of it.
+ return adoptRef(new WebPagePopupImpl(client)).leakRef();
+#else
+ UNUSED_PARAM(client);
return 0;
+#endif
}
} // namespace WebKit