1/*
2 * Copyright (C) 2010-2017 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 "config.h"
28#include "WebChromeClient.h"
29
30#include "APIArray.h"
31#include "APISecurityOrigin.h"
32#include "DrawingArea.h"
33#include "FindController.h"
34#include "FrameInfoData.h"
35#include "HangDetectionDisabler.h"
36#include "InjectedBundleNavigationAction.h"
37#include "InjectedBundleNodeHandle.h"
38#include "NavigationActionData.h"
39#include "PageBanner.h"
40#include "UserData.h"
41#include "WebColorChooser.h"
42#include "WebCoreArgumentCoders.h"
43#include "WebDataListSuggestionPicker.h"
44#include "WebFrame.h"
45#include "WebFrameLoaderClient.h"
46#include "WebFullScreenManager.h"
47#include "WebHitTestResultData.h"
48#include "WebImage.h"
49#include "WebOpenPanelResultListener.h"
50#include "WebPage.h"
51#include "WebPageCreationParameters.h"
52#include "WebPageProxyMessages.h"
53#include "WebPopupMenu.h"
54#include "WebProcess.h"
55#include "WebProcessPoolMessages.h"
56#include "WebProcessProxyMessages.h"
57#include "WebSearchPopupMenu.h"
58#include <WebCore/ApplicationCacheStorage.h>
59#include <WebCore/AXObjectCache.h>
60#include <WebCore/ColorChooser.h>
61#include <WebCore/ContentRuleListResults.h>
62#include <WebCore/DataListSuggestionPicker.h>
63#include <WebCore/DatabaseTracker.h>
64#include <WebCore/DocumentLoader.h>
65#include <WebCore/DocumentStorageAccess.h>
66#include <WebCore/FileChooser.h>
67#include <WebCore/FileIconLoader.h>
68#include <WebCore/Frame.h>
69#include <WebCore/FrameLoadRequest.h>
70#include <WebCore/FrameLoader.h>
71#include <WebCore/FrameView.h>
72#include <WebCore/FullscreenManager.h>
73#include <WebCore/HTMLInputElement.h>
74#include <WebCore/HTMLNames.h>
75#include <WebCore/HTMLParserIdioms.h>
76#include <WebCore/HTMLPlugInImageElement.h>
77#include <WebCore/Icon.h>
78#include <WebCore/NotImplemented.h>
79#include <WebCore/Page.h>
80#include <WebCore/RegistrableDomain.h>
81#include <WebCore/ScriptController.h>
82#include <WebCore/SecurityOrigin.h>
83#include <WebCore/SecurityOriginData.h>
84#include <WebCore/Settings.h>
85
86#if PLATFORM(IOS_FAMILY) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))
87#include "PlaybackSessionManager.h"
88#include "VideoFullscreenManager.h"
89#endif
90
91#if ENABLE(ASYNC_SCROLLING)
92#include "RemoteScrollingCoordinator.h"
93#endif
94
95#if PLATFORM(GTK)
96#include "PrinterListGtk.h"
97#endif
98
99namespace WebKit {
100using namespace WebCore;
101using namespace HTMLNames;
102
103static double area(WebFrame* frame)
104{
105 IntSize size = frame->visibleContentBoundsExcludingScrollbars().size();
106 return static_cast<double>(size.height()) * size.width();
107}
108
109static WebFrame* findLargestFrameInFrameSet(WebPage& page)
110{
111 // Approximate what a user could consider a default target frame for application menu operations.
112
113 WebFrame* mainFrame = page.mainWebFrame();
114 if (!mainFrame || !mainFrame->isFrameSet())
115 return nullptr;
116
117 WebFrame* largestSoFar = nullptr;
118
119 Ref<API::Array> frameChildren = mainFrame->childFrames();
120 size_t count = frameChildren->size();
121 for (size_t i = 0; i < count; ++i) {
122 auto* childFrame = frameChildren->at<WebFrame>(i);
123 if (!largestSoFar || area(childFrame) > area(largestSoFar))
124 largestSoFar = childFrame;
125 }
126
127 return largestSoFar;
128}
129
130WebChromeClient::WebChromeClient(WebPage& page)
131 : m_page(page)
132{
133}
134
135void WebChromeClient::didInsertMenuElement(HTMLMenuElement& element)
136{
137 m_page.didInsertMenuElement(element);
138}
139
140void WebChromeClient::didRemoveMenuElement(HTMLMenuElement& element)
141{
142 m_page.didRemoveMenuElement(element);
143}
144
145void WebChromeClient::didInsertMenuItemElement(HTMLMenuItemElement& element)
146{
147 m_page.didInsertMenuItemElement(element);
148}
149
150void WebChromeClient::didRemoveMenuItemElement(HTMLMenuItemElement& element)
151{
152 m_page.didRemoveMenuItemElement(element);
153}
154
155inline WebChromeClient::~WebChromeClient()
156{
157}
158
159void WebChromeClient::chromeDestroyed()
160{
161 delete this;
162}
163
164void WebChromeClient::setWindowRect(const FloatRect& windowFrame)
165{
166 m_page.sendSetWindowFrame(windowFrame);
167}
168
169FloatRect WebChromeClient::windowRect()
170{
171#if PLATFORM(IOS_FAMILY)
172 return FloatRect();
173#else
174#if PLATFORM(MAC)
175 if (m_page.hasCachedWindowFrame())
176 return m_page.windowFrameInUnflippedScreenCoordinates();
177#endif
178
179 FloatRect newWindowFrame;
180
181 if (!WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPageProxy::GetWindowFrame(), Messages::WebPageProxy::GetWindowFrame::Reply(newWindowFrame), m_page.pageID()))
182 return FloatRect();
183
184 return newWindowFrame;
185#endif
186}
187
188FloatRect WebChromeClient::pageRect()
189{
190 return FloatRect(FloatPoint(), m_page.size());
191}
192
193void WebChromeClient::focus()
194{
195 m_page.send(Messages::WebPageProxy::SetFocus(true));
196}
197
198void WebChromeClient::unfocus()
199{
200 m_page.send(Messages::WebPageProxy::SetFocus(false));
201}
202
203#if PLATFORM(COCOA)
204
205void WebChromeClient::elementDidFocus(Element& element)
206{
207 m_page.elementDidFocus(element);
208}
209
210void WebChromeClient::elementDidRefocus(Element& element)
211{
212 m_page.elementDidRefocus(element);
213}
214
215void WebChromeClient::elementDidBlur(Element& element)
216{
217 m_page.elementDidBlur(element);
218}
219
220void WebChromeClient::focusedElementDidChangeInputMode(Element& element, InputMode mode)
221{
222 m_page.focusedElementDidChangeInputMode(element, mode);
223}
224
225void WebChromeClient::makeFirstResponder()
226{
227 m_page.send(Messages::WebPageProxy::MakeFirstResponder());
228}
229
230void WebChromeClient::assistiveTechnologyMakeFirstResponder()
231{
232 m_page.send(Messages::WebPageProxy::AssistiveTechnologyMakeFirstResponder());
233}
234
235#endif
236
237bool WebChromeClient::canTakeFocus(FocusDirection)
238{
239 notImplemented();
240 return true;
241}
242
243void WebChromeClient::takeFocus(FocusDirection direction)
244{
245 m_page.send(Messages::WebPageProxy::TakeFocus(direction));
246}
247
248void WebChromeClient::focusedElementChanged(Element* element)
249{
250 if (!is<HTMLInputElement>(element))
251 return;
252
253 HTMLInputElement& inputElement = downcast<HTMLInputElement>(*element);
254 if (!inputElement.isText())
255 return;
256
257 WebFrame* webFrame = WebFrame::fromCoreFrame(*element->document().frame());
258 ASSERT(webFrame);
259 m_page.injectedBundleFormClient().didFocusTextField(&m_page, &inputElement, webFrame);
260}
261
262void WebChromeClient::focusedFrameChanged(Frame* frame)
263{
264 WebFrame* webFrame = frame ? WebFrame::fromCoreFrame(*frame) : nullptr;
265
266 WebProcess::singleton().parentProcessConnection()->send(Messages::WebPageProxy::FocusedFrameChanged(webFrame ? webFrame->frameID() : 0), m_page.pageID());
267}
268
269Page* WebChromeClient::createWindow(Frame& frame, const FrameLoadRequest& request, const WindowFeatures& windowFeatures, const NavigationAction& navigationAction)
270{
271#if ENABLE(FULLSCREEN_API)
272 if (frame.document() && frame.document()->fullscreenManager().currentFullscreenElement())
273 frame.document()->fullscreenManager().cancelFullscreen();
274#endif
275
276 auto& webProcess = WebProcess::singleton();
277
278 NavigationActionData navigationActionData;
279 navigationActionData.navigationType = navigationAction.type();
280 navigationActionData.modifiers = InjectedBundleNavigationAction::modifiersForNavigationAction(navigationAction);
281 navigationActionData.mouseButton = InjectedBundleNavigationAction::mouseButtonForNavigationAction(navigationAction);
282 navigationActionData.syntheticClickType = InjectedBundleNavigationAction::syntheticClickTypeForNavigationAction(navigationAction);
283 navigationActionData.clickLocationInRootViewCoordinates = InjectedBundleNavigationAction::clickLocationInRootViewCoordinatesForNavigationAction(navigationAction);
284 navigationActionData.userGestureTokenIdentifier = webProcess.userGestureTokenIdentifier(navigationAction.userGestureToken());
285 navigationActionData.canHandleRequest = m_page.canHandleRequest(request.resourceRequest());
286 navigationActionData.shouldOpenExternalURLsPolicy = navigationAction.shouldOpenExternalURLsPolicy();
287 navigationActionData.downloadAttribute = navigationAction.downloadAttribute();
288
289 WebFrame* webFrame = WebFrame::fromCoreFrame(frame);
290
291 Optional<PageIdentifier> newPageID;
292 Optional<WebPageCreationParameters> parameters;
293 if (!webProcess.parentProcessConnection()->sendSync(Messages::WebPageProxy::CreateNewPage(webFrame->info(), webFrame->page()->pageID(), request.resourceRequest(), windowFeatures, navigationActionData), Messages::WebPageProxy::CreateNewPage::Reply(newPageID, parameters), m_page.pageID()))
294 return nullptr;
295
296 if (!newPageID)
297 return nullptr;
298 ASSERT(parameters);
299 if (parameters->sessionID == m_page.sessionID())
300 parameters->oldPageID = m_page.pageID();
301
302 webProcess.createWebPage(*newPageID, WTFMove(*parameters));
303 return webProcess.webPage(*newPageID)->corePage();
304}
305
306void WebChromeClient::show()
307{
308 m_page.show();
309}
310
311bool WebChromeClient::canRunModal()
312{
313 return m_page.canRunModal();
314}
315
316void WebChromeClient::runModal()
317{
318 m_page.runModal();
319}
320
321void WebChromeClient::reportProcessCPUTime(Seconds cpuTime, ActivityStateForCPUSampling activityState)
322{
323 WebProcess::singleton().send(Messages::WebProcessPool::ReportWebContentCPUTime(cpuTime, static_cast<uint64_t>(activityState)), 0);
324}
325
326void WebChromeClient::setToolbarsVisible(bool toolbarsAreVisible)
327{
328 m_page.send(Messages::WebPageProxy::SetToolbarsAreVisible(toolbarsAreVisible));
329}
330
331bool WebChromeClient::toolbarsVisible()
332{
333 API::InjectedBundle::PageUIClient::UIElementVisibility toolbarsVisibility = m_page.injectedBundleUIClient().toolbarsAreVisible(&m_page);
334 if (toolbarsVisibility != API::InjectedBundle::PageUIClient::UIElementVisibility::Unknown)
335 return toolbarsVisibility == API::InjectedBundle::PageUIClient::UIElementVisibility::Visible;
336
337 bool toolbarsAreVisible = true;
338 if (!WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPageProxy::GetToolbarsAreVisible(), Messages::WebPageProxy::GetToolbarsAreVisible::Reply(toolbarsAreVisible), m_page.pageID()))
339 return true;
340
341 return toolbarsAreVisible;
342}
343
344void WebChromeClient::setStatusbarVisible(bool statusBarIsVisible)
345{
346 m_page.send(Messages::WebPageProxy::SetStatusBarIsVisible(statusBarIsVisible));
347}
348
349bool WebChromeClient::statusbarVisible()
350{
351 API::InjectedBundle::PageUIClient::UIElementVisibility statusbarVisibility = m_page.injectedBundleUIClient().statusBarIsVisible(&m_page);
352 if (statusbarVisibility != API::InjectedBundle::PageUIClient::UIElementVisibility::Unknown)
353 return statusbarVisibility == API::InjectedBundle::PageUIClient::UIElementVisibility::Visible;
354
355 bool statusBarIsVisible = true;
356 if (!WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPageProxy::GetStatusBarIsVisible(), Messages::WebPageProxy::GetStatusBarIsVisible::Reply(statusBarIsVisible), m_page.pageID()))
357 return true;
358
359 return statusBarIsVisible;
360}
361
362void WebChromeClient::setScrollbarsVisible(bool)
363{
364 notImplemented();
365}
366
367bool WebChromeClient::scrollbarsVisible()
368{
369 notImplemented();
370 return true;
371}
372
373void WebChromeClient::setMenubarVisible(bool menuBarVisible)
374{
375 m_page.send(Messages::WebPageProxy::SetMenuBarIsVisible(menuBarVisible));
376}
377
378bool WebChromeClient::menubarVisible()
379{
380 API::InjectedBundle::PageUIClient::UIElementVisibility menubarVisibility = m_page.injectedBundleUIClient().menuBarIsVisible(&m_page);
381 if (menubarVisibility != API::InjectedBundle::PageUIClient::UIElementVisibility::Unknown)
382 return menubarVisibility == API::InjectedBundle::PageUIClient::UIElementVisibility::Visible;
383
384 bool menuBarIsVisible = true;
385 if (!WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPageProxy::GetMenuBarIsVisible(), Messages::WebPageProxy::GetMenuBarIsVisible::Reply(menuBarIsVisible), m_page.pageID()))
386 return true;
387
388 return menuBarIsVisible;
389}
390
391void WebChromeClient::setResizable(bool resizable)
392{
393 m_page.send(Messages::WebPageProxy::SetIsResizable(resizable));
394}
395
396void WebChromeClient::addMessageToConsole(MessageSource source, MessageLevel level, const String& message, unsigned lineNumber, unsigned columnNumber, const String& sourceID)
397{
398 // Notify the bundle client.
399 m_page.injectedBundleUIClient().willAddMessageToConsole(&m_page, source, level, message, lineNumber, columnNumber, sourceID);
400}
401
402bool WebChromeClient::canRunBeforeUnloadConfirmPanel()
403{
404 return m_page.canRunBeforeUnloadConfirmPanel();
405}
406
407bool WebChromeClient::runBeforeUnloadConfirmPanel(const String& message, Frame& frame)
408{
409 WebFrame* webFrame = WebFrame::fromCoreFrame(frame);
410
411 bool shouldClose = false;
412
413 HangDetectionDisabler hangDetectionDisabler;
414
415 if (!m_page.sendSyncWithDelayedReply(Messages::WebPageProxy::RunBeforeUnloadConfirmPanel(webFrame->frameID(), SecurityOriginData::fromFrame(&frame), message), Messages::WebPageProxy::RunBeforeUnloadConfirmPanel::Reply(shouldClose)))
416 return false;
417
418 return shouldClose;
419}
420
421void WebChromeClient::closeWindowSoon()
422{
423 // FIXME: This code assumes that the client will respond to a close page
424 // message by actually closing the page. Safari does this, but there is
425 // no guarantee that other applications will, which will leave this page
426 // half detached. This approach is an inherent limitation making parts of
427 // a close execute synchronously as part of window.close, but other parts
428 // later on.
429
430 m_page.corePage()->setGroupName(String());
431
432 if (WebFrame* frame = m_page.mainWebFrame()) {
433 if (Frame* coreFrame = frame->coreFrame())
434 coreFrame->loader().stopForUserCancel();
435 }
436
437 m_page.sendClose();
438}
439
440static bool shouldSuppressJavaScriptDialogs(Frame& frame)
441{
442 if (frame.loader().opener() && frame.loader().stateMachine().isDisplayingInitialEmptyDocument() && frame.loader().provisionalDocumentLoader())
443 return true;
444
445 return false;
446}
447
448void WebChromeClient::runJavaScriptAlert(Frame& frame, const String& alertText)
449{
450 if (shouldSuppressJavaScriptDialogs(frame))
451 return;
452
453 WebFrame* webFrame = WebFrame::fromCoreFrame(frame);
454 ASSERT(webFrame);
455
456 // Notify the bundle client.
457 m_page.injectedBundleUIClient().willRunJavaScriptAlert(&m_page, alertText, webFrame);
458
459 HangDetectionDisabler hangDetectionDisabler;
460
461 m_page.sendSyncWithDelayedReply(Messages::WebPageProxy::RunJavaScriptAlert(webFrame->frameID(), SecurityOriginData::fromFrame(&frame), alertText), Messages::WebPageProxy::RunJavaScriptAlert::Reply());
462}
463
464bool WebChromeClient::runJavaScriptConfirm(Frame& frame, const String& message)
465{
466 if (shouldSuppressJavaScriptDialogs(frame))
467 return false;
468
469 WebFrame* webFrame = WebFrame::fromCoreFrame(frame);
470 ASSERT(webFrame);
471
472 // Notify the bundle client.
473 m_page.injectedBundleUIClient().willRunJavaScriptConfirm(&m_page, message, webFrame);
474
475 HangDetectionDisabler hangDetectionDisabler;
476
477 bool result = false;
478 if (!m_page.sendSyncWithDelayedReply(Messages::WebPageProxy::RunJavaScriptConfirm(webFrame->frameID(), SecurityOriginData::fromFrame(&frame), message), Messages::WebPageProxy::RunJavaScriptConfirm::Reply(result)))
479 return false;
480
481 return result;
482}
483
484bool WebChromeClient::runJavaScriptPrompt(Frame& frame, const String& message, const String& defaultValue, String& result)
485{
486 if (shouldSuppressJavaScriptDialogs(frame))
487 return false;
488
489 WebFrame* webFrame = WebFrame::fromCoreFrame(frame);
490 ASSERT(webFrame);
491
492 // Notify the bundle client.
493 m_page.injectedBundleUIClient().willRunJavaScriptPrompt(&m_page, message, defaultValue, webFrame);
494
495 HangDetectionDisabler hangDetectionDisabler;
496
497 if (!m_page.sendSyncWithDelayedReply(Messages::WebPageProxy::RunJavaScriptPrompt(webFrame->frameID(), SecurityOriginData::fromFrame(&frame), message, defaultValue), Messages::WebPageProxy::RunJavaScriptPrompt::Reply(result)))
498 return false;
499
500 return !result.isNull();
501}
502
503void WebChromeClient::setStatusbarText(const String& statusbarText)
504{
505 // Notify the bundle client.
506 m_page.injectedBundleUIClient().willSetStatusbarText(&m_page, statusbarText);
507
508 m_page.send(Messages::WebPageProxy::SetStatusText(statusbarText));
509}
510
511KeyboardUIMode WebChromeClient::keyboardUIMode()
512{
513 return m_page.keyboardUIMode();
514}
515
516#if ENABLE(POINTER_LOCK)
517
518bool WebChromeClient::requestPointerLock()
519{
520 m_page.send(Messages::WebPageProxy::RequestPointerLock());
521 return true;
522}
523
524void WebChromeClient::requestPointerUnlock()
525{
526 m_page.send(Messages::WebPageProxy::RequestPointerUnlock());
527}
528
529#endif
530
531void WebChromeClient::invalidateRootView(const IntRect&)
532{
533 // Do nothing here, there's no concept of invalidating the window in the web process.
534}
535
536void WebChromeClient::invalidateContentsAndRootView(const IntRect& rect)
537{
538 if (Document* document = m_page.corePage()->mainFrame().document()) {
539 if (document->printing())
540 return;
541 }
542
543 m_page.drawingArea()->setNeedsDisplayInRect(rect);
544}
545
546void WebChromeClient::invalidateContentsForSlowScroll(const IntRect& rect)
547{
548 if (Document* document = m_page.corePage()->mainFrame().document()) {
549 if (document->printing())
550 return;
551 }
552
553 m_page.pageDidScroll();
554#if USE(COORDINATED_GRAPHICS)
555 FrameView* frameView = m_page.mainFrame()->view();
556 if (frameView && frameView->delegatesScrolling()) {
557 m_page.drawingArea()->scroll(rect, IntSize());
558 return;
559 }
560#endif
561 m_page.drawingArea()->setNeedsDisplayInRect(rect);
562}
563
564void WebChromeClient::scroll(const IntSize& scrollDelta, const IntRect& scrollRect, const IntRect& clipRect)
565{
566 m_page.pageDidScroll();
567 m_page.drawingArea()->scroll(intersection(scrollRect, clipRect), scrollDelta);
568}
569
570IntPoint WebChromeClient::screenToRootView(const IntPoint& point) const
571{
572 return m_page.screenToRootView(point);
573}
574
575IntRect WebChromeClient::rootViewToScreen(const IntRect& rect) const
576{
577 return m_page.rootViewToScreen(rect);
578}
579
580IntPoint WebChromeClient::accessibilityScreenToRootView(const IntPoint& point) const
581{
582 return m_page.accessibilityScreenToRootView(point);
583}
584
585IntRect WebChromeClient::rootViewToAccessibilityScreen(const IntRect& rect) const
586{
587 return m_page.rootViewToAccessibilityScreen(rect);
588}
589
590void WebChromeClient::didFinishLoadingImageForElement(HTMLImageElement& element)
591{
592 m_page.didFinishLoadingImageForElement(element);
593}
594
595PlatformPageClient WebChromeClient::platformPageClient() const
596{
597 notImplemented();
598 return 0;
599}
600
601void WebChromeClient::intrinsicContentsSizeChanged(const IntSize& size) const
602{
603 m_page.updateIntrinsicContentSizeIfNeeded(size);
604}
605
606void WebChromeClient::contentsSizeChanged(Frame& frame, const IntSize& size) const
607{
608 FrameView* frameView = frame.view();
609
610 if (frameView && frameView->effectiveFrameFlattening() == FrameFlattening::Disabled) {
611 WebFrame* largestFrame = findLargestFrameInFrameSet(m_page);
612 if (largestFrame != m_cachedFrameSetLargestFrame.get()) {
613 m_cachedFrameSetLargestFrame = largestFrame;
614 m_page.send(Messages::WebPageProxy::FrameSetLargestFrameChanged(largestFrame ? largestFrame->frameID() : 0));
615 }
616 }
617
618 if (&frame.page()->mainFrame() != &frame)
619 return;
620
621 m_page.send(Messages::WebPageProxy::DidChangeContentSize(size));
622
623 m_page.drawingArea()->mainFrameContentSizeChanged(size);
624
625 if (frameView && !frameView->delegatesScrolling()) {
626 bool hasHorizontalScrollbar = frameView->horizontalScrollbar();
627 bool hasVerticalScrollbar = frameView->verticalScrollbar();
628
629 if (hasHorizontalScrollbar != m_cachedMainFrameHasHorizontalScrollbar || hasVerticalScrollbar != m_cachedMainFrameHasVerticalScrollbar) {
630 m_page.send(Messages::WebPageProxy::DidChangeScrollbarsForMainFrame(hasHorizontalScrollbar, hasVerticalScrollbar));
631
632 m_cachedMainFrameHasHorizontalScrollbar = hasHorizontalScrollbar;
633 m_cachedMainFrameHasVerticalScrollbar = hasVerticalScrollbar;
634 }
635 }
636}
637
638void WebChromeClient::scrollRectIntoView(const IntRect&) const
639{
640 notImplemented();
641}
642
643bool WebChromeClient::shouldUnavailablePluginMessageBeButton(RenderEmbeddedObject::PluginUnavailabilityReason pluginUnavailabilityReason) const
644{
645 switch (pluginUnavailabilityReason) {
646 case RenderEmbeddedObject::PluginMissing:
647 // FIXME: <rdar://problem/8794397> We should only return true when there is a
648 // missingPluginButtonClicked callback defined on the Page UI client.
649 case RenderEmbeddedObject::InsecurePluginVersion:
650 return true;
651
652
653 case RenderEmbeddedObject::PluginCrashed:
654 case RenderEmbeddedObject::PluginBlockedByContentSecurityPolicy:
655 case RenderEmbeddedObject::UnsupportedPlugin:
656 case RenderEmbeddedObject::PluginTooSmall:
657 return false;
658 }
659
660 ASSERT_NOT_REACHED();
661 return false;
662}
663
664void WebChromeClient::unavailablePluginButtonClicked(Element& element, RenderEmbeddedObject::PluginUnavailabilityReason pluginUnavailabilityReason) const
665{
666#if ENABLE(NETSCAPE_PLUGIN_API)
667 ASSERT(element.hasTagName(objectTag) || element.hasTagName(embedTag) || element.hasTagName(appletTag));
668 ASSERT(pluginUnavailabilityReason == RenderEmbeddedObject::PluginMissing || pluginUnavailabilityReason == RenderEmbeddedObject::InsecurePluginVersion || pluginUnavailabilityReason);
669
670 auto& pluginElement = downcast<HTMLPlugInImageElement>(element);
671
672 String frameURLString = pluginElement.document().frame()->loader().documentLoader()->responseURL().string();
673 String pageURLString = m_page.mainFrame()->loader().documentLoader()->responseURL().string();
674 String pluginURLString = pluginElement.document().completeURL(pluginElement.url()).string();
675 URL pluginspageAttributeURL = pluginElement.document().completeURL(stripLeadingAndTrailingHTMLSpaces(pluginElement.attributeWithoutSynchronization(pluginspageAttr)));
676 if (!pluginspageAttributeURL.protocolIsInHTTPFamily())
677 pluginspageAttributeURL = URL();
678 m_page.send(Messages::WebPageProxy::UnavailablePluginButtonClicked(pluginUnavailabilityReason, pluginElement.serviceType(), pluginURLString, pluginspageAttributeURL.string(), frameURLString, pageURLString));
679#else
680 UNUSED_PARAM(element);
681 UNUSED_PARAM(pluginUnavailabilityReason);
682#endif // ENABLE(NETSCAPE_PLUGIN_API)
683}
684
685void WebChromeClient::mouseDidMoveOverElement(const HitTestResult& hitTestResult, unsigned modifierFlags)
686{
687 RefPtr<API::Object> userData;
688
689 // Notify the bundle client.
690 m_page.injectedBundleUIClient().mouseDidMoveOverElement(&m_page, hitTestResult, OptionSet<WebEvent::Modifier>::fromRaw(modifierFlags), userData);
691
692 // Notify the UIProcess.
693 WebHitTestResultData webHitTestResultData(hitTestResult);
694 m_page.send(Messages::WebPageProxy::MouseDidMoveOverElement(webHitTestResultData, modifierFlags, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
695}
696
697void WebChromeClient::setToolTip(const String& toolTip, TextDirection)
698{
699 // Only send a tool tip to the WebProcess if it has changed since the last time this function was called.
700
701 if (toolTip == m_cachedToolTip)
702 return;
703 m_cachedToolTip = toolTip;
704
705 m_page.send(Messages::WebPageProxy::SetToolTip(m_cachedToolTip));
706}
707
708void WebChromeClient::print(Frame& frame)
709{
710 WebFrame* webFrame = WebFrame::fromCoreFrame(frame);
711 ASSERT(webFrame);
712
713#if PLATFORM(GTK) && HAVE(GTK_UNIX_PRINTING)
714 // When printing synchronously in GTK+ we need to make sure that we have a list of Printers before starting the print operation.
715 // Getting the list of printers is done synchronously by GTK+, but using a nested main loop that might process IPC messages
716 // comming from the UI process like EndPrinting. When the EndPriting message is received while the printer list is being populated,
717 // the print operation is finished unexpectely and the web process crashes, see https://bugs.webkit.org/show_bug.cgi?id=126979.
718 // The PrinterListGtk class gets the list of printers in the constructor so we just need to ensure there's an instance alive
719 // during the synchronous print operation.
720 RefPtr<PrinterListGtk> printerList = PrinterListGtk::getOrCreate();
721 if (!printerList) {
722 // PrinterListGtk::getOrCreate() returns nullptr when called while a printers enumeration is ongoing.
723 // This can happen if a synchronous print is started by a JavaScript and another one is inmeditaley started
724 // from a JavaScript event listener. The second print operation is handled by the nested main loop used by GTK+
725 // to enumerate the printers, and we end up here trying to get a reference of an object that is being constructed.
726 // It's very unlikely that the user wants to print twice in a row, and other browsers don't do two print operations
727 // in this particular case either. So, the safest solution is to return early here and ignore the second print.
728 // See https://bugs.webkit.org/show_bug.cgi?id=141035
729 return;
730 }
731#endif
732
733 m_page.sendSyncWithDelayedReply(Messages::WebPageProxy::PrintFrame(webFrame->frameID()), Messages::WebPageProxy::PrintFrame::Reply());
734}
735
736void WebChromeClient::exceededDatabaseQuota(Frame& frame, const String& databaseName, DatabaseDetails details)
737{
738 WebFrame* webFrame = WebFrame::fromCoreFrame(frame);
739 ASSERT(webFrame);
740
741 auto& origin = frame.document()->securityOrigin();
742 auto& originData = origin.data();
743 auto& tracker = DatabaseTracker::singleton();
744 auto currentQuota = tracker.quota(originData);
745 auto currentOriginUsage = tracker.usage(originData);
746 uint64_t newQuota = 0;
747 auto securityOrigin = API::SecurityOrigin::create(SecurityOriginData::fromDatabaseIdentifier(originData.databaseIdentifier())->securityOrigin());
748 newQuota = m_page.injectedBundleUIClient().didExceedDatabaseQuota(&m_page, securityOrigin.ptr(), databaseName, details.displayName(), currentQuota, currentOriginUsage, details.currentUsage(), details.expectedUsage());
749
750 if (!newQuota)
751 m_page.sendSyncWithDelayedReply(Messages::WebPageProxy::ExceededDatabaseQuota(webFrame->frameID(), originData.databaseIdentifier(), databaseName, details.displayName(), currentQuota, currentOriginUsage, details.currentUsage(), details.expectedUsage()), Messages::WebPageProxy::ExceededDatabaseQuota::Reply(newQuota));
752
753 tracker.setQuota(originData, newQuota);
754}
755
756void WebChromeClient::reachedMaxAppCacheSize(int64_t)
757{
758 notImplemented();
759}
760
761void WebChromeClient::reachedApplicationCacheOriginQuota(SecurityOrigin& origin, int64_t totalBytesNeeded)
762{
763 auto securityOrigin = API::SecurityOrigin::createFromString(origin.toString());
764 if (m_page.injectedBundleUIClient().didReachApplicationCacheOriginQuota(&m_page, securityOrigin.ptr(), totalBytesNeeded))
765 return;
766
767 auto& cacheStorage = m_page.corePage()->applicationCacheStorage();
768 int64_t currentQuota = 0;
769 if (!cacheStorage.calculateQuotaForOrigin(origin, currentQuota))
770 return;
771
772 uint64_t newQuota = 0;
773 m_page.sendSyncWithDelayedReply(Messages::WebPageProxy::ReachedApplicationCacheOriginQuota(origin.data().databaseIdentifier(), currentQuota, totalBytesNeeded), Messages::WebPageProxy::ReachedApplicationCacheOriginQuota::Reply(newQuota));
774
775 cacheStorage.storeUpdatedQuotaForOrigin(&origin, newQuota);
776}
777
778bool WebChromeClient::shouldReplaceWithGeneratedFileForUpload(const String& path, String& generatedFilename)
779{
780 generatedFilename = m_page.injectedBundleUIClient().shouldGenerateFileForUpload(&m_page, path);
781 return !generatedFilename.isNull();
782}
783
784String WebChromeClient::generateReplacementFile(const String& path)
785{
786 return m_page.injectedBundleUIClient().generateFileForUpload(&m_page, path);
787}
788
789#if ENABLE(INPUT_TYPE_COLOR)
790
791std::unique_ptr<ColorChooser> WebChromeClient::createColorChooser(ColorChooserClient& client, const Color& initialColor)
792{
793 return std::make_unique<WebColorChooser>(&m_page, &client, initialColor);
794}
795
796#endif
797
798#if ENABLE(DATALIST_ELEMENT)
799
800std::unique_ptr<DataListSuggestionPicker> WebChromeClient::createDataListSuggestionPicker(DataListSuggestionsClient& client)
801{
802 return std::make_unique<WebDataListSuggestionPicker>(&m_page, &client);
803}
804
805#endif
806
807void WebChromeClient::runOpenPanel(Frame& frame, FileChooser& fileChooser)
808{
809 if (m_page.activeOpenPanelResultListener())
810 return;
811
812 m_page.setActiveOpenPanelResultListener(WebOpenPanelResultListener::create(m_page, fileChooser));
813
814 auto* webFrame = WebFrame::fromCoreFrame(frame);
815 ASSERT(webFrame);
816 m_page.send(Messages::WebPageProxy::RunOpenPanel(webFrame->frameID(), SecurityOriginData::fromFrame(&frame), fileChooser.settings()));
817}
818
819void WebChromeClient::showShareSheet(ShareDataWithParsedURL& shareData, CompletionHandler<void(bool)>&& callback)
820{
821 m_page.showShareSheet(shareData, WTFMove(callback));
822}
823
824void WebChromeClient::loadIconForFiles(const Vector<String>& filenames, FileIconLoader& loader)
825{
826 loader.iconLoaded(createIconForFiles(filenames));
827}
828
829#if !PLATFORM(IOS_FAMILY)
830
831void WebChromeClient::setCursor(const Cursor& cursor)
832{
833 m_page.send(Messages::WebPageProxy::SetCursor(cursor));
834}
835
836void WebChromeClient::setCursorHiddenUntilMouseMoves(bool hiddenUntilMouseMoves)
837{
838 m_page.send(Messages::WebPageProxy::SetCursorHiddenUntilMouseMoves(hiddenUntilMouseMoves));
839}
840
841RefPtr<Icon> WebChromeClient::createIconForFiles(const Vector<String>& filenames)
842{
843 return Icon::createIconForFiles(filenames);
844}
845
846#endif
847
848void WebChromeClient::didAssociateFormControls(const Vector<RefPtr<Element>>& elements, WebCore::Frame& frame)
849{
850 WebFrame* webFrame = WebFrame::fromCoreFrame(frame);
851 ASSERT(webFrame);
852 return m_page.injectedBundleFormClient().didAssociateFormControls(&m_page, elements, webFrame);
853}
854
855bool WebChromeClient::shouldNotifyOnFormChanges()
856{
857 return m_page.injectedBundleFormClient().shouldNotifyOnFormChanges(&m_page);
858}
859
860bool WebChromeClient::selectItemWritingDirectionIsNatural()
861{
862 return false;
863}
864
865bool WebChromeClient::selectItemAlignmentFollowsMenuWritingDirection()
866{
867 return true;
868}
869
870RefPtr<PopupMenu> WebChromeClient::createPopupMenu(PopupMenuClient& client) const
871{
872 return WebPopupMenu::create(&m_page, &client);
873}
874
875RefPtr<SearchPopupMenu> WebChromeClient::createSearchPopupMenu(PopupMenuClient& client) const
876{
877 return WebSearchPopupMenu::create(&m_page, &client);
878}
879
880GraphicsLayerFactory* WebChromeClient::graphicsLayerFactory() const
881{
882 if (auto drawingArea = m_page.drawingArea())
883 return drawingArea->graphicsLayerFactory();
884 return nullptr;
885}
886
887#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
888
889RefPtr<DisplayRefreshMonitor> WebChromeClient::createDisplayRefreshMonitor(PlatformDisplayID displayID) const
890{
891 return m_page.drawingArea()->createDisplayRefreshMonitor(displayID);
892}
893
894#endif
895
896void WebChromeClient::attachRootGraphicsLayer(Frame&, GraphicsLayer* layer)
897{
898 if (layer)
899 m_page.enterAcceleratedCompositingMode(layer);
900 else
901 m_page.exitAcceleratedCompositingMode();
902}
903
904void WebChromeClient::attachViewOverlayGraphicsLayer(GraphicsLayer* graphicsLayer)
905{
906 if (auto drawingArea = m_page.drawingArea())
907 drawingArea->attachViewOverlayGraphicsLayer(graphicsLayer);
908}
909
910void WebChromeClient::setNeedsOneShotDrawingSynchronization()
911{
912 notImplemented();
913}
914
915void WebChromeClient::scheduleCompositingLayerFlush()
916{
917 if (m_page.drawingArea())
918 m_page.drawingArea()->scheduleCompositingLayerFlush();
919}
920
921void WebChromeClient::contentRuleListNotification(const URL& url, const ContentRuleListResults& results)
922{
923#if ENABLE(CONTENT_EXTENSIONS)
924 ASSERT(results.shouldNotifyApplication());
925 m_page.send(Messages::WebPageProxy::ContentRuleListNotification(url, results));
926#endif
927}
928
929bool WebChromeClient::adjustLayerFlushThrottling(LayerFlushThrottleState::Flags flags)
930{
931 return m_page.drawingArea() && m_page.drawingArea()->adjustLayerFlushThrottling(flags);
932}
933
934bool WebChromeClient::layerTreeStateIsFrozen() const
935{
936 if (m_page.drawingArea())
937 return m_page.drawingArea()->layerTreeStateIsFrozen();
938
939 return false;
940}
941
942bool WebChromeClient::layerFlushThrottlingIsActive() const
943{
944 if (m_page.drawingArea())
945 return m_page.drawingArea()->layerFlushThrottlingIsActive();
946
947 return false;
948}
949
950#if ENABLE(ASYNC_SCROLLING)
951
952RefPtr<ScrollingCoordinator> WebChromeClient::createScrollingCoordinator(Page& page) const
953{
954 ASSERT_UNUSED(page, m_page.corePage() == &page);
955#if PLATFORM(COCOA)
956 if (m_page.drawingArea()->type() != DrawingAreaTypeRemoteLayerTree)
957 return nullptr;
958 return RemoteScrollingCoordinator::create(&m_page);
959#else
960 return nullptr;
961#endif
962}
963
964#endif
965
966#if (PLATFORM(IOS_FAMILY) && HAVE(AVKIT)) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))
967
968bool WebChromeClient::supportsVideoFullscreen(HTMLMediaElementEnums::VideoFullscreenMode mode)
969{
970 return m_page.videoFullscreenManager().supportsVideoFullscreen(mode);
971}
972
973bool WebChromeClient::supportsVideoFullscreenStandby()
974{
975 return m_page.videoFullscreenManager().supportsVideoFullscreenStandby();
976}
977
978void WebChromeClient::setUpPlaybackControlsManager(HTMLMediaElement& mediaElement)
979{
980 m_page.playbackSessionManager().setUpPlaybackControlsManager(mediaElement);
981}
982
983void WebChromeClient::clearPlaybackControlsManager()
984{
985 m_page.playbackSessionManager().clearPlaybackControlsManager();
986}
987
988void WebChromeClient::enterVideoFullscreenForVideoElement(HTMLVideoElement& videoElement, HTMLMediaElementEnums::VideoFullscreenMode mode, bool standby)
989{
990#if ENABLE(FULLSCREEN_API) && PLATFORM(IOS_FAMILY)
991 ASSERT(standby || mode != HTMLMediaElementEnums::VideoFullscreenModeNone);
992#else
993 ASSERT(mode != HTMLMediaElementEnums::VideoFullscreenModeNone);
994#endif
995 m_page.videoFullscreenManager().enterVideoFullscreenForVideoElement(videoElement, mode, standby);
996}
997
998void WebChromeClient::exitVideoFullscreenForVideoElement(HTMLVideoElement& videoElement)
999{
1000 m_page.videoFullscreenManager().exitVideoFullscreenForVideoElement(videoElement);
1001}
1002
1003#endif
1004
1005#if PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE)
1006
1007void WebChromeClient::exitVideoFullscreenToModeWithoutAnimation(HTMLVideoElement& videoElement, HTMLMediaElementEnums::VideoFullscreenMode targetMode)
1008{
1009 m_page.videoFullscreenManager().exitVideoFullscreenToModeWithoutAnimation(videoElement, targetMode);
1010}
1011
1012#endif
1013
1014#if ENABLE(FULLSCREEN_API)
1015
1016bool WebChromeClient::supportsFullScreenForElement(const Element&, bool withKeyboard)
1017{
1018 return m_page.fullScreenManager()->supportsFullScreen(withKeyboard);
1019}
1020
1021void WebChromeClient::enterFullScreenForElement(Element& element)
1022{
1023 m_page.fullScreenManager()->enterFullScreenForElement(&element);
1024}
1025
1026void WebChromeClient::exitFullScreenForElement(Element* element)
1027{
1028 m_page.fullScreenManager()->exitFullScreenForElement(element);
1029}
1030
1031#endif
1032
1033#if PLATFORM(IOS_FAMILY)
1034
1035FloatSize WebChromeClient::screenSize() const
1036{
1037 return m_page.screenSize();
1038}
1039
1040FloatSize WebChromeClient::availableScreenSize() const
1041{
1042 return m_page.availableScreenSize();
1043}
1044
1045FloatSize WebChromeClient::overrideScreenSize() const
1046{
1047 return m_page.overrideScreenSize();
1048}
1049
1050#endif
1051
1052void WebChromeClient::dispatchDisabledAdaptationsDidChange(const OptionSet<DisabledAdaptations>& disabledAdaptations) const
1053{
1054 m_page.disabledAdaptationsDidChange(disabledAdaptations);
1055}
1056
1057void WebChromeClient::dispatchViewportPropertiesDidChange(const ViewportArguments& viewportArguments) const
1058{
1059 m_page.viewportPropertiesDidChange(viewportArguments);
1060}
1061
1062void WebChromeClient::notifyScrollerThumbIsVisibleInRect(const IntRect& scrollerThumb)
1063{
1064 m_page.send(Messages::WebPageProxy::NotifyScrollerThumbIsVisibleInRect(scrollerThumb));
1065}
1066
1067void WebChromeClient::recommendedScrollbarStyleDidChange(ScrollbarStyle newStyle)
1068{
1069 m_page.send(Messages::WebPageProxy::RecommendedScrollbarStyleDidChange(static_cast<int32_t>(newStyle)));
1070}
1071
1072Optional<ScrollbarOverlayStyle> WebChromeClient::preferredScrollbarOverlayStyle()
1073{
1074 return m_page.scrollbarOverlayStyle();
1075}
1076
1077Color WebChromeClient::underlayColor() const
1078{
1079 return m_page.underlayColor();
1080}
1081
1082void WebChromeClient::pageExtendedBackgroundColorDidChange(Color backgroundColor) const
1083{
1084#if PLATFORM(MAC)
1085 m_page.send(Messages::WebPageProxy::PageExtendedBackgroundColorDidChange(backgroundColor));
1086#else
1087 UNUSED_PARAM(backgroundColor);
1088#endif
1089}
1090
1091void WebChromeClient::wheelEventHandlersChanged(bool hasHandlers)
1092{
1093 m_page.wheelEventHandlersChanged(hasHandlers);
1094}
1095
1096String WebChromeClient::plugInStartLabelTitle(const String& mimeType) const
1097{
1098 return m_page.injectedBundleUIClient().plugInStartLabelTitle(mimeType);
1099}
1100
1101String WebChromeClient::plugInStartLabelSubtitle(const String& mimeType) const
1102{
1103 return m_page.injectedBundleUIClient().plugInStartLabelSubtitle(mimeType);
1104}
1105
1106String WebChromeClient::plugInExtraStyleSheet() const
1107{
1108 return m_page.injectedBundleUIClient().plugInExtraStyleSheet();
1109}
1110
1111String WebChromeClient::plugInExtraScript() const
1112{
1113 return m_page.injectedBundleUIClient().plugInExtraScript();
1114}
1115
1116void WebChromeClient::enableSuddenTermination()
1117{
1118 m_page.send(Messages::WebProcessProxy::EnableSuddenTermination());
1119}
1120
1121void WebChromeClient::disableSuddenTermination()
1122{
1123 m_page.send(Messages::WebProcessProxy::DisableSuddenTermination());
1124}
1125
1126void WebChromeClient::didAddHeaderLayer(GraphicsLayer& headerParent)
1127{
1128#if ENABLE(RUBBER_BANDING)
1129 if (PageBanner* banner = m_page.headerPageBanner())
1130 banner->didAddParentLayer(&headerParent);
1131#else
1132 UNUSED_PARAM(headerParent);
1133#endif
1134}
1135
1136void WebChromeClient::didAddFooterLayer(GraphicsLayer& footerParent)
1137{
1138#if ENABLE(RUBBER_BANDING)
1139 if (PageBanner* banner = m_page.footerPageBanner())
1140 banner->didAddParentLayer(&footerParent);
1141#else
1142 UNUSED_PARAM(footerParent);
1143#endif
1144}
1145
1146bool WebChromeClient::shouldUseTiledBackingForFrameView(const FrameView& frameView) const
1147{
1148 return m_page.drawingArea()->shouldUseTiledBackingForFrameView(frameView);
1149}
1150
1151void WebChromeClient::isPlayingMediaDidChange(MediaProducer::MediaStateFlags state, uint64_t sourceElementID)
1152{
1153 m_page.send(Messages::WebPageProxy::IsPlayingMediaDidChange(state, sourceElementID));
1154}
1155
1156void WebChromeClient::handleAutoplayEvent(AutoplayEvent event, OptionSet<AutoplayEventFlags> flags)
1157{
1158 m_page.send(Messages::WebPageProxy::HandleAutoplayEvent(event, flags));
1159}
1160
1161#if ENABLE(MEDIA_SESSION)
1162
1163void WebChromeClient::hasMediaSessionWithActiveMediaElementsDidChange(bool state)
1164{
1165 m_page.send(Messages::WebPageProxy::HasMediaSessionWithActiveMediaElementsDidChange(state));
1166}
1167
1168void WebChromeClient::mediaSessionMetadataDidChange(const MediaSessionMetadata& metadata)
1169{
1170 m_page.send(Messages::WebPageProxy::MediaSessionMetadataDidChange(metadata));
1171}
1172
1173void WebChromeClient::focusedContentMediaElementDidChange(uint64_t elementID)
1174{
1175 m_page.send(Messages::WebPageProxy::FocusedContentMediaElementDidChange(elementID));
1176}
1177
1178#endif
1179
1180#if ENABLE(WEB_CRYPTO)
1181
1182bool WebChromeClient::wrapCryptoKey(const Vector<uint8_t>& key, Vector<uint8_t>& wrappedKey) const
1183{
1184 bool succeeded;
1185 if (!WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPageProxy::WrapCryptoKey(key), Messages::WebPageProxy::WrapCryptoKey::Reply(succeeded, wrappedKey), m_page.pageID()))
1186 return false;
1187 return succeeded;
1188}
1189
1190bool WebChromeClient::unwrapCryptoKey(const Vector<uint8_t>& wrappedKey, Vector<uint8_t>& key) const
1191{
1192 bool succeeded;
1193 if (!WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPageProxy::UnwrapCryptoKey(wrappedKey), Messages::WebPageProxy::UnwrapCryptoKey::Reply(succeeded, key), m_page.pageID()))
1194 return false;
1195 return succeeded;
1196}
1197
1198#endif
1199
1200String WebChromeClient::signedPublicKeyAndChallengeString(unsigned keySizeIndex, const String& challengeString, const URL& url) const
1201{
1202 String result;
1203 if (!WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPageProxy::SignedPublicKeyAndChallengeString(keySizeIndex, challengeString, url), Messages::WebPageProxy::SignedPublicKeyAndChallengeString::Reply(result), m_page.pageID()))
1204 return emptyString();
1205 return result;
1206}
1207
1208#if ENABLE(TELEPHONE_NUMBER_DETECTION) && PLATFORM(MAC)
1209
1210void WebChromeClient::handleTelephoneNumberClick(const String& number, const IntPoint& point)
1211{
1212 m_page.handleTelephoneNumberClick(number, point);
1213}
1214
1215#endif
1216
1217#if ENABLE(SERVICE_CONTROLS)
1218
1219void WebChromeClient::handleSelectionServiceClick(FrameSelection& selection, const Vector<String>& telephoneNumbers, const IntPoint& point)
1220{
1221 m_page.handleSelectionServiceClick(selection, telephoneNumbers, point);
1222}
1223
1224bool WebChromeClient::hasRelevantSelectionServices(bool isTextOnly) const
1225{
1226 return (isTextOnly && WebProcess::singleton().hasSelectionServices()) || WebProcess::singleton().hasRichContentServices();
1227}
1228
1229#endif
1230
1231bool WebChromeClient::shouldDispatchFakeMouseMoveEvents() const
1232{
1233 return m_page.shouldDispatchFakeMouseMoveEvents();
1234}
1235
1236void WebChromeClient::handleAutoFillButtonClick(HTMLInputElement& inputElement)
1237{
1238 RefPtr<API::Object> userData;
1239
1240 // Notify the bundle client.
1241 auto nodeHandle = InjectedBundleNodeHandle::getOrCreate(inputElement);
1242 m_page.injectedBundleUIClient().didClickAutoFillButton(m_page, nodeHandle.get(), userData);
1243
1244 // Notify the UIProcess.
1245 m_page.send(Messages::WebPageProxy::HandleAutoFillButtonClick(UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
1246}
1247
1248void WebChromeClient::inputElementDidResignStrongPasswordAppearance(HTMLInputElement& inputElement)
1249{
1250 RefPtr<API::Object> userData;
1251
1252 // Notify the bundle client.
1253 auto nodeHandle = InjectedBundleNodeHandle::getOrCreate(inputElement);
1254 m_page.injectedBundleUIClient().didResignInputElementStrongPasswordAppearance(m_page, nodeHandle.get(), userData);
1255
1256 // Notify the UIProcess.
1257 m_page.send(Messages::WebPageProxy::DidResignInputElementStrongPasswordAppearance { UserData { WebProcess::singleton().transformObjectsToHandles(userData.get()).get() } });
1258}
1259
1260#if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS_FAMILY)
1261
1262void WebChromeClient::addPlaybackTargetPickerClient(uint64_t contextId)
1263{
1264 m_page.send(Messages::WebPageProxy::AddPlaybackTargetPickerClient(contextId));
1265}
1266
1267void WebChromeClient::removePlaybackTargetPickerClient(uint64_t contextId)
1268{
1269 m_page.send(Messages::WebPageProxy::RemovePlaybackTargetPickerClient(contextId));
1270}
1271
1272void WebChromeClient::showPlaybackTargetPicker(uint64_t contextId, const IntPoint& position, bool isVideo)
1273{
1274 FrameView* frameView = m_page.mainFrame()->view();
1275 FloatRect rect(frameView->contentsToRootView(frameView->windowToContents(position)), FloatSize());
1276 m_page.send(Messages::WebPageProxy::ShowPlaybackTargetPicker(contextId, rect, isVideo));
1277}
1278
1279void WebChromeClient::playbackTargetPickerClientStateDidChange(uint64_t contextId, MediaProducer::MediaStateFlags state)
1280{
1281 m_page.send(Messages::WebPageProxy::PlaybackTargetPickerClientStateDidChange(contextId, state));
1282}
1283
1284void WebChromeClient::setMockMediaPlaybackTargetPickerEnabled(bool enabled)
1285{
1286 m_page.send(Messages::WebPageProxy::SetMockMediaPlaybackTargetPickerEnabled(enabled));
1287}
1288
1289void WebChromeClient::setMockMediaPlaybackTargetPickerState(const String& name, MediaPlaybackTargetContext::State state)
1290{
1291 m_page.send(Messages::WebPageProxy::SetMockMediaPlaybackTargetPickerState(name, state));
1292}
1293
1294#endif
1295
1296void WebChromeClient::imageOrMediaDocumentSizeChanged(const IntSize& newSize)
1297{
1298 m_page.imageOrMediaDocumentSizeChanged(newSize);
1299}
1300
1301#if ENABLE(VIDEO) && USE(GSTREAMER)
1302
1303void WebChromeClient::requestInstallMissingMediaPlugins(const String& details, const String& description, MediaPlayerRequestInstallMissingPluginsCallback& callback)
1304{
1305 m_page.requestInstallMissingMediaPlugins(details, description, callback);
1306}
1307
1308#endif
1309
1310void WebChromeClient::didInvalidateDocumentMarkerRects()
1311{
1312 m_page.findController().didInvalidateDocumentMarkerRects();
1313}
1314
1315#if ENABLE(RESOURCE_LOAD_STATISTICS)
1316void WebChromeClient::hasStorageAccess(RegistrableDomain&& subFrameDomain, RegistrableDomain&& topFrameDomain, uint64_t frameID, PageIdentifier, CompletionHandler<void(bool)>&& completionHandler)
1317{
1318 m_page.hasStorageAccess(WTFMove(subFrameDomain), WTFMove(topFrameDomain), frameID, WTFMove(completionHandler));
1319}
1320
1321void WebChromeClient::requestStorageAccess(RegistrableDomain&& subFrameDomain, RegistrableDomain&& topFrameDomain, uint64_t frameID, PageIdentifier, CompletionHandler<void(StorageAccessWasGranted, StorageAccessPromptWasShown)>&& completionHandler)
1322{
1323 m_page.requestStorageAccess(WTFMove(subFrameDomain), WTFMove(topFrameDomain), frameID, WTFMove(completionHandler));
1324}
1325#endif
1326
1327#if ENABLE(DEVICE_ORIENTATION)
1328void WebChromeClient::shouldAllowDeviceOrientationAndMotionAccess(Frame& frame, bool mayPrompt, CompletionHandler<void(DeviceOrientationOrMotionPermissionState)>&& callback)
1329{
1330 auto* webFrame = WebFrame::fromCoreFrame(frame);
1331 ASSERT(webFrame);
1332 m_page.shouldAllowDeviceOrientationAndMotionAccess(webFrame->frameID(), SecurityOriginData::fromFrame(&frame), mayPrompt, WTFMove(callback));
1333}
1334#endif
1335
1336void WebChromeClient::configureLoggingChannel(const String& channelName, WTFLogChannelState state, WTFLogLevel level)
1337{
1338 m_page.configureLoggingChannel(channelName, state, level);
1339}
1340
1341bool WebChromeClient::userIsInteracting() const
1342{
1343 return m_page.userIsInteracting();
1344}
1345
1346void WebChromeClient::setUserIsInteracting(bool userIsInteracting)
1347{
1348 m_page.setUserIsInteracting(userIsInteracting);
1349}
1350
1351} // namespace WebKit
1352