2 * Copyright (C) 2012 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #include "WebPagePopupImpl.h"
35 #include "ContextFeatures.h"
36 #include "DOMWindowPagePopup.h"
37 #include "DocumentLoader.h"
38 #include "EmptyClients.h"
39 #include "FocusController.h"
40 #include "FrameView.h"
42 #include "PagePopupClient.h"
43 #include "PageWidgetDelegate.h"
45 #include "WebCursorInfo.h"
46 #include "WebInputEventConversion.h"
47 #include "WebPagePopup.h"
48 #include "WebSettingsImpl.h"
49 #include "WebViewClient.h"
50 #include "WebViewImpl.h"
51 #include "WebWidgetClient.h"
53 using namespace WebCore;
58 #if ENABLE(PAGE_POPUP)
60 class PagePopupChromeClient : public EmptyChromeClient, public WebCore::PageClientChromium {
61 WTF_MAKE_NONCOPYABLE(PagePopupChromeClient);
62 WTF_MAKE_FAST_ALLOCATED;
65 explicit PagePopupChromeClient(WebPagePopupImpl* popup)
68 ASSERT(m_popup->widgetClient());
72 virtual void closeWindowSoon() OVERRIDE
74 m_popup->closePopup();
77 virtual FloatRect windowRect() OVERRIDE
79 return FloatRect(m_popup->m_windowRectInScreen.x, m_popup->m_windowRectInScreen.y, m_popup->m_windowRectInScreen.width, m_popup->m_windowRectInScreen.height);
82 virtual void setWindowRect(const FloatRect& rect) OVERRIDE
84 m_popup->m_windowRectInScreen = IntRect(rect);
85 m_popup->widgetClient()->setWindowRect(m_popup->m_windowRectInScreen);
88 virtual void addMessageToConsole(MessageSource, MessageLevel, const String& message, unsigned lineNumber, const String&) OVERRIDE
91 fprintf(stderr, "CONSOLE MESSSAGE:%u: %s\n", lineNumber, message.utf8().data());
93 UNUSED_PARAM(message);
94 UNUSED_PARAM(lineNumber);
98 virtual void invalidateContentsAndRootView(const IntRect& paintRect, bool) OVERRIDE
100 if (paintRect.isEmpty())
102 m_popup->widgetClient()->didInvalidateRect(paintRect);
105 virtual void scroll(const IntSize& scrollDelta, const IntRect& scrollRect, const IntRect& clipRect) OVERRIDE
107 m_popup->widgetClient()->didScrollRect(scrollDelta.width(), scrollDelta.height(), intersection(scrollRect, clipRect));
110 virtual void invalidateContentsForSlowScroll(const IntRect& updateRect, bool immediate) OVERRIDE
112 invalidateContentsAndRootView(updateRect, immediate);
115 virtual void scheduleAnimation() OVERRIDE
117 m_popup->widgetClient()->scheduleAnimation();
120 virtual void* webView() const OVERRIDE
122 return m_popup->m_webView;
125 virtual FloatSize minimumWindowSize() const OVERRIDE
127 return FloatSize(0, 0);
130 virtual PlatformPageClient platformPageClient() const OVERRIDE
132 return PlatformPageClient(this);
135 virtual void setCursor(const WebCore::Cursor& cursor) OVERRIDE
137 if (m_popup->m_webView->client())
138 m_popup->m_webView->client()->didChangeCursor(WebCursorInfo(cursor));
141 // PageClientChromium methods:
142 virtual WebKit::WebScreenInfo screenInfo() OVERRIDE
144 return m_popup->m_webView->client()->screenInfo();
147 WebPagePopupImpl* m_popup;
150 class PagePopupFeaturesClient : public ContextFeaturesClient {
151 virtual bool isEnabled(Document*, ContextFeatures::FeatureType, bool) OVERRIDE;
154 bool PagePopupFeaturesClient::isEnabled(Document*, ContextFeatures::FeatureType type, bool defaultValue)
156 if (type == ContextFeatures::PagePopup)
161 // WebPagePopupImpl ----------------------------------------------------------------
163 WebPagePopupImpl::WebPagePopupImpl(WebWidgetClient* client)
164 : m_widgetClient(client)
170 WebPagePopupImpl::~WebPagePopupImpl()
175 bool WebPagePopupImpl::initialize(WebViewImpl* webView, PagePopupClient* popupClient, const IntRect&)
180 m_popupClient = popupClient;
182 resize(m_popupClient->contentSize());
184 if (!initializePage())
186 m_widgetClient->show(WebNavigationPolicy());
192 bool WebPagePopupImpl::initializePage()
194 Page::PageClients pageClients;
195 fillWithEmptyClients(pageClients);
196 m_chromeClient = adoptPtr(new PagePopupChromeClient(this));
197 pageClients.chromeClient = m_chromeClient.get();
199 m_page = adoptPtr(new Page(pageClients));
200 m_page->settings()->setScriptEnabled(true);
201 m_page->settings()->setAllowScriptsToCloseWindows(true);
202 m_page->setDeviceScaleFactor(m_webView->deviceScaleFactor());
203 m_page->settings()->setDeviceSupportsTouch(m_webView->page()->settings()->deviceSupportsTouch());
205 unsigned layoutMilestones = DidFirstLayout | DidFirstVisuallyNonEmptyLayout;
206 m_page->addLayoutMilestones(static_cast<LayoutMilestones>(layoutMilestones));
208 static ContextFeaturesClient* pagePopupFeaturesClient = new PagePopupFeaturesClient();
209 provideContextFeaturesTo(m_page.get(), pagePopupFeaturesClient);
210 static FrameLoaderClient* emptyFrameLoaderClient = new EmptyFrameLoaderClient();
211 RefPtr<Frame> frame = Frame::create(m_page.get(), 0, emptyFrameLoaderClient);
212 frame->setView(FrameView::create(frame.get()));
214 frame->view()->resize(m_popupClient->contentSize());
215 frame->view()->setTransparent(false);
217 DOMWindowPagePopup::install(frame->document()->domWindow(), m_popupClient);
219 DocumentWriter* writer = frame->loader()->activeDocumentLoader()->writer();
220 writer->setMIMEType("text/html");
221 writer->setEncoding("UTF-8", false);
223 m_popupClient->writeDocument(*writer);
228 void WebPagePopupImpl::destoryPage()
233 if (m_page->mainFrame())
234 m_page->mainFrame()->loader()->frameDetached();
239 WebSize WebPagePopupImpl::size()
241 return m_popupClient->contentSize();
244 void WebPagePopupImpl::animate(double)
246 PageWidgetDelegate::animate(m_page.get(), monotonicallyIncreasingTime());
249 void WebPagePopupImpl::setCompositorSurfaceReady()
253 void WebPagePopupImpl::composite(bool)
257 void WebPagePopupImpl::layout()
259 PageWidgetDelegate::layout(m_page.get());
262 void WebPagePopupImpl::paint(WebCanvas* canvas, const WebRect& rect, PaintOptions)
265 PageWidgetDelegate::paint(m_page.get(), 0, canvas, rect, PageWidgetDelegate::Opaque, m_webView->settingsImpl()->applyDeviceScaleFactorInCompositor());
268 void WebPagePopupImpl::resize(const WebSize& newSize)
270 m_windowRectInScreen = WebRect(m_windowRectInScreen.x, m_windowRectInScreen.y, newSize.width, newSize.height);
271 m_widgetClient->setWindowRect(m_windowRectInScreen);
274 m_page->mainFrame()->view()->resize(newSize);
275 m_widgetClient->didInvalidateRect(WebRect(0, 0, newSize.width, newSize.height));
278 bool WebPagePopupImpl::handleKeyEvent(const WebKeyboardEvent&)
280 // The main WebView receives key events and forward them to this via handleKeyEvent().
281 ASSERT_NOT_REACHED();
285 bool WebPagePopupImpl::handleCharEvent(const WebKeyboardEvent&)
287 // The main WebView receives key events and forward them to this via handleKeyEvent().
288 ASSERT_NOT_REACHED();
292 #if ENABLE(GESTURE_EVENTS)
293 bool WebPagePopupImpl::handleGestureEvent(const WebGestureEvent& event)
295 if (m_closing || !m_page || !m_page->mainFrame() || !m_page->mainFrame()->view())
297 Frame& frame = *m_page->mainFrame();
298 return frame.eventHandler()->handleGestureEvent(PlatformGestureEventBuilder(frame.view(), event));
302 bool WebPagePopupImpl::handleInputEvent(const WebInputEvent& event)
306 return PageWidgetDelegate::handleInputEvent(m_page.get(), *this, event);
309 bool WebPagePopupImpl::handleKeyEvent(const PlatformKeyboardEvent& event)
311 if (m_closing || !m_page->mainFrame() || !m_page->mainFrame()->view())
313 return m_page->mainFrame()->eventHandler()->keyEvent(event);
316 void WebPagePopupImpl::setFocus(bool enable)
320 m_page->focusController()->setFocused(enable);
322 m_page->focusController()->setActive(true);
325 void WebPagePopupImpl::close()
328 destoryPage(); // In case closePopup() was not called.
333 void WebPagePopupImpl::closePopup()
336 m_page->setGroupName(String());
337 m_page->mainFrame()->loader()->stopAllLoaders();
338 m_page->mainFrame()->loader()->stopLoading(UnloadEventPolicyNone);
339 DOMWindowPagePopup::uninstall(m_page->mainFrame()->document()->domWindow());
345 // m_widgetClient might be 0 because this widget might be already closed.
346 if (m_widgetClient) {
347 // closeWidgetSoon() will call this->close() later.
348 m_widgetClient->closeWidgetSoon();
351 m_popupClient->didClosePopup();
354 #endif // ENABLE(PAGE_POPUP)
356 // WebPagePopup ----------------------------------------------------------------
358 WebPagePopup* WebPagePopup::create(WebWidgetClient* client)
360 #if ENABLE(PAGE_POPUP)
363 // A WebPagePopupImpl instance usually has two references.
364 // - One owned by the instance itself. It represents the visible widget.
365 // - One owned by a WebViewImpl. It's released when the WebViewImpl ask the
366 // WebPagePopupImpl to close.
367 // We need them because the closing operation is asynchronous and the widget
368 // can be closed while the WebViewImpl is unaware of it.
369 return adoptRef(new WebPagePopupImpl(client)).leakRef();
371 UNUSED_PARAM(client);
376 } // namespace WebKit