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, MessageType, MessageLevel, const String& message, unsigned int 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::init(WebViewImpl* webView, PagePopupClient* popupClient, const IntRect&)
180
m_popupClient = popupClient;
182
resize(m_popupClient->contentSize());
186
m_widgetClient->show(WebNavigationPolicy());
192
bool WebPagePopupImpl::initPage()
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
WebSize WebPagePopupImpl::size()
230
return m_popupClient->contentSize();
233
void WebPagePopupImpl::animate(double)
235
PageWidgetDelegate::animate(m_page.get(), monotonicallyIncreasingTime());
238
void WebPagePopupImpl::setCompositorSurfaceReady()
242
void WebPagePopupImpl::composite(bool)
246
void WebPagePopupImpl::layout()
248
PageWidgetDelegate::layout(m_page.get());
251
void WebPagePopupImpl::paint(WebCanvas* canvas, const WebRect& rect, PaintOptions)
253
PageWidgetDelegate::paint(m_page.get(), 0, canvas, rect, PageWidgetDelegate::Opaque, m_webView->settingsImpl()->applyDeviceScaleFactorInCompositor());
256
void WebPagePopupImpl::resize(const WebSize& newSize)
258
m_windowRectInScreen = WebRect(m_windowRectInScreen.x, m_windowRectInScreen.y, newSize.width, newSize.height);
259
m_widgetClient->setWindowRect(m_windowRectInScreen);
262
m_page->mainFrame()->view()->resize(newSize);
263
m_widgetClient->didInvalidateRect(WebRect(0, 0, newSize.width, newSize.height));
266
bool WebPagePopupImpl::handleKeyEvent(const WebKeyboardEvent&)
268
// The main WebView receives key events and forward them to this via handleKeyEvent().
269
ASSERT_NOT_REACHED();
273
bool WebPagePopupImpl::handleCharEvent(const WebKeyboardEvent&)
275
// The main WebView receives key events and forward them to this via handleKeyEvent().
276
ASSERT_NOT_REACHED();
280
#if ENABLE(GESTURE_EVENTS)
281
bool WebPagePopupImpl::handleGestureEvent(const WebGestureEvent& event)
283
if (m_closing || !m_page || !m_page->mainFrame() || !m_page->mainFrame()->view())
285
Frame& frame = *m_page->mainFrame();
286
return frame.eventHandler()->handleGestureEvent(PlatformGestureEventBuilder(frame.view(), event));
290
bool WebPagePopupImpl::handleInputEvent(const WebInputEvent& event)
294
return PageWidgetDelegate::handleInputEvent(m_page.get(), *this, event);
297
bool WebPagePopupImpl::handleKeyEvent(const PlatformKeyboardEvent& event)
299
if (m_closing || !m_page->mainFrame() || !m_page->mainFrame()->view())
301
return m_page->mainFrame()->eventHandler()->keyEvent(event);
304
void WebPagePopupImpl::setFocus(bool enable)
308
m_page->focusController()->setFocused(enable);
310
m_page->focusController()->setActive(true);
313
void WebPagePopupImpl::close()
316
if (m_page && m_page->mainFrame())
317
m_page->mainFrame()->loader()->frameDetached();
323
void WebPagePopupImpl::closePopup()
326
m_page->setGroupName(String());
327
m_page->mainFrame()->loader()->stopAllLoaders();
328
m_page->mainFrame()->loader()->stopLoading(UnloadEventPolicyNone);
329
DOMWindowPagePopup::uninstall(m_page->mainFrame()->document()->domWindow());
332
// m_widgetClient might be 0 because this widget might be already closed.
333
if (m_widgetClient) {
334
// closeWidgetSoon() will call this->close() later.
335
m_widgetClient->closeWidgetSoon();
338
m_popupClient->didClosePopup();
341
#endif // ENABLE(PAGE_POPUP)
343
// WebPagePopup ----------------------------------------------------------------
345
WebPagePopup* WebPagePopup::create(WebWidgetClient* client)
347
#if ENABLE(PAGE_POPUP)
350
// A WebPagePopupImpl instance usually has two references.
351
// - One owned by the instance itself. It represents the visible widget.
352
// - One owned by a WebViewImpl. It's released when the WebViewImpl ask the
353
// WebPagePopupImpl to close.
354
// We need them because the closing operation is asynchronous and the widget
355
// can be closed while the WebViewImpl is unaware of it.
356
return adoptRef(new WebPagePopupImpl(client)).leakRef();
358
UNUSED_PARAM(client);
363
} // namespace WebKit