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