diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-05-07 11:21:11 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-05-07 11:21:11 +0200 |
commit | 2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47 (patch) | |
tree | 988e8c5b116dd0466244ae2fe5af8ee9be926d76 /Source/WebKit/chromium/src/WebPagePopupImpl.cpp | |
parent | dd91e772430dc294e3bf478c119ef8d43c0a3358 (diff) | |
download | qtwebkit-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.cpp | 286 |
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 |