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 | 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 | |
306 | void WebChromeClient::show() |
307 | { |
308 | m_page.show(); |
309 | } |
310 | |
311 | bool WebChromeClient::canRunModal() |
312 | { |
313 | return m_page.canRunModal(); |
314 | } |
315 | |
316 | void WebChromeClient::runModal() |
317 | { |
318 | m_page.runModal(); |
319 | } |
320 | |
321 | void WebChromeClient::reportProcessCPUTime(Seconds cpuTime, ActivityStateForCPUSampling activityState) |
322 | { |
323 | WebProcess::singleton().send(Messages::WebProcessPool::ReportWebContentCPUTime(cpuTime, static_cast<uint64_t>(activityState)), 0); |
324 | } |
325 | |
326 | void WebChromeClient::setToolbarsVisible(bool toolbarsAreVisible) |
327 | { |
328 | m_page.send(Messages::WebPageProxy::SetToolbarsAreVisible(toolbarsAreVisible)); |
329 | } |
330 | |
331 | bool 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 | |
344 | void WebChromeClient::setStatusbarVisible(bool statusBarIsVisible) |
345 | { |
346 | m_page.send(Messages::WebPageProxy::SetStatusBarIsVisible(statusBarIsVisible)); |
347 | } |
348 | |
349 | bool 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 | |
362 | void WebChromeClient::setScrollbarsVisible(bool) |
363 | { |
364 | notImplemented(); |
365 | } |
366 | |
367 | bool WebChromeClient::scrollbarsVisible() |
368 | { |
369 | notImplemented(); |
370 | return true; |
371 | } |
372 | |
373 | void WebChromeClient::(bool ) |
374 | { |
375 | m_page.send(Messages::WebPageProxy::SetMenuBarIsVisible(menuBarVisible)); |
376 | } |
377 | |
378 | bool WebChromeClient::() |
379 | { |
380 | API::InjectedBundle::PageUIClient::UIElementVisibility = 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 = 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 | |
391 | void WebChromeClient::setResizable(bool resizable) |
392 | { |
393 | m_page.send(Messages::WebPageProxy::SetIsResizable(resizable)); |
394 | } |
395 | |
396 | void 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 | |
402 | bool WebChromeClient::canRunBeforeUnloadConfirmPanel() |
403 | { |
404 | return m_page.canRunBeforeUnloadConfirmPanel(); |
405 | } |
406 | |
407 | bool 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 | |
421 | void 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 | |
440 | static 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 | |
448 | void 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 | |
464 | bool 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 | |
484 | bool 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 | |
503 | void 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 | |
511 | KeyboardUIMode WebChromeClient::keyboardUIMode() |
512 | { |
513 | return m_page.keyboardUIMode(); |
514 | } |
515 | |
516 | #if ENABLE(POINTER_LOCK) |
517 | |
518 | bool WebChromeClient::requestPointerLock() |
519 | { |
520 | m_page.send(Messages::WebPageProxy::RequestPointerLock()); |
521 | return true; |
522 | } |
523 | |
524 | void WebChromeClient::requestPointerUnlock() |
525 | { |
526 | m_page.send(Messages::WebPageProxy::RequestPointerUnlock()); |
527 | } |
528 | |
529 | #endif |
530 | |
531 | void WebChromeClient::invalidateRootView(const IntRect&) |
532 | { |
533 | // Do nothing here, there's no concept of invalidating the window in the web process. |
534 | } |
535 | |
536 | void 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 | |
546 | void 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 | |
564 | void 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 | |
570 | IntPoint WebChromeClient::screenToRootView(const IntPoint& point) const |
571 | { |
572 | return m_page.screenToRootView(point); |
573 | } |
574 | |
575 | IntRect WebChromeClient::rootViewToScreen(const IntRect& rect) const |
576 | { |
577 | return m_page.rootViewToScreen(rect); |
578 | } |
579 | |
580 | IntPoint WebChromeClient::accessibilityScreenToRootView(const IntPoint& point) const |
581 | { |
582 | return m_page.accessibilityScreenToRootView(point); |
583 | } |
584 | |
585 | IntRect WebChromeClient::rootViewToAccessibilityScreen(const IntRect& rect) const |
586 | { |
587 | return m_page.rootViewToAccessibilityScreen(rect); |
588 | } |
589 | |
590 | void WebChromeClient::didFinishLoadingImageForElement(HTMLImageElement& element) |
591 | { |
592 | m_page.didFinishLoadingImageForElement(element); |
593 | } |
594 | |
595 | PlatformPageClient WebChromeClient::platformPageClient() const |
596 | { |
597 | notImplemented(); |
598 | return 0; |
599 | } |
600 | |
601 | void WebChromeClient::intrinsicContentsSizeChanged(const IntSize& size) const |
602 | { |
603 | m_page.updateIntrinsicContentSizeIfNeeded(size); |
604 | } |
605 | |
606 | void 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 | |
638 | void WebChromeClient::scrollRectIntoView(const IntRect&) const |
639 | { |
640 | notImplemented(); |
641 | } |
642 | |
643 | bool 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 | |
664 | void 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 | |
685 | void 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 | |
697 | void 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 | |
708 | void 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 | |
736 | void 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 | |
756 | void WebChromeClient::reachedMaxAppCacheSize(int64_t) |
757 | { |
758 | notImplemented(); |
759 | } |
760 | |
761 | void 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 | |
778 | bool WebChromeClient::shouldReplaceWithGeneratedFileForUpload(const String& path, String& generatedFilename) |
779 | { |
780 | generatedFilename = m_page.injectedBundleUIClient().shouldGenerateFileForUpload(&m_page, path); |
781 | return !generatedFilename.isNull(); |
782 | } |
783 | |
784 | String WebChromeClient::generateReplacementFile(const String& path) |
785 | { |
786 | return m_page.injectedBundleUIClient().generateFileForUpload(&m_page, path); |
787 | } |
788 | |
789 | #if ENABLE(INPUT_TYPE_COLOR) |
790 | |
791 | std::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 | |
800 | std::unique_ptr<DataListSuggestionPicker> WebChromeClient::createDataListSuggestionPicker(DataListSuggestionsClient& client) |
801 | { |
802 | return std::make_unique<WebDataListSuggestionPicker>(&m_page, &client); |
803 | } |
804 | |
805 | #endif |
806 | |
807 | void 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 | |
819 | void WebChromeClient::showShareSheet(ShareDataWithParsedURL& shareData, CompletionHandler<void(bool)>&& callback) |
820 | { |
821 | m_page.showShareSheet(shareData, WTFMove(callback)); |
822 | } |
823 | |
824 | void WebChromeClient::loadIconForFiles(const Vector<String>& filenames, FileIconLoader& loader) |
825 | { |
826 | loader.iconLoaded(createIconForFiles(filenames)); |
827 | } |
828 | |
829 | #if !PLATFORM(IOS_FAMILY) |
830 | |
831 | void WebChromeClient::setCursor(const Cursor& cursor) |
832 | { |
833 | m_page.send(Messages::WebPageProxy::SetCursor(cursor)); |
834 | } |
835 | |
836 | void WebChromeClient::setCursorHiddenUntilMouseMoves(bool hiddenUntilMouseMoves) |
837 | { |
838 | m_page.send(Messages::WebPageProxy::SetCursorHiddenUntilMouseMoves(hiddenUntilMouseMoves)); |
839 | } |
840 | |
841 | RefPtr<Icon> WebChromeClient::createIconForFiles(const Vector<String>& filenames) |
842 | { |
843 | return Icon::createIconForFiles(filenames); |
844 | } |
845 | |
846 | #endif |
847 | |
848 | void 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 | |
855 | bool WebChromeClient::shouldNotifyOnFormChanges() |
856 | { |
857 | return m_page.injectedBundleFormClient().shouldNotifyOnFormChanges(&m_page); |
858 | } |
859 | |
860 | bool WebChromeClient::selectItemWritingDirectionIsNatural() |
861 | { |
862 | return false; |
863 | } |
864 | |
865 | bool WebChromeClient::() |
866 | { |
867 | return true; |
868 | } |
869 | |
870 | RefPtr<PopupMenu> WebChromeClient::(PopupMenuClient& client) const |
871 | { |
872 | return WebPopupMenu::create(&m_page, &client); |
873 | } |
874 | |
875 | RefPtr<SearchPopupMenu> WebChromeClient::(PopupMenuClient& client) const |
876 | { |
877 | return WebSearchPopupMenu::create(&m_page, &client); |
878 | } |
879 | |
880 | GraphicsLayerFactory* 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 | |
889 | RefPtr<DisplayRefreshMonitor> WebChromeClient::createDisplayRefreshMonitor(PlatformDisplayID displayID) const |
890 | { |
891 | return m_page.drawingArea()->createDisplayRefreshMonitor(displayID); |
892 | } |
893 | |
894 | #endif |
895 | |
896 | void WebChromeClient::attachRootGraphicsLayer(Frame&, GraphicsLayer* layer) |
897 | { |
898 | if (layer) |
899 | m_page.enterAcceleratedCompositingMode(layer); |
900 | else |
901 | m_page.exitAcceleratedCompositingMode(); |
902 | } |
903 | |
904 | void WebChromeClient::attachViewOverlayGraphicsLayer(GraphicsLayer* graphicsLayer) |
905 | { |
906 | if (auto drawingArea = m_page.drawingArea()) |
907 | drawingArea->attachViewOverlayGraphicsLayer(graphicsLayer); |
908 | } |
909 | |
910 | void WebChromeClient::setNeedsOneShotDrawingSynchronization() |
911 | { |
912 | notImplemented(); |
913 | } |
914 | |
915 | void WebChromeClient::scheduleCompositingLayerFlush() |
916 | { |
917 | if (m_page.drawingArea()) |
918 | m_page.drawingArea()->scheduleCompositingLayerFlush(); |
919 | } |
920 | |
921 | void 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 | |
929 | bool WebChromeClient::adjustLayerFlushThrottling(LayerFlushThrottleState::Flags flags) |
930 | { |
931 | return m_page.drawingArea() && m_page.drawingArea()->adjustLayerFlushThrottling(flags); |
932 | } |
933 | |
934 | bool WebChromeClient::layerTreeStateIsFrozen() const |
935 | { |
936 | if (m_page.drawingArea()) |
937 | return m_page.drawingArea()->layerTreeStateIsFrozen(); |
938 | |
939 | return false; |
940 | } |
941 | |
942 | bool 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 | |
952 | RefPtr<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 | |
968 | bool WebChromeClient::supportsVideoFullscreen(HTMLMediaElementEnums::VideoFullscreenMode mode) |
969 | { |
970 | return m_page.videoFullscreenManager().supportsVideoFullscreen(mode); |
971 | } |
972 | |
973 | bool WebChromeClient::supportsVideoFullscreenStandby() |
974 | { |
975 | return m_page.videoFullscreenManager().supportsVideoFullscreenStandby(); |
976 | } |
977 | |
978 | void WebChromeClient::setUpPlaybackControlsManager(HTMLMediaElement& mediaElement) |
979 | { |
980 | m_page.playbackSessionManager().setUpPlaybackControlsManager(mediaElement); |
981 | } |
982 | |
983 | void WebChromeClient::clearPlaybackControlsManager() |
984 | { |
985 | m_page.playbackSessionManager().clearPlaybackControlsManager(); |
986 | } |
987 | |
988 | void 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 | |
998 | void 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 | |
1007 | void 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 | |
1016 | bool WebChromeClient::supportsFullScreenForElement(const Element&, bool withKeyboard) |
1017 | { |
1018 | return m_page.fullScreenManager()->supportsFullScreen(withKeyboard); |
1019 | } |
1020 | |
1021 | void WebChromeClient::enterFullScreenForElement(Element& element) |
1022 | { |
1023 | m_page.fullScreenManager()->enterFullScreenForElement(&element); |
1024 | } |
1025 | |
1026 | void WebChromeClient::exitFullScreenForElement(Element* element) |
1027 | { |
1028 | m_page.fullScreenManager()->exitFullScreenForElement(element); |
1029 | } |
1030 | |
1031 | #endif |
1032 | |
1033 | #if PLATFORM(IOS_FAMILY) |
1034 | |
1035 | FloatSize WebChromeClient::screenSize() const |
1036 | { |
1037 | return m_page.screenSize(); |
1038 | } |
1039 | |
1040 | FloatSize WebChromeClient::availableScreenSize() const |
1041 | { |
1042 | return m_page.availableScreenSize(); |
1043 | } |
1044 | |
1045 | FloatSize WebChromeClient::overrideScreenSize() const |
1046 | { |
1047 | return m_page.overrideScreenSize(); |
1048 | } |
1049 | |
1050 | #endif |
1051 | |
1052 | void WebChromeClient::dispatchDisabledAdaptationsDidChange(const OptionSet<DisabledAdaptations>& disabledAdaptations) const |
1053 | { |
1054 | m_page.disabledAdaptationsDidChange(disabledAdaptations); |
1055 | } |
1056 | |
1057 | void WebChromeClient::dispatchViewportPropertiesDidChange(const ViewportArguments& viewportArguments) const |
1058 | { |
1059 | m_page.viewportPropertiesDidChange(viewportArguments); |
1060 | } |
1061 | |
1062 | void WebChromeClient::notifyScrollerThumbIsVisibleInRect(const IntRect& scrollerThumb) |
1063 | { |
1064 | m_page.send(Messages::WebPageProxy::NotifyScrollerThumbIsVisibleInRect(scrollerThumb)); |
1065 | } |
1066 | |
1067 | void WebChromeClient::recommendedScrollbarStyleDidChange(ScrollbarStyle newStyle) |
1068 | { |
1069 | m_page.send(Messages::WebPageProxy::RecommendedScrollbarStyleDidChange(static_cast<int32_t>(newStyle))); |
1070 | } |
1071 | |
1072 | Optional<ScrollbarOverlayStyle> WebChromeClient::preferredScrollbarOverlayStyle() |
1073 | { |
1074 | return m_page.scrollbarOverlayStyle(); |
1075 | } |
1076 | |
1077 | Color WebChromeClient::underlayColor() const |
1078 | { |
1079 | return m_page.underlayColor(); |
1080 | } |
1081 | |
1082 | void 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 | |
1091 | void WebChromeClient::wheelEventHandlersChanged(bool hasHandlers) |
1092 | { |
1093 | m_page.wheelEventHandlersChanged(hasHandlers); |
1094 | } |
1095 | |
1096 | String WebChromeClient::plugInStartLabelTitle(const String& mimeType) const |
1097 | { |
1098 | return m_page.injectedBundleUIClient().plugInStartLabelTitle(mimeType); |
1099 | } |
1100 | |
1101 | String WebChromeClient::plugInStartLabelSubtitle(const String& mimeType) const |
1102 | { |
1103 | return m_page.injectedBundleUIClient().plugInStartLabelSubtitle(mimeType); |
1104 | } |
1105 | |
1106 | String WebChromeClient::() const |
1107 | { |
1108 | return m_page.injectedBundleUIClient().plugInExtraStyleSheet(); |
1109 | } |
1110 | |
1111 | String WebChromeClient::() const |
1112 | { |
1113 | return m_page.injectedBundleUIClient().plugInExtraScript(); |
1114 | } |
1115 | |
1116 | void WebChromeClient::enableSuddenTermination() |
1117 | { |
1118 | m_page.send(Messages::WebProcessProxy::EnableSuddenTermination()); |
1119 | } |
1120 | |
1121 | void WebChromeClient::disableSuddenTermination() |
1122 | { |
1123 | m_page.send(Messages::WebProcessProxy::DisableSuddenTermination()); |
1124 | } |
1125 | |
1126 | void WebChromeClient::(GraphicsLayer& ) |
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 | |
1136 | void WebChromeClient::(GraphicsLayer& ) |
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 | |
1146 | bool WebChromeClient::shouldUseTiledBackingForFrameView(const FrameView& frameView) const |
1147 | { |
1148 | return m_page.drawingArea()->shouldUseTiledBackingForFrameView(frameView); |
1149 | } |
1150 | |
1151 | void WebChromeClient::isPlayingMediaDidChange(MediaProducer::MediaStateFlags state, uint64_t sourceElementID) |
1152 | { |
1153 | m_page.send(Messages::WebPageProxy::IsPlayingMediaDidChange(state, sourceElementID)); |
1154 | } |
1155 | |
1156 | void 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 | |
1163 | void WebChromeClient::hasMediaSessionWithActiveMediaElementsDidChange(bool state) |
1164 | { |
1165 | m_page.send(Messages::WebPageProxy::HasMediaSessionWithActiveMediaElementsDidChange(state)); |
1166 | } |
1167 | |
1168 | void WebChromeClient::mediaSessionMetadataDidChange(const MediaSessionMetadata& metadata) |
1169 | { |
1170 | m_page.send(Messages::WebPageProxy::MediaSessionMetadataDidChange(metadata)); |
1171 | } |
1172 | |
1173 | void 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 | |
1182 | bool 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 | |
1190 | bool 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 | |
1200 | String 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 | |
1210 | void 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 | |
1219 | void WebChromeClient::handleSelectionServiceClick(FrameSelection& selection, const Vector<String>& telephoneNumbers, const IntPoint& point) |
1220 | { |
1221 | m_page.handleSelectionServiceClick(selection, telephoneNumbers, point); |
1222 | } |
1223 | |
1224 | bool WebChromeClient::hasRelevantSelectionServices(bool isTextOnly) const |
1225 | { |
1226 | return (isTextOnly && WebProcess::singleton().hasSelectionServices()) || WebProcess::singleton().hasRichContentServices(); |
1227 | } |
1228 | |
1229 | #endif |
1230 | |
1231 | bool WebChromeClient::shouldDispatchFakeMouseMoveEvents() const |
1232 | { |
1233 | return m_page.shouldDispatchFakeMouseMoveEvents(); |
1234 | } |
1235 | |
1236 | void 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 | |
1248 | void 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 | |
1262 | void WebChromeClient::addPlaybackTargetPickerClient(uint64_t contextId) |
1263 | { |
1264 | m_page.send(Messages::WebPageProxy::AddPlaybackTargetPickerClient(contextId)); |
1265 | } |
1266 | |
1267 | void WebChromeClient::removePlaybackTargetPickerClient(uint64_t contextId) |
1268 | { |
1269 | m_page.send(Messages::WebPageProxy::RemovePlaybackTargetPickerClient(contextId)); |
1270 | } |
1271 | |
1272 | void 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 | |
1279 | void WebChromeClient::playbackTargetPickerClientStateDidChange(uint64_t contextId, MediaProducer::MediaStateFlags state) |
1280 | { |
1281 | m_page.send(Messages::WebPageProxy::PlaybackTargetPickerClientStateDidChange(contextId, state)); |
1282 | } |
1283 | |
1284 | void WebChromeClient::setMockMediaPlaybackTargetPickerEnabled(bool enabled) |
1285 | { |
1286 | m_page.send(Messages::WebPageProxy::SetMockMediaPlaybackTargetPickerEnabled(enabled)); |
1287 | } |
1288 | |
1289 | void WebChromeClient::setMockMediaPlaybackTargetPickerState(const String& name, MediaPlaybackTargetContext::State state) |
1290 | { |
1291 | m_page.send(Messages::WebPageProxy::SetMockMediaPlaybackTargetPickerState(name, state)); |
1292 | } |
1293 | |
1294 | #endif |
1295 | |
1296 | void WebChromeClient::imageOrMediaDocumentSizeChanged(const IntSize& newSize) |
1297 | { |
1298 | m_page.imageOrMediaDocumentSizeChanged(newSize); |
1299 | } |
1300 | |
1301 | #if ENABLE(VIDEO) && USE(GSTREAMER) |
1302 | |
1303 | void WebChromeClient::requestInstallMissingMediaPlugins(const String& details, const String& description, MediaPlayerRequestInstallMissingPluginsCallback& callback) |
1304 | { |
1305 | m_page.requestInstallMissingMediaPlugins(details, description, callback); |
1306 | } |
1307 | |
1308 | #endif |
1309 | |
1310 | void WebChromeClient::didInvalidateDocumentMarkerRects() |
1311 | { |
1312 | m_page.findController().didInvalidateDocumentMarkerRects(); |
1313 | } |
1314 | |
1315 | #if ENABLE(RESOURCE_LOAD_STATISTICS) |
1316 | void 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 | |
1321 | void 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) |
1328 | void 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 | |
1336 | void WebChromeClient::configureLoggingChannel(const String& channelName, WTFLogChannelState state, WTFLogLevel level) |
1337 | { |
1338 | m_page.configureLoggingChannel(channelName, state, level); |
1339 | } |
1340 | |
1341 | bool WebChromeClient::userIsInteracting() const |
1342 | { |
1343 | return m_page.userIsInteracting(); |
1344 | } |
1345 | |
1346 | void WebChromeClient::setUserIsInteracting(bool userIsInteracting) |
1347 | { |
1348 | m_page.setUserIsInteracting(userIsInteracting); |
1349 | } |
1350 | |
1351 | } // namespace WebKit |
1352 | |