~ubuntu-branches/ubuntu/raring/qtwebkit-source/raring-proposed

« back to all changes in this revision

Viewing changes to Source/WebKit/chromium/src/WebPagePopupImpl.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-02-18 14:24:18 UTC
  • Revision ID: package-import@ubuntu.com-20130218142418-eon0jmjg3nj438uy
Tags: upstream-2.3
ImportĀ upstreamĀ versionĀ 2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2012 Google Inc. All rights reserved.
 
3
 *
 
4
 * Redistribution and use in source and binary forms, with or without
 
5
 * modification, are permitted provided that the following conditions are
 
6
 * met:
 
7
 *
 
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
 
13
 * distribution.
 
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.
 
17
 *
 
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.
 
29
 */
 
30
 
 
31
#include "config.h"
 
32
#include "WebPagePopupImpl.h"
 
33
 
 
34
#include "Chrome.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"
 
41
#include "Page.h"
 
42
#include "PagePopupClient.h"
 
43
#include "PageWidgetDelegate.h"
 
44
#include "Settings.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"
 
52
 
 
53
using namespace WebCore;
 
54
using namespace std;
 
55
 
 
56
namespace WebKit {
 
57
 
 
58
#if ENABLE(PAGE_POPUP)
 
59
 
 
60
class PagePopupChromeClient : public EmptyChromeClient, public WebCore::PageClientChromium {
 
61
    WTF_MAKE_NONCOPYABLE(PagePopupChromeClient);
 
62
    WTF_MAKE_FAST_ALLOCATED;
 
63
 
 
64
public:
 
65
    explicit PagePopupChromeClient(WebPagePopupImpl* popup)
 
66
        : m_popup(popup)
 
67
    {
 
68
        ASSERT(m_popup->widgetClient());
 
69
    }
 
70
 
 
71
private:
 
72
    virtual void closeWindowSoon() OVERRIDE
 
73
    {
 
74
        m_popup->closePopup();
 
75
    }
 
76
 
 
77
    virtual FloatRect windowRect() OVERRIDE
 
78
    {
 
79
        return FloatRect(m_popup->m_windowRectInScreen.x, m_popup->m_windowRectInScreen.y, m_popup->m_windowRectInScreen.width, m_popup->m_windowRectInScreen.height);
 
80
    }
 
81
 
 
82
    virtual void setWindowRect(const FloatRect& rect) OVERRIDE
 
83
    {
 
84
        m_popup->m_windowRectInScreen = IntRect(rect);
 
85
        m_popup->widgetClient()->setWindowRect(m_popup->m_windowRectInScreen);
 
86
    }
 
87
 
 
88
    virtual void addMessageToConsole(MessageSource, MessageType, MessageLevel, const String& message, unsigned int lineNumber, const String&) OVERRIDE
 
89
    {
 
90
#ifndef NDEBUG
 
91
        fprintf(stderr, "CONSOLE MESSSAGE:%u: %s\n", lineNumber, message.utf8().data());
 
92
#else
 
93
        UNUSED_PARAM(message);
 
94
        UNUSED_PARAM(lineNumber);
 
95
#endif
 
96
    }
 
97
 
 
98
    virtual void invalidateContentsAndRootView(const IntRect& paintRect, bool) OVERRIDE
 
99
    {
 
100
        if (paintRect.isEmpty())
 
101
            return;
 
102
        m_popup->widgetClient()->didInvalidateRect(paintRect);
 
103
    }
 
104
 
 
105
    virtual void scroll(const IntSize& scrollDelta, const IntRect& scrollRect, const IntRect& clipRect) OVERRIDE
 
106
    {
 
107
        m_popup->widgetClient()->didScrollRect(scrollDelta.width(), scrollDelta.height(), intersection(scrollRect, clipRect));
 
108
    }
 
109
 
 
110
    virtual void invalidateContentsForSlowScroll(const IntRect& updateRect, bool immediate) OVERRIDE
 
111
    {
 
112
        invalidateContentsAndRootView(updateRect, immediate);
 
113
    }
 
114
 
 
115
    virtual void scheduleAnimation() OVERRIDE
 
116
    {
 
117
        m_popup->widgetClient()->scheduleAnimation();
 
118
    }
 
119
 
 
120
    virtual void* webView() const OVERRIDE
 
121
    {
 
122
        return m_popup->m_webView;
 
123
    }
 
124
 
 
125
    virtual FloatSize minimumWindowSize() const OVERRIDE
 
126
    {
 
127
        return FloatSize(0, 0);
 
128
    }
 
129
 
 
130
    virtual PlatformPageClient platformPageClient() const OVERRIDE
 
131
    {
 
132
        return PlatformPageClient(this);
 
133
    }
 
134
 
 
135
    virtual void setCursor(const WebCore::Cursor& cursor) OVERRIDE
 
136
    {
 
137
        if (m_popup->m_webView->client())
 
138
            m_popup->m_webView->client()->didChangeCursor(WebCursorInfo(cursor));
 
139
    }
 
140
 
 
141
    // PageClientChromium methods:
 
142
    virtual WebKit::WebScreenInfo screenInfo() OVERRIDE
 
143
    {
 
144
        return m_popup->m_webView->client()->screenInfo();
 
145
    }
 
146
 
 
147
    WebPagePopupImpl* m_popup;
 
148
};
 
149
 
 
150
class PagePopupFeaturesClient : public ContextFeaturesClient {
 
151
    virtual bool isEnabled(Document*, ContextFeatures::FeatureType, bool) OVERRIDE;
 
152
};
 
153
 
 
154
bool PagePopupFeaturesClient::isEnabled(Document*, ContextFeatures::FeatureType type, bool defaultValue)
 
155
{
 
156
    if (type == ContextFeatures::PagePopup)
 
157
        return true;
 
158
    return defaultValue;
 
159
}
 
160
 
 
161
// WebPagePopupImpl ----------------------------------------------------------------
 
162
 
 
163
WebPagePopupImpl::WebPagePopupImpl(WebWidgetClient* client)
 
164
    : m_widgetClient(client)
 
165
    , m_closing(false)
 
166
{
 
167
    ASSERT(client);
 
168
}
 
169
 
 
170
WebPagePopupImpl::~WebPagePopupImpl()
 
171
{
 
172
    ASSERT(!m_page);
 
173
}
 
174
 
 
175
bool WebPagePopupImpl::init(WebViewImpl* webView, PagePopupClient* popupClient, const IntRect&)
 
176
{
 
177
    ASSERT(webView);
 
178
    ASSERT(popupClient);
 
179
    m_webView = webView;
 
180
    m_popupClient = popupClient;
 
181
 
 
182
    resize(m_popupClient->contentSize());
 
183
 
 
184
    if (!initPage())
 
185
        return false;
 
186
    m_widgetClient->show(WebNavigationPolicy());
 
187
    setFocus(true);
 
188
 
 
189
    return true;
 
190
}
 
191
 
 
192
bool WebPagePopupImpl::initPage()
 
193
{
 
194
    Page::PageClients pageClients;
 
195
    fillWithEmptyClients(pageClients);
 
196
    m_chromeClient = adoptPtr(new PagePopupChromeClient(this));
 
197
    pageClients.chromeClient = m_chromeClient.get();
 
198
 
 
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());
 
204
 
 
205
    unsigned layoutMilestones = DidFirstLayout | DidFirstVisuallyNonEmptyLayout;
 
206
    m_page->addLayoutMilestones(static_cast<LayoutMilestones>(layoutMilestones));
 
207
 
 
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()));
 
213
    frame->init();
 
214
    frame->view()->resize(m_popupClient->contentSize());
 
215
    frame->view()->setTransparent(false);
 
216
 
 
217
    DOMWindowPagePopup::install(frame->document()->domWindow(), m_popupClient);
 
218
 
 
219
    DocumentWriter* writer = frame->loader()->activeDocumentLoader()->writer();
 
220
    writer->setMIMEType("text/html");
 
221
    writer->setEncoding("UTF-8", false);
 
222
    writer->begin();
 
223
    m_popupClient->writeDocument(*writer);
 
224
    writer->end();
 
225
    return true;
 
226
}
 
227
 
 
228
WebSize WebPagePopupImpl::size()
 
229
{
 
230
    return m_popupClient->contentSize();
 
231
}
 
232
 
 
233
void WebPagePopupImpl::animate(double)
 
234
{
 
235
    PageWidgetDelegate::animate(m_page.get(), monotonicallyIncreasingTime());
 
236
}
 
237
 
 
238
void WebPagePopupImpl::setCompositorSurfaceReady()
 
239
{
 
240
}
 
241
 
 
242
void WebPagePopupImpl::composite(bool)
 
243
{
 
244
}
 
245
 
 
246
void WebPagePopupImpl::layout()
 
247
{
 
248
    PageWidgetDelegate::layout(m_page.get());
 
249
}
 
250
 
 
251
void WebPagePopupImpl::paint(WebCanvas* canvas, const WebRect& rect, PaintOptions)
 
252
{
 
253
    PageWidgetDelegate::paint(m_page.get(), 0, canvas, rect, PageWidgetDelegate::Opaque, m_webView->settingsImpl()->applyDeviceScaleFactorInCompositor());
 
254
}
 
255
 
 
256
void WebPagePopupImpl::resize(const WebSize& newSize)
 
257
{
 
258
    m_windowRectInScreen = WebRect(m_windowRectInScreen.x, m_windowRectInScreen.y, newSize.width, newSize.height);
 
259
    m_widgetClient->setWindowRect(m_windowRectInScreen);
 
260
 
 
261
    if (m_page)
 
262
        m_page->mainFrame()->view()->resize(newSize);
 
263
    m_widgetClient->didInvalidateRect(WebRect(0, 0, newSize.width, newSize.height));
 
264
}
 
265
 
 
266
bool WebPagePopupImpl::handleKeyEvent(const WebKeyboardEvent&)
 
267
{
 
268
    // The main WebView receives key events and forward them to this via handleKeyEvent().
 
269
    ASSERT_NOT_REACHED();
 
270
    return false;
 
271
}
 
272
 
 
273
bool WebPagePopupImpl::handleCharEvent(const WebKeyboardEvent&)
 
274
{
 
275
    // The main WebView receives key events and forward them to this via handleKeyEvent().
 
276
    ASSERT_NOT_REACHED();
 
277
    return false;
 
278
}
 
279
 
 
280
#if ENABLE(GESTURE_EVENTS)
 
281
bool WebPagePopupImpl::handleGestureEvent(const WebGestureEvent& event)
 
282
{
 
283
    if (m_closing || !m_page || !m_page->mainFrame() || !m_page->mainFrame()->view())
 
284
        return false;
 
285
    Frame& frame = *m_page->mainFrame();
 
286
    return frame.eventHandler()->handleGestureEvent(PlatformGestureEventBuilder(frame.view(), event));
 
287
}
 
288
#endif
 
289
 
 
290
bool WebPagePopupImpl::handleInputEvent(const WebInputEvent& event)
 
291
{
 
292
    if (m_closing)
 
293
        return false;
 
294
    return PageWidgetDelegate::handleInputEvent(m_page.get(), *this, event);
 
295
}
 
296
 
 
297
bool WebPagePopupImpl::handleKeyEvent(const PlatformKeyboardEvent& event)
 
298
{
 
299
    if (m_closing || !m_page->mainFrame() || !m_page->mainFrame()->view())
 
300
        return false;
 
301
    return m_page->mainFrame()->eventHandler()->keyEvent(event);
 
302
}
 
303
 
 
304
void WebPagePopupImpl::setFocus(bool enable)
 
305
{
 
306
    if (!m_page)
 
307
        return;
 
308
    m_page->focusController()->setFocused(enable);
 
309
    if (enable)
 
310
        m_page->focusController()->setActive(true);
 
311
}
 
312
 
 
313
void WebPagePopupImpl::close()
 
314
{
 
315
    m_closing = true;
 
316
    if (m_page && m_page->mainFrame())
 
317
        m_page->mainFrame()->loader()->frameDetached();
 
318
    m_page.clear();
 
319
    m_widgetClient = 0;
 
320
    deref();
 
321
}
 
322
 
 
323
void WebPagePopupImpl::closePopup()
 
324
{
 
325
    if (m_page) {
 
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());
 
330
    }
 
331
    m_closing = true;
 
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();
 
336
    }
 
337
 
 
338
    m_popupClient->didClosePopup();
 
339
}
 
340
 
 
341
#endif // ENABLE(PAGE_POPUP)
 
342
 
 
343
// WebPagePopup ----------------------------------------------------------------
 
344
 
 
345
WebPagePopup* WebPagePopup::create(WebWidgetClient* client)
 
346
{
 
347
#if ENABLE(PAGE_POPUP)
 
348
    if (!client)
 
349
        CRASH();
 
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();
 
357
#else
 
358
    UNUSED_PARAM(client);
 
359
    return 0;
 
360
#endif
 
361
}
 
362
 
 
363
} // namespace WebKit