Removing PAGE_VISIBILITY_API compile guard.
[WebKit-https.git] / Source / WebKit2 / WebProcess / WebPage / WebPage.cpp
1 /*
2  * Copyright (C) 2010, 2011, 2012, 2013 Apple Inc. All rights reserved.
3  * Copyright (C) 2012 Intel Corporation. All rights reserved.
4  * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
17  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
19  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
25  * THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #include "config.h"
29 #include "WebPage.h"
30
31 #include "Arguments.h"
32 #include "DataReference.h"
33 #include "DecoderAdapter.h"
34 #include "DragControllerAction.h"
35 #include "DrawingArea.h"
36 #include "DrawingAreaMessages.h"
37 #include "EditingRange.h"
38 #include "EditorState.h"
39 #include "EventDispatcher.h"
40 #include "InjectedBundle.h"
41 #include "InjectedBundleBackForwardList.h"
42 #include "InjectedBundleUserMessageCoders.h"
43 #include "LayerTreeHost.h"
44 #include "LegacySessionState.h"
45 #include "Logging.h"
46 #include "NetscapePlugin.h"
47 #include "NotificationPermissionRequestManager.h"
48 #include "PageBanner.h"
49 #include "PluginProcessAttributes.h"
50 #include "PluginProxy.h"
51 #include "PluginView.h"
52 #include "PrintInfo.h"
53 #include "SelectionOverlayController.h"
54 #include "SessionTracker.h"
55 #include "ShareableBitmap.h"
56 #include "TelephoneNumberOverlayController.h"
57 #include "VisitedLinkTableController.h"
58 #include "WKSharedAPICast.h"
59 #include "WebAlternativeTextClient.h"
60 #include "WebBackForwardListItem.h"
61 #include "WebBackForwardListProxy.h"
62 #include "WebChromeClient.h"
63 #include "WebColorChooser.h"
64 #include "WebContextMenu.h"
65 #include "WebContextMenuClient.h"
66 #include "WebContextMessages.h"
67 #include "WebCoreArgumentCoders.h"
68 #include "WebDocumentLoader.h"
69 #include "WebDragClient.h"
70 #include "WebEditorClient.h"
71 #include "WebEvent.h"
72 #include "WebEventConversion.h"
73 #include "WebFrame.h"
74 #include "WebFrameLoaderClient.h"
75 #include "WebFullScreenManager.h"
76 #include "WebFullScreenManagerMessages.h"
77 #include "WebGeolocationClient.h"
78 #include "WebImage.h"
79 #include "WebInspector.h"
80 #include "WebInspectorClient.h"
81 #include "WebInspectorMessages.h"
82 #include "WebNotificationClient.h"
83 #include "WebOpenPanelResultListener.h"
84 #include "WebPageCreationParameters.h"
85 #include "WebPageGroupProxy.h"
86 #include "WebPageMessages.h"
87 #include "WebPageProxyMessages.h"
88 #include "WebPlugInClient.h"
89 #include "WebPopupMenu.h"
90 #include "WebPreferencesDefinitions.h"
91 #include "WebPreferencesKeys.h"
92 #include "WebPreferencesStore.h"
93 #include "WebProcess.h"
94 #include "WebProcessProxyMessages.h"
95 #include "WebProgressTrackerClient.h"
96 #include "WebUndoStep.h"
97 #include "WebUserContentController.h"
98 #include <JavaScriptCore/APICast.h>
99 #include <WebCore/ArchiveResource.h>
100 #include <WebCore/Chrome.h>
101 #include <WebCore/ContextMenuController.h>
102 #include <WebCore/DatabaseManager.h>
103 #include <WebCore/DocumentFragment.h>
104 #include <WebCore/DocumentLoader.h>
105 #include <WebCore/DocumentMarkerController.h>
106 #include <WebCore/DragController.h>
107 #include <WebCore/DragData.h>
108 #include <WebCore/ElementIterator.h>
109 #include <WebCore/EventHandler.h>
110 #include <WebCore/FocusController.h>
111 #include <WebCore/FormState.h>
112 #include <WebCore/FrameLoadRequest.h>
113 #include <WebCore/FrameLoaderTypes.h>
114 #include <WebCore/FrameView.h>
115 #include <WebCore/HTMLFormElement.h>
116 #include <WebCore/HTMLInputElement.h>
117 #include <WebCore/HTMLPlugInElement.h>
118 #include <WebCore/HTMLPlugInImageElement.h>
119 #include <WebCore/HistoryController.h>
120 #include <WebCore/HistoryItem.h>
121 #include <WebCore/HitTestResult.h>
122 #include <WebCore/JSDOMWindow.h>
123 #include <WebCore/KeyboardEvent.h>
124 #include <WebCore/MIMETypeRegistry.h>
125 #include <WebCore/MainFrame.h>
126 #include <WebCore/MouseEvent.h>
127 #include <WebCore/Page.h>
128 #include <WebCore/PageThrottler.h>
129 #include <WebCore/PlatformKeyboardEvent.h>
130 #include <WebCore/PluginDocument.h>
131 #include <WebCore/PrintContext.h>
132 #include <WebCore/Range.h>
133 #include <WebCore/RenderLayer.h>
134 #include <WebCore/RenderTreeAsText.h>
135 #include <WebCore/RenderView.h>
136 #include <WebCore/ResourceBuffer.h>
137 #include <WebCore/ResourceRequest.h>
138 #include <WebCore/ResourceResponse.h>
139 #include <WebCore/RuntimeEnabledFeatures.h>
140 #include <WebCore/SchemeRegistry.h>
141 #include <WebCore/ScriptController.h>
142 #include <WebCore/SerializedScriptValue.h>
143 #include <WebCore/SessionID.h>
144 #include <WebCore/Settings.h>
145 #include <WebCore/ShadowRoot.h>
146 #include <WebCore/SharedBuffer.h>
147 #include <WebCore/SubframeLoader.h>
148 #include <WebCore/SubstituteData.h>
149 #include <WebCore/TextIterator.h>
150 #include <WebCore/UserInputBridge.h>
151 #include <WebCore/VisiblePosition.h>
152 #include <WebCore/VisibleUnits.h>
153 #include <WebCore/markup.h>
154 #include <bindings/ScriptValue.h>
155 #include <profiler/ProfilerDatabase.h>
156 #include <runtime/JSCInlines.h>
157 #include <runtime/JSCJSValue.h>
158 #include <runtime/JSLock.h>
159 #include <wtf/RunLoop.h>
160
161 #if ENABLE(MHTML)
162 #include <WebCore/MHTMLArchive.h>
163 #endif
164
165 #if ENABLE(BATTERY_STATUS)
166 #include "WebBatteryClient.h"
167 #endif
168
169 #if ENABLE(VIBRATION)
170 #include "WebVibrationClient.h"
171 #endif
172
173 #if ENABLE(PROXIMITY_EVENTS)
174 #include "WebDeviceProximityClient.h"
175 #endif
176
177 #if PLATFORM(COCOA)
178 #include "PDFPlugin.h"
179 #include "RemoteLayerTreeTransaction.h"
180 #include <WebCore/LegacyWebArchive.h>
181 #endif
182
183 #if PLATFORM(GTK)
184 #include <gtk/gtk.h>
185 #include "DataObjectGtk.h"
186 #include "WebPrintOperationGtk.h"
187 #endif
188
189 #if PLATFORM(IOS)
190 #include "WebVideoFullscreenManager.h"
191 #include <CoreGraphics/CoreGraphics.h>
192 #include <WebCore/Icon.h>
193 #endif
194
195 #ifndef NDEBUG
196 #include <wtf/RefCountedLeakCounter.h>
197 #endif
198
199 #if USE(COORDINATED_GRAPHICS)
200 #include "CoordinatedLayerTreeHostMessages.h"
201 #endif
202
203 using namespace JSC;
204 using namespace WebCore;
205
206 namespace WebKit {
207
208 class SendStopResponsivenessTimer {
209 public:
210     SendStopResponsivenessTimer(WebPage* page)
211         : m_page(page)
212     {
213     }
214     
215     ~SendStopResponsivenessTimer()
216     {
217         m_page->send(Messages::WebPageProxy::StopResponsivenessTimer());
218     }
219
220 private:
221     WebPage* m_page;
222 };
223
224 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, webPageCounter, ("WebPage"));
225
226 PassRefPtr<WebPage> WebPage::create(uint64_t pageID, const WebPageCreationParameters& parameters)
227 {
228     RefPtr<WebPage> page = adoptRef(new WebPage(pageID, parameters));
229
230     if (page->pageGroup()->isVisibleToInjectedBundle() && WebProcess::shared().injectedBundle())
231         WebProcess::shared().injectedBundle()->didCreatePage(page.get());
232
233     return page.release();
234 }
235
236 WebPage::WebPage(uint64_t pageID, const WebPageCreationParameters& parameters)
237     : m_pageID(pageID)
238     , m_viewSize(parameters.viewSize)
239     , m_hasSeenPlugin(false)
240     , m_useFixedLayout(false)
241     , m_drawsBackground(true)
242     , m_drawsTransparentBackground(false)
243     , m_isInRedo(false)
244     , m_isClosed(false)
245     , m_tabToLinks(false)
246     , m_asynchronousPluginInitializationEnabled(false)
247     , m_asynchronousPluginInitializationEnabledForAllPlugins(false)
248     , m_artificialPluginInitializationDelayEnabled(false)
249     , m_scrollingPerformanceLoggingEnabled(false)
250     , m_mainFrameIsScrollable(true)
251 #if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
252     , m_readyToFindPrimarySnapshottedPlugin(false)
253     , m_didFindPrimarySnapshottedPlugin(false)
254     , m_numberOfPrimarySnapshotDetectionAttempts(0)
255     , m_determinePrimarySnapshottedPlugInTimer(RunLoop::main(), this, &WebPage::determinePrimarySnapshottedPlugInTimerFired)
256 #endif
257 #if ENABLE(SERVICE_CONTROLS)
258     , m_serviceControlsEnabled(false)
259 #endif
260     , m_layerHostingMode(parameters.layerHostingMode)
261 #if PLATFORM(COCOA)
262     , m_pdfPluginEnabled(false)
263     , m_hasCachedWindowFrame(false)
264     , m_viewGestureGeometryCollector(*this)
265 #elif PLATFORM(GTK) && HAVE(ACCESSIBILITY)
266     , m_accessibilityObject(0)
267 #endif
268     , m_setCanStartMediaTimer(RunLoop::main(), this, &WebPage::setCanStartMediaTimerFired)
269     , m_sendDidUpdateViewStateTimer(RunLoop::main(), this, &WebPage::didUpdateViewStateTimerFired)
270     , m_formClient(std::make_unique<API::InjectedBundle::FormClient>())
271     , m_uiClient(std::make_unique<API::InjectedBundle::PageUIClient>())
272     , m_findController(this)
273 #if ENABLE(INPUT_TYPE_COLOR)
274     , m_activeColorChooser(0)
275 #endif
276     , m_userContentController(parameters.userContentControllerID ? WebUserContentController::getOrCreate(parameters.userContentControllerID) : nullptr)
277 #if ENABLE(GEOLOCATION)
278     , m_geolocationPermissionRequestManager(this)
279 #endif
280     , m_canRunBeforeUnloadConfirmPanel(parameters.canRunBeforeUnloadConfirmPanel)
281     , m_canRunModal(parameters.canRunModal)
282     , m_isRunningModal(false)
283     , m_cachedMainFrameIsPinnedToLeftSide(true)
284     , m_cachedMainFrameIsPinnedToRightSide(true)
285     , m_cachedMainFrameIsPinnedToTopSide(true)
286     , m_cachedMainFrameIsPinnedToBottomSide(true)
287     , m_canShortCircuitHorizontalWheelEvents(false)
288     , m_numWheelEventHandlers(0)
289     , m_cachedPageCount(0)
290     , m_autoSizingShouldExpandToViewHeight(false)
291 #if ENABLE(CONTEXT_MENUS)
292     , m_isShowingContextMenu(false)
293 #endif
294 #if PLATFORM(IOS)
295     , m_obscuredTopInset(0)
296     , m_hasReceivedVisibleContentRectsAfterDidCommitLoad(false)
297     , m_scaleWasSetByUIProcess(false)
298     , m_userHasChangedPageScaleFactor(false)
299     , m_userIsInteracting(false)
300     , m_hasPendingBlurNotification(false)
301     , m_useTestingViewportConfiguration(false)
302     , m_screenSize(parameters.screenSize)
303     , m_availableScreenSize(parameters.availableScreenSize)
304     , m_deviceOrientation(0)
305     , m_inDynamicSizeUpdate(false)
306 #endif
307     , m_inspectorClient(0)
308     , m_backgroundColor(Color::white)
309     , m_maximumRenderingSuppressionToken(0)
310     , m_scrollPinningBehavior(DoNotPin)
311     , m_useAsyncScrolling(false)
312     , m_viewState(parameters.viewState)
313     , m_processSuppressionDisabledByWebPreference("Process suppression is disabled.")
314     , m_pendingNavigationID(0)
315     , m_pageScaleWithoutThumbnailScale(1)
316     , m_thumbnailScale(1)
317 #if ENABLE(WEBGL)
318     , m_systemWebGLPolicy(WebGLAllowCreation)
319 #endif
320     , m_pageOverlayController(*this)
321 {
322     ASSERT(m_pageID);
323     // FIXME: This is a non-ideal location for this Setting and
324     // 4ms should be adopted project-wide now, https://bugs.webkit.org/show_bug.cgi?id=61214
325     Settings::setDefaultMinDOMTimerInterval(0.004);
326
327 #if PLATFORM(IOS)
328     Settings::setShouldManageAudioSessionCategory(true);
329 #endif
330
331     Page::PageClients pageClients;
332     pageClients.chromeClient = new WebChromeClient(this);
333 #if ENABLE(CONTEXT_MENUS)
334     pageClients.contextMenuClient = new WebContextMenuClient(this);
335 #endif
336     pageClients.editorClient = new WebEditorClient(this);
337 #if ENABLE(DRAG_SUPPORT)
338     pageClients.dragClient = new WebDragClient(this);
339 #endif
340     pageClients.backForwardClient = WebBackForwardListProxy::create(this);
341 #if ENABLE(INSPECTOR)
342     m_inspectorClient = new WebInspectorClient(this);
343     pageClients.inspectorClient = m_inspectorClient;
344 #endif
345 #if USE(AUTOCORRECTION_PANEL)
346     pageClients.alternativeTextClient = new WebAlternativeTextClient(this);
347 #endif
348     pageClients.plugInClient = new WebPlugInClient(this);
349     pageClients.loaderClientForMainFrame = new WebFrameLoaderClient;
350     pageClients.progressTrackerClient = new WebProgressTrackerClient(*this);
351
352     pageClients.userContentController = m_userContentController ? &m_userContentController->userContentController() : nullptr;
353     pageClients.visitedLinkStore = VisitedLinkTableController::getOrCreate(parameters.visitedLinkTableID);
354
355     m_page = std::make_unique<Page>(pageClients);
356
357     m_drawingArea = DrawingArea::create(this, parameters);
358     m_drawingArea->setPaintingEnabled(false);
359     m_pageOverlayController.initialize();
360
361 #if ENABLE(ASYNC_SCROLLING)
362     m_useAsyncScrolling = parameters.store.getBoolValueForKey(WebPreferencesKey::threadedScrollingEnabledKey());
363     if (!m_drawingArea->supportsAsyncScrolling())
364         m_useAsyncScrolling = false;
365     m_page->settings().setScrollingCoordinatorEnabled(m_useAsyncScrolling);
366 #endif
367
368     m_mainFrame = WebFrame::createWithCoreMainFrame(this, &m_page->mainFrame());
369
370 #if ENABLE(BATTERY_STATUS)
371     WebCore::provideBatteryTo(m_page.get(), new WebBatteryClient(this));
372 #endif
373 #if ENABLE(GEOLOCATION)
374     WebCore::provideGeolocationTo(m_page.get(), new WebGeolocationClient(this));
375 #endif
376 #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
377     WebCore::provideNotification(m_page.get(), new WebNotificationClient(this));
378 #endif
379 #if ENABLE(VIBRATION)
380     WebCore::provideVibrationTo(m_page.get(), new WebVibrationClient(this));
381 #endif
382 #if ENABLE(PROXIMITY_EVENTS)
383     WebCore::provideDeviceProximityTo(m_page.get(), new WebDeviceProximityClient(this));
384 #endif
385
386 #if ENABLE(REMOTE_INSPECTOR)
387     m_page->setRemoteInspectionAllowed(true);
388 #endif
389
390     m_page->setCanStartMedia(false);
391     m_mayStartMediaWhenInWindow = parameters.mayStartMediaWhenInWindow;
392
393     m_pageGroup = WebProcess::shared().webPageGroup(parameters.pageGroupData);
394     m_page->setGroupName(m_pageGroup->identifier());
395     m_page->setDeviceScaleFactor(parameters.deviceScaleFactor);
396 #if PLATFORM(IOS)
397     m_page->setTextAutosizingWidth(parameters.textAutosizingWidth);
398 #endif
399
400     updatePreferences(parameters.store);
401     platformInitialize();
402
403     setUseFixedLayout(parameters.useFixedLayout);
404
405     setDrawsBackground(parameters.drawsBackground);
406     setDrawsTransparentBackground(parameters.drawsTransparentBackground);
407
408     setUnderlayColor(parameters.underlayColor);
409
410     setPaginationMode(parameters.paginationMode);
411     setPaginationBehavesLikeColumns(parameters.paginationBehavesLikeColumns);
412     setPageLength(parameters.pageLength);
413     setGapBetweenPages(parameters.gapBetweenPages);
414
415     // If the page is created off-screen, its visibilityState should be prerender.
416     m_page->setViewState(m_viewState);
417     if (!isVisible())
418         m_page->setIsPrerender();
419     m_page->createPageThrottler();
420
421     updateIsInWindow(true);
422
423     setMinimumLayoutSize(parameters.minimumLayoutSize);
424     setAutoSizingShouldExpandToViewHeight(parameters.autoSizingShouldExpandToViewHeight);
425     
426     setScrollPinningBehavior(parameters.scrollPinningBehavior);
427     setBackgroundExtendsBeyondPage(parameters.backgroundExtendsBeyondPage);
428
429     setTopContentInset(parameters.topContentInset);
430
431     m_userAgent = parameters.userAgent;
432
433     WebBackForwardListProxy::setHighestItemIDFromUIProcess(parameters.highestUsedBackForwardItemID);
434     
435     if (!parameters.sessionState.isEmpty())
436         restoreSession(parameters.sessionState);
437
438     if (parameters.sessionID.isValid())
439         setSessionID(parameters.sessionID);
440
441     m_drawingArea->setPaintingEnabled(true);
442     
443     setMediaVolume(parameters.mediaVolume);
444
445     // We use the DidFirstVisuallyNonEmptyLayout milestone to determine when to unfreeze the layer tree.
446     m_page->addLayoutMilestones(DidFirstLayout | DidFirstVisuallyNonEmptyLayout);
447
448     WebProcess::shared().addMessageReceiver(Messages::WebPage::messageReceiverName(), m_pageID, *this);
449
450     // FIXME: This should be done in the object constructors, and the objects themselves should be message receivers.
451     WebProcess::shared().addMessageReceiver(Messages::DrawingArea::messageReceiverName(), m_pageID, *this);
452 #if USE(COORDINATED_GRAPHICS)
453     WebProcess::shared().addMessageReceiver(Messages::CoordinatedLayerTreeHost::messageReceiverName(), m_pageID, *this);
454 #endif
455 #if ENABLE(INSPECTOR)
456     WebProcess::shared().addMessageReceiver(Messages::WebInspector::messageReceiverName(), m_pageID, *this);
457 #endif
458 #if ENABLE(FULLSCREEN_API)
459     WebProcess::shared().addMessageReceiver(Messages::WebFullScreenManager::messageReceiverName(), m_pageID, *this);
460 #endif
461
462 #ifndef NDEBUG
463     webPageCounter.increment();
464 #endif
465
466 #if ENABLE(ASYNC_SCROLLING)
467     if (m_useAsyncScrolling)
468         WebProcess::shared().eventDispatcher().addScrollingTreeForPage(this);
469 #endif
470 }
471
472 void WebPage::reinitializeWebPage(const WebPageCreationParameters& parameters)
473 {
474     if (m_viewState != parameters.viewState)
475         setViewState(parameters.viewState);
476     if (m_layerHostingMode != parameters.layerHostingMode)
477         setLayerHostingMode(static_cast<unsigned>(parameters.layerHostingMode));
478 }
479
480 WebPage::~WebPage()
481 {
482     if (m_backForwardList)
483         m_backForwardList->detach();
484
485     ASSERT(!m_page);
486
487 #if ENABLE(ASYNC_SCROLLING)
488     if (m_useAsyncScrolling)
489         WebProcess::shared().eventDispatcher().removeScrollingTreeForPage(this);
490 #endif
491
492     m_sandboxExtensionTracker.invalidate();
493
494     for (auto* pluginView : m_pluginViews)
495         pluginView->webPageDestroyed();
496
497 #if !PLATFORM(IOS)
498     if (m_headerBanner)
499         m_headerBanner->detachFromPage();
500     if (m_footerBanner)
501         m_footerBanner->detachFromPage();
502 #endif // !PLATFORM(IOS)
503
504     WebProcess::shared().removeMessageReceiver(Messages::WebPage::messageReceiverName(), m_pageID);
505
506     // FIXME: This should be done in the object destructors, and the objects themselves should be message receivers.
507     WebProcess::shared().removeMessageReceiver(Messages::DrawingArea::messageReceiverName(), m_pageID);
508 #if USE(COORDINATED_GRAPHICS)
509     WebProcess::shared().removeMessageReceiver(Messages::CoordinatedLayerTreeHost::messageReceiverName(), m_pageID);
510 #endif
511 #if ENABLE(INSPECTOR)
512     WebProcess::shared().removeMessageReceiver(Messages::WebInspector::messageReceiverName(), m_pageID);
513 #endif
514 #if ENABLE(FULLSCREEN_API)
515     WebProcess::shared().removeMessageReceiver(Messages::WebFullScreenManager::messageReceiverName(), m_pageID);
516 #endif
517
518 #ifndef NDEBUG
519     webPageCounter.decrement();
520 #endif
521 }
522
523 void WebPage::dummy(bool&)
524 {
525 }
526
527 IPC::Connection* WebPage::messageSenderConnection()
528 {
529     return WebProcess::shared().parentProcessConnection();
530 }
531
532 uint64_t WebPage::messageSenderDestinationID()
533 {
534     return pageID();
535 }
536
537 #if ENABLE(CONTEXT_MENUS)
538 void WebPage::initializeInjectedBundleContextMenuClient(WKBundlePageContextMenuClientBase* client)
539 {
540     m_contextMenuClient.initialize(client);
541 }
542 #endif
543
544 void WebPage::initializeInjectedBundleEditorClient(WKBundlePageEditorClientBase* client)
545 {
546     m_editorClient.initialize(client);
547 }
548
549 void WebPage::setInjectedBundleFormClient(std::unique_ptr<API::InjectedBundle::FormClient> formClient)
550 {
551     if (!formClient) {
552         m_formClient = std::make_unique<API::InjectedBundle::FormClient>();
553         return;
554     }
555
556     m_formClient = std::move(formClient);
557 }
558
559 void WebPage::initializeInjectedBundleLoaderClient(WKBundlePageLoaderClientBase* client)
560 {
561     m_loaderClient.initialize(client);
562
563     // It would be nice to get rid of this code and transition all clients to using didLayout instead of
564     // didFirstLayoutInFrame and didFirstVisuallyNonEmptyLayoutInFrame. In the meantime, this is required
565     // for backwards compatibility.
566     LayoutMilestones milestones = 0;
567     if (client) {
568         if (m_loaderClient.client().didFirstLayoutForFrame)
569             milestones |= WebCore::DidFirstLayout;
570         if (m_loaderClient.client().didFirstVisuallyNonEmptyLayoutForFrame)
571             milestones |= WebCore::DidFirstVisuallyNonEmptyLayout;
572     }
573
574     if (milestones)
575         listenForLayoutMilestones(milestones);
576 }
577
578 void WebPage::initializeInjectedBundlePolicyClient(WKBundlePagePolicyClientBase* client)
579 {
580     m_policyClient.initialize(client);
581 }
582
583 void WebPage::initializeInjectedBundleResourceLoadClient(WKBundlePageResourceLoadClientBase* client)
584 {
585     m_resourceLoadClient.initialize(client);
586 }
587
588 void WebPage::setInjectedBundleUIClient(std::unique_ptr<API::InjectedBundle::PageUIClient> uiClient)
589 {
590     if (!uiClient) {
591         m_uiClient = std::make_unique<API::InjectedBundle::PageUIClient>();
592         return;
593     }
594
595     m_uiClient = std::move(uiClient);
596 }
597
598 #if ENABLE(FULLSCREEN_API)
599 void WebPage::initializeInjectedBundleFullScreenClient(WKBundlePageFullScreenClientBase* client)
600 {
601     m_fullScreenClient.initialize(client);
602 }
603 #endif
604
605 void WebPage::initializeInjectedBundleDiagnosticLoggingClient(WKBundlePageDiagnosticLoggingClientBase* client)
606 {
607     m_logDiagnosticMessageClient.initialize(client);
608 }
609
610 #if ENABLE(NETSCAPE_PLUGIN_API)
611 PassRefPtr<Plugin> WebPage::createPlugin(WebFrame* frame, HTMLPlugInElement* pluginElement, const Plugin::Parameters& parameters, String& newMIMEType)
612 {
613     String frameURLString = frame->coreFrame()->loader().documentLoader()->responseURL().string();
614     String pageURLString = m_page->mainFrame().loader().documentLoader()->responseURL().string();
615     PluginProcessType processType = pluginElement->displayState() == HTMLPlugInElement::WaitingForSnapshot ? PluginProcessTypeSnapshot : PluginProcessTypeNormal;
616
617     bool allowOnlyApplicationPlugins = !frame->coreFrame()->loader().subframeLoader().allowPlugins(NotAboutToInstantiatePlugin);
618
619     uint64_t pluginProcessToken;
620     uint32_t pluginLoadPolicy;
621     String unavailabilityDescription;
622     if (!sendSync(Messages::WebPageProxy::FindPlugin(parameters.mimeType, static_cast<uint32_t>(processType), parameters.url.string(), frameURLString, pageURLString, allowOnlyApplicationPlugins), Messages::WebPageProxy::FindPlugin::Reply(pluginProcessToken, newMIMEType, pluginLoadPolicy, unavailabilityDescription)))
623         return nullptr;
624
625     bool isBlockedPlugin = static_cast<PluginModuleLoadPolicy>(pluginLoadPolicy) == PluginModuleBlocked;
626
627     if (isBlockedPlugin || !pluginProcessToken) {
628 #if ENABLE(PDFKIT_PLUGIN)
629         String path = parameters.url.path();
630         if (shouldUsePDFPlugin() && (MIMETypeRegistry::isPDFOrPostScriptMIMEType(parameters.mimeType) || (parameters.mimeType.isEmpty() && (path.endsWith(".pdf", false) || path.endsWith(".ps", false))))) {
631             RefPtr<PDFPlugin> pdfPlugin = PDFPlugin::create(frame);
632             return pdfPlugin.release();
633         }
634 #else
635         UNUSED_PARAM(frame);
636 #endif
637     }
638
639     if (isBlockedPlugin) {
640         bool replacementObscured = false;
641         if (pluginElement->renderer()->isEmbeddedObject()) {
642             RenderEmbeddedObject* renderObject = toRenderEmbeddedObject(pluginElement->renderer());
643             renderObject->setPluginUnavailabilityReasonWithDescription(RenderEmbeddedObject::InsecurePluginVersion, unavailabilityDescription);
644             replacementObscured = renderObject->isReplacementObscured();
645             renderObject->setUnavailablePluginIndicatorIsHidden(replacementObscured);
646         }
647
648         send(Messages::WebPageProxy::DidBlockInsecurePluginVersion(parameters.mimeType, parameters.url.string(), frameURLString, pageURLString, replacementObscured));
649         return nullptr;
650     }
651
652     if (!pluginProcessToken)
653         return nullptr;
654
655     bool isRestartedProcess = (pluginElement->displayState() == HTMLPlugInElement::Restarting || pluginElement->displayState() == HTMLPlugInElement::RestartingWithPendingMouseClick);
656     return PluginProxy::create(pluginProcessToken, isRestartedProcess);
657 }
658
659 #endif // ENABLE(NETSCAPE_PLUGIN_API)
660
661 #if ENABLE(WEBGL) && !PLATFORM(COCOA)
662 WebCore::WebGLLoadPolicy WebPage::webGLPolicyForURL(WebFrame*, const String& /* url */)
663 {
664     return WebGLAllowCreation;
665 }
666
667 WebCore::WebGLLoadPolicy WebPage::resolveWebGLPolicyForURL(WebFrame*, const String& /* url */)
668 {
669     return WebGLAllowCreation;
670 }
671 #endif
672
673 EditorState WebPage::editorState() const
674 {
675     Frame& frame = m_page->focusController().focusedOrMainFrame();
676
677     EditorState result;
678
679     if (PluginView* pluginView = focusedPluginViewForFrame(frame)) {
680         if (!pluginView->getSelectionString().isNull()) {
681             result.selectionIsNone = false;
682             result.selectionIsRange = true;
683             result.isInPlugin = true;
684             return result;
685         }
686     }
687
688     const VisibleSelection& selection = frame.selection().selection();
689
690     result.selectionIsNone = selection.isNone();
691     result.selectionIsRange = selection.isRange();
692     result.isContentEditable = selection.isContentEditable();
693     result.isContentRichlyEditable = selection.isContentRichlyEditable();
694     result.isInPasswordField = selection.isInPasswordField();
695     result.hasComposition = frame.editor().hasComposition();
696     result.shouldIgnoreCompositionSelectionChange = frame.editor().ignoreCompositionSelectionChange();
697
698 #if PLATFORM(IOS)
699     if (frame.editor().hasComposition()) {
700         RefPtr<Range> compositionRange = frame.editor().compositionRange();
701         Vector<WebCore::SelectionRect> compositionRects;
702         compositionRange->collectSelectionRects(compositionRects);
703         if (compositionRects.size())
704             result.firstMarkedRect = compositionRects[0].rect();
705         if (compositionRects.size() > 1)
706             result.lastMarkedRect = compositionRects.last().rect();
707         else
708             result.lastMarkedRect = result.firstMarkedRect;
709         result.markedText = plainTextReplacingNoBreakSpace(compositionRange.get());
710     }
711     FrameView* view = frame.view();
712     if (selection.isCaret()) {
713         result.caretRectAtStart = view->contentsToRootView(frame.selection().absoluteCaretBounds());
714         result.caretRectAtEnd = result.caretRectAtStart;
715         // FIXME: The following check should take into account writing direction.
716         result.isReplaceAllowed = result.isContentEditable && atBoundaryOfGranularity(selection.start(), WordGranularity, DirectionForward);
717         result.wordAtSelection = plainTextReplacingNoBreakSpace(wordRangeFromPosition(selection.start()).get());
718         if (selection.isContentEditable())
719             charactersAroundPosition(selection.start(), result.characterAfterSelection, result.characterBeforeSelection, result.twoCharacterBeforeSelection);
720     } else if (selection.isRange()) {
721         result.caretRectAtStart = view->contentsToRootView(VisiblePosition(selection.start()).absoluteCaretBounds());
722         result.caretRectAtEnd = view->contentsToRootView(VisiblePosition(selection.end()).absoluteCaretBounds());
723         RefPtr<Range> selectedRange = selection.toNormalizedRange();
724         selectedRange->collectSelectionRects(result.selectionRects);
725         convertSelectionRectsToRootView(view, result.selectionRects);
726         String selectedText = plainTextReplacingNoBreakSpace(selectedRange.get(), TextIteratorDefaultBehavior, true);
727         // FIXME: We should disallow replace when the string contains only CJ characters.
728         result.isReplaceAllowed = result.isContentEditable && !result.isInPasswordField && !selectedText.containsOnlyWhitespace();
729         result.selectedTextLength = selectedText.length();
730         const int maxSelectedTextLength = 200;
731         if (selectedText.length() <= maxSelectedTextLength)
732             result.wordAtSelection = selectedText;
733     }
734 #endif
735
736 #if PLATFORM(GTK)
737     result.cursorRect = frame.selection().absoluteCaretBounds();
738 #endif
739
740     return result;
741 }
742
743 String WebPage::renderTreeExternalRepresentation() const
744 {
745     return externalRepresentation(m_mainFrame->coreFrame(), RenderAsTextBehaviorNormal);
746 }
747
748 String WebPage::renderTreeExternalRepresentationForPrinting() const
749 {
750     return externalRepresentation(m_mainFrame->coreFrame(), RenderAsTextPrintingMode);
751 }
752
753 uint64_t WebPage::renderTreeSize() const
754 {
755     if (!m_page)
756         return 0;
757     return m_page->renderTreeSize();
758 }
759
760 void WebPage::setTracksRepaints(bool trackRepaints)
761 {
762     if (FrameView* view = mainFrameView())
763         view->setTracksRepaints(trackRepaints);
764 }
765
766 bool WebPage::isTrackingRepaints() const
767 {
768     if (FrameView* view = mainFrameView())
769         return view->isTrackingRepaints();
770
771     return false;
772 }
773
774 void WebPage::resetTrackedRepaints()
775 {
776     if (FrameView* view = mainFrameView())
777         view->resetTrackedRepaints();
778 }
779
780 PassRefPtr<API::Array> WebPage::trackedRepaintRects()
781 {
782     FrameView* view = mainFrameView();
783     if (!view)
784         return API::Array::create();
785
786     Vector<RefPtr<API::Object>> repaintRects;
787     repaintRects.reserveInitialCapacity(view->trackedRepaintRects().size());
788
789     for (const auto& repaintRect : view->trackedRepaintRects())
790         repaintRects.uncheckedAppend(API::Rect::create(toAPI(repaintRect)));
791
792     return API::Array::create(std::move(repaintRects));
793 }
794
795 PluginView* WebPage::focusedPluginViewForFrame(Frame& frame)
796 {
797     if (!frame.document()->isPluginDocument())
798         return 0;
799
800     PluginDocument* pluginDocument = static_cast<PluginDocument*>(frame.document());
801
802     if (pluginDocument->focusedElement() != pluginDocument->pluginElement())
803         return 0;
804
805     PluginView* pluginView = static_cast<PluginView*>(pluginDocument->pluginWidget());
806     return pluginView;
807 }
808
809 PluginView* WebPage::pluginViewForFrame(Frame* frame)
810 {
811     if (!frame->document()->isPluginDocument())
812         return 0;
813
814     PluginDocument* pluginDocument = static_cast<PluginDocument*>(frame->document());
815     PluginView* pluginView = static_cast<PluginView*>(pluginDocument->pluginWidget());
816     return pluginView;
817 }
818
819 void WebPage::executeEditingCommand(const String& commandName, const String& argument)
820 {
821     Frame& frame = m_page->focusController().focusedOrMainFrame();
822
823     if (PluginView* pluginView = focusedPluginViewForFrame(frame)) {
824         pluginView->handleEditingCommand(commandName, argument);
825         return;
826     }
827     
828     frame.editor().command(commandName).execute(argument);
829 }
830
831 bool WebPage::isEditingCommandEnabled(const String& commandName)
832 {
833     Frame& frame = m_page->focusController().focusedOrMainFrame();
834
835     if (PluginView* pluginView = focusedPluginViewForFrame(frame))
836         return pluginView->isEditingCommandEnabled(commandName);
837     
838     Editor::Command command = frame.editor().command(commandName);
839     return command.isSupported() && command.isEnabled();
840 }
841     
842 void WebPage::clearMainFrameName()
843 {
844     if (Frame* frame = mainFrame())
845         frame->tree().clearName();
846 }
847
848 void WebPage::enterAcceleratedCompositingMode(GraphicsLayer* layer)
849 {
850     m_drawingArea->setRootCompositingLayer(layer);
851 }
852
853 void WebPage::exitAcceleratedCompositingMode()
854 {
855     m_drawingArea->setRootCompositingLayer(0);
856 }
857
858 void WebPage::close()
859 {
860     if (m_isClosed)
861         return;
862
863     m_isClosed = true;
864
865     // If there is still no URL, then we never loaded anything in this page, so nothing to report.
866     if (!mainWebFrame()->url().isEmpty())
867         reportUsedFeatures();
868
869     if (pageGroup()->isVisibleToInjectedBundle() && WebProcess::shared().injectedBundle())
870         WebProcess::shared().injectedBundle()->willDestroyPage(this);
871
872 #if ENABLE(INSPECTOR)
873     m_inspector = 0;
874 #endif
875 #if ENABLE(FULLSCREEN_API)
876     m_fullScreenManager = 0;
877 #endif
878
879     if (m_activePopupMenu) {
880         m_activePopupMenu->disconnectFromPage();
881         m_activePopupMenu = 0;
882     }
883
884     if (m_activeOpenPanelResultListener) {
885         m_activeOpenPanelResultListener->disconnectFromPage();
886         m_activeOpenPanelResultListener = 0;
887     }
888
889 #if ENABLE(INPUT_TYPE_COLOR)
890     if (m_activeColorChooser) {
891         m_activeColorChooser->disconnectFromPage();
892         m_activeColorChooser = 0;
893     }
894 #endif
895
896 #if PLATFORM(GTK)
897     if (m_printOperation) {
898         m_printOperation->disconnectFromPage();
899         m_printOperation = nullptr;
900     }
901 #endif
902
903     m_sandboxExtensionTracker.invalidate();
904
905 #if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
906     m_determinePrimarySnapshottedPlugInTimer.stop();
907 #endif
908
909 #if ENABLE(CONTEXT_MENUS)
910     m_contextMenuClient.initialize(0);
911 #endif
912     m_editorClient.initialize(0);
913     m_formClient = std::make_unique<API::InjectedBundle::FormClient>();
914     m_loaderClient.initialize(0);
915     m_policyClient.initialize(0);
916     m_resourceLoadClient.initialize(0);
917     m_uiClient = std::make_unique<API::InjectedBundle::PageUIClient>();
918 #if ENABLE(FULLSCREEN_API)
919     m_fullScreenClient.initialize(0);
920 #endif
921     m_logDiagnosticMessageClient.initialize(0);
922
923     m_printContext = nullptr;
924     m_mainFrame->coreFrame()->loader().detachFromParent();
925     m_page = nullptr;
926     m_drawingArea = nullptr;
927
928     bool isRunningModal = m_isRunningModal;
929     m_isRunningModal = false;
930
931     // The WebPage can be destroyed by this call.
932     WebProcess::shared().removeWebPage(m_pageID);
933
934     if (isRunningModal)
935         RunLoop::main().stop();
936 }
937
938 void WebPage::tryClose()
939 {
940     SendStopResponsivenessTimer stopper(this);
941
942     if (!corePage()->userInputBridge().tryClosePage()) {
943         send(Messages::WebPageProxy::StopResponsivenessTimer());
944         return;
945     }
946
947     send(Messages::WebPageProxy::ClosePage(true));
948 }
949
950 void WebPage::sendClose()
951 {
952     send(Messages::WebPageProxy::ClosePage(false));
953 }
954
955 void WebPage::loadURLInFrame(const String& url, uint64_t frameID)
956 {
957     WebFrame* frame = WebProcess::shared().webFrame(frameID);
958     if (!frame)
959         return;
960
961     frame->coreFrame()->loader().load(FrameLoadRequest(frame->coreFrame(), ResourceRequest(URL(URL(), url))));
962 }
963
964 void WebPage::loadRequest(uint64_t navigationID, const ResourceRequest& request, const SandboxExtension::Handle& sandboxExtensionHandle, IPC::MessageDecoder& decoder)
965 {
966     SendStopResponsivenessTimer stopper(this);
967
968     RefPtr<API::Object> userData;
969     InjectedBundleUserMessageDecoder userMessageDecoder(userData);
970     if (!decoder.decode(userMessageDecoder))
971         return;
972
973     m_pendingNavigationID = navigationID;
974
975     m_sandboxExtensionTracker.beginLoad(m_mainFrame.get(), sandboxExtensionHandle);
976
977     // Let the InjectedBundle know we are about to start the load, passing the user data from the UIProcess
978     // to all the client to set up any needed state.
979     m_loaderClient.willLoadURLRequest(this, request, userData.get());
980
981     // Initate the load in WebCore.
982     corePage()->userInputBridge().loadRequest(FrameLoadRequest(m_mainFrame->coreFrame(), request));
983
984     ASSERT(!m_pendingNavigationID);
985 }
986
987 void WebPage::loadDataImpl(uint64_t navigationID, PassRefPtr<SharedBuffer> sharedBuffer, const String& MIMEType, const String& encodingName, const URL& baseURL, const URL& unreachableURL, IPC::MessageDecoder& decoder)
988 {
989     SendStopResponsivenessTimer stopper(this);
990
991     RefPtr<API::Object> userData;
992     InjectedBundleUserMessageDecoder userMessageDecoder(userData);
993     if (!decoder.decode(userMessageDecoder))
994         return;
995
996     m_pendingNavigationID = navigationID;
997
998     ResourceRequest request(baseURL);
999     SubstituteData substituteData(sharedBuffer, MIMEType, encodingName, unreachableURL);
1000
1001     // Let the InjectedBundle know we are about to start the load, passing the user data from the UIProcess
1002     // to all the client to set up any needed state.
1003     m_loaderClient.willLoadDataRequest(this, request, const_cast<SharedBuffer*>(substituteData.content()), substituteData.mimeType(), substituteData.textEncoding(), substituteData.failingURL(), userData.get());
1004
1005     // Initate the load in WebCore.
1006     m_mainFrame->coreFrame()->loader().load(FrameLoadRequest(m_mainFrame->coreFrame(), request, substituteData));
1007 }
1008
1009 void WebPage::loadString(uint64_t navigationID, const String& htmlString, const String& MIMEType, const URL& baseURL, const URL& unreachableURL, IPC::MessageDecoder& decoder)
1010 {
1011     if (!htmlString.isNull() && htmlString.is8Bit()) {
1012         RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(htmlString.characters8()), htmlString.length() * sizeof(LChar));
1013         loadDataImpl(navigationID, sharedBuffer, MIMEType, ASCIILiteral("latin1"), baseURL, unreachableURL, decoder);
1014     } else {
1015         RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(htmlString.characters16()), htmlString.length() * sizeof(UChar));
1016         loadDataImpl(navigationID, sharedBuffer, MIMEType, ASCIILiteral("utf-16"), baseURL, unreachableURL, decoder);
1017     }
1018 }
1019
1020 void WebPage::loadData(const IPC::DataReference& data, const String& MIMEType, const String& encodingName, const String& baseURLString, IPC::MessageDecoder& decoder)
1021 {
1022     RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(data.data()), data.size());
1023     URL baseURL = baseURLString.isEmpty() ? blankURL() : URL(URL(), baseURLString);
1024     loadDataImpl(0, sharedBuffer, MIMEType, encodingName, baseURL, URL(), decoder);
1025 }
1026
1027 void WebPage::loadHTMLString(uint64_t navigationID, const String& htmlString, const String& baseURLString, IPC::MessageDecoder& decoder)
1028 {
1029     URL baseURL = baseURLString.isEmpty() ? blankURL() : URL(URL(), baseURLString);
1030     loadString(navigationID, htmlString, ASCIILiteral("text/html"), baseURL, URL(), decoder);
1031 }
1032
1033 void WebPage::loadAlternateHTMLString(const String& htmlString, const String& baseURLString, const String& unreachableURLString, IPC::MessageDecoder& decoder)
1034 {
1035     URL baseURL = baseURLString.isEmpty() ? blankURL() : URL(URL(), baseURLString);
1036     URL unreachableURL = unreachableURLString.isEmpty() ? URL() : URL(URL(), unreachableURLString);
1037     loadString(0, htmlString, ASCIILiteral("text/html"), baseURL, unreachableURL, decoder);
1038 }
1039
1040 void WebPage::loadPlainTextString(const String& string, IPC::MessageDecoder& decoder)
1041 {
1042     loadString(0, string, ASCIILiteral("text/plain"), blankURL(), URL(), decoder);
1043 }
1044
1045 void WebPage::loadWebArchiveData(const IPC::DataReference& webArchiveData, IPC::MessageDecoder& decoder)
1046 {
1047     RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(webArchiveData.data()), webArchiveData.size() * sizeof(uint8_t));
1048     loadDataImpl(0, sharedBuffer, ASCIILiteral("application/x-webarchive"), ASCIILiteral("utf-16"), blankURL(), URL(), decoder);
1049 }
1050
1051 void WebPage::stopLoadingFrame(uint64_t frameID)
1052 {
1053     WebFrame* frame = WebProcess::shared().webFrame(frameID);
1054     if (!frame)
1055         return;
1056
1057     corePage()->userInputBridge().stopLoadingFrame(frame->coreFrame());
1058 }
1059
1060 void WebPage::stopLoading()
1061 {
1062     SendStopResponsivenessTimer stopper(this);
1063
1064     corePage()->userInputBridge().stopLoadingFrame(m_mainFrame->coreFrame());
1065 }
1066
1067 bool WebPage::defersLoading() const
1068 {
1069     return m_page->defersLoading();
1070 }
1071
1072 void WebPage::setDefersLoading(bool defersLoading)
1073 {
1074     m_page->setDefersLoading(defersLoading);
1075 }
1076
1077 void WebPage::reload(uint64_t navigationID, bool reloadFromOrigin, const SandboxExtension::Handle& sandboxExtensionHandle)
1078 {
1079     SendStopResponsivenessTimer stopper(this);
1080
1081     ASSERT(!m_pendingNavigationID);
1082     m_pendingNavigationID = navigationID;
1083
1084     m_sandboxExtensionTracker.beginLoad(m_mainFrame.get(), sandboxExtensionHandle);
1085     corePage()->userInputBridge().reloadFrame(m_mainFrame->coreFrame(), reloadFromOrigin);
1086 }
1087
1088 void WebPage::goForward(uint64_t navigationID, uint64_t backForwardItemID)
1089 {
1090     SendStopResponsivenessTimer stopper(this);
1091
1092     HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID);
1093     ASSERT(item);
1094     if (!item)
1095         return;
1096
1097     ASSERT(!m_pendingNavigationID);
1098     if (!item->isInPageCache())
1099         m_pendingNavigationID = navigationID;
1100
1101     m_page->goToItem(item, FrameLoadType::Forward);
1102 }
1103
1104 void WebPage::goBack(uint64_t navigationID, uint64_t backForwardItemID)
1105 {
1106     SendStopResponsivenessTimer stopper(this);
1107
1108     HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID);
1109     ASSERT(item);
1110     if (!item)
1111         return;
1112
1113     ASSERT(!m_pendingNavigationID);
1114     if (!item->isInPageCache())
1115         m_pendingNavigationID = navigationID;
1116
1117     m_page->goToItem(item, FrameLoadType::Back);
1118 }
1119
1120 void WebPage::goToBackForwardItem(uint64_t navigationID, uint64_t backForwardItemID)
1121 {
1122     SendStopResponsivenessTimer stopper(this);
1123
1124     HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID);
1125     ASSERT(item);
1126     if (!item)
1127         return;
1128
1129     ASSERT(!m_pendingNavigationID);
1130     if (!item->isInPageCache())
1131         m_pendingNavigationID = navigationID;
1132
1133     m_page->goToItem(item, FrameLoadType::IndexedBackForward);
1134 }
1135
1136 void WebPage::tryRestoreScrollPosition()
1137 {
1138     m_page->mainFrame().loader().history().restoreScrollPositionAndViewState();
1139 }
1140
1141 void WebPage::layoutIfNeeded()
1142 {
1143     if (m_mainFrame->coreFrame()->view())
1144         m_mainFrame->coreFrame()->view()->updateLayoutAndStyleIfNeededRecursive();
1145 }
1146
1147 WebPage* WebPage::fromCorePage(Page* page)
1148 {
1149     return static_cast<WebChromeClient&>(page->chrome().client()).page();
1150 }
1151
1152 void WebPage::setSize(const WebCore::IntSize& viewSize)
1153 {
1154     if (m_viewSize == viewSize)
1155         return;
1156
1157     FrameView* view = m_page->mainFrame().view();
1158     view->resize(viewSize);
1159     m_drawingArea->setNeedsDisplay();
1160     
1161     m_viewSize = viewSize;
1162
1163 #if USE(TILED_BACKING_STORE)
1164     if (view->useFixedLayout())
1165         sendViewportAttributesChanged();
1166 #endif
1167
1168     m_pageOverlayController.didChangeViewSize();
1169 }
1170
1171 #if USE(TILED_BACKING_STORE)
1172 void WebPage::setFixedVisibleContentRect(const IntRect& rect)
1173 {
1174     ASSERT(m_useFixedLayout);
1175
1176     m_page->mainFrame().view()->setFixedVisibleContentRect(rect);
1177 }
1178
1179 void WebPage::sendViewportAttributesChanged()
1180 {
1181     ASSERT(m_useFixedLayout);
1182
1183     // Viewport properties have no impact on zero sized fixed viewports.
1184     if (m_viewSize.isEmpty())
1185         return;
1186
1187     // Recalculate the recommended layout size, when the available size (device pixel) changes.
1188     Settings& settings = m_page->settings();
1189
1190     int minimumLayoutFallbackWidth = std::max(settings.layoutFallbackWidth(), m_viewSize.width());
1191
1192     // If unset  we use the viewport dimensions. This fits with the behavior of desktop browsers.
1193     int deviceWidth = (settings.deviceWidth() > 0) ? settings.deviceWidth() : m_viewSize.width();
1194     int deviceHeight = (settings.deviceHeight() > 0) ? settings.deviceHeight() : m_viewSize.height();
1195
1196     ViewportAttributes attr = computeViewportAttributes(m_page->viewportArguments(), minimumLayoutFallbackWidth, deviceWidth, deviceHeight, 1, m_viewSize);
1197
1198     FrameView* view = m_page->mainFrame().view();
1199
1200     // If no layout was done yet set contentFixedOrigin to (0,0).
1201     IntPoint contentFixedOrigin = view->didFirstLayout() ? view->fixedVisibleContentRect().location() : IntPoint();
1202
1203     // Put the width and height to the viewport width and height. In css units however.
1204     // Use FloatSize to avoid truncated values during scale.
1205     FloatSize contentFixedSize = m_viewSize;
1206
1207 #if ENABLE(CSS_DEVICE_ADAPTATION)
1208     // CSS viewport descriptors might be applied to already affected viewport size
1209     // if the page enables/disables stylesheets, so need to keep initial viewport size.
1210     view->setInitialViewportSize(roundedIntSize(contentFixedSize));
1211 #endif
1212
1213     contentFixedSize.scale(1 / attr.initialScale);
1214     setFixedVisibleContentRect(IntRect(contentFixedOrigin, roundedIntSize(contentFixedSize)));
1215
1216     attr.initialScale = m_page->viewportArguments().zoom; // Resets auto (-1) if no value was set by user.
1217
1218     // This also takes care of the relayout.
1219     setFixedLayoutSize(roundedIntSize(attr.layoutSize));
1220
1221     send(Messages::WebPageProxy::DidChangeViewportProperties(attr));
1222 }
1223 #endif
1224
1225 void WebPage::scrollMainFrameIfNotAtMaxScrollPosition(const IntSize& scrollOffset)
1226 {
1227     FrameView* frameView = m_page->mainFrame().view();
1228
1229     IntPoint scrollPosition = frameView->scrollPosition();
1230     IntPoint maximumScrollPosition = frameView->maximumScrollPosition();
1231
1232     // If the current scroll position in a direction is the max scroll position 
1233     // we don't want to scroll at all.
1234     IntSize newScrollOffset;
1235     if (scrollPosition.x() < maximumScrollPosition.x())
1236         newScrollOffset.setWidth(scrollOffset.width());
1237     if (scrollPosition.y() < maximumScrollPosition.y())
1238         newScrollOffset.setHeight(scrollOffset.height());
1239
1240     if (newScrollOffset.isZero())
1241         return;
1242
1243     frameView->setScrollPosition(frameView->scrollPosition() + newScrollOffset);
1244 }
1245
1246 void WebPage::drawRect(GraphicsContext& graphicsContext, const IntRect& rect)
1247 {
1248     GraphicsContextStateSaver stateSaver(graphicsContext);
1249     graphicsContext.clip(rect);
1250
1251     m_mainFrame->coreFrame()->view()->paint(&graphicsContext, rect);
1252 }
1253
1254 double WebPage::textZoomFactor() const
1255 {
1256     Frame* frame = m_mainFrame->coreFrame();
1257     if (!frame)
1258         return 1;
1259     return frame->textZoomFactor();
1260 }
1261
1262 void WebPage::setTextZoomFactor(double zoomFactor)
1263 {
1264     PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame());
1265     if (pluginView && pluginView->handlesPageScaleFactor())
1266         return;
1267
1268     Frame* frame = m_mainFrame->coreFrame();
1269     if (!frame)
1270         return;
1271     frame->setTextZoomFactor(static_cast<float>(zoomFactor));
1272 }
1273
1274 double WebPage::pageZoomFactor() const
1275 {
1276     PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame());
1277     if (pluginView && pluginView->handlesPageScaleFactor())
1278         return pluginView->pageScaleFactor();
1279
1280     Frame* frame = m_mainFrame->coreFrame();
1281     if (!frame)
1282         return 1;
1283     return frame->pageZoomFactor();
1284 }
1285
1286 void WebPage::setPageZoomFactor(double zoomFactor)
1287 {
1288     PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame());
1289     if (pluginView && pluginView->handlesPageScaleFactor()) {
1290         pluginView->setPageScaleFactor(zoomFactor, IntPoint());
1291         return;
1292     }
1293
1294     Frame* frame = m_mainFrame->coreFrame();
1295     if (!frame)
1296         return;
1297     frame->setPageZoomFactor(static_cast<float>(zoomFactor));
1298 }
1299
1300 void WebPage::setPageAndTextZoomFactors(double pageZoomFactor, double textZoomFactor)
1301 {
1302     PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame());
1303     if (pluginView && pluginView->handlesPageScaleFactor()) {
1304         pluginView->setPageScaleFactor(pageZoomFactor, IntPoint());
1305         return;
1306     }
1307
1308     Frame* frame = m_mainFrame->coreFrame();
1309     if (!frame)
1310         return;
1311     return frame->setPageAndTextZoomFactors(static_cast<float>(pageZoomFactor), static_cast<float>(textZoomFactor));
1312 }
1313
1314 void WebPage::windowScreenDidChange(uint64_t displayID)
1315 {
1316     m_page->chrome().windowScreenDidChange(static_cast<PlatformDisplayID>(displayID));
1317 }
1318
1319 void WebPage::scalePage(double scale, const IntPoint& origin)
1320 {
1321     bool willChangeScaleFactor = scale != pageScaleFactor();
1322
1323 #if PLATFORM(IOS)
1324     if (willChangeScaleFactor) {
1325         if (!m_inDynamicSizeUpdate)
1326             m_dynamicSizeUpdateHistory.clear();
1327         m_scaleWasSetByUIProcess = false;
1328     }
1329 #endif
1330     PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame());
1331     if (pluginView && pluginView->handlesPageScaleFactor()) {
1332         pluginView->setPageScaleFactor(scale, origin);
1333         return;
1334     }
1335
1336     m_page->setPageScaleFactor(scale, origin);
1337
1338     // We can't early return before setPageScaleFactor because the origin might be different.
1339     if (!willChangeScaleFactor)
1340         return;
1341
1342     for (auto* pluginView : m_pluginViews)
1343         pluginView->pageScaleFactorDidChange();
1344
1345     if (m_drawingArea->layerTreeHost())
1346         m_drawingArea->layerTreeHost()->deviceOrPageScaleFactorChanged();
1347
1348     send(Messages::WebPageProxy::PageScaleFactorDidChange(scale));
1349 }
1350
1351 void WebPage::scalePageInViewCoordinates(double scale, IntPoint centerInViewCoordinates)
1352 {
1353     if (scale == pageScaleFactor())
1354         return;
1355
1356     IntPoint scrollPositionAtNewScale = mainFrameView()->rootViewToContents(-centerInViewCoordinates);
1357     double scaleRatio = scale / pageScaleFactor();
1358     scrollPositionAtNewScale.scale(scaleRatio, scaleRatio);
1359     scalePage(scale, scrollPositionAtNewScale);
1360 }
1361
1362 double WebPage::pageScaleFactor() const
1363 {
1364     PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame());
1365     if (pluginView && pluginView->handlesPageScaleFactor())
1366         return pluginView->pageScaleFactor();
1367
1368     return m_page->pageScaleFactor();
1369 }
1370
1371 void WebPage::setDeviceScaleFactor(float scaleFactor)
1372 {
1373     if (scaleFactor == m_page->deviceScaleFactor())
1374         return;
1375
1376     m_page->setDeviceScaleFactor(scaleFactor);
1377
1378     // Tell all our plug-in views that the device scale factor changed.
1379 #if PLATFORM(MAC)
1380     for (auto* pluginView : m_pluginViews)
1381         pluginView->setDeviceScaleFactor(scaleFactor);
1382
1383     updateHeaderAndFooterLayersForDeviceScaleChange(scaleFactor);
1384 #endif
1385
1386     if (m_findController.isShowingOverlay()) {
1387         // We must have updated layout to get the selection rects right.
1388         layoutIfNeeded();
1389         m_findController.deviceScaleFactorDidChange();
1390     }
1391
1392     if (m_drawingArea->layerTreeHost())
1393         m_drawingArea->layerTreeHost()->deviceOrPageScaleFactorChanged();
1394
1395     m_pageOverlayController.didChangeDeviceScaleFactor();
1396 }
1397
1398 float WebPage::deviceScaleFactor() const
1399 {
1400     return m_page->deviceScaleFactor();
1401 }
1402
1403 void WebPage::setUseFixedLayout(bool fixed)
1404 {
1405     // Do not overwrite current settings if initially setting it to false.
1406     if (m_useFixedLayout == fixed)
1407         return;
1408     m_useFixedLayout = fixed;
1409
1410 #if !PLATFORM(IOS)
1411     m_page->settings().setFixedElementsLayoutRelativeToFrame(fixed);
1412 #endif
1413 #if USE(COORDINATED_GRAPHICS)
1414     m_page->settings().setAcceleratedCompositingForFixedPositionEnabled(fixed);
1415     m_page->settings().setFixedPositionCreatesStackingContext(fixed);
1416     m_page->settings().setDelegatesPageScaling(fixed);
1417     m_page->settings().setScrollingCoordinatorEnabled(fixed);
1418 #endif
1419
1420 #if USE(TILED_BACKING_STORE) && ENABLE(SMOOTH_SCROLLING)
1421     // Delegated scrolling will be enabled when the FrameView is created if fixed layout is enabled.
1422     // Ensure we don't do animated scrolling in the WebProcess in that case.
1423     m_page->settings().setScrollAnimatorEnabled(!fixed);
1424 #endif
1425
1426     FrameView* view = mainFrameView();
1427     if (!view)
1428         return;
1429
1430 #if USE(TILED_BACKING_STORE)
1431     view->setDelegatesScrolling(fixed);
1432     view->setPaintsEntireContents(fixed);
1433 #endif
1434     view->setUseFixedLayout(fixed);
1435     if (!fixed)
1436         setFixedLayoutSize(IntSize());
1437 }
1438
1439 void WebPage::setFixedLayoutSize(const IntSize& size)
1440 {
1441     FrameView* view = mainFrameView();
1442     if (!view || view->fixedLayoutSize() == size)
1443         return;
1444
1445     view->setFixedLayoutSize(size);
1446 }
1447
1448 void WebPage::listenForLayoutMilestones(uint32_t milestones)
1449 {
1450     if (!m_page)
1451         return;
1452     m_page->addLayoutMilestones(static_cast<LayoutMilestones>(milestones));
1453 }
1454
1455 void WebPage::setSuppressScrollbarAnimations(bool suppressAnimations)
1456 {
1457     m_page->setShouldSuppressScrollbarAnimations(suppressAnimations);
1458 }
1459     
1460 void WebPage::setEnableVerticalRubberBanding(bool enableVerticalRubberBanding)
1461 {
1462     m_page->setVerticalScrollElasticity(enableVerticalRubberBanding ? ScrollElasticityAllowed : ScrollElasticityNone);
1463 }
1464     
1465 void WebPage::setEnableHorizontalRubberBanding(bool enableHorizontalRubberBanding)
1466 {
1467     m_page->setHorizontalScrollElasticity(enableHorizontalRubberBanding ? ScrollElasticityAllowed : ScrollElasticityNone);
1468 }
1469
1470 void WebPage::setBackgroundExtendsBeyondPage(bool backgroundExtendsBeyondPage)
1471 {
1472     if (m_page->settings().backgroundShouldExtendBeyondPage() != backgroundExtendsBeyondPage)
1473         m_page->settings().setBackgroundShouldExtendBeyondPage(backgroundExtendsBeyondPage);
1474 }
1475
1476 void WebPage::setPaginationMode(uint32_t mode)
1477 {
1478     Pagination pagination = m_page->pagination();
1479     pagination.mode = static_cast<Pagination::Mode>(mode);
1480     m_page->setPagination(pagination);
1481 }
1482
1483 void WebPage::setPaginationBehavesLikeColumns(bool behavesLikeColumns)
1484 {
1485     Pagination pagination = m_page->pagination();
1486     pagination.behavesLikeColumns = behavesLikeColumns;
1487     m_page->setPagination(pagination);
1488 }
1489
1490 void WebPage::setPageLength(double pageLength)
1491 {
1492     Pagination pagination = m_page->pagination();
1493     pagination.pageLength = pageLength;
1494     m_page->setPagination(pagination);
1495 }
1496
1497 void WebPage::setGapBetweenPages(double gap)
1498 {
1499     Pagination pagination = m_page->pagination();
1500     pagination.gap = gap;
1501     m_page->setPagination(pagination);
1502 }
1503
1504 void WebPage::postInjectedBundleMessage(const String& messageName, IPC::MessageDecoder& decoder)
1505 {
1506     InjectedBundle* injectedBundle = WebProcess::shared().injectedBundle();
1507     if (!injectedBundle)
1508         return;
1509
1510     RefPtr<API::Object> messageBody;
1511     InjectedBundleUserMessageDecoder messageBodyDecoder(messageBody);
1512     if (!decoder.decode(messageBodyDecoder))
1513         return;
1514
1515     injectedBundle->didReceiveMessageToPage(this, messageName, messageBody.get());
1516 }
1517
1518 void WebPage::installPageOverlay(PassRefPtr<PageOverlay> pageOverlay, PageOverlay::FadeMode fadeMode)
1519 {
1520     m_pageOverlayController.installPageOverlay(pageOverlay, fadeMode);
1521 }
1522
1523 void WebPage::uninstallPageOverlay(PageOverlay* pageOverlay, PageOverlay::FadeMode fadeMode)
1524 {
1525     m_pageOverlayController.uninstallPageOverlay(pageOverlay, fadeMode);
1526 }
1527
1528 #if !PLATFORM(IOS)
1529 void WebPage::setHeaderPageBanner(PassRefPtr<PageBanner> pageBanner)
1530 {
1531     if (m_headerBanner)
1532         m_headerBanner->detachFromPage();
1533
1534     m_headerBanner = pageBanner;
1535
1536     if (m_headerBanner)
1537         m_headerBanner->addToPage(PageBanner::Header, this);
1538 }
1539
1540 PageBanner* WebPage::headerPageBanner()
1541 {
1542     return m_headerBanner.get();
1543 }
1544
1545 void WebPage::setFooterPageBanner(PassRefPtr<PageBanner> pageBanner)
1546 {
1547     if (m_footerBanner)
1548         m_footerBanner->detachFromPage();
1549
1550     m_footerBanner = pageBanner;
1551
1552     if (m_footerBanner)
1553         m_footerBanner->addToPage(PageBanner::Footer, this);
1554 }
1555
1556 PageBanner* WebPage::footerPageBanner()
1557 {
1558     return m_footerBanner.get();
1559 }
1560
1561 void WebPage::hidePageBanners()
1562 {
1563     if (m_headerBanner)
1564         m_headerBanner->hide();
1565     if (m_footerBanner)
1566         m_footerBanner->hide();
1567 }
1568
1569 void WebPage::showPageBanners()
1570 {
1571     if (m_headerBanner)
1572         m_headerBanner->showIfHidden();
1573     if (m_footerBanner)
1574         m_footerBanner->showIfHidden();
1575 }
1576 #endif // !PLATFORM(IOS)
1577
1578 void WebPage::takeSnapshot(IntRect snapshotRect, IntSize bitmapSize, uint32_t options, uint64_t callbackID)
1579 {
1580     SnapshotOptions snapshotOptions = static_cast<SnapshotOptions>(options);
1581     snapshotOptions |= SnapshotOptionsShareable;
1582
1583     RefPtr<WebImage> image = snapshotAtSize(snapshotRect, bitmapSize, snapshotOptions);
1584
1585     ShareableBitmap::Handle handle;
1586     if (image)
1587         image->bitmap()->createHandle(handle, SharedMemory::ReadOnly);
1588
1589     send(Messages::WebPageProxy::ImageCallback(handle, callbackID));
1590 }
1591
1592 PassRefPtr<WebImage> WebPage::scaledSnapshotWithOptions(const IntRect& rect, double additionalScaleFactor, SnapshotOptions options)
1593 {
1594     IntRect snapshotRect = rect;
1595     if (options & SnapshotOptionsRespectDrawingAreaTransform)
1596         snapshotRect = m_drawingArea->rootLayerTransform().inverse().mapRect(snapshotRect);
1597
1598     IntSize bitmapSize = snapshotRect.size();
1599     double scaleFactor = additionalScaleFactor;
1600     if (!(options & SnapshotOptionsExcludeDeviceScaleFactor))
1601         scaleFactor *= corePage()->deviceScaleFactor();
1602     bitmapSize.scale(scaleFactor);
1603
1604     return snapshotAtSize(rect, bitmapSize, options);
1605 }
1606
1607 PassRefPtr<WebImage> WebPage::snapshotAtSize(const IntRect& rect, const IntSize& bitmapSize, SnapshotOptions options)
1608 {
1609     Frame* coreFrame = m_mainFrame->coreFrame();
1610     if (!coreFrame)
1611         return nullptr;
1612
1613     FrameView* frameView = coreFrame->view();
1614     if (!frameView)
1615         return nullptr;
1616
1617     IntRect snapshotRect = rect;
1618     if (options & SnapshotOptionsRespectDrawingAreaTransform)
1619         snapshotRect = m_drawingArea->rootLayerTransform().inverse().mapRect(snapshotRect);
1620
1621     float horizontalScaleFactor = static_cast<float>(bitmapSize.width()) / rect.width();
1622     float verticalScaleFactor = static_cast<float>(bitmapSize.height()) / rect.height();
1623     float scaleFactor = std::max(horizontalScaleFactor, verticalScaleFactor);
1624
1625     RefPtr<WebImage> snapshot = WebImage::create(bitmapSize, snapshotOptionsToImageOptions(options));
1626     if (!snapshot->bitmap())
1627         return nullptr;
1628
1629     auto graphicsContext = snapshot->bitmap()->createGraphicsContext();
1630
1631     graphicsContext->fillRect(IntRect(IntPoint(), bitmapSize), frameView->baseBackgroundColor(), ColorSpaceDeviceRGB);
1632
1633     if (!(options & SnapshotOptionsExcludeDeviceScaleFactor)) {
1634         double deviceScaleFactor = corePage()->deviceScaleFactor();
1635         graphicsContext->applyDeviceScaleFactor(deviceScaleFactor);
1636         scaleFactor /= deviceScaleFactor;
1637     }
1638
1639     graphicsContext->scale(FloatSize(scaleFactor, scaleFactor));
1640     graphicsContext->translate(-snapshotRect.x(), -snapshotRect.y());
1641
1642     FrameView::SelectionInSnapshot shouldPaintSelection = FrameView::IncludeSelection;
1643     if (options & SnapshotOptionsExcludeSelectionHighlighting)
1644         shouldPaintSelection = FrameView::ExcludeSelection;
1645
1646     FrameView::CoordinateSpaceForSnapshot coordinateSpace = FrameView::DocumentCoordinates;
1647     if (options & SnapshotOptionsInViewCoordinates)
1648         coordinateSpace = FrameView::ViewCoordinates;
1649
1650     frameView->paintContentsForSnapshot(graphicsContext.get(), snapshotRect, shouldPaintSelection, coordinateSpace);
1651
1652     if (options & SnapshotOptionsPaintSelectionRectangle) {
1653         FloatRect selectionRectangle = m_mainFrame->coreFrame()->selection().selectionBounds();
1654         graphicsContext->setStrokeColor(Color(0xFF, 0, 0), ColorSpaceDeviceRGB);
1655         graphicsContext->strokeRect(selectionRectangle, 1);
1656     }
1657     
1658     return snapshot.release();
1659 }
1660
1661 void WebPage::pageDidScroll()
1662 {
1663 #if PLATFORM(IOS)
1664     if (!m_inDynamicSizeUpdate)
1665         m_dynamicSizeUpdateHistory.clear();
1666 #endif
1667     m_uiClient->pageDidScroll(this);
1668
1669     send(Messages::WebPageProxy::PageDidScroll());
1670 }
1671
1672 #if USE(TILED_BACKING_STORE)
1673 void WebPage::pageDidRequestScroll(const IntPoint& point)
1674 {
1675     send(Messages::WebPageProxy::PageDidRequestScroll(point));
1676 }
1677 #endif
1678
1679 #if ENABLE(CONTEXT_MENUS)
1680 WebContextMenu* WebPage::contextMenu()
1681 {
1682     if (!m_contextMenu)
1683         m_contextMenu = WebContextMenu::create(this);
1684     return m_contextMenu.get();
1685 }
1686
1687 WebContextMenu* WebPage::contextMenuAtPointInWindow(const IntPoint& point)
1688 {
1689     corePage()->contextMenuController().clearContextMenu();
1690     
1691     // Simulate a mouse click to generate the correct menu.
1692     PlatformMouseEvent mouseEvent(point, point, RightButton, PlatformEvent::MousePressed, 1, false, false, false, false, currentTime());
1693     bool handled = corePage()->userInputBridge().handleContextMenuEvent(mouseEvent, &corePage()->mainFrame());
1694     if (!handled)
1695         return 0;
1696
1697     return contextMenu();
1698 }
1699 #endif
1700
1701 // Events 
1702
1703 static const WebEvent* g_currentEvent = 0;
1704
1705 // FIXME: WebPage::currentEvent is used by the plug-in code to avoid having to convert from DOM events back to
1706 // WebEvents. When we get the event handling sorted out, this should go away and the Widgets should get the correct
1707 // platform events passed to the event handler code.
1708 const WebEvent* WebPage::currentEvent()
1709 {
1710     return g_currentEvent;
1711 }
1712
1713 class CurrentEvent {
1714 public:
1715     explicit CurrentEvent(const WebEvent& event)
1716         : m_previousCurrentEvent(g_currentEvent)
1717     {
1718         g_currentEvent = &event;
1719     }
1720
1721     ~CurrentEvent()
1722     {
1723         g_currentEvent = m_previousCurrentEvent;
1724     }
1725
1726 private:
1727     const WebEvent* m_previousCurrentEvent;
1728 };
1729
1730 #if ENABLE(CONTEXT_MENUS)
1731 static bool isContextClick(const PlatformMouseEvent& event)
1732 {
1733     if (event.button() == WebCore::RightButton)
1734         return true;
1735
1736 #if PLATFORM(COCOA)
1737     // FIXME: this really should be about OSX-style UI, not about the Mac port
1738     if (event.button() == WebCore::LeftButton && event.ctrlKey())
1739         return true;
1740 #endif
1741
1742     return false;
1743 }
1744
1745 static bool handleContextMenuEvent(const PlatformMouseEvent& platformMouseEvent, WebPage* page)
1746 {
1747     IntPoint point = page->corePage()->mainFrame().view()->windowToContents(platformMouseEvent.position());
1748     HitTestResult result = page->corePage()->mainFrame().eventHandler().hitTestResultAtPoint(point);
1749
1750     Frame* frame = &page->corePage()->mainFrame();
1751     if (result.innerNonSharedNode())
1752         frame = result.innerNonSharedNode()->document().frame();
1753
1754     bool handled = page->corePage()->userInputBridge().handleContextMenuEvent(platformMouseEvent, frame);
1755     if (handled)
1756         page->contextMenu()->show();
1757
1758     return handled;
1759 }
1760 #endif
1761
1762 static bool handleMouseEvent(const WebMouseEvent& mouseEvent, WebPage* page, bool onlyUpdateScrollbars)
1763 {
1764     Frame& frame = page->corePage()->mainFrame();
1765     if (!frame.view())
1766         return false;
1767
1768     PlatformMouseEvent platformMouseEvent = platform(mouseEvent);
1769
1770     switch (platformMouseEvent.type()) {
1771         case PlatformEvent::MousePressed: {
1772 #if ENABLE(CONTEXT_MENUS)
1773             if (isContextClick(platformMouseEvent))
1774                 page->corePage()->contextMenuController().clearContextMenu();
1775 #endif
1776
1777             bool handled = page->corePage()->userInputBridge().handleMousePressEvent(platformMouseEvent);
1778 #if ENABLE(CONTEXT_MENUS)
1779             if (isContextClick(platformMouseEvent))
1780                 handled = handleContextMenuEvent(platformMouseEvent, page);
1781 #endif
1782             return handled;
1783         }
1784         case PlatformEvent::MouseReleased:
1785             return page->corePage()->userInputBridge().handleMouseReleaseEvent(platformMouseEvent);
1786
1787         case PlatformEvent::MouseMoved:
1788             if (onlyUpdateScrollbars)
1789                 return page->corePage()->userInputBridge().handleMouseMoveOnScrollbarEvent(platformMouseEvent);
1790             return page->corePage()->userInputBridge().handleMouseMoveEvent(platformMouseEvent);
1791         default:
1792             ASSERT_NOT_REACHED();
1793             return false;
1794     }
1795 }
1796
1797 void WebPage::mouseEvent(const WebMouseEvent& mouseEvent)
1798 {
1799     ASSERT(m_page->pageThrottler());
1800     m_page->pageThrottler()->didReceiveUserInput();
1801
1802 #if ENABLE(CONTEXT_MENUS)
1803     // Don't try to handle any pending mouse events if a context menu is showing.
1804     if (m_isShowingContextMenu) {
1805         send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(mouseEvent.type()), false));
1806         return;
1807     }
1808 #endif
1809     bool handled = m_pageOverlayController.handleMouseEvent(mouseEvent);
1810
1811 #if !PLATFORM(IOS)
1812     if (!handled && m_headerBanner)
1813         handled = m_headerBanner->mouseEvent(mouseEvent);
1814     if (!handled && m_footerBanner)
1815         handled = m_footerBanner->mouseEvent(mouseEvent);
1816 #endif // !PLATFORM(IOS)
1817
1818     if (!handled && canHandleUserEvents()) {
1819         CurrentEvent currentEvent(mouseEvent);
1820
1821         // We need to do a full, normal hit test during this mouse event if the page is active or if a mouse
1822         // button is currently pressed. It is possible that neither of those things will be true since on
1823         // Lion when legacy scrollbars are enabled, WebKit receives mouse events all the time. If it is one
1824         // of those cases where the page is not active and the mouse is not pressed, then we can fire a more
1825         // efficient scrollbars-only version of the event.
1826         bool onlyUpdateScrollbars = !(m_page->focusController().isActive() || (mouseEvent.button() != WebMouseEvent::NoButton));
1827         handled = handleMouseEvent(mouseEvent, this, onlyUpdateScrollbars);
1828     }
1829
1830     send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(mouseEvent.type()), handled));
1831 }
1832
1833 void WebPage::mouseEventSyncForTesting(const WebMouseEvent& mouseEvent, bool& handled)
1834 {
1835     handled = m_pageOverlayController.handleMouseEvent(mouseEvent);
1836 #if !PLATFORM(IOS)
1837     if (!handled && m_headerBanner)
1838         handled = m_headerBanner->mouseEvent(mouseEvent);
1839     if (!handled && m_footerBanner)
1840         handled = m_footerBanner->mouseEvent(mouseEvent);
1841 #endif // !PLATFORM(IOS)
1842
1843     if (!handled) {
1844         CurrentEvent currentEvent(mouseEvent);
1845
1846         // We need to do a full, normal hit test during this mouse event if the page is active or if a mouse
1847         // button is currently pressed. It is possible that neither of those things will be true since on 
1848         // Lion when legacy scrollbars are enabled, WebKit receives mouse events all the time. If it is one 
1849         // of those cases where the page is not active and the mouse is not pressed, then we can fire a more
1850         // efficient scrollbars-only version of the event.
1851         bool onlyUpdateScrollbars = !(m_page->focusController().isActive() || (mouseEvent.button() != WebMouseEvent::NoButton));
1852         handled = handleMouseEvent(mouseEvent, this, onlyUpdateScrollbars);
1853     }
1854 }
1855
1856 static bool handleWheelEvent(const WebWheelEvent& wheelEvent, Page* page)
1857 {
1858     Frame& frame = page->mainFrame();
1859     if (!frame.view())
1860         return false;
1861
1862     PlatformWheelEvent platformWheelEvent = platform(wheelEvent);
1863     return page->userInputBridge().handleWheelEvent(platformWheelEvent);
1864 }
1865
1866 void WebPage::wheelEvent(const WebWheelEvent& wheelEvent)
1867 {
1868     ASSERT(m_page->pageThrottler());
1869     m_page->pageThrottler()->didReceiveUserInput();
1870
1871     bool handled = false;
1872
1873     if (canHandleUserEvents()) {
1874         CurrentEvent currentEvent(wheelEvent);
1875
1876         handled = handleWheelEvent(wheelEvent, m_page.get());
1877     }
1878     send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(wheelEvent.type()), handled));
1879 }
1880
1881 void WebPage::wheelEventSyncForTesting(const WebWheelEvent& wheelEvent, bool& handled)
1882 {
1883     CurrentEvent currentEvent(wheelEvent);
1884
1885     if (ScrollingCoordinator* scrollingCoordinator = m_page->scrollingCoordinator())
1886         scrollingCoordinator->commitTreeStateIfNeeded();
1887
1888     handled = handleWheelEvent(wheelEvent, m_page.get());
1889 }
1890
1891 static bool handleKeyEvent(const WebKeyboardEvent& keyboardEvent, Page* page)
1892 {
1893     if (!page->mainFrame().view())
1894         return false;
1895
1896     if (keyboardEvent.type() == WebEvent::Char && keyboardEvent.isSystemKey())
1897         return page->userInputBridge().handleAccessKeyEvent(platform(keyboardEvent));
1898     return page->userInputBridge().handleKeyEvent(platform(keyboardEvent));
1899 }
1900
1901 void WebPage::keyEvent(const WebKeyboardEvent& keyboardEvent)
1902 {
1903     ASSERT(m_page->pageThrottler());
1904     m_page->pageThrottler()->didReceiveUserInput();
1905
1906     bool handled = false;
1907
1908     if (canHandleUserEvents()) {
1909         CurrentEvent currentEvent(keyboardEvent);
1910
1911         handled = handleKeyEvent(keyboardEvent, m_page.get());
1912         // FIXME: Platform default behaviors should be performed during normal DOM event dispatch (in most cases, in default keydown event handler).
1913         if (!handled)
1914             handled = performDefaultBehaviorForKeyEvent(keyboardEvent);
1915     }
1916     send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(keyboardEvent.type()), handled));
1917 }
1918
1919 void WebPage::keyEventSyncForTesting(const WebKeyboardEvent& keyboardEvent, bool& handled)
1920 {
1921     CurrentEvent currentEvent(keyboardEvent);
1922
1923     Frame& frame = m_page->focusController().focusedOrMainFrame();
1924     frame.document()->updateStyleIfNeeded();
1925
1926     handled = handleKeyEvent(keyboardEvent, m_page.get());
1927     if (!handled)
1928         handled = performDefaultBehaviorForKeyEvent(keyboardEvent);
1929 }
1930
1931 void WebPage::validateCommand(const String& commandName, uint64_t callbackID)
1932 {
1933     bool isEnabled = false;
1934     int32_t state = 0;
1935     Frame& frame = m_page->focusController().focusedOrMainFrame();
1936     if (PluginView* pluginView = focusedPluginViewForFrame(frame))
1937         isEnabled = pluginView->isEditingCommandEnabled(commandName);
1938     else {
1939         Editor::Command command = frame.editor().command(commandName);
1940         state = command.state();
1941         isEnabled = command.isSupported() && command.isEnabled();
1942     }
1943
1944     send(Messages::WebPageProxy::ValidateCommandCallback(commandName, isEnabled, state, callbackID));
1945 }
1946
1947 void WebPage::executeEditCommand(const String& commandName)
1948 {
1949     executeEditingCommand(commandName, String());
1950 }
1951
1952 uint64_t WebPage::restoreSession(const LegacySessionState& sessionState)
1953 {
1954     const BackForwardListItemVector& list = sessionState.list();
1955     size_t size = list.size();
1956     uint64_t currentItemID = 0;
1957     for (size_t i = 0; i < size; ++i) {
1958         WebBackForwardListItem* webItem = list[i].get();
1959         DecoderAdapter decoder(webItem->backForwardData().data(), webItem->backForwardData().size());
1960         
1961         RefPtr<HistoryItem> item = HistoryItem::decodeBackForwardTree(webItem->url(), webItem->title(), webItem->originalURL(), decoder);
1962         if (!item) {
1963             LOG_ERROR("Failed to decode a HistoryItem from session state data.");
1964             return 0;
1965         }
1966         
1967         if (i == sessionState.currentIndex())
1968             currentItemID = webItem->itemID();
1969         
1970         WebBackForwardListProxy::addItemFromUIProcess(list[i]->itemID(), item.release());
1971     }    
1972     ASSERT(currentItemID);
1973     return currentItemID;
1974 }
1975
1976 void WebPage::restoreSessionAndNavigateToCurrentItem(uint64_t navigationID, const LegacySessionState& sessionState)
1977 {
1978     if (uint64_t currentItemID = restoreSession(sessionState))
1979         goToBackForwardItem(navigationID, currentItemID);
1980 }
1981
1982 #if ENABLE(TOUCH_EVENTS)
1983 static bool handleTouchEvent(const WebTouchEvent& touchEvent, Page* page)
1984 {
1985     if (!page->mainFrame().view())
1986         return false;
1987
1988     return page->mainFrame().eventHandler().handleTouchEvent(platform(touchEvent));
1989 }
1990 #endif
1991
1992 #if ENABLE(IOS_TOUCH_EVENTS)
1993 void WebPage::dispatchTouchEvent(const WebTouchEvent& touchEvent, bool& handled)
1994 {
1995     RefPtr<Frame> oldFocusedFrame = m_page->focusController().focusedFrame();
1996     RefPtr<Element> oldFocusedElement = oldFocusedFrame ? oldFocusedFrame->document()->focusedElement() : nullptr;
1997     m_userIsInteracting = true;
1998
1999     m_lastInteractionLocation = touchEvent.position();
2000     CurrentEvent currentEvent(touchEvent);
2001     handled = handleTouchEvent(touchEvent, m_page.get());
2002
2003     RefPtr<Frame> newFocusedFrame = m_page->focusController().focusedFrame();
2004     RefPtr<Element> newFocusedElement = newFocusedFrame ? newFocusedFrame->document()->focusedElement() : nullptr;
2005
2006     // If the focus has not changed, we need to notify the client anyway, since it might be
2007     // necessary to start assisting the node.
2008     // If the node has been focused by JavaScript without user interaction, the
2009     // keyboard is not on screen.
2010     if (newFocusedElement && newFocusedElement == oldFocusedElement)
2011         elementDidFocus(newFocusedElement.get());
2012
2013     m_userIsInteracting = false;
2014 }
2015
2016 void WebPage::touchEventSync(const WebTouchEvent& touchEvent, bool& handled)
2017 {
2018     EventDispatcher::TouchEventQueue queuedEvents;
2019     WebProcess::shared().eventDispatcher().getQueuedTouchEventsForPage(*this, queuedEvents);
2020     dispatchAsynchronousTouchEvents(queuedEvents);
2021
2022     dispatchTouchEvent(touchEvent, handled);
2023 }
2024 #elif ENABLE(TOUCH_EVENTS)
2025 void WebPage::touchEvent(const WebTouchEvent& touchEvent)
2026 {
2027
2028     bool handled = false;
2029     if (canHandleUserEvents()) {
2030         CurrentEvent currentEvent(touchEvent);
2031
2032         handled = handleTouchEvent(touchEvent, m_page.get());
2033     }
2034     send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(touchEvent.type()), handled));
2035 }
2036
2037 void WebPage::touchEventSyncForTesting(const WebTouchEvent& touchEvent, bool& handled)
2038 {
2039     CurrentEvent currentEvent(touchEvent);
2040     handled = handleTouchEvent(touchEvent, m_page.get());
2041 }
2042 #endif
2043
2044 bool WebPage::scroll(Page* page, ScrollDirection direction, ScrollGranularity granularity)
2045 {
2046     return page->userInputBridge().scrollRecursively(direction, granularity);
2047 }
2048
2049 bool WebPage::logicalScroll(Page* page, ScrollLogicalDirection direction, ScrollGranularity granularity)
2050 {
2051     return page->userInputBridge().logicalScrollRecursively(direction, granularity);
2052 }
2053
2054 bool WebPage::scrollBy(uint32_t scrollDirection, uint32_t scrollGranularity)
2055 {
2056     return scroll(m_page.get(), static_cast<ScrollDirection>(scrollDirection), static_cast<ScrollGranularity>(scrollGranularity));
2057 }
2058
2059 void WebPage::centerSelectionInVisibleArea()
2060 {
2061     Frame& frame = m_page->focusController().focusedOrMainFrame();
2062     frame.selection().revealSelection(ScrollAlignment::alignCenterAlways);
2063     m_findController.showFindIndicatorInSelection();
2064 }
2065
2066 #if ENABLE(REMOTE_INSPECTOR)
2067 void WebPage::setAllowsRemoteInspection(bool allow)
2068 {
2069     m_page->setRemoteInspectionAllowed(allow);
2070 }
2071 #endif
2072
2073 void WebPage::setDrawsBackground(bool drawsBackground)
2074 {
2075     if (m_drawsBackground == drawsBackground)
2076         return;
2077
2078     m_drawsBackground = drawsBackground;
2079
2080     for (Frame* coreFrame = m_mainFrame->coreFrame(); coreFrame; coreFrame = coreFrame->tree().traverseNext()) {
2081         if (FrameView* view = coreFrame->view())
2082             view->setTransparent(!drawsBackground);
2083     }
2084
2085     m_drawingArea->pageBackgroundTransparencyChanged();
2086     m_drawingArea->setNeedsDisplay();
2087 }
2088
2089 void WebPage::setDrawsTransparentBackground(bool drawsTransparentBackground)
2090 {
2091     if (m_drawsTransparentBackground == drawsTransparentBackground)
2092         return;
2093
2094     m_drawsTransparentBackground = drawsTransparentBackground;
2095
2096     Color backgroundColor = drawsTransparentBackground ? Color::transparent : Color::white;
2097     for (Frame* coreFrame = m_mainFrame->coreFrame(); coreFrame; coreFrame = coreFrame->tree().traverseNext()) {
2098         if (FrameView* view = coreFrame->view())
2099             view->setBaseBackgroundColor(backgroundColor);
2100     }
2101
2102     m_drawingArea->pageBackgroundTransparencyChanged();
2103     m_drawingArea->setNeedsDisplay();
2104 }
2105
2106 void WebPage::setTopContentInset(float contentInset)
2107 {
2108     if (contentInset == m_page->topContentInset())
2109         return;
2110
2111     m_page->setTopContentInset(contentInset);
2112
2113     for (auto* pluginView : m_pluginViews)
2114         pluginView->topContentInsetDidChange();
2115 }
2116
2117 void WebPage::viewWillStartLiveResize()
2118 {
2119     if (!m_page)
2120         return;
2121
2122     // FIXME: This should propagate to all ScrollableAreas.
2123     Frame& frame = m_page->focusController().focusedOrMainFrame();
2124     if (FrameView* view = frame.view())
2125         view->willStartLiveResize();
2126 }
2127
2128 void WebPage::viewWillEndLiveResize()
2129 {
2130     if (!m_page)
2131         return;
2132
2133     // FIXME: This should propagate to all ScrollableAreas.
2134     Frame& frame = m_page->focusController().focusedOrMainFrame();
2135     if (FrameView* view = frame.view())
2136         view->willEndLiveResize();
2137 }
2138
2139 void WebPage::setInitialFocus(bool forward, bool isKeyboardEventValid, const WebKeyboardEvent& event)
2140 {
2141     if (!m_page)
2142         return;
2143
2144     Frame& frame = m_page->focusController().focusedOrMainFrame();
2145     frame.document()->setFocusedElement(0);
2146
2147     if (isKeyboardEventValid && event.type() == WebEvent::KeyDown) {
2148         PlatformKeyboardEvent platformEvent(platform(event));
2149         platformEvent.disambiguateKeyDownEvent(PlatformEvent::RawKeyDown);
2150         m_page->focusController().setInitialFocus(forward ? FocusDirectionForward : FocusDirectionBackward, KeyboardEvent::create(platformEvent, frame.document()->defaultView()).get());
2151         return;
2152     }
2153
2154     m_page->focusController().setInitialFocus(forward ? FocusDirectionForward : FocusDirectionBackward, 0);
2155 }
2156
2157 void WebPage::setWindowResizerSize(const IntSize& windowResizerSize)
2158 {
2159     if (m_windowResizerSize == windowResizerSize)
2160         return;
2161
2162     m_windowResizerSize = windowResizerSize;
2163
2164     for (Frame* coreFrame = m_mainFrame->coreFrame(); coreFrame; coreFrame = coreFrame->tree().traverseNext()) {
2165         FrameView* view = coreFrame->view();
2166         if (view)
2167             view->windowResizerRectChanged();
2168     }
2169 }
2170
2171 void WebPage::setCanStartMediaTimerFired()
2172 {
2173     if (m_page)
2174         m_page->setCanStartMedia(true);
2175 }
2176
2177 #if !PLATFORM(MAC)
2178 void WebPage::didUpdateViewStateTimerFired()
2179 {
2180     send(Messages::WebPageProxy::DidUpdateViewState());
2181 }
2182 #endif
2183
2184 inline bool WebPage::canHandleUserEvents() const
2185 {
2186 #if USE(TILED_BACKING_STORE)
2187     // Should apply only if the area was frozen by didStartPageTransition().
2188     return !m_drawingArea->layerTreeStateIsFrozen();
2189 #endif
2190     return true;
2191 }
2192
2193 void WebPage::updateIsInWindow(bool isInitialState)
2194 {
2195     bool isInWindow = m_viewState & WebCore::ViewState::IsInWindow;
2196
2197     if (!isInWindow) {
2198         m_setCanStartMediaTimer.stop();
2199         m_page->setCanStartMedia(false);
2200         
2201         // The WebProcess does not yet know about this page; no need to tell it we're leaving the window.
2202         if (!isInitialState)
2203             WebProcess::shared().pageWillLeaveWindow(m_pageID);
2204     } else {
2205         // Defer the call to Page::setCanStartMedia() since it ends up sending a synchronous message to the UI process
2206         // in order to get plug-in connections, and the UI process will be waiting for the Web process to update the backing
2207         // store after moving the view into a window, until it times out and paints white. See <rdar://problem/9242771>.
2208         if (m_mayStartMediaWhenInWindow)
2209             m_setCanStartMediaTimer.startOneShot(0);
2210
2211         WebProcess::shared().pageDidEnterWindow(m_pageID);
2212     }
2213
2214     if (isInWindow)
2215         layoutIfNeeded();
2216 }
2217
2218 void WebPage::setViewState(ViewState::Flags viewState, bool wantsDidUpdateViewState)
2219 {
2220     ViewState::Flags changed = m_viewState ^ viewState;
2221     m_viewState = viewState;
2222
2223     m_drawingArea->viewStateDidChange(changed);
2224     m_page->setViewState(viewState);
2225     for (auto* pluginView : m_pluginViews)
2226         pluginView->viewStateDidChange(changed);
2227
2228     if (changed & ViewState::IsInWindow)
2229         updateIsInWindow();
2230
2231     if (wantsDidUpdateViewState)
2232         m_sendDidUpdateViewStateTimer.startOneShot(0);
2233 }
2234
2235 void WebPage::setLayerHostingMode(unsigned layerHostingMode)
2236 {
2237     m_layerHostingMode = static_cast<LayerHostingMode>(layerHostingMode);
2238
2239     m_drawingArea->setLayerHostingMode(m_layerHostingMode);
2240
2241     for (auto* pluginView : m_pluginViews)
2242         pluginView->setLayerHostingMode(m_layerHostingMode);
2243 }
2244
2245 void WebPage::setSessionID(SessionID sessionID)
2246 {
2247     if (sessionID.isEphemeral())
2248         WebProcess::shared().ensurePrivateBrowsingSession(sessionID);
2249     m_page->setSessionID(sessionID);
2250 }
2251
2252 void WebPage::didReceivePolicyDecision(uint64_t frameID, uint64_t listenerID, uint32_t policyAction, uint64_t downloadID)
2253 {
2254     WebFrame* frame = WebProcess::shared().webFrame(frameID);
2255     if (!frame)
2256         return;
2257     frame->didReceivePolicyDecision(listenerID, static_cast<PolicyAction>(policyAction), downloadID);
2258 }
2259
2260 void WebPage::didStartPageTransition()
2261 {
2262     m_drawingArea->setLayerTreeStateIsFrozen(true);
2263 }
2264
2265 void WebPage::didCompletePageTransition()
2266 {
2267 #if USE(TILED_BACKING_STORE)
2268     if (m_mainFrame->coreFrame()->view()->delegatesScrolling())
2269         // Wait until the UI process sent us the visible rect it wants rendered.
2270         send(Messages::WebPageProxy::PageTransitionViewportReady());
2271     else
2272 #endif
2273         
2274     m_drawingArea->setLayerTreeStateIsFrozen(false);
2275 }
2276
2277 void WebPage::show()
2278 {
2279     send(Messages::WebPageProxy::ShowPage());
2280 }
2281
2282 void WebPage::setUserAgent(const String& userAgent)
2283 {
2284     m_userAgent = userAgent;
2285 }
2286
2287 String WebPage::userAgent(const URL& url) const
2288 {
2289     String userAgent = platformUserAgent(url);
2290     if (!userAgent.isEmpty())
2291         return userAgent;
2292
2293     return m_userAgent;
2294 }
2295
2296 void WebPage::suspendActiveDOMObjectsAndAnimations()
2297 {
2298     m_page->suspendActiveDOMObjectsAndAnimations();
2299 }
2300
2301 void WebPage::resumeActiveDOMObjectsAndAnimations()
2302 {
2303     m_page->resumeActiveDOMObjectsAndAnimations();
2304 }
2305
2306 IntPoint WebPage::screenToRootView(const IntPoint& point)
2307 {
2308     IntPoint windowPoint;
2309     sendSync(Messages::WebPageProxy::ScreenToRootView(point), Messages::WebPageProxy::ScreenToRootView::Reply(windowPoint));
2310     return windowPoint;
2311 }
2312     
2313 IntRect WebPage::rootViewToScreen(const IntRect& rect)
2314 {
2315     IntRect screenRect;
2316     sendSync(Messages::WebPageProxy::RootViewToScreen(rect), Messages::WebPageProxy::RootViewToScreen::Reply(screenRect));
2317     return screenRect;
2318 }
2319     
2320 #if PLATFORM(IOS)
2321 IntPoint WebPage::accessibilityScreenToRootView(const IntPoint& point)
2322 {
2323     IntPoint windowPoint;
2324     sendSync(Messages::WebPageProxy::AccessibilityScreenToRootView(point), Messages::WebPageProxy::AccessibilityScreenToRootView::Reply(windowPoint));
2325     return windowPoint;
2326 }
2327
2328 IntRect WebPage::rootViewToAccessibilityScreen(const IntRect& rect)
2329 {
2330     IntRect screenRect;
2331     sendSync(Messages::WebPageProxy::RootViewToAccessibilityScreen(rect), Messages::WebPageProxy::RootViewToAccessibilityScreen::Reply(screenRect));
2332     return screenRect;
2333 }
2334 #endif
2335
2336 IntRect WebPage::windowResizerRect() const
2337 {
2338     if (m_windowResizerSize.isEmpty())
2339         return IntRect();
2340
2341     IntSize frameViewSize;
2342     if (Frame* coreFrame = m_mainFrame->coreFrame()) {
2343         if (FrameView* view = coreFrame->view())
2344             frameViewSize = view->size();
2345     }
2346
2347     return IntRect(frameViewSize.width() - m_windowResizerSize.width(), frameViewSize.height() - m_windowResizerSize.height(), 
2348                    m_windowResizerSize.width(), m_windowResizerSize.height());
2349 }
2350
2351 KeyboardUIMode WebPage::keyboardUIMode()
2352 {
2353     bool fullKeyboardAccessEnabled = WebProcess::shared().fullKeyboardAccessEnabled();
2354     return static_cast<KeyboardUIMode>((fullKeyboardAccessEnabled ? KeyboardAccessFull : KeyboardAccessDefault) | (m_tabToLinks ? KeyboardAccessTabsToLinks : 0));
2355 }
2356
2357 void WebPage::runJavaScriptInMainFrame(const String& script, uint64_t callbackID)
2358 {
2359     // NOTE: We need to be careful when running scripts that the objects we depend on don't
2360     // disappear during script execution.
2361
2362     // Retain the SerializedScriptValue at this level so it (and the internal data) lives
2363     // long enough for the DataReference to be encoded by the sent message.
2364     RefPtr<SerializedScriptValue> serializedResultValue;
2365     IPC::DataReference dataReference;
2366
2367     JSLockHolder lock(JSDOMWindow::commonVM());
2368     if (JSValue resultValue = m_mainFrame->coreFrame()->script().executeScript(script, true).jsValue()) {
2369         if ((serializedResultValue = SerializedScriptValue::create(m_mainFrame->jsContext(), toRef(m_mainFrame->coreFrame()->script().globalObject(mainThreadNormalWorld())->globalExec(), resultValue), 0)))
2370             dataReference = serializedResultValue->data();
2371     }
2372
2373     send(Messages::WebPageProxy::ScriptValueCallback(dataReference, callbackID));
2374 }
2375
2376 void WebPage::getContentsAsString(uint64_t callbackID)
2377 {
2378     String resultString = m_mainFrame->contentsAsString();
2379     send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
2380 }
2381
2382 #if ENABLE(MHTML)
2383 void WebPage::getContentsAsMHTMLData(uint64_t callbackID, bool useBinaryEncoding)
2384 {
2385     IPC::DataReference dataReference;
2386
2387     RefPtr<SharedBuffer> buffer = useBinaryEncoding
2388         ? MHTMLArchive::generateMHTMLDataUsingBinaryEncoding(m_page.get())
2389         : MHTMLArchive::generateMHTMLData(m_page.get());
2390
2391     if (buffer)
2392         dataReference = IPC::DataReference(reinterpret_cast<const uint8_t*>(buffer->data()), buffer->size());
2393
2394     send(Messages::WebPageProxy::DataCallback(dataReference, callbackID));
2395 }
2396 #endif
2397
2398 void WebPage::getRenderTreeExternalRepresentation(uint64_t callbackID)
2399 {
2400     String resultString = renderTreeExternalRepresentation();
2401     send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
2402 }
2403
2404 static Frame* frameWithSelection(Page* page)
2405 {
2406     for (Frame* frame = &page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
2407         if (frame->selection().isRange())
2408             return frame;
2409     }
2410
2411     return 0;
2412 }
2413
2414 void WebPage::getSelectionAsWebArchiveData(uint64_t callbackID)
2415 {
2416     IPC::DataReference dataReference;
2417
2418 #if PLATFORM(COCOA)
2419     RefPtr<LegacyWebArchive> archive;
2420     RetainPtr<CFDataRef> data;
2421
2422     Frame* frame = frameWithSelection(m_page.get());
2423     if (frame) {
2424         archive = LegacyWebArchive::createFromSelection(frame);
2425         data = archive->rawDataRepresentation();
2426         dataReference = IPC::DataReference(CFDataGetBytePtr(data.get()), CFDataGetLength(data.get()));
2427     }
2428 #endif
2429
2430     send(Messages::WebPageProxy::DataCallback(dataReference, callbackID));
2431 }
2432
2433 void WebPage::getSelectionOrContentsAsString(uint64_t callbackID)
2434 {
2435     String resultString = m_mainFrame->selectionAsString();
2436     if (resultString.isEmpty())
2437         resultString = m_mainFrame->contentsAsString();
2438     send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
2439 }
2440
2441 void WebPage::getSourceForFrame(uint64_t frameID, uint64_t callbackID)
2442 {
2443     String resultString;
2444     if (WebFrame* frame = WebProcess::shared().webFrame(frameID))
2445        resultString = frame->source();
2446
2447     send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
2448 }
2449
2450 void WebPage::getMainResourceDataOfFrame(uint64_t frameID, uint64_t callbackID)
2451 {
2452     IPC::DataReference dataReference;
2453
2454     RefPtr<ResourceBuffer> buffer;
2455     RefPtr<SharedBuffer> pdfResource;
2456     if (WebFrame* frame = WebProcess::shared().webFrame(frameID)) {
2457         if (PluginView* pluginView = pluginViewForFrame(frame->coreFrame())) {
2458             if ((pdfResource = pluginView->liveResourceData()))
2459                 dataReference = IPC::DataReference(reinterpret_cast<const uint8_t*>(pdfResource->data()), pdfResource->size());
2460         }
2461
2462         if (dataReference.isEmpty()) {
2463             if (DocumentLoader* loader = frame->coreFrame()->loader().documentLoader()) {
2464                 if ((buffer = loader->mainResourceData()))
2465                     dataReference = IPC::DataReference(reinterpret_cast<const uint8_t*>(buffer->data()), buffer->size());
2466             }
2467         }
2468     }
2469
2470     send(Messages::WebPageProxy::DataCallback(dataReference, callbackID));
2471 }
2472
2473 static PassRefPtr<SharedBuffer> resourceDataForFrame(Frame* frame, const URL& resourceURL)
2474 {
2475     DocumentLoader* loader = frame->loader().documentLoader();
2476     if (!loader)
2477         return 0;
2478
2479     RefPtr<ArchiveResource> subresource = loader->subresource(resourceURL);
2480     if (!subresource)
2481         return 0;
2482
2483     return subresource->data();
2484 }
2485
2486 void WebPage::getResourceDataFromFrame(uint64_t frameID, const String& resourceURLString, uint64_t callbackID)
2487 {
2488     IPC::DataReference dataReference;
2489     URL resourceURL(URL(), resourceURLString);
2490
2491     RefPtr<SharedBuffer> buffer;
2492     if (WebFrame* frame = WebProcess::shared().webFrame(frameID)) {
2493         buffer = resourceDataForFrame(frame->coreFrame(), resourceURL);
2494         if (!buffer) {
2495             // Try to get the resource data from the cache.
2496             buffer = cachedResponseDataForURL(resourceURL);
2497         }
2498
2499         if (buffer)
2500             dataReference = IPC::DataReference(reinterpret_cast<const uint8_t*>(buffer->data()), buffer->size());
2501     }
2502
2503     send(Messages::WebPageProxy::DataCallback(dataReference, callbackID));
2504 }
2505
2506 void WebPage::getWebArchiveOfFrame(uint64_t frameID, uint64_t callbackID)
2507 {
2508     IPC::DataReference dataReference;
2509
2510 #if PLATFORM(COCOA)
2511     RetainPtr<CFDataRef> data;
2512     if (WebFrame* frame = WebProcess::shared().webFrame(frameID)) {
2513         if ((data = frame->webArchiveData(0, 0)))
2514             dataReference = IPC::DataReference(CFDataGetBytePtr(data.get()), CFDataGetLength(data.get()));
2515     }
2516 #else
2517     UNUSED_PARAM(frameID);
2518 #endif
2519
2520     send(Messages::WebPageProxy::DataCallback(dataReference, callbackID));
2521 }
2522
2523 void WebPage::forceRepaintWithoutCallback()
2524 {
2525     m_drawingArea->forceRepaint();
2526 }
2527
2528 void WebPage::forceRepaint(uint64_t callbackID)
2529 {
2530     if (m_drawingArea->forceRepaintAsync(callbackID))
2531         return;
2532
2533     forceRepaintWithoutCallback();
2534     send(Messages::WebPageProxy::VoidCallback(callbackID));
2535 }
2536
2537 void WebPage::preferencesDidChange(const WebPreferencesStore& store)
2538 {
2539     WebPreferencesStore::removeTestRunnerOverrides();
2540     updatePreferences(store);
2541 }
2542
2543 void WebPage::updatePreferences(const WebPreferencesStore& store)
2544 {
2545     Settings& settings = m_page->settings();
2546
2547     m_tabToLinks = store.getBoolValueForKey(WebPreferencesKey::tabsToLinksKey());
2548     m_asynchronousPluginInitializationEnabled = store.getBoolValueForKey(WebPreferencesKey::asynchronousPluginInitializationEnabledKey());
2549     m_asynchronousPluginInitializationEnabledForAllPlugins = store.getBoolValueForKey(WebPreferencesKey::asynchronousPluginInitializationEnabledForAllPluginsKey());
2550     m_artificialPluginInitializationDelayEnabled = store.getBoolValueForKey(WebPreferencesKey::artificialPluginInitializationDelayEnabledKey());
2551
2552     m_scrollingPerformanceLoggingEnabled = store.getBoolValueForKey(WebPreferencesKey::scrollingPerformanceLoggingEnabledKey());
2553
2554 #if PLATFORM(COCOA)
2555     m_pdfPluginEnabled = store.getBoolValueForKey(WebPreferencesKey::pdfPluginEnabledKey());
2556 #endif
2557
2558 #if ENABLE(SERVICE_CONTROLS)
2559     m_serviceControlsEnabled = store.getBoolValueForKey(WebPreferencesKey::serviceControlsEnabledKey());
2560 #endif
2561
2562     // FIXME: This should be generated from macro expansion for all preferences,
2563     // but we currently don't match the naming of WebCore exactly so we are
2564     // handrolling the boolean and integer preferences until that is fixed.
2565
2566 #define INITIALIZE_SETTINGS(KeyUpper, KeyLower, TypeName, Type, DefaultValue) settings.set##KeyUpper(store.get##TypeName##ValueForKey(WebPreferencesKey::KeyLower##Key()));
2567
2568     FOR_EACH_WEBKIT_STRING_PREFERENCE(INITIALIZE_SETTINGS)
2569
2570 #undef INITIALIZE_SETTINGS
2571
2572     settings.setScriptEnabled(store.getBoolValueForKey(WebPreferencesKey::javaScriptEnabledKey()));
2573     settings.setScriptMarkupEnabled(store.getBoolValueForKey(WebPreferencesKey::javaScriptMarkupEnabledKey()));
2574     settings.setLoadsImagesAutomatically(store.getBoolValueForKey(WebPreferencesKey::loadsImagesAutomaticallyKey()));
2575     settings.setLoadsSiteIconsIgnoringImageLoadingSetting(store.getBoolValueForKey(WebPreferencesKey::loadsSiteIconsIgnoringImageLoadingPreferenceKey()));
2576     settings.setPluginsEnabled(store.getBoolValueForKey(WebPreferencesKey::pluginsEnabledKey()));
2577     settings.setJavaEnabled(store.getBoolValueForKey(WebPreferencesKey::javaEnabledKey()));
2578     settings.setJavaEnabledForLocalFiles(store.getBoolValueForKey(WebPreferencesKey::javaEnabledForLocalFilesKey()));    
2579     settings.setOfflineWebApplicationCacheEnabled(store.getBoolValueForKey(WebPreferencesKey::offlineWebApplicationCacheEnabledKey()));
2580     settings.setLocalStorageEnabled(store.getBoolValueForKey(WebPreferencesKey::localStorageEnabledKey()));
2581     settings.setXSSAuditorEnabled(store.getBoolValueForKey(WebPreferencesKey::xssAuditorEnabledKey()));
2582     settings.setFrameFlatteningEnabled(store.getBoolValueForKey(WebPreferencesKey::frameFlatteningEnabledKey()));
2583     if (store.getBoolValueForKey(WebPreferencesKey::privateBrowsingEnabledKey()) && !usesEphemeralSession())
2584         setSessionID(SessionID::legacyPrivateSessionID());
2585     else if (!store.getBoolValueForKey(WebPreferencesKey::privateBrowsingEnabledKey()) && sessionID() == SessionID::legacyPrivateSessionID())
2586         setSessionID(SessionID::defaultSessionID());
2587     settings.setDeveloperExtrasEnabled(store.getBoolValueForKey(WebPreferencesKey::developerExtrasEnabledKey()));
2588     settings.setJavaScriptExperimentsEnabled(store.getBoolValueForKey(WebPreferencesKey::javaScriptExperimentsEnabledKey()));
2589     settings.setTextAreasAreResizable(store.getBoolValueForKey(WebPreferencesKey::textAreasAreResizableKey()));
2590     settings.setNeedsSiteSpecificQuirks(store.getBoolValueForKey(WebPreferencesKey::needsSiteSpecificQuirksKey()));
2591     settings.setJavaScriptCanOpenWindowsAutomatically(store.getBoolValueForKey(WebPreferencesKey::javaScriptCanOpenWindowsAutomaticallyKey()));
2592     settings.setForceFTPDirectoryListings(store.getBoolValueForKey(WebPreferencesKey::forceFTPDirectoryListingsKey()));
2593     settings.setDNSPrefetchingEnabled(store.getBoolValueForKey(WebPreferencesKey::dnsPrefetchingEnabledKey()));
2594 #if ENABLE(WEB_ARCHIVE)
2595     settings.setWebArchiveDebugModeEnabled(store.getBoolValueForKey(WebPreferencesKey::webArchiveDebugModeEnabledKey()));
2596 #endif
2597     settings.setLocalFileContentSniffingEnabled(store.getBoolValueForKey(WebPreferencesKey::localFileContentSniffingEnabledKey()));
2598     settings.setUsesPageCache(store.getBoolValueForKey(WebPreferencesKey::usesPageCacheKey()));
2599     settings.setPageCacheSupportsPlugins(store.getBoolValueForKey(WebPreferencesKey::pageCacheSupportsPluginsKey()));
2600     settings.setAuthorAndUserStylesEnabled(store.getBoolValueForKey(WebPreferencesKey::authorAndUserStylesEnabledKey()));
2601     settings.setPaginateDuringLayoutEnabled(store.getBoolValueForKey(WebPreferencesKey::paginateDuringLayoutEnabledKey()));
2602     settings.setDOMPasteAllowed(store.getBoolValueForKey(WebPreferencesKey::domPasteAllowedKey()));
2603     settings.setJavaScriptCanAccessClipboard(store.getBoolValueForKey(WebPreferencesKey::javaScriptCanAccessClipboardKey()));
2604     settings.setShouldPrintBackgrounds(store.getBoolValueForKey(WebPreferencesKey::shouldPrintBackgroundsKey()));
2605     settings.setWebSecurityEnabled(store.getBoolValueForKey(WebPreferencesKey::webSecurityEnabledKey()));
2606     settings.setAllowUniversalAccessFromFileURLs(store.getBoolValueForKey(WebPreferencesKey::allowUniversalAccessFromFileURLsKey()));
2607     settings.setAllowFileAccessFromFileURLs(store.getBoolValueForKey(WebPreferencesKey::allowFileAccessFromFileURLsKey()));
2608
2609     settings.setMinimumFontSize(store.getDoubleValueForKey(WebPreferencesKey::minimumFontSizeKey()));
2610     settings.setMinimumLogicalFontSize(store.getDoubleValueForKey(WebPreferencesKey::minimumLogicalFontSizeKey()));
2611     settings.setDefaultFontSize(store.getDoubleValueForKey(WebPreferencesKey::defaultFontSizeKey()));
2612     settings.setDefaultFixedFontSize(store.getDoubleValueForKey(WebPreferencesKey::defaultFixedFontSizeKey()));
2613     settings.setScreenFontSubstitutionEnabled(store.getBoolValueForKey(WebPreferencesKey::screenFontSubstitutionEnabledKey())
2614 #if PLATFORM(COCOA)
2615         || WebProcess::shared().shouldForceScreenFontSubstitution()
2616 #endif
2617     );
2618     settings.setLayoutFallbackWidth(store.getUInt32ValueForKey(WebPreferencesKey::layoutFallbackWidthKey()));
2619     settings.setDeviceWidth(store.getUInt32ValueForKey(WebPreferencesKey::deviceWidthKey()));
2620     settings.setDeviceHeight(store.getUInt32ValueForKey(WebPreferencesKey::deviceHeightKey()));
2621     settings.setEditableLinkBehavior(static_cast<WebCore::EditableLinkBehavior>(store.getUInt32ValueForKey(WebPreferencesKey::editableLinkBehaviorKey())));
2622     settings.setShowsToolTipOverTruncatedText(store.getBoolValueForKey(WebPreferencesKey::showsToolTipOverTruncatedTextKey()));
2623
2624     settings.setAcceleratedCompositingForOverflowScrollEnabled(store.getBoolValueForKey(WebPreferencesKey::acceleratedCompositingForOverflowScrollEnabledKey()));
2625     settings.setAcceleratedCompositingEnabled(store.getBoolValueForKey(WebPreferencesKey::acceleratedCompositingEnabledKey()));
2626     settings.setAcceleratedDrawingEnabled(store.getBoolValueForKey(WebPreferencesKey::acceleratedDrawingEnabledKey()));
2627     settings.setCanvasUsesAcceleratedDrawing(store.getBoolValueForKey(WebPreferencesKey::canvasUsesAcceleratedDrawingKey()));
2628     settings.setShowDebugBorders(store.getBoolValueForKey(WebPreferencesKey::compositingBordersVisibleKey()));
2629     settings.setShowRepaintCounter(store.getBoolValueForKey(WebPreferencesKey::compositingRepaintCountersVisibleKey()));
2630     settings.setShowTiledScrollingIndicator(store.getBoolValueForKey(WebPreferencesKey::tiledScrollingIndicatorVisibleKey()));
2631     settings.setAggressiveTileRetentionEnabled(store.getBoolValueForKey(WebPreferencesKey::aggressiveTileRetentionEnabledKey()));
2632     settings.setTemporaryTileCohortRetentionEnabled(store.getBoolValueForKey(WebPreferencesKey::temporaryTileCohortRetentionEnabledKey()));
2633     RuntimeEnabledFeatures::sharedFeatures().setCSSRegionsEnabled(store.getBoolValueForKey(WebPreferencesKey::cssRegionsEnabledKey()));
2634     RuntimeEnabledFeatures::sharedFeatures().setCSSCompositingEnabled(store.getBoolValueForKey(WebPreferencesKey::cssCompositingEnabledKey()));
2635     settings.setWebGLEnabled(store.getBoolValueForKey(WebPreferencesKey::webGLEnabledKey()));
2636     settings.setMultithreadedWebGLEnabled(store.getBoolValueForKey(WebPreferencesKey::multithreadedWebGLEnabledKey()));
2637     settings.setForceSoftwareWebGLRendering(store.getBoolValueForKey(WebPreferencesKey::forceSoftwareWebGLRenderingKey()));
2638     settings.setAccelerated2dCanvasEnabled(store.getBoolValueForKey(WebPreferencesKey::accelerated2dCanvasEnabledKey()));
2639     settings.setMediaPlaybackRequiresUserGesture(store.getBoolValueForKey(WebPreferencesKey::mediaPlaybackRequiresUserGestureKey()));
2640     settings.setMediaPlaybackAllowsInline(store.getBoolValueForKey(WebPreferencesKey::mediaPlaybackAllowsInlineKey()));
2641     settings.setMockScrollbarsEnabled(store.getBoolValueForKey(WebPreferencesKey::mockScrollbarsEnabledKey()));
2642     settings.setHyperlinkAuditingEnabled(store.getBoolValueForKey(WebPreferencesKey::hyperlinkAuditingEnabledKey()));
2643     settings.setRequestAnimationFrameEnabled(store.getBoolValueForKey(WebPreferencesKey::requestAnimationFrameEnabledKey()));
2644 #if ENABLE(SMOOTH_SCROLLING)
2645     settings.setScrollAnimatorEnabled(store.getBoolValueForKey(WebPreferencesKey::scrollAnimatorEnabledKey()));
2646 #endif
2647     settings.setInteractiveFormValidationEnabled(store.getBoolValueForKey(WebPreferencesKey::interactiveFormValidationEnabledKey()));
2648     settings.setSpatialNavigationEnabled(store.getBoolValueForKey(WebPreferencesKey::spatialNavigationEnabledKey()));
2649
2650 #if ENABLE(SQL_DATABASE)
2651     DatabaseManager::manager().setIsAvailable(store.getBoolValueForKey(WebPreferencesKey::databasesEnabledKey()));
2652 #endif
2653
2654 #if ENABLE(FULLSCREEN_API)
2655     settings.setFullScreenEnabled(store.getBoolValueForKey(WebPreferencesKey::fullScreenEnabledKey()));
2656 #endif
2657
2658 #if USE(AVFOUNDATION)
2659     settings.setAVFoundationEnabled(store.getBoolValueForKey(WebPreferencesKey::isAVFoundationEnabledKey()));
2660 #endif
2661
2662 #if PLATFORM(COCOA)
2663     settings.setQTKitEnabled(store.getBoolValueForKey(WebPreferencesKey::isQTKitEnabledKey()));
2664 #endif
2665
2666 #if PLATFORM(IOS)
2667     settings.setAVKitEnabled(true);
2668 #endif
2669
2670 #if ENABLE(IOS_TEXT_AUTOSIZING)
2671     settings.setMinimumZoomFontSize(store.getDoubleValueForKey(WebPreferencesKey::minimumZoomFontSizeKey()));
2672 #endif
2673
2674 #if ENABLE(WEB_AUDIO)
2675     settings.setWebAudioEnabled(store.getBoolValueForKey(WebPreferencesKey::webAudioEnabledKey()));
2676 #endif
2677
2678 #if ENABLE(MEDIA_STREAM)
2679     settings.setMediaStreamEnabled(store.getBoolValueForKey(WebPreferencesKey::mediaStreamEnabledKey()));
2680 #endif
2681
2682 #if ENABLE(SERVICE_CONTROLS)
2683     settings.setImageControlsEnabled(store.getBoolValueForKey(WebPreferencesKey::imageControlsEnabledKey()));
2684 #endif
2685
2686 #if ENABLE(IOS_AIRPLAY)
2687     settings.setMediaPlaybackAllowsAirPlay(store.getBoolValueForKey(WebPreferencesKey::mediaPlaybackAllowsAirPlayKey()));
2688 #endif
2689
2690     settings.setApplicationChromeMode(store.getBoolValueForKey(WebPreferencesKey::applicationChromeModeKey()));
2691     settings.setSuppressesIncrementalRendering(store.getBoolValueForKey(WebPreferencesKey::suppressesIncrementalRenderingKey()));
2692     settings.setIncrementalRenderingSuppressionTimeoutInSeconds(store.getDoubleValueForKey(WebPreferencesKey::incrementalRenderingSuppressionTimeoutKey()));
2693     settings.setBackspaceKeyNavigationEnabled(store.getBoolValueForKey(WebPreferencesKey::backspaceKeyNavigationEnabledKey()));
2694     settings.setWantsBalancedSetDefersLoadingBehavior(store.getBoolValueForKey(WebPreferencesKey::wantsBalancedSetDefersLoadingBehaviorKey()));
2695     settings.setCaretBrowsingEnabled(store.getBoolValueForKey(WebPreferencesKey::caretBrowsingEnabledKey()));
2696
2697 #if ENABLE(VIDEO_TRACK)
2698     settings.setShouldDisplaySubtitles(store.getBoolValueForKey(WebPreferencesKey::shouldDisplaySubtitlesKey()));
2699     settings.setShouldDisplayCaptions(store.getBoolValueForKey(WebPreferencesKey::shouldDisplayCaptionsKey()));
2700     settings.setShouldDisplayTextDescriptions(store.getBoolValueForKey(WebPreferencesKey::shouldDisplayTextDescriptionsKey()));
2701 #endif
2702
2703 #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
2704     settings.setNotificationsEnabled(store.getBoolValueForKey(WebPreferencesKey::notificationsEnabledKey()));
2705 #endif
2706
2707     settings.setShouldRespectImageOrientation(store.getBoolValueForKey(WebPreferencesKey::shouldRespectImageOrientationKey()));
2708     settings.setStorageBlockingPolicy(static_cast<SecurityOrigin::StorageBlockingPolicy>(store.getUInt32ValueForKey(WebPreferencesKey::storageBlockingPolicyKey())));
2709     settings.setCookieEnabled(store.getBoolValueForKey(WebPreferencesKey::cookieEnabledKey()));
2710
2711     settings.setDiagnosticLoggingEnabled(store.getBoolValueForKey(WebPreferencesKey::diagnosticLoggingEnabledKey()));
2712
2713     settings.setScrollingPerformanceLoggingEnabled(m_scrollingPerformanceLoggingEnabled);
2714
2715     settings.setPlugInSnapshottingEnabled(store.getBoolValueForKey(WebPreferencesKey::plugInSnapshottingEnabledKey()));
2716     settings.setSnapshotAllPlugIns(store.getBoolValueForKey(WebPreferencesKey::snapshotAllPlugInsKey()));
2717     settings.setAutostartOriginPlugInSnapshottingEnabled(store.getBoolValueForKey(WebPreferencesKey::autostartOriginPlugInSnapshottingEnabledKey()));
2718     settings.setPrimaryPlugInSnapshotDetectionEnabled(store.getBoolValueForKey(WebPreferencesKey::primaryPlugInSnapshotDetectionEnabledKey()));
2719     settings.setUsesEncodingDetector(store.getBoolValueForKey(WebPreferencesKey::usesEncodingDetectorKey()));
2720
2721 #if ENABLE(TEXT_AUTOSIZING)
2722     settings.setTextAutosizingEnabled(store.getBoolValueForKey(WebPreferencesKey::textAutosizingEnabledKey()));
2723 #endif
2724
2725     settings.setLogsPageMessagesToSystemConsoleEnabled(store.getBoolValueForKey(WebPreferencesKey::logsPageMessagesToSystemConsoleEnabledKey()));
2726     settings.setAsynchronousSpellCheckingEnabled(store.getBoolValueForKey(WebPreferencesKey::asynchronousSpellCheckingEnabledKey()));
2727
2728     settings.setSmartInsertDeleteEnabled(store.getBoolValueForKey(WebPreferencesKey::smartInsertDeleteEnabledKey()));
2729     settings.setSelectTrailingWhitespaceEnabled(store.getBoolValueForKey(WebPreferencesKey::selectTrailingWhitespaceEnabledKey()));
2730     settings.setShowsURLsInToolTips(store.getBoolValueForKey(WebPreferencesKey::showsURLsInToolTipsEnabledKey()));
2731
2732 #if ENABLE(HIDDEN_PAGE_DOM_TIMER_THROTTLING)
2733     settings.setHiddenPageDOMTimerThrottlingEnabled(store.getBoolValueForKey(WebPreferencesKey::hiddenPageDOMTimerThrottlingEnabledKey()));
2734 #endif
2735
2736     settings.setHiddenPageCSSAnimationSuspensionEnabled(store.getBoolValueForKey(WebPreferencesKey::hiddenPageCSSAnimationSuspensionEnabledKey()));
2737     settings.setLowPowerVideoAudioBufferSizeEnabled(store.getBoolValueForKey(WebPreferencesKey::lowPowerVideoAudioBufferSizeEnabledKey()));
2738     settings.setSimpleLineLayoutEnabled(store.getBoolValueForKey(WebPreferencesKey::simpleLineLayoutEnabledKey()));
2739     settings.setSimpleLineLayoutDebugBordersEnabled(store.getBoolValueForKey(WebPreferencesKey::simpleLineLayoutDebugBordersEnabledKey()));
2740
2741     settings.setSubpixelCSSOMElementMetricsEnabled(store.getBoolValueForKey(WebPreferencesKey::subpixelCSSOMElementMetricsEnabledKey()));
2742
2743     settings.setUseLegacyTextAlignPositionedElementBehavior(store.getBoolValueForKey(WebPreferencesKey::useLegacyTextAlignPositionedElementBehaviorKey()));
2744
2745 #if ENABLE(MEDIA_SOURCE)
2746     settings.setMediaSourceEnabled(store.getBoolValueForKey(WebPreferencesKey::mediaSourceEnabledKey()));
2747 #endif
2748
2749     settings.setShouldConvertPositionStyleOnCopy(store.getBoolValueForKey(WebPreferencesKey::shouldConvertPositionStyleOnCopyKey()));
2750
2751     settings.setStandalone(store.getBoolValueForKey(WebPreferencesKey::standaloneKey()));
2752     settings.setTelephoneNumberParsingEnabled(store.getBoolValueForKey(WebPreferencesKey::telephoneNumberParsingEnabledKey()));
2753     settings.setAlwaysUseBaselineOfPrimaryFont(store.getBoolValueForKey(WebPreferencesKey::alwaysUseBaselineOfPrimaryFontKey()));
2754     settings.setAllowMultiElementImplicitSubmission(store.getBoolValueForKey(WebPreferencesKey::allowMultiElementImplicitSubmissionKey()));
2755     settings.setAlwaysUseAcceleratedOverflowScroll(store.getBoolValueForKey(WebPreferencesKey::alwaysUseAcceleratedOverflowScrollKey()));
2756
2757     settings.setPasswordEchoEnabled(store.getBoolValueForKey(WebPreferencesKey::passwordEchoEnabledKey()));
2758     settings.setPasswordEchoDurationInSeconds(store.getDoubleValueForKey(WebPreferencesKey::passwordEchoDurationKey()));
2759     
2760     settings.setLayoutInterval(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::duration<double>(store.getDoubleValueForKey(WebPreferencesKey::layoutIntervalKey()))));
2761     settings.setMaxParseDuration(store.getDoubleValueForKey(WebPreferencesKey::maxParseDurationKey()));
2762
2763     settings.setEnableInheritURIQueryComponent(store.getBoolValueForKey(WebPreferencesKey::enableInheritURIQueryComponentKey()));
2764
2765     settings.setShouldDispatchJavaScriptWindowOnErrorEvents(true);
2766
2767 #if PLATFORM(IOS)
2768     settings.setUseImageDocumentForSubframePDF(true);
2769 #endif
2770
2771     if (store.getBoolValueForKey(WebPreferencesKey::pageVisibilityBasedProcessSuppressionEnabledKey()))
2772         m_processSuppressionDisabledByWebPreference.stop();
2773     else
2774         m_processSuppressionDisabledByWebPreference.start();
2775
2776     platformPreferencesDidChange(store);
2777
2778     if (m_drawingArea)
2779         m_drawingArea->updatePreferences(store);
2780
2781     m_pageOverlayController.didChangePreferences();
2782 }
2783
2784 #if PLATFORM(COCOA)
2785 void WebPage::willCommitLayerTree(RemoteLayerTreeTransaction& layerTransaction)
2786 {
2787     layerTransaction.setContentsSize(corePage()->mainFrame().view()->contentsSize());
2788     layerTransaction.setPageScaleFactor(corePage()->pageScaleFactor());
2789     layerTransaction.setRenderTreeSize(corePage()->renderTreeSize());
2790     layerTransaction.setPageExtendedBackgroundColor(corePage()->pageExtendedBackgroundColor());
2791 #if PLATFORM(IOS)
2792     layerTransaction.setScaleWasSetByUIProcess(scaleWasSetByUIProcess());
2793     layerTransaction.setMinimumScaleFactor(minimumPageScaleFactor());
2794     layerTransaction.setMaximumScaleFactor(maximumPageScaleFactor());
2795     layerTransaction.setAllowsUserScaling(allowsUserScaling());
2796 #endif
2797 }
2798 #endif
2799
2800     
2801 #if ENABLE(INSPECTOR)
2802 WebInspector* WebPage::inspector()
2803 {
2804     if (m_isClosed)
2805         return 0;
2806     if (!m_inspector)
2807         m_inspector = WebInspector::create(this, m_inspectorClient);
2808     return m_inspector.get();
2809 }
2810 #endif
2811     
2812 #if PLATFORM(IOS)
2813 WebVideoFullscreenManager* WebPage::videoFullscreenManager()
2814 {
2815     if (!m_videoFullscreenManager)
2816         m_videoFullscreenManager = WebVideoFullscreenManager::create(this);
2817     return m_videoFullscreenManager.get();
2818 }
2819 #endif
2820
2821 #if ENABLE(FULLSCREEN_API)
2822 WebFullScreenManager* WebPage::fullScreenManager()
2823 {
2824     if (!m_fullScreenManager)
2825         m_fullScreenManager = WebFullScreenManager::create(this);
2826     return m_fullScreenManager.get();
2827 }
2828 #endif
2829
2830 NotificationPermissionRequestManager* WebPage::notificationPermissionRequestManager()
2831 {
2832     if (m_notificationPermissionRequestManager)
2833         return m_notificationPermissionRequestManager.get();
2834
2835     m_notificationPermissionRequestManager = NotificationPermissionRequestManager::create(this);
2836     return m_notificationPermissionRequestManager.get();
2837 }
2838
2839 #if !PLATFORM(GTK) && !PLATFORM(COCOA)
2840 bool WebPage::handleEditingKeyboardEvent(KeyboardEvent* evt)
2841 {
2842     Node* node = evt->target()->toNode();
2843     ASSERT(node);
2844     Frame* frame = node->document().frame();
2845     ASSERT(frame);
2846
2847     const PlatformKeyboardEvent* keyEvent = evt->keyEvent();
2848     if (!keyEvent)
2849         return false;
2850
2851     Editor::Command command = frame->editor().command(interpretKeyEvent(evt));
2852
2853     if (keyEvent->type() == PlatformEvent::RawKeyDown) {
2854         // WebKit doesn't have enough information about mode to decide how commands that just insert text if executed via Editor should be treated,
2855         // so we leave it upon WebCore to either handle them immediately (e.g. Tab that changes focus) or let a keypress event be generated
2856         // (e.g. Tab that inserts a Tab character, or Enter).
2857         return !command.isTextInsertion() && command.execute(evt);
2858     }
2859
2860     if (command.execute(evt))
2861         return true;
2862
2863     // Don't allow text insertion for nodes that cannot edit.
2864     if (!frame->editor().canEdit())
2865         return false;
2866
2867     // Don't insert null or control characters as they can result in unexpected behaviour
2868     if (evt->charCode() < ' ')
2869         return false;
2870
2871     return frame->editor().insertText(evt->keyEvent()->text(), evt);
2872 }
2873 #endif
2874
2875 #if ENABLE(DRAG_SUPPORT)
2876
2877 #if PLATFORM(GTK)
2878 void WebPage::performDragControllerAction(uint64_t action, WebCore::DragData dragData)
2879 {
2880     if (!m_page) {
2881         send(Messages::WebPageProxy::DidPerformDragControllerAction(DragOperationNone, false, 0));
2882         DataObjectGtk* data = const_cast<DataObjectGtk*>(dragData.platformData());
2883         data->deref();
2884         return;
2885     }
2886
2887     switch (action) {
2888     case DragControllerActionEntered: {
2889         DragOperation resolvedDragOperation = m_page->dragController().dragEntered(dragData);
2890         send(Messages::WebPageProxy::DidPerformDragControllerAction(resolvedDragOperation, m_page->dragController().mouseIsOverFileInput(), m_page->dragController().numberOfItemsToBeAccepted()));
2891         break;
2892     }
2893     case DragControllerActionUpdated: {
2894         DragOperation resolvedDragOperation = m_page->dragController().dragEntered(dragData);
2895         send(Messages::WebPageProxy::DidPerformDragControllerAction(resolvedDragOperation, m_page->dragController().mouseIsOverFileInput(), m_page->dragController().numberOfItemsToBeAccepted()));
2896         break;
2897     }
2898     case DragControllerActionExited:
2899         m_page->dragController().dragExited(dragData);
2900         break;
2901
2902     case DragControllerActionPerformDragOperation: {
2903         m_page->dragController().performDragOperation(dragData);
2904         break;
2905     }
2906
2907     default:
2908         ASSERT_NOT_REACHED();
2909     }
2910     // DragData does not delete its platformData so we need to do that here.
2911     DataObjectGtk* data = const_cast<DataObjectGtk*>(dragData.platformData());
2912     data->deref();
2913 }
2914
2915 #else
2916 void WebPage::performDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, const String& dragStorageName, uint32_t flags, const SandboxExtension::Handle& sandboxExtensionHandle, const SandboxExtension::HandleArray& sandboxExtensionsHandleArray)
2917 {
2918     if (!m_page) {
2919         send(Messages::WebPageProxy::DidPerformDragControllerAction(DragOperationNone, false, 0));
2920         return;
2921     }
2922
2923     DragData dragData(dragStorageName, clientPosition, globalPosition, static_cast<DragOperation>(draggingSourceOperationMask), static_cast<DragApplicationFlags>(flags));
2924     switch (action) {
2925     case DragControllerActionEntered: {
2926         DragOperation resolvedDragOperation = m_page->dragController().dragEntered(dragData);
2927         send(Messages::WebPageProxy::DidPerformDragControllerAction(resolvedDragOperation, m_page->dragController().mouseIsOverFileInput(), m_page->dragController().numberOfItemsToBeAccepted()));
2928         break;
2929
2930     }
2931     case DragControllerActionUpdated: {
2932         DragOperation resolvedDragOperation = m_page->dragController().dragUpdated(dragData);
2933         send(Messages::WebPageProxy::DidPerformDragControllerAction(resolvedDragOperation, m_page->dragController().mouseIsOverFileInput(), m_page->dragController().numberOfItemsToBeAccepted()));
2934         break;
2935     }
2936     case DragControllerActionExited:
2937         m_page->dragController().dragExited(dragData);
2938         break;
2939         
2940     case DragControllerActionPerformDragOperation: {
2941         ASSERT(!m_pendingDropSandboxExtension);
2942
2943         m_pendingDropSandboxExtension = SandboxExtension::create(sandboxExtensionHandle);
2944         for (size_t i = 0; i < sandboxExtensionsHandleArray.size(); i++) {
2945             if (RefPtr<SandboxExtension> extension = SandboxExtension::create(sandboxExtensionsHandleArray[i]))
2946                 m_pendingDropExtensionsForFileUpload.append(extension);
2947         }
2948
2949         m_page->dragController().performDragOperation(dragData);
2950
2951         // If we started loading a local file, the sandbox extension tracker would have adopted this
2952         // pending drop sandbox extension. If not, we'll play it safe and clear it.
2953         m_pendingDropSandboxExtension = nullptr;
2954
2955         m_pendingDropExtensionsForFileUpload.clear();
2956         break;
2957     }
2958
2959     default:
2960         ASSERT_NOT_REACHED();
2961     }
2962 }
2963 #endif
2964
2965 void WebPage::dragEnded(WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t operation)
2966 {
2967     IntPoint adjustedClientPosition(clientPosition.x() + m_page->dragController().dragOffset().x(), clientPosition.y() + m_page->dragController().dragOffset().y());
2968     IntPoint adjustedGlobalPosition(globalPosition.x() + m_page->dragController().dragOffset().x(), globalPosition.y() + m_page->dragController().dragOffset().y());
2969
2970     m_page->dragController().dragEnded();
2971     FrameView* view = m_page->mainFrame().view();
2972     if (!view)
2973         return;
2974     // FIXME: These are fake modifier keys here, but they should be real ones instead.
2975     PlatformMouseEvent event(adjustedClientPosition, adjustedGlobalPosition, LeftButton, PlatformEvent::MouseMoved, 0, false, false, false, false, currentTime());
2976     m_page->mainFrame().eventHandler().dragSourceEndedAt(event, (DragOperation)operation);
2977 }
2978
2979 void WebPage::willPerformLoadDragDestinationAction()
2980 {
2981     m_sandboxExtensionTracker.willPerformLoadDragDestinationAction(m_pendingDropSandboxExtension.release());
2982 }
2983
2984 void WebPage::mayPerformUploadDragDestinationAction()
2985 {
2986     for (size_t i = 0; i < m_pendingDropExtensionsForFileUpload.size(); i++)
2987         m_pendingDropExtensionsForFileUpload[i]->consumePermanently();
2988     m_pendingDropExtensionsForFileUpload.clear();
2989 }
2990     
2991 #endif // ENABLE(DRAG_SUPPORT)
2992
2993 WebUndoStep* WebPage::webUndoStep(uint64_t stepID)
2994 {
2995     return m_undoStepMap.get(stepID);
2996 }
2997
2998 void WebPage::addWebUndoStep(uint64_t stepID, WebUndoStep* entry)
2999 {
3000     m_undoStepMap.set(stepID, entry);
3001 }
3002
3003 void WebPage::removeWebEditCommand(uint64_t stepID)
3004 {
3005     m_undoStepMap.remove(stepID);
3006 }
3007
3008 void WebPage::unapplyEditCommand(uint64_t stepID)
3009 {
3010     WebUndoStep* step = webUndoStep(stepID);
3011     if (!step)
3012         return;
3013
3014     step->step()->unapply();
3015 }
3016
3017 void WebPage::reapplyEditCommand(uint64_t stepID)
3018 {
3019     WebUndoStep* step = webUndoStep(stepID);
3020     if (!step)
3021         return;
3022
3023     m_isInRedo = true;
3024     step->step()->reapply();
3025     m_isInRedo = false;
3026 }
3027
3028 void WebPage::didRemoveEditCommand(uint64_t commandID)
3029 {
3030     removeWebEditCommand(commandID);
3031 }
3032
3033 void WebPage::setActivePopupMenu(WebPopupMenu* menu)
3034 {
3035     m_activePopupMenu = menu;
3036 }
3037
3038 #if ENABLE(INPUT_TYPE_COLOR)
3039 void WebPage::setActiveColorChooser(WebColorChooser* colorChooser)
3040 {
3041     m_activeColorChooser = colorChooser;
3042 }
3043
3044 void WebPage::didEndColorPicker()
3045 {
3046     m_activeColorChooser->didEndChooser();
3047 }
3048
3049 void WebPage::didChooseColor(const WebCore::Color& color)
3050 {
3051     m_activeColorChooser->didChooseColor(color);
3052 }
3053 #endif
3054
3055 void WebPage::setActiveOpenPanelResultListener(PassRefPtr<WebOpenPanelResultListener> openPanelResultListener)
3056 {
3057     m_activeOpenPanelResultListener = openPanelResultListener;
3058 }
3059
3060 bool WebPage::findStringFromInjectedBundle(const String& target, FindOptions options)
3061 {
3062     return m_page->findString(target, options);
3063 }
3064
3065 void WebPage::findString(const String& string, uint32_t options, uint32_t maxMatchCount)
3066 {
3067     m_findController.findString(string, static_cast<FindOptions>(options), maxMatchCount);
3068 }
3069
3070 void WebPage::findStringMatches(const String& string, uint32_t options, uint32_t maxMatchCount)
3071 {
3072     m_findController.findStringMatches(string, static_cast<FindOptions>(options), maxMatchCount);
3073 }
3074
3075 void WebPage::getImageForFindMatch(uint32_t matchIndex)
3076 {
3077     m_findController.getImageForFindMatch(matchIndex);
3078 }
3079
3080 void WebPage::selectFindMatch(uint32_t matchIndex)
3081 {
3082     m_findController.selectFindMatch(matchIndex);
3083 }
3084
3085 void WebPage::hideFindUI()
3086 {
3087     m_findController.hideFindUI();
3088 }
3089
3090 void WebPage::countStringMatches(const String& string, uint32_t options, uint32_t maxMatchCount)
3091 {
3092     m_findController.countStringMatches(string, static_cast<FindOptions>(options), maxMatchCount);
3093 }
3094
3095 void WebPage::didChangeSelectedIndexForActivePopupMenu(int32_t newIndex)
3096 {
3097     changeSelectedIndex(newIndex);
3098     m_activePopupMenu = 0;
3099 }
3100
3101 void WebPage::changeSelectedIndex(int32_t index)
3102 {
3103     if (!m_activePopupMenu)
3104         return;
3105
3106     m_activePopupMenu->didChangeSelectedIndex(index);
3107 }
3108
3109 #if PLATFORM(IOS)
3110 void WebPage::didChooseFilesForOpenPanelWithDisplayStringAndIcon(const Vector<String>& files, const String& displayString, const IPC::DataReference& iconData)
3111 {
3112     if (!m_activeOpenPanelResultListener)
3113         return;
3114
3115     RefPtr<Icon> icon;
3116     if (!iconData.isEmpty()) {
3117         RetainPtr<CFDataRef> dataRef = adoptCF(CFDataCreate(nullptr, iconData.data(), iconData.size()));
3118         RetainPtr<CGDataProviderRef> imageProviderRef = adoptCF(CGDataProviderCreateWithCFData(dataRef.get()));
3119         RetainPtr<CGImageRef> imageRef = adoptCF(CGImageCreateWithJPEGDataProvider(imageProviderRef.get(), nullptr, true, kCGRenderingIntentDefault));
3120         icon = Icon::createIconForImage(imageRef.get());
3121     }
3122
3123     m_activeOpenPanelResultListener->didChooseFilesWithDisplayStringAndIcon(files, displayString, icon.get());
3124     m_activeOpenPanelResultListener = nullptr;
3125 }
3126 #endif
3127
3128 void WebPage::didChooseFilesForOpenPanel(const Vector<String>& files)
3129 {
3130     if (!m_activeOpenPanelResultListener)
3131         return;
3132
3133     m_activeOpenPanelResultListener->didChooseFiles(files);
3134     m_activeOpenPanelResultListener = 0;
3135 }
3136
3137 void WebPage::didCancelForOpenPanel()
3138 {
3139     m_activeOpenPanelResultListener = 0;
3140 }
3141
3142 #if ENABLE(SANDBOX_EXTENSIONS)
3143 void WebPage::extendSandboxForFileFromOpenPanel(const SandboxExtension::Handle& handle)
3144 {
3145     SandboxExtension::create(handle)->consumePermanently();
3146 }
3147 #endif
3148
3149 #if ENABLE(GEOLOCATION)
3150 void WebPage::didReceiveGeolocationPermissionDecision(uint64_t geolocationID, bool allowed)
3151 {
3152     m_geolocationPermissionRequestManager.didReceiveGeolocationPermissionDecision(geolocationID, allowed);
3153 }
3154 #endif
3155
3156 void WebPage::didReceiveNotificationPermissionDecision(uint64_t notificationID, bool allowed)
3157 {
3158     notificationPermissionRequestManager()->didReceiveNotificationPermissionDecision(notificationID, allowed);
3159 }
3160
3161 #if !PLATFORM(IOS)
3162 void WebPage::advanceToNextMisspelling(bool startBeforeSelection)
3163 {
3164     Frame& frame = m_page->focusController().focusedOrMainFrame();
3165     frame.editor().advanceToNextMisspelling(startBeforeSelection);
3166 }
3167 #endif
3168
3169 void WebPage::changeSpellingToWord(const String& word)
3170 {
3171     replaceSelectionWithText(&m_page->focusController().focusedOrMainFrame(), word);
3172 }
3173
3174 void WebPage::unmarkAllMisspellings()
3175 {
3176     for (Frame* frame = &m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
3177         if (Document* document = frame->document())
3178             document->markers().removeMarkers(DocumentMarker::Spelling);
3179     }
3180 }
3181
3182 void WebPage::unmarkAllBadGrammar()
3183 {
3184     for (Frame* frame = &m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
3185         if (Document* document = frame->document())
3186             document->markers().removeMarkers(DocumentMarker::Grammar);
3187     }
3188 }
3189
3190 #if USE(APPKIT)
3191 void WebPage::uppercaseWord()
3192 {
3193     m_page->focusController().focusedOrMainFrame().editor().uppercaseWord();
3194 }
3195
3196 void WebPage::lowercaseWord()
3197 {
3198     m_page->focusController().focusedOrMainFrame().editor().lowercaseWord();
3199 }
3200
3201 void WebPage::capitalizeWord()
3202 {
3203     m_page->focusController().focusedOrMainFrame().editor().capitalizeWord();
3204 }
3205 #endif
3206     
3207 void WebPage::setTextForActivePopupMenu(int32_t index)
3208 {
3209     if (!m_activePopupMenu)
3210         return;
3211
3212     m_activePopupMenu->setTextForIndex(index);
3213 }
3214
3215 #if PLATFORM(GTK)
3216 void WebPage::failedToShowPopupMenu()
3217 {
3218     if (!m_activePopupMenu)
3219         return;
3220
3221     m_activePopupMenu->client()->popupDidHide();
3222 }
3223 #endif
3224
3225 #if ENABLE(CONTEXT_MENUS)
3226 void WebPage::didSelectItemFromActiveContextMenu(const WebContextMenuItemData& item)
3227 {
3228     if (!m_contextMenu)
3229         return;
3230
3231     m_contextMenu->itemSelected(item);
3232     m_contextMenu = 0;
3233 }
3234 #endif
3235
3236 void WebPage::replaceSelectionWithText(Frame* frame, const String& text)
3237 {
3238     bool selectReplacement = true;
3239     bool smartReplace = false;
3240     return frame->editor().replaceSelectionWithText(text, selectReplacement, smartReplace);
3241 }
3242
3243 #if !PLATFORM(IOS)
3244 void WebPage::clearSelection()
3245 {
3246     m_page->focusController().focusedOrMainFrame().selection().clear();
3247 }
3248 #endif
3249
3250 bool WebPage::mainFrameHasCustomContentProvider() const
3251 {
3252     if (Frame* frame = mainFrame()) {
3253         WebFrameLoaderClient* webFrameLoaderClient = toWebFrameLoaderClient(frame->loader().client());
3254         ASSERT(webFrameLoaderClient);
3255         return webFrameLoaderClient->frameHasCustomContentProvider();
3256     }
3257
3258     return false;
3259 }
3260
3261 void WebPage::addMIMETypeWithCustomContentProvider(const String& mimeType)
3262 {
3263     m_mimeTypesWithCustomContentProviders.add(mimeType);
3264 }
3265
3266 void WebPage::updateMainFrameScrollOffsetPinning()
3267 {
3268     Frame& frame = m_page->mainFrame();
3269     IntPoint scrollPosition = frame.view()->scrollPosition();
3270     IntPoint maximumScrollPosition = frame.view()->maximumScrollPosition();
3271     IntPoint minimumScrollPosition = frame.view()->minimumScrollPosition();
3272
3273     bool isPinnedToLeftSide = (scrollPosition.x() <= minimumScrollPosition.x());
3274     bool isPinnedToRightSide = (scrollPosition.x() >= maximumScrollPosition.x());
3275     bool isPinnedToTopSide = (scrollPosition.y() <= minimumScrollPosition.y());
3276     bool isPinnedToBottomSide = (scrollPosition.y() >= maximumScrollPosition.y());
3277
3278     if (isPinnedToLeftSide != m_cachedMainFrameIsPinnedToLeftSide || isPinnedToRightSide != m_cachedMainFrameIsPinnedToRightSide || isPinnedToTopSide != m_cachedMainFrameIsPinnedToTopSide || isPinnedToBottomSide != m_cachedMainFrameIsPinnedToBottomSide) {
3279         send(Messages::WebPageProxy::DidChangeScrollOffsetPinningForMainFrame(isPinnedToLeftSide, isPinnedToRightSide, isPinnedToTopSide, isPinnedToBottomSide));
3280         
3281         m_cachedMainFrameIsPinnedToLeftSide = isPinnedToLeftSide;
3282         m_cachedMainFrameIsPinnedToRightSide = isPinnedToRightSide;
3283         m_cachedMainFrameIsPinnedToTopSide = isPinnedToTopSide;
3284         m_cachedMainFrameIsPinnedToBottomSide = isPinnedToBottomSide;
3285     }
3286 }
3287
3288 void WebPage::mainFrameDidLayout()
3289 {
3290     unsigned pageCount = m_page->pageCount();
3291     if (pageCount != m_cachedPageCount) {
3292         send(Messages::WebPageProxy::DidChangePageCount(pageCount));
3293         m_cachedPageCount = pageCount;
3294     }
3295
3296 #if USE(TILED_BACKING_STORE)
3297     if (m_drawingArea && m_drawingArea->layerTreeHost()) {
3298         double red, green, blue, alpha;
3299         m_mainFrame->getDocumentBackgroundColor(&red, &green, &blue, &alpha);
3300         RGBA32 rgba = makeRGBA32FromFloats(red, green, blue, alpha);
3301         if (m_backgroundColor.rgb() != rgba) {
3302             m_backgroundColor.setRGB(rgba);
3303             m_drawingArea->layerTreeHost()->setBackgroundColor(m_backgroundColor);
3304         }
3305     }
3306 #endif
3307
3308 #if PLATFORM(MAC)
3309     m_viewGestureGeometryCollector.mainFrameDidLayout();
3310 #endif
3311 #if PLATFORM(IOS)
3312     if (FrameView* frameView = mainFrameView()) {
3313         IntSize newContentSize = frameView->contentsSize();
3314         if (m_viewportConfiguration.contentsSize() != newContentSize) {
3315             m_viewportConfiguration.setContentsSize(newContentSize);
3316             viewportConfigurationChanged();
3317         }
3318     }
3319 #endif
3320 }
3321
3322 void WebPage::addPluginView(PluginView* pluginView)
3323 {
3324     ASSERT(!m_pluginViews.contains(pluginView));
3325
3326     m_pluginViews.add(pluginView);
3327     m_hasSeenPlugin = true;
3328 #if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
3329     LOG(Plugins, "Primary Plug-In Detection: triggering detection from addPluginView(%p)", pluginView);
3330     m_determinePrimarySnapshottedPlugInTimer.startOneShot(0);
3331 #endif
3332 }
3333
3334 void WebPage::removePluginView(PluginView* pluginView)
3335 {
3336     ASSERT(m_pluginViews.contains(pluginView));
3337
3338     m_pluginViews.remove(pluginView);
3339 #if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
3340     LOG(Plugins, "Primary Plug-In Detection: removePluginView(%p)", pluginView);
3341 #endif
3342 }
3343
3344 void WebPage::sendSetWindowFrame(const FloatRect& windowFrame)
3345 {
3346 #if PLATFORM(COCOA)
3347     m_hasCachedWindowFrame = false;
3348 #endif
3349     send(Messages::WebPageProxy::SetWindowFrame(windowFrame));
3350 }
3351
3352 #if PLATFORM(COCOA)
3353 void WebPage::windowAndViewFramesChanged(const FloatRect& windowFrameInScreenCoordinates, const FloatRect& windowFrameInUnflippedScreenCoordinates, const FloatRect& viewFrameInWindowCoordinates, const FloatPoint& accessibilityViewCoordinates)
3354 {
3355     m_windowFrameInScreenCoordinates = windowFrameInScreenCoordinates;
3356     m_windowFrameInUnflippedScreenCoordinates = windowFrameInUnflippedScreenCoordinates;
3357     m_viewFrameInWindowCoordinates = viewFrameInWindowCoordinates;
3358     m_accessibilityPosition = accessibilityViewCoordinates;
3359     
3360     // Tell all our plug-in views that the window and view frames have changed.
3361     for (auto* pluginView : m_pluginViews)
3362         pluginView->windowAndViewFramesChanged(enclosingIntRect(windowFrameInScreenCoordinates), enclosingIntRect(viewFrameInWindowCoordinates));
3363
3364     m_hasCachedWindowFrame = !m_windowFrameInUnflippedScreenCoordinates.isEmpty();
3365 }
3366 #endif
3367
3368 void WebPage::setMainFrameIsScrollable(bool isScrollable)
3369 {
3370     m_mainFrameIsScrollable = isScrollable;
3371     m_drawingArea->mainFrameScrollabilityChanged(isScrollable);
3372
3373     if (FrameView* frameView = m_mainFrame->coreFrame()->view()) {
3374         frameView->setCanHaveScrollbars(isScrollable);
3375         frameView->setProhibitsScrolling(!isScrollable);
3376     }
3377 }
3378
3379 bool WebPage::windowIsFocused() const
3380 {
3381     return m_page->focusController().isActive();
3382 }
3383
3384 bool WebPage::windowAndWebPageAreFocused() const
3385 {
3386     if (!isVisible())
3387         return false;
3388
3389     return m_page->focusController().isFocused() && m_page->focusController().isActive();
3390 }
3391
3392 void WebPage::didReceiveMessage(IPC::Connection* connection, IPC::MessageDecoder& decoder)
3393 {
3394     if (decoder.messageReceiverName() == Messages::DrawingArea::messageReceiverName()) {
3395         if (m_drawingArea)
3396             m_drawingArea->didReceiveDrawingAreaMessage(connection, decoder);
3397         return;
3398     }
3399
3400 #if USE(TILED_BACKING_STORE)
3401     if (decoder.messageReceiverName() == Messages::CoordinatedLayerTreeHost::messageReceiverName()) {
3402         if (m_drawingArea)
3403             m_drawingArea->didReceiveCoordinatedLayerTreeHostMessage(connection, decoder);
3404         return;
3405     }
3406 #endif
3407     
3408 #if ENABLE(INSPECTOR)
3409     if (decoder.messageReceiverName() == Messages::WebInspector::messageReceiverName()) {
3410         if (WebInspector* inspector = this->inspector())
3411             inspector->didReceiveWebInspectorMessage(connection, decoder);
3412         return;
3413     }
3414 #endif
3415
3416 #if ENABLE(FULLSCREEN_API)
3417     if (decoder.messageReceiverName() == Messages::WebFullScreenManager::messageReceiverName()) {
3418         fullScreenManager()->didReceiveMessage(connection, decoder);
3419         return;
3420     }
3421 #endif
3422
3423     didReceiveWebPageMessage(connection, decoder);
3424 }
3425
3426 void WebPage::didReceiveSyncMessage(IPC::Connection* connection, IPC::MessageDecoder& decoder, std::unique_ptr<IPC::MessageEncoder>& replyEncoder)
3427 {   
3428     didReceiveSyncWebPageMessage(connection, decoder, replyEncoder);
3429 }
3430     
3431 InjectedBundleBackForwardList* WebPage::backForwardList()
3432 {
3433     if (!m_backForwardList)
3434         m_backForwardList = InjectedBundleBackForwardList::create(this);
3435     return m_backForwardList.get();
3436 }
3437
3438 #if ENABLE(ASYNC_SCROLLING)
3439 ScrollingCoordinator* WebPage::scrollingCoordinator() const
3440 {
3441     return m_page->scrollingCoordinator();
3442 }
3443 #endif
3444
3445 WebPage::SandboxExtensionTracker::~SandboxExtensionTracker()
3446 {
3447     invalidate();
3448 }
3449
3450 void WebPage::SandboxExtensionTracker::invalidate()
3451 {
3452     m_pendingProvisionalSandboxExtension = nullptr;
3453
3454     if (m_provisionalSandboxExtension) {
3455         m_provisionalSandboxExtension->revoke();
3456         m_provisionalSandboxExtension = nullptr;
3457     }
3458
3459     if (m_committedSandboxExtension) {
3460         m_committedSandboxExtension->revoke();
3461         m_committedSandboxExtension = nullptr;
3462     }
3463 }
3464
3465 void WebPage::SandboxExtensionTracker::willPerformLoadDragDestinationAction(PassRefPtr<SandboxExtension> pendingDropSandboxExtension)
3466 {
3467     setPendingProvisionalSandboxExtension(pendingDropSandboxExtension);
3468 }
3469
3470 void WebPage::SandboxExtensionTracker::beginLoad(WebFrame* frame, const SandboxExtension::Handle& handle)
3471 {
3472     ASSERT_UNUSED(frame, frame->isMainFrame());
3473
3474     setPendingProvisionalSandboxExtension(SandboxExtension::create(handle));
3475 }
3476
3477 void WebPage::SandboxExtensionTracker::setPendingProvisionalSandboxExtension(PassRefPtr<SandboxExtension> pendingProvisionalSandboxExtension)
3478 {
3479     m_pendingProvisionalSandboxExtension = pendingProvisionalSandboxExtension;    
3480 }
3481
3482 static bool shouldReuseCommittedSandboxExtension(WebFrame* frame)
3483 {
3484     ASSERT(frame->isMainFrame());
3485
3486     FrameLoader& frameLoader = frame->coreFrame()->loader();
3487     FrameLoadType frameLoadType = frameLoader.loadType();
3488
3489     // If the page is being reloaded, it should reuse whatever extension is committed.
3490     if (frameLoadType == FrameLoadType::Reload || frameLoadType == FrameLoadType::ReloadFromOrigin)
3491         return true;
3492
3493     DocumentLoader* documentLoader = frameLoader.documentLoader();
3494     DocumentLoader* provisionalDocumentLoader = frameLoader.provisionalDocumentLoader();
3495     if (!documentLoader || !provisionalDocumentLoader)
3496         return false;
3497
3498     if (documentLoader->url().isLocalFile() && provisionalDocumentLoader->url().isLocalFile())
3499         return true;
3500
3501     return false;
3502 }
3503
3504 void WebPage::SandboxExtensionTracker::didStartProvisionalLoad(WebFrame* frame)
3505 {
3506     if (!frame->isMainFrame())
3507         return;
3508
3509     // We should only reuse the commited sandbox extension if it is not null. It can be
3510     // null if the last load was for an error page.
3511     if (m_committedSandboxExtension && shouldReuseCommittedSandboxExtension(frame))
3512         m_pendingProvisionalSandboxExtension = m_committedSandboxExtension;
3513
3514     ASSERT(!m_provisionalSandboxExtension);
3515
3516     m_provisionalSandboxExtension = m_pendingProvisionalSandboxExtension.release();
3517     if (!m_provisionalSandboxExtension)
3518         return;
3519
3520     ASSERT(!m_provisionalSandboxExtension || frame->coreFrame()->loader().provisionalDocumentLoader()->url().isLocalFile());
3521
3522     m_provisionalSandboxExtension->consume();
3523 }
3524
3525 void WebPage::SandboxExtensionTracker::didCommitProvisionalLoad(WebFrame* frame)
3526 {
3527     if (!frame->isMainFrame())
3528         return;
3529
3530     if (m_committedSandboxExtension)
3531         m_committedSandboxExtension->revoke();
3532
3533     m_committedSandboxExtension = m_provisionalSandboxExtension.release();
3534
3535     // We can also have a non-null m_pendingProvisionalSandboxExtension if a new load is being started.
3536     // This extension is not cleared, because it does not pertain to the failed load, and will be needed.
3537 }
3538
3539 void WebPage::SandboxExtensionTracker::didFailProvisionalLoad(WebFrame* frame)
3540 {
3541     if (!frame->isMainFrame())
3542         return;
3543
3544     if (!m_provisionalSandboxExtension)
3545         return;
3546
3547 &n