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