WebKit2: Implement WebChromeClient::exceededDatabaseQuota
[WebKit-https.git] / WebKit2 / WebProcess / WebCoreSupport / WebChromeClient.cpp
1 /*
2  * Copyright (C) 2010 Apple Inc. All rights reserved.
3  * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
18  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24  * THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #include "WebChromeClient.h"
28
29 #define DISABLE_NOT_IMPLEMENTED_WARNINGS 1
30 #include "NotImplemented.h"
31
32 #include "DrawingArea.h"
33 #include "InjectedBundleUserMessageCoders.h"
34 #include "WebContextMenu.h"
35 #include "WebCoreArgumentCoders.h"
36 #include "WebFrame.h"
37 #include "WebFrameLoaderClient.h"
38 #include "WebPage.h"
39 #include "WebPageCreationParameters.h"
40 #include "WebPageProxyMessages.h"
41 #include "WebPopupMenu.h"
42 #include "WebPreferencesStore.h"
43 #include "WebProcess.h"
44 #include "WebProcessProxyMessageKinds.h"
45 #include "WebSearchPopupMenu.h"
46 #include <WebCore/DatabaseTracker.h>
47 #include <WebCore/FileChooser.h>
48 #include <WebCore/Frame.h>
49 #include <WebCore/FrameLoader.h>
50 #include <WebCore/Page.h>
51 #include <WebCore/SecurityOrigin.h>
52
53 using namespace WebCore;
54
55 namespace WebKit {
56
57 void WebChromeClient::chromeDestroyed()
58 {
59     delete this;
60 }
61
62 void WebChromeClient::setWindowRect(const FloatRect& windowFrame)
63 {
64     m_page->send(Messages::WebPageProxy::SetWindowFrame(windowFrame));
65 }
66
67 FloatRect WebChromeClient::windowRect()
68 {
69     FloatRect newWindowFrame;
70
71     if (!WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::GetWindowFrame(), Messages::WebPageProxy::GetWindowFrame::Reply(newWindowFrame), m_page->pageID()))
72         return FloatRect();
73
74     return newWindowFrame;
75 }
76
77 FloatRect WebChromeClient::pageRect()
78 {
79     notImplemented();
80     return FloatRect();
81 }
82
83 float WebChromeClient::scaleFactor()
84 {
85     notImplemented();
86     return 1.0;
87 }
88
89 void WebChromeClient::focus()
90 {
91     notImplemented();
92 }
93
94 void WebChromeClient::unfocus()
95 {
96     notImplemented();
97 }
98
99 bool WebChromeClient::canTakeFocus(FocusDirection)
100 {
101     notImplemented();
102     return true;
103 }
104
105 void WebChromeClient::takeFocus(FocusDirection direction)
106 {
107     m_page->send(Messages::WebPageProxy::TakeFocus(direction == FocusDirectionForward ? true : false));
108 }
109
110 void WebChromeClient::focusedNodeChanged(Node*)
111 {
112     notImplemented();
113 }
114
115 void WebChromeClient::focusedFrameChanged(Frame* frame)
116 {
117     WebFrame* webFrame = frame ? static_cast<WebFrameLoaderClient*>(frame->loader()->client())->webFrame() : 0;
118
119     WebProcess::shared().connection()->send(Messages::WebPageProxy::FocusedFrameChanged(webFrame ? webFrame->frameID() : 0), m_page->pageID());
120 }
121
122 Page* WebChromeClient::createWindow(Frame*, const FrameLoadRequest&, const WindowFeatures& windowFeatures, const NavigationAction& navigationAction)
123 {
124     uint32_t modifiers = modifiersForNavigationAction(navigationAction);
125     int32_t mouseButton = mouseButtonForNavigationAction(navigationAction);
126
127     uint64_t newPageID = 0;
128     WebPageCreationParameters parameters;
129     if (!WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::CreateNewPage(windowFeatures, modifiers, mouseButton), Messages::WebPageProxy::CreateNewPage::Reply(newPageID, parameters), m_page->pageID()))
130         return 0;
131
132     if (!newPageID)
133         return 0;
134
135     WebProcess::shared().createWebPage(newPageID, parameters);
136     return WebProcess::shared().webPage(newPageID)->corePage();
137 }
138
139 void WebChromeClient::show()
140 {
141     m_page->show();
142 }
143
144 bool WebChromeClient::canRunModal()
145 {
146     notImplemented();
147     return false;
148 }
149
150 void WebChromeClient::runModal()
151 {
152     notImplemented();
153 }
154
155 void WebChromeClient::setToolbarsVisible(bool toolbarsAreVisible)
156 {
157     m_page->send(Messages::WebPageProxy::SetToolbarsAreVisible(toolbarsAreVisible));
158 }
159
160 bool WebChromeClient::toolbarsVisible()
161 {
162     bool toolbarsAreVisible = true;
163     if (!WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::GetToolbarsAreVisible(), Messages::WebPageProxy::GetToolbarsAreVisible::Reply(toolbarsAreVisible), m_page->pageID()))
164         return true;
165
166     return toolbarsAreVisible;
167 }
168
169 void WebChromeClient::setStatusbarVisible(bool statusBarIsVisible)
170 {
171     m_page->send(Messages::WebPageProxy::SetStatusBarIsVisible(statusBarIsVisible));
172 }
173
174 bool WebChromeClient::statusbarVisible()
175 {
176     bool statusBarIsVisible = true;
177     if (!WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::GetStatusBarIsVisible(), Messages::WebPageProxy::GetStatusBarIsVisible::Reply(statusBarIsVisible), m_page->pageID()))
178         return true;
179
180     return statusBarIsVisible;
181 }
182
183 void WebChromeClient::setScrollbarsVisible(bool)
184 {
185     notImplemented();
186 }
187
188 bool WebChromeClient::scrollbarsVisible()
189 {
190     notImplemented();
191     return true;
192 }
193
194 void WebChromeClient::setMenubarVisible(bool menuBarVisible)
195 {
196     m_page->send(Messages::WebPageProxy::SetMenuBarIsVisible(menuBarVisible));
197 }
198
199 bool WebChromeClient::menubarVisible()
200 {
201     bool menuBarIsVisible = true;
202     if (!WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::GetMenuBarIsVisible(), Messages::WebPageProxy::GetMenuBarIsVisible::Reply(menuBarIsVisible), m_page->pageID()))
203         return true;
204
205     return menuBarIsVisible;
206 }
207
208 void WebChromeClient::setResizable(bool resizable)
209 {
210     m_page->send(Messages::WebPageProxy::SetIsResizable(resizable));
211 }
212
213 void WebChromeClient::addMessageToConsole(MessageSource, MessageType, MessageLevel, const String& message, unsigned int lineNumber, const String& sourceID)
214 {
215     // Notify the bundle client.
216     m_page->injectedBundleUIClient().willAddMessageToConsole(m_page, message, lineNumber);
217
218     notImplemented();
219 }
220
221 bool WebChromeClient::canRunBeforeUnloadConfirmPanel()
222 {
223     bool canRun = false;
224     if (!WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::CanRunBeforeUnloadConfirmPanel(), Messages::WebPageProxy::CanRunBeforeUnloadConfirmPanel::Reply(canRun), m_page->pageID()))
225         return false;
226
227     return canRun;
228 }
229
230 bool WebChromeClient::runBeforeUnloadConfirmPanel(const String& message, Frame* frame)
231 {
232     WebFrame* webFrame = static_cast<WebFrameLoaderClient*>(frame->loader()->client())->webFrame();
233
234     bool shouldClose = false;
235     if (!WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::RunBeforeUnloadConfirmPanel(message, webFrame->frameID()), Messages::WebPageProxy::RunBeforeUnloadConfirmPanel::Reply(shouldClose), m_page->pageID()))
236         return false;
237
238     return shouldClose;
239 }
240
241 void WebChromeClient::closeWindowSoon()
242 {
243     // FIXME: This code assumes that the client will respond to a close page
244     // message by actually closing the page. Safari does this, but there is
245     // no guarantee that other applications will, which will leave this page
246     // half detached. This approach is an inherent limitation making parts of
247     // a close execute synchronously as part of window.close, but other parts
248     // later on.
249
250     m_page->corePage()->setGroupName(String());
251
252     if (WebFrame* frame = m_page->mainFrame()) {
253         if (Frame* coreFrame = frame->coreFrame())
254             coreFrame->loader()->stopForUserCancel();
255     }
256
257     m_page->sendClose();
258 }
259
260 void WebChromeClient::runJavaScriptAlert(Frame* frame, const String& alertText)
261 {
262     WebFrame* webFrame = static_cast<WebFrameLoaderClient*>(frame->loader()->client())->webFrame();
263
264     // Notify the bundle client.
265     m_page->injectedBundleUIClient().willRunJavaScriptAlert(m_page, alertText, webFrame);
266
267     WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::RunJavaScriptAlert(webFrame->frameID(), alertText), Messages::WebPageProxy::RunJavaScriptAlert::Reply(), m_page->pageID());
268 }
269
270 bool WebChromeClient::runJavaScriptConfirm(Frame* frame, const String& message)
271 {
272     WebFrame* webFrame = static_cast<WebFrameLoaderClient*>(frame->loader()->client())->webFrame();
273
274     // Notify the bundle client.
275     m_page->injectedBundleUIClient().willRunJavaScriptConfirm(m_page, message, webFrame);
276
277     bool result = false;
278     if (!WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::RunJavaScriptConfirm(webFrame->frameID(), message), Messages::WebPageProxy::RunJavaScriptConfirm::Reply(result), m_page->pageID()))
279         return false;
280
281     return result;
282 }
283
284 bool WebChromeClient::runJavaScriptPrompt(Frame* frame, const String& message, const String& defaultValue, String& result)
285 {
286     WebFrame* webFrame = static_cast<WebFrameLoaderClient*>(frame->loader()->client())->webFrame();
287
288     // Notify the bundle client.
289     m_page->injectedBundleUIClient().willRunJavaScriptPrompt(m_page, message, defaultValue, webFrame);
290
291     if (!WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::RunJavaScriptPrompt(webFrame->frameID(), message, defaultValue), Messages::WebPageProxy::RunJavaScriptPrompt::Reply(result), m_page->pageID()))
292         return false;
293
294     return !result.isNull();
295 }
296
297 void WebChromeClient::setStatusbarText(const String& statusbarText)
298 {
299     // Notify the bundle client.
300     m_page->injectedBundleUIClient().willSetStatusbarText(m_page, statusbarText);
301
302     m_page->send(Messages::WebPageProxy::SetStatusText(statusbarText));
303 }
304
305 bool WebChromeClient::shouldInterruptJavaScript()
306 {
307     notImplemented();
308     return false;
309 }
310
311 bool WebChromeClient::tabsToLinks() const
312 {
313     notImplemented();
314     return false;
315 }
316
317 IntRect WebChromeClient::windowResizerRect() const
318 {
319     return m_page->windowResizerRect();
320 }
321
322 void WebChromeClient::invalidateWindow(const IntRect& rect, bool immediate)
323 {
324     m_page->drawingArea()->invalidateWindow(rect, immediate);
325 }
326
327 void WebChromeClient::invalidateContentsAndWindow(const IntRect& rect, bool immediate)
328 {
329     m_page->drawingArea()->invalidateContentsAndWindow(rect, immediate);
330 }
331
332 void WebChromeClient::invalidateContentsForSlowScroll(const IntRect& rect, bool immediate)
333 {
334     m_page->pageDidScroll();
335     m_page->drawingArea()->invalidateContentsForSlowScroll(rect, immediate);
336 }
337
338 void WebChromeClient::scroll(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
339 {
340     m_page->pageDidScroll();
341     m_page->drawingArea()->scroll(scrollDelta, rectToScroll, clipRect);
342 }
343
344 #if ENABLE(TILED_BACKING_STORE)
345 void WebChromeClient::delegatedScrollRequested(const IntSize& scrollDelta)
346 {
347     m_page->pageDidRequestScroll(scrollDelta);
348 }
349 #endif
350
351 IntPoint WebChromeClient::screenToWindow(const IntPoint&) const
352 {
353     notImplemented();
354     return IntPoint();
355 }
356
357 IntRect WebChromeClient::windowToScreen(const IntRect&) const
358 {
359     notImplemented();
360     return IntRect();
361 }
362
363 PlatformPageClient WebChromeClient::platformPageClient() const
364 {
365     notImplemented();
366     return 0;
367 }
368
369 void WebChromeClient::contentsSizeChanged(Frame* frame, const IntSize& size) const
370 {
371 #if PLATFORM(QT)
372 #if ENABLE(TILED_BACKING_STORE)
373     if (frame->page()->mainFrame() == frame)
374         m_page->resizeToContentsIfNeeded();
375 #endif
376
377     WebFrame* webFrame = static_cast<WebFrameLoaderClient*>(frame->loader()->client())->webFrame();
378
379     if (!m_page->mainFrame() || m_page->mainFrame() != webFrame)
380         return;
381
382     m_page->send(Messages::WebPageProxy::DidChangeContentsSize(size));
383 #endif
384 }
385
386 void WebChromeClient::scrollRectIntoView(const IntRect&, const ScrollView*) const
387 {
388     notImplemented();
389 }
390
391 void WebChromeClient::scrollbarsModeDidChange() const
392 {
393     notImplemented();
394 }
395
396 void WebChromeClient::mouseDidMoveOverElement(const HitTestResult& hitTestResult, unsigned modifierFlags)
397 {
398     RefPtr<APIObject> userData;
399
400     // Notify the bundle client.
401     m_page->injectedBundleUIClient().mouseDidMoveOverElement(m_page, hitTestResult, static_cast<WebEvent::Modifiers>(modifierFlags), userData);
402
403     // Notify the UIProcess.
404     m_page->send(Messages::WebPageProxy::MouseDidMoveOverElement(modifierFlags, InjectedBundleUserMessageEncoder(userData.get())));
405 }
406
407 void WebChromeClient::setToolTip(const String& toolTip, TextDirection)
408 {
409     // Only send a tool tip to the WebProcess if it has changed since the last time this function was called.
410
411     if (toolTip == m_cachedToolTip)
412         return;
413     m_cachedToolTip = toolTip;
414
415     m_page->send(Messages::WebPageProxy::SetToolTip(m_cachedToolTip));
416 }
417
418 void WebChromeClient::print(Frame*)
419 {
420     notImplemented();
421 }
422
423 #if ENABLE(DATABASE)
424 void WebChromeClient::exceededDatabaseQuota(Frame* frame, const String& databaseName)
425 {
426     WebFrame* webFrame = static_cast<WebFrameLoaderClient*>(frame->loader()->client())->webFrame();
427     SecurityOrigin* origin = frame->document()->securityOrigin();
428
429     DatabaseDetails details = DatabaseTracker::tracker().detailsForNameAndOrigin(databaseName, origin);
430     unsigned long long currentQuota = DatabaseTracker::tracker().quotaForOrigin(origin);
431     unsigned long long newQuota = 0;
432     WebProcess::shared().connection()->sendSync(
433         Messages::WebPageProxy::ExceededDatabaseQuota(webFrame->frameID(), origin->databaseIdentifier(), databaseName, details.displayName(), currentQuota, details.currentUsage(), details.expectedUsage()),
434         Messages::WebPageProxy::ExceededDatabaseQuota::Reply(newQuota), m_page->pageID());
435
436     DatabaseTracker::tracker().setQuota(origin, newQuota);
437 }
438 #endif
439
440
441 #if ENABLE(OFFLINE_WEB_APPLICATIONS)
442 void WebChromeClient::reachedMaxAppCacheSize(int64_t)
443 {
444     notImplemented();
445 }
446
447 void WebChromeClient::reachedApplicationCacheOriginQuota(SecurityOrigin*)
448 {
449     notImplemented();
450 }
451 #endif
452
453 #if ENABLE(DASHBOARD_SUPPORT)
454 void WebChromeClient::dashboardRegionsChanged()
455 {
456     notImplemented();
457 }
458 #endif
459
460 void WebChromeClient::populateVisitedLinks()
461 {
462 }
463
464 FloatRect WebChromeClient::customHighlightRect(Node*, const AtomicString& type, const FloatRect& lineRect)
465 {
466     notImplemented();
467     return FloatRect();
468 }
469
470 void WebChromeClient::paintCustomHighlight(Node*, const AtomicString& type, const FloatRect& boxRect, const FloatRect& lineRect,
471                                   bool behindText, bool entireLine)
472 {
473     notImplemented();
474 }
475
476 bool WebChromeClient::shouldReplaceWithGeneratedFileForUpload(const String& path, String& generatedFilename)
477 {
478     notImplemented();
479     return false;
480 }
481
482 String WebChromeClient::generateReplacementFile(const String& path)
483 {
484     notImplemented();
485     return String();
486 }
487
488 bool WebChromeClient::paintCustomScrollbar(GraphicsContext*, const FloatRect&, ScrollbarControlSize, 
489                                            ScrollbarControlState, ScrollbarPart pressedPart, bool vertical,
490                                            float value, float proportion, ScrollbarControlPartMask)
491 {
492     notImplemented();
493     return false;
494 }
495
496 bool WebChromeClient::paintCustomScrollCorner(GraphicsContext*, const FloatRect&)
497 {
498     notImplemented();
499     return false;
500 }
501
502 void WebChromeClient::requestGeolocationPermissionForFrame(Frame*, Geolocation*)
503 {
504     notImplemented();
505 }
506
507 void WebChromeClient::cancelGeolocationPermissionRequestForFrame(Frame*, Geolocation*)
508 {
509     notImplemented();
510 }
511
512 void WebChromeClient::runOpenPanel(Frame*, PassRefPtr<FileChooser>)
513 {
514     notImplemented();
515 }
516
517 void WebChromeClient::chooseIconForFiles(const Vector<String>&, FileChooser*)
518 {
519     notImplemented();
520 }
521
522 void WebChromeClient::setCursor(const Cursor& cursor)
523 {
524 #if USE(LAZY_NATIVE_CURSOR)
525     m_page->send(Messages::WebPageProxy::SetCursor(cursor));
526 #endif
527 }
528
529 void WebChromeClient::formStateDidChange(const Node*)
530 {
531     notImplemented();
532 }
533
534 void WebChromeClient::formDidFocus(const Node*)
535
536     notImplemented();
537 }
538
539 void WebChromeClient::formDidBlur(const Node*)
540 {
541     notImplemented();
542 }
543
544 bool WebChromeClient::selectItemWritingDirectionIsNatural()
545 {
546     return true;
547 }
548
549 PassRefPtr<WebCore::PopupMenu> WebChromeClient::createPopupMenu(WebCore::PopupMenuClient* client) const
550 {
551     return WebPopupMenu::create(m_page, client);
552 }
553
554 PassRefPtr<WebCore::SearchPopupMenu> WebChromeClient::createSearchPopupMenu(WebCore::PopupMenuClient* client) const
555 {
556     return WebSearchPopupMenu::create(m_page, client);
557 }
558
559 #if ENABLE(CONTEXT_MENUS)
560 void WebChromeClient::showContextMenu()
561 {
562     m_page->contextMenu()->show();
563 }
564 #endif
565
566 PassOwnPtr<HTMLParserQuirks> WebChromeClient::createHTMLParserQuirks()
567 {
568     notImplemented();
569     return 0;
570 }
571
572 #if USE(ACCELERATED_COMPOSITING)
573 void WebChromeClient::attachRootGraphicsLayer(Frame*, GraphicsLayer* layer)
574 {
575     if (layer)
576         m_page->enterAcceleratedCompositingMode(layer);
577     else
578         m_page->exitAcceleratedCompositingMode();
579 }
580
581 void WebChromeClient::setNeedsOneShotDrawingSynchronization()
582 {
583     notImplemented();
584 }
585
586 void WebChromeClient::scheduleCompositingLayerSync()
587 {
588     if (m_page->drawingArea())
589         m_page->drawingArea()->scheduleCompositingLayerSync();
590 }
591
592 #endif
593
594 #if ENABLE(NOTIFICATIONS)
595 WebCore::NotificationPresenter* WebChromeClient::notificationPresenter() const
596 {
597     return 0;
598 }
599 #endif
600
601 #if ENABLE(TOUCH_EVENTS)
602 void WebChromeClient::needTouchEvents(bool)
603 {
604 }
605 #endif
606
607 #if PLATFORM(WIN)
608 void WebChromeClient::setLastSetCursorToCurrentCursor()
609 {
610 }
611 #endif
612
613 void WebChromeClient::dispatchViewportDataDidChange(const ViewportArguments& args) const
614 {
615     m_page->send(Messages::WebPageProxy::DidChangeViewportData(args));
616 }
617
618 } // namespace WebKit