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