• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010, 2011 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 #include "config.h"
27 #include "WebPage.h"
28 
29 #include "Arguments.h"
30 #include "DataReference.h"
31 #include "DecoderAdapter.h"
32 #include "DrawingArea.h"
33 #include "InjectedBundle.h"
34 #include "InjectedBundleBackForwardList.h"
35 #include "LayerTreeHost.h"
36 #include "MessageID.h"
37 #include "NetscapePlugin.h"
38 #include "PageOverlay.h"
39 #include "PluginProxy.h"
40 #include "PluginView.h"
41 #include "PrintInfo.h"
42 #include "RunLoop.h"
43 #include "SessionState.h"
44 #include "ShareableBitmap.h"
45 #include "WebBackForwardList.h"
46 #include "WebBackForwardListItem.h"
47 #include "WebBackForwardListProxy.h"
48 #include "WebChromeClient.h"
49 #include "WebContextMenu.h"
50 #include "WebContextMenuClient.h"
51 #include "WebContextMessages.h"
52 #include "WebCoreArgumentCoders.h"
53 #include "WebDragClient.h"
54 #include "WebEditorClient.h"
55 #include "WebEvent.h"
56 #include "WebEventConversion.h"
57 #include "WebFrame.h"
58 #include "WebFullScreenManager.h"
59 #include "WebGeolocationClient.h"
60 #include "WebImage.h"
61 #include "WebInspector.h"
62 #include "WebInspectorClient.h"
63 #include "WebOpenPanelResultListener.h"
64 #include "WebPageCreationParameters.h"
65 #include "WebPageGroupProxy.h"
66 #include "WebPageProxyMessages.h"
67 #include "WebPopupMenu.h"
68 #include "WebPreferencesStore.h"
69 #include "WebProcess.h"
70 #include "WebProcessProxyMessages.h"
71 #include <JavaScriptCore/APICast.h>
72 #include <WebCore/AbstractDatabase.h>
73 #include <WebCore/ArchiveResource.h>
74 #include <WebCore/Chrome.h>
75 #include <WebCore/ContextMenuController.h>
76 #include <WebCore/DocumentFragment.h>
77 #include <WebCore/DocumentLoader.h>
78 #include <WebCore/DocumentMarkerController.h>
79 #include <WebCore/DragController.h>
80 #include <WebCore/DragData.h>
81 #include <WebCore/EditingBehavior.h>
82 #include <WebCore/EventHandler.h>
83 #include <WebCore/FocusController.h>
84 #include <WebCore/FormState.h>
85 #include <WebCore/Frame.h>
86 #include <WebCore/FrameLoadRequest.h>
87 #include <WebCore/FrameLoaderTypes.h>
88 #include <WebCore/FrameView.h>
89 #include <WebCore/HTMLFormElement.h>
90 #include <WebCore/HistoryItem.h>
91 #include <WebCore/KeyboardEvent.h>
92 #include <WebCore/MouseEvent.h>
93 #include <WebCore/Page.h>
94 #include <WebCore/PlatformKeyboardEvent.h>
95 #include <WebCore/PrintContext.h>
96 #include <WebCore/RenderLayer.h>
97 #include <WebCore/RenderTreeAsText.h>
98 #include <WebCore/RenderView.h>
99 #include <WebCore/ReplaceSelectionCommand.h>
100 #include <WebCore/ResourceRequest.h>
101 #include <WebCore/SchemeRegistry.h>
102 #include <WebCore/SerializedScriptValue.h>
103 #include <WebCore/Settings.h>
104 #include <WebCore/SharedBuffer.h>
105 #include <WebCore/SubstituteData.h>
106 #include <WebCore/TextIterator.h>
107 #include <WebCore/markup.h>
108 #include <runtime/JSLock.h>
109 #include <runtime/JSValue.h>
110 
111 #include <WebCore/Range.h>
112 #include <WebCore/VisiblePosition.h>
113 
114 #if PLATFORM(MAC) || PLATFORM(WIN)
115 #include <WebCore/LegacyWebArchive.h>
116 #endif
117 
118 #if ENABLE(PLUGIN_PROCESS)
119 #if PLATFORM(MAC)
120 #include "MachPort.h"
121 #endif
122 #endif
123 
124 #if PLATFORM(QT)
125 #include "HitTestResult.h"
126 #endif
127 
128 #ifndef NDEBUG
129 #include <wtf/RefCountedLeakCounter.h>
130 #endif
131 
132 using namespace JSC;
133 using namespace WebCore;
134 
135 namespace WebKit {
136 
137 #ifndef NDEBUG
138 static WTF::RefCountedLeakCounter webPageCounter("WebPage");
139 #endif
140 
create(uint64_t pageID,const WebPageCreationParameters & parameters)141 PassRefPtr<WebPage> WebPage::create(uint64_t pageID, const WebPageCreationParameters& parameters)
142 {
143     RefPtr<WebPage> page = adoptRef(new WebPage(pageID, parameters));
144 
145     if (page->pageGroup()->isVisibleToInjectedBundle() && WebProcess::shared().injectedBundle())
146         WebProcess::shared().injectedBundle()->didCreatePage(page.get());
147 
148     return page.release();
149 }
150 
WebPage(uint64_t pageID,const WebPageCreationParameters & parameters)151 WebPage::WebPage(uint64_t pageID, const WebPageCreationParameters& parameters)
152     : m_viewSize(parameters.viewSize)
153     , m_drawsBackground(true)
154     , m_drawsTransparentBackground(false)
155     , m_isInRedo(false)
156     , m_isClosed(false)
157     , m_tabToLinks(false)
158 #if PLATFORM(MAC)
159     , m_windowIsVisible(false)
160     , m_isSmartInsertDeleteEnabled(parameters.isSmartInsertDeleteEnabled)
161     , m_keyboardEventBeingInterpreted(0)
162 #elif PLATFORM(WIN)
163     , m_nativeWindow(parameters.nativeWindow)
164 #endif
165     , m_findController(this)
166     , m_geolocationPermissionRequestManager(this)
167     , m_pageID(pageID)
168     , m_canRunBeforeUnloadConfirmPanel(parameters.canRunBeforeUnloadConfirmPanel)
169     , m_canRunModal(parameters.canRunModal)
170     , m_isRunningModal(false)
171     , m_userSpaceScaleFactor(parameters.userSpaceScaleFactor)
172     , m_cachedMainFrameIsPinnedToLeftSide(false)
173     , m_cachedMainFrameIsPinnedToRightSide(false)
174     , m_isShowingContextMenu(false)
175 #if PLATFORM(WIN)
176     , m_gestureReachedScrollingLimit(false)
177 #endif
178 {
179     ASSERT(m_pageID);
180 
181     Page::PageClients pageClients;
182     pageClients.chromeClient = new WebChromeClient(this);
183     pageClients.contextMenuClient = new WebContextMenuClient(this);
184     pageClients.editorClient = new WebEditorClient(this);
185     pageClients.dragClient = new WebDragClient(this);
186     pageClients.backForwardClient = WebBackForwardListProxy::create(this);
187 #if ENABLE(CLIENT_BASED_GEOLOCATION)
188     pageClients.geolocationClient = new WebGeolocationClient(this);
189 #endif
190 #if ENABLE(INSPECTOR)
191     pageClients.inspectorClient = new WebInspectorClient(this);
192 #endif
193     m_page = adoptPtr(new Page(pageClients));
194 
195     // Qt does not yet call setIsInWindow. Until it does, just leave
196     // this line out so plug-ins and video will work. Eventually all platforms
197     // should call setIsInWindow and this comment and #if should be removed,
198     // leaving behind the setCanStartMedia call.
199 #if !PLATFORM(QT)
200     m_page->setCanStartMedia(false);
201 #endif
202 
203     updatePreferences(parameters.store);
204 
205     m_pageGroup = WebProcess::shared().webPageGroup(parameters.pageGroupData);
206     m_page->setGroupName(m_pageGroup->identifier());
207 
208     platformInitialize();
209     Settings::setDefaultMinDOMTimerInterval(0.004);
210 
211     m_drawingArea = DrawingArea::create(this, parameters);
212     m_mainFrame = WebFrame::createMainFrame(this);
213 
214     setDrawsBackground(parameters.drawsBackground);
215     setDrawsTransparentBackground(parameters.drawsTransparentBackground);
216 
217     setMemoryCacheMessagesEnabled(parameters.areMemoryCacheClientCallsEnabled);
218 
219     setActive(parameters.isActive);
220     setFocused(parameters.isFocused);
221     setIsInWindow(parameters.isInWindow);
222 
223     m_userAgent = parameters.userAgent;
224 
225     WebBackForwardListProxy::setHighestItemIDFromUIProcess(parameters.highestUsedBackForwardItemID);
226 
227     if (!parameters.sessionState.isEmpty())
228         restoreSession(parameters.sessionState);
229 
230 #ifndef NDEBUG
231     webPageCounter.increment();
232 #endif
233 }
234 
~WebPage()235 WebPage::~WebPage()
236 {
237     if (m_backForwardList)
238         m_backForwardList->detach();
239 
240     ASSERT(!m_page);
241 
242     m_sandboxExtensionTracker.invalidate();
243 
244 #if PLATFORM(MAC)
245     ASSERT(m_pluginViews.isEmpty());
246 #endif
247 
248 #ifndef NDEBUG
249     webPageCounter.decrement();
250 #endif
251 }
252 
dummy(bool &)253 void WebPage::dummy(bool&)
254 {
255 }
256 
connection() const257 CoreIPC::Connection* WebPage::connection() const
258 {
259     return WebProcess::shared().connection();
260 }
261 
initializeInjectedBundleContextMenuClient(WKBundlePageContextMenuClient * client)262 void WebPage::initializeInjectedBundleContextMenuClient(WKBundlePageContextMenuClient* client)
263 {
264     m_contextMenuClient.initialize(client);
265 }
266 
initializeInjectedBundleEditorClient(WKBundlePageEditorClient * client)267 void WebPage::initializeInjectedBundleEditorClient(WKBundlePageEditorClient* client)
268 {
269     m_editorClient.initialize(client);
270 }
271 
initializeInjectedBundleFormClient(WKBundlePageFormClient * client)272 void WebPage::initializeInjectedBundleFormClient(WKBundlePageFormClient* client)
273 {
274     m_formClient.initialize(client);
275 }
276 
initializeInjectedBundleLoaderClient(WKBundlePageLoaderClient * client)277 void WebPage::initializeInjectedBundleLoaderClient(WKBundlePageLoaderClient* client)
278 {
279     m_loaderClient.initialize(client);
280 }
281 
initializeInjectedBundlePolicyClient(WKBundlePagePolicyClient * client)282 void WebPage::initializeInjectedBundlePolicyClient(WKBundlePagePolicyClient* client)
283 {
284     m_policyClient.initialize(client);
285 }
286 
initializeInjectedBundleResourceLoadClient(WKBundlePageResourceLoadClient * client)287 void WebPage::initializeInjectedBundleResourceLoadClient(WKBundlePageResourceLoadClient* client)
288 {
289     m_resourceLoadClient.initialize(client);
290 }
291 
initializeInjectedBundleUIClient(WKBundlePageUIClient * client)292 void WebPage::initializeInjectedBundleUIClient(WKBundlePageUIClient* client)
293 {
294     m_uiClient.initialize(client);
295 }
296 
297 #if ENABLE(FULLSCREEN_API)
initializeInjectedBundleFullScreenClient(WKBundlePageFullScreenClient * client)298 void WebPage::initializeInjectedBundleFullScreenClient(WKBundlePageFullScreenClient* client)
299 {
300     m_fullScreenClient.initialize(client);
301 }
302 #endif
303 
createPlugin(const Plugin::Parameters & parameters)304 PassRefPtr<Plugin> WebPage::createPlugin(const Plugin::Parameters& parameters)
305 {
306     String pluginPath;
307 
308     if (!WebProcess::shared().connection()->sendSync(
309             Messages::WebContext::GetPluginPath(parameters.mimeType, parameters.url.string()),
310             Messages::WebContext::GetPluginPath::Reply(pluginPath), 0)) {
311         return 0;
312     }
313 
314     if (pluginPath.isNull())
315         return 0;
316 
317 #if ENABLE(PLUGIN_PROCESS)
318     return PluginProxy::create(pluginPath);
319 #else
320     return NetscapePlugin::create(NetscapePluginModule::getOrCreate(pluginPath));
321 #endif
322 }
323 
editorState() const324 EditorState WebPage::editorState() const
325 {
326     Frame* frame = m_page->focusController()->focusedOrMainFrame();
327     ASSERT(frame);
328 
329     EditorState result;
330     result.selectionIsNone = frame->selection()->isNone();
331     result.selectionIsRange = frame->selection()->isRange();
332     result.isContentEditable = frame->selection()->isContentEditable();
333     result.isContentRichlyEditable = frame->selection()->isContentRichlyEditable();
334     result.isInPasswordField = frame->selection()->isInPasswordField();
335     result.hasComposition = frame->editor()->hasComposition();
336 
337     return result;
338 }
339 
renderTreeExternalRepresentation() const340 String WebPage::renderTreeExternalRepresentation() const
341 {
342     return externalRepresentation(m_mainFrame->coreFrame(), RenderAsTextBehaviorNormal);
343 }
344 
executeEditingCommand(const String & commandName,const String & argument)345 void WebPage::executeEditingCommand(const String& commandName, const String& argument)
346 {
347     Frame* frame = m_page->focusController()->focusedOrMainFrame();
348     if (!frame)
349         return;
350     frame->editor()->command(commandName).execute(argument);
351 }
352 
isEditingCommandEnabled(const String & commandName)353 bool WebPage::isEditingCommandEnabled(const String& commandName)
354 {
355     Frame* frame = m_page->focusController()->focusedOrMainFrame();
356     if (!frame)
357         return false;
358 
359     Editor::Command command = frame->editor()->command(commandName);
360     return command.isSupported() && command.isEnabled();
361 }
362 
clearMainFrameName()363 void WebPage::clearMainFrameName()
364 {
365     mainFrame()->coreFrame()->tree()->clearName();
366 }
367 
368 #if USE(ACCELERATED_COMPOSITING)
enterAcceleratedCompositingMode(GraphicsLayer * layer)369 void WebPage::enterAcceleratedCompositingMode(GraphicsLayer* layer)
370 {
371     m_drawingArea->setRootCompositingLayer(layer);
372 }
373 
exitAcceleratedCompositingMode()374 void WebPage::exitAcceleratedCompositingMode()
375 {
376     m_drawingArea->setRootCompositingLayer(0);
377 }
378 #endif
379 
close()380 void WebPage::close()
381 {
382     if (m_isClosed)
383         return;
384 
385     m_isClosed = true;
386 
387     if (pageGroup()->isVisibleToInjectedBundle() && WebProcess::shared().injectedBundle())
388         WebProcess::shared().injectedBundle()->willDestroyPage(this);
389 
390 #if ENABLE(INSPECTOR)
391     m_inspector = 0;
392 #endif
393 #if ENABLE(FULLSCREEN_API)
394     m_fullScreenManager = 0;
395 #endif
396 
397     if (m_activePopupMenu) {
398         m_activePopupMenu->disconnectFromPage();
399         m_activePopupMenu = 0;
400     }
401 
402     if (m_activeOpenPanelResultListener) {
403         m_activeOpenPanelResultListener->disconnectFromPage();
404         m_activeOpenPanelResultListener = 0;
405     }
406 
407     m_sandboxExtensionTracker.invalidate();
408 
409     m_printContext = nullptr;
410 
411     m_mainFrame->coreFrame()->loader()->detachFromParent();
412     m_page.clear();
413 
414     m_drawingArea.clear();
415 
416     bool isRunningModal = m_isRunningModal;
417     m_isRunningModal = false;
418 
419     // The WebPage can be destroyed by this call.
420     WebProcess::shared().removeWebPage(m_pageID);
421 
422     if (isRunningModal)
423         WebProcess::shared().runLoop()->stop();
424 }
425 
tryClose()426 void WebPage::tryClose()
427 {
428     if (!m_mainFrame->coreFrame()->loader()->shouldClose())
429         return;
430 
431     sendClose();
432 }
433 
sendClose()434 void WebPage::sendClose()
435 {
436     send(Messages::WebPageProxy::ClosePage());
437 }
438 
loadURL(const String & url,const SandboxExtension::Handle & sandboxExtensionHandle)439 void WebPage::loadURL(const String& url, const SandboxExtension::Handle& sandboxExtensionHandle)
440 {
441     loadURLRequest(ResourceRequest(KURL(KURL(), url)), sandboxExtensionHandle);
442 }
443 
loadURLRequest(const ResourceRequest & request,const SandboxExtension::Handle & sandboxExtensionHandle)444 void WebPage::loadURLRequest(const ResourceRequest& request, const SandboxExtension::Handle& sandboxExtensionHandle)
445 {
446     m_sandboxExtensionTracker.beginLoad(m_mainFrame.get(), sandboxExtensionHandle);
447     m_mainFrame->coreFrame()->loader()->load(request, false);
448 }
449 
loadData(PassRefPtr<SharedBuffer> sharedBuffer,const String & MIMEType,const String & encodingName,const KURL & baseURL,const KURL & unreachableURL)450 void WebPage::loadData(PassRefPtr<SharedBuffer> sharedBuffer, const String& MIMEType, const String& encodingName, const KURL& baseURL, const KURL& unreachableURL)
451 {
452     ResourceRequest request(baseURL);
453     SubstituteData substituteData(sharedBuffer, MIMEType, encodingName, unreachableURL);
454     m_mainFrame->coreFrame()->loader()->load(request, substituteData, false);
455 }
456 
loadHTMLString(const String & htmlString,const String & baseURLString)457 void WebPage::loadHTMLString(const String& htmlString, const String& baseURLString)
458 {
459     RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(htmlString.characters()), htmlString.length() * sizeof(UChar));
460     KURL baseURL = baseURLString.isEmpty() ? blankURL() : KURL(KURL(), baseURLString);
461     loadData(sharedBuffer, "text/html", "utf-16", baseURL, KURL());
462 }
463 
loadAlternateHTMLString(const String & htmlString,const String & baseURLString,const String & unreachableURLString)464 void WebPage::loadAlternateHTMLString(const String& htmlString, const String& baseURLString, const String& unreachableURLString)
465 {
466     RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(htmlString.characters()), htmlString.length() * sizeof(UChar));
467     KURL baseURL = baseURLString.isEmpty() ? blankURL() : KURL(KURL(), baseURLString);
468     KURL unreachableURL = unreachableURLString.isEmpty() ? KURL() : KURL(KURL(), unreachableURLString);
469     loadData(sharedBuffer, "text/html", "utf-16", baseURL, unreachableURL);
470 }
471 
loadPlainTextString(const String & string)472 void WebPage::loadPlainTextString(const String& string)
473 {
474     RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(string.characters()), string.length() * sizeof(UChar));
475     loadData(sharedBuffer, "text/plain", "utf-16", blankURL(), KURL());
476 }
477 
linkClicked(const String & url,const WebMouseEvent & event)478 void WebPage::linkClicked(const String& url, const WebMouseEvent& event)
479 {
480     Frame* frame = m_page->mainFrame();
481     if (!frame)
482         return;
483 
484     RefPtr<Event> coreEvent;
485     if (event.type() != WebEvent::NoType)
486         coreEvent = MouseEvent::create(eventNames().clickEvent, frame->document()->defaultView(), platform(event), 0, 0);
487 
488     frame->loader()->loadFrameRequest(FrameLoadRequest(frame->document()->securityOrigin(), ResourceRequest(url)),
489         false, false, coreEvent.get(), 0, SendReferrer);
490 }
491 
stopLoadingFrame(uint64_t frameID)492 void WebPage::stopLoadingFrame(uint64_t frameID)
493 {
494     WebFrame* frame = WebProcess::shared().webFrame(frameID);
495     if (!frame)
496         return;
497 
498     frame->coreFrame()->loader()->stopForUserCancel();
499 }
500 
stopLoading()501 void WebPage::stopLoading()
502 {
503     m_mainFrame->coreFrame()->loader()->stopForUserCancel();
504 }
505 
setDefersLoading(bool defersLoading)506 void WebPage::setDefersLoading(bool defersLoading)
507 {
508     m_page->setDefersLoading(defersLoading);
509 }
510 
reload(bool reloadFromOrigin)511 void WebPage::reload(bool reloadFromOrigin)
512 {
513     m_mainFrame->coreFrame()->loader()->reload(reloadFromOrigin);
514 }
515 
goForward(uint64_t backForwardItemID,const SandboxExtension::Handle & sandboxExtensionHandle)516 void WebPage::goForward(uint64_t backForwardItemID, const SandboxExtension::Handle& sandboxExtensionHandle)
517 {
518     HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID);
519     ASSERT(item);
520     if (!item)
521         return;
522 
523     m_sandboxExtensionTracker.beginLoad(m_mainFrame.get(), sandboxExtensionHandle);
524     m_page->goToItem(item, FrameLoadTypeForward);
525 }
526 
goBack(uint64_t backForwardItemID,const SandboxExtension::Handle & sandboxExtensionHandle)527 void WebPage::goBack(uint64_t backForwardItemID, const SandboxExtension::Handle& sandboxExtensionHandle)
528 {
529     HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID);
530     ASSERT(item);
531     if (!item)
532         return;
533 
534     m_sandboxExtensionTracker.beginLoad(m_mainFrame.get(), sandboxExtensionHandle);
535     m_page->goToItem(item, FrameLoadTypeBack);
536 }
537 
goToBackForwardItem(uint64_t backForwardItemID,const SandboxExtension::Handle & sandboxExtensionHandle)538 void WebPage::goToBackForwardItem(uint64_t backForwardItemID, const SandboxExtension::Handle& sandboxExtensionHandle)
539 {
540     HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID);
541     ASSERT(item);
542     if (!item)
543         return;
544 
545     m_sandboxExtensionTracker.beginLoad(m_mainFrame.get(), sandboxExtensionHandle);
546     m_page->goToItem(item, FrameLoadTypeIndexedBackForward);
547 }
548 
layoutIfNeeded()549 void WebPage::layoutIfNeeded()
550 {
551     if (m_mainFrame->coreFrame()->view())
552         m_mainFrame->coreFrame()->view()->updateLayoutAndStyleIfNeededRecursive();
553 }
554 
setSize(const WebCore::IntSize & viewSize)555 void WebPage::setSize(const WebCore::IntSize& viewSize)
556 {
557 #if ENABLE(TILED_BACKING_STORE)
558     // If we are resizing to content ignore external attempts.
559     if (!m_resizesToContentsLayoutSize.isEmpty())
560         return;
561 #endif
562 
563     if (m_viewSize == viewSize)
564         return;
565 
566     Frame* frame = m_page->mainFrame();
567 
568     frame->view()->resize(viewSize);
569     frame->view()->setNeedsLayout();
570     m_drawingArea->setNeedsDisplay(IntRect(IntPoint(0, 0), viewSize));
571 
572     m_viewSize = viewSize;
573 }
574 
575 #if ENABLE(TILED_BACKING_STORE)
setActualVisibleContentRect(const IntRect & rect)576 void WebPage::setActualVisibleContentRect(const IntRect& rect)
577 {
578     Frame* frame = m_page->mainFrame();
579 
580     frame->view()->setActualVisibleContentRect(rect);
581 }
582 
setResizesToContentsUsingLayoutSize(const IntSize & targetLayoutSize)583 void WebPage::setResizesToContentsUsingLayoutSize(const IntSize& targetLayoutSize)
584 {
585     if (m_resizesToContentsLayoutSize == targetLayoutSize)
586         return;
587 
588     m_resizesToContentsLayoutSize = targetLayoutSize;
589 
590     Frame* frame = m_page->mainFrame();
591     if (m_resizesToContentsLayoutSize.isEmpty()) {
592         frame->view()->setDelegatesScrolling(false);
593         frame->view()->setUseFixedLayout(false);
594         frame->view()->setPaintsEntireContents(false);
595     } else {
596         frame->view()->setDelegatesScrolling(true);
597         frame->view()->setUseFixedLayout(true);
598         frame->view()->setPaintsEntireContents(true);
599         frame->view()->setFixedLayoutSize(m_resizesToContentsLayoutSize);
600     }
601     frame->view()->forceLayout();
602 }
603 
resizeToContentsIfNeeded()604 void WebPage::resizeToContentsIfNeeded()
605 {
606     if (m_resizesToContentsLayoutSize.isEmpty())
607         return;
608 
609     Frame* frame = m_page->mainFrame();
610 
611     IntSize contentSize = frame->view()->contentsSize();
612     if (contentSize == m_viewSize)
613         return;
614 
615     m_viewSize = contentSize;
616     frame->view()->resize(m_viewSize);
617     frame->view()->setNeedsLayout();
618 }
619 #endif
620 
scrollMainFrameIfNotAtMaxScrollPosition(const IntSize & scrollOffset)621 void WebPage::scrollMainFrameIfNotAtMaxScrollPosition(const IntSize& scrollOffset)
622 {
623     Frame* frame = m_page->mainFrame();
624 
625     IntPoint scrollPosition = frame->view()->scrollPosition();
626     IntPoint maximumScrollPosition = frame->view()->maximumScrollPosition();
627 
628     // If the current scroll position in a direction is the max scroll position
629     // we don't want to scroll at all.
630     IntSize newScrollOffset;
631     if (scrollPosition.x() < maximumScrollPosition.x())
632         newScrollOffset.setWidth(scrollOffset.width());
633     if (scrollPosition.y() < maximumScrollPosition.y())
634         newScrollOffset.setHeight(scrollOffset.height());
635 
636     if (newScrollOffset.isZero())
637         return;
638 
639     frame->view()->setScrollPosition(frame->view()->scrollPosition() + newScrollOffset);
640 }
641 
drawRect(GraphicsContext & graphicsContext,const IntRect & rect)642 void WebPage::drawRect(GraphicsContext& graphicsContext, const IntRect& rect)
643 {
644     graphicsContext.save();
645     graphicsContext.clip(rect);
646     m_mainFrame->coreFrame()->view()->paint(&graphicsContext, rect);
647     graphicsContext.restore();
648 }
649 
drawPageOverlay(GraphicsContext & graphicsContext,const IntRect & rect)650 void WebPage::drawPageOverlay(GraphicsContext& graphicsContext, const IntRect& rect)
651 {
652     ASSERT(m_pageOverlay);
653 
654     graphicsContext.save();
655     graphicsContext.clip(rect);
656     m_pageOverlay->drawRect(graphicsContext, rect);
657     graphicsContext.restore();
658 }
659 
textZoomFactor() const660 double WebPage::textZoomFactor() const
661 {
662     Frame* frame = m_mainFrame->coreFrame();
663     if (!frame)
664         return 1;
665     return frame->textZoomFactor();
666 }
667 
setTextZoomFactor(double zoomFactor)668 void WebPage::setTextZoomFactor(double zoomFactor)
669 {
670     Frame* frame = m_mainFrame->coreFrame();
671     if (!frame)
672         return;
673     frame->setTextZoomFactor(static_cast<float>(zoomFactor));
674 }
675 
pageZoomFactor() const676 double WebPage::pageZoomFactor() const
677 {
678     Frame* frame = m_mainFrame->coreFrame();
679     if (!frame)
680         return 1;
681     return frame->pageZoomFactor();
682 }
683 
setPageZoomFactor(double zoomFactor)684 void WebPage::setPageZoomFactor(double zoomFactor)
685 {
686     Frame* frame = m_mainFrame->coreFrame();
687     if (!frame)
688         return;
689     frame->setPageZoomFactor(static_cast<float>(zoomFactor));
690 }
691 
setPageAndTextZoomFactors(double pageZoomFactor,double textZoomFactor)692 void WebPage::setPageAndTextZoomFactors(double pageZoomFactor, double textZoomFactor)
693 {
694     Frame* frame = m_mainFrame->coreFrame();
695     if (!frame)
696         return;
697     return frame->setPageAndTextZoomFactors(static_cast<float>(pageZoomFactor), static_cast<float>(textZoomFactor));
698 }
699 
scaleWebView(double scale,const IntPoint & origin)700 void WebPage::scaleWebView(double scale, const IntPoint& origin)
701 {
702     Frame* frame = m_mainFrame->coreFrame();
703     if (!frame)
704         return;
705     frame->scalePage(scale, origin);
706 
707     send(Messages::WebPageProxy::ViewScaleFactorDidChange(scale));
708 }
709 
viewScaleFactor() const710 double WebPage::viewScaleFactor() const
711 {
712     Frame* frame = m_mainFrame->coreFrame();
713     if (!frame)
714         return 1;
715     return frame->pageScaleFactor();
716 }
717 
setUseFixedLayout(bool fixed)718 void WebPage::setUseFixedLayout(bool fixed)
719 {
720     Frame* frame = m_mainFrame->coreFrame();
721     if (!frame)
722         return;
723 
724     FrameView* view = frame->view();
725     if (!view)
726         return;
727 
728     view->setUseFixedLayout(fixed);
729     if (!fixed)
730         view->setFixedLayoutSize(IntSize());
731 }
732 
setFixedLayoutSize(const IntSize & size)733 void WebPage::setFixedLayoutSize(const IntSize& size)
734 {
735     Frame* frame = m_mainFrame->coreFrame();
736     if (!frame)
737         return;
738 
739     FrameView* view = frame->view();
740     if (!view)
741         return;
742 
743     view->setFixedLayoutSize(size);
744     view->forceLayout();
745 }
746 
installPageOverlay(PassRefPtr<PageOverlay> pageOverlay)747 void WebPage::installPageOverlay(PassRefPtr<PageOverlay> pageOverlay)
748 {
749     bool shouldFadeIn = true;
750 
751     if (m_pageOverlay) {
752         m_pageOverlay->setPage(0);
753 
754         if (pageOverlay) {
755             // We're installing a page overlay when a page overlay is already active.
756             // In this case we don't want to fade in the new overlay.
757             shouldFadeIn = false;
758         }
759     }
760 
761     m_pageOverlay = pageOverlay;
762     m_pageOverlay->setPage(this);
763 
764     if (shouldFadeIn)
765         m_pageOverlay->startFadeInAnimation();
766 
767     m_drawingArea->didInstallPageOverlay();
768     m_pageOverlay->setNeedsDisplay();
769 }
770 
uninstallPageOverlay(PageOverlay * pageOverlay,bool fadeOut)771 void WebPage::uninstallPageOverlay(PageOverlay* pageOverlay, bool fadeOut)
772 {
773     if (pageOverlay != m_pageOverlay)
774         return;
775 
776     if (fadeOut) {
777         m_pageOverlay->startFadeOutAnimation();
778         return;
779     }
780 
781     m_pageOverlay->setPage(0);
782     m_pageOverlay = nullptr;
783 
784     m_drawingArea->didUninstallPageOverlay();
785 }
786 
snapshotInViewCoordinates(const IntRect & rect,ImageOptions options)787 PassRefPtr<WebImage> WebPage::snapshotInViewCoordinates(const IntRect& rect, ImageOptions options)
788 {
789     FrameView* frameView = m_mainFrame->coreFrame()->view();
790     if (!frameView)
791         return 0;
792 
793     frameView->updateLayoutAndStyleIfNeededRecursive();
794 
795     PaintBehavior oldBehavior = frameView->paintBehavior();
796     frameView->setPaintBehavior(oldBehavior | PaintBehaviorFlattenCompositingLayers);
797 
798     RefPtr<WebImage> snapshot = WebImage::create(rect.size(), options);
799     OwnPtr<WebCore::GraphicsContext> graphicsContext = snapshot->bitmap()->createGraphicsContext();
800 
801     graphicsContext->save();
802     graphicsContext->translate(-rect.x(), -rect.y());
803     frameView->paint(graphicsContext.get(), rect);
804     graphicsContext->restore();
805 
806     frameView->setPaintBehavior(oldBehavior);
807 
808     return snapshot.release();
809 }
810 
scaledSnapshotInDocumentCoordinates(const IntRect & rect,double scaleFactor,ImageOptions options)811 PassRefPtr<WebImage> WebPage::scaledSnapshotInDocumentCoordinates(const IntRect& rect, double scaleFactor, ImageOptions options)
812 {
813     FrameView* frameView = m_mainFrame->coreFrame()->view();
814     if (!frameView)
815         return 0;
816 
817     frameView->updateLayoutAndStyleIfNeededRecursive();
818 
819     PaintBehavior oldBehavior = frameView->paintBehavior();
820     frameView->setPaintBehavior(oldBehavior | PaintBehaviorFlattenCompositingLayers);
821 
822     bool scale = scaleFactor != 1;
823     IntSize size = rect.size();
824     if (scale)
825         size = IntSize(ceil(rect.width() * scaleFactor), ceil(rect.height() * scaleFactor));
826 
827     RefPtr<WebImage> snapshot = WebImage::create(size, options);
828     OwnPtr<WebCore::GraphicsContext> graphicsContext = snapshot->bitmap()->createGraphicsContext();
829     graphicsContext->save();
830 
831     if (scale)
832         graphicsContext->scale(FloatSize(scaleFactor, scaleFactor));
833 
834     graphicsContext->translate(-rect.x(), -rect.y());
835     frameView->paintContents(graphicsContext.get(), rect);
836     graphicsContext->restore();
837 
838     frameView->setPaintBehavior(oldBehavior);
839 
840     return snapshot.release();
841 }
842 
snapshotInDocumentCoordinates(const IntRect & rect,ImageOptions options)843 PassRefPtr<WebImage> WebPage::snapshotInDocumentCoordinates(const IntRect& rect, ImageOptions options)
844 {
845     return scaledSnapshotInDocumentCoordinates(rect, 1, options);
846 }
847 
pageDidScroll()848 void WebPage::pageDidScroll()
849 {
850     // Hide the find indicator.
851     m_findController.hideFindIndicator();
852 
853     m_uiClient.pageDidScroll(this);
854 
855     send(Messages::WebPageProxy::PageDidScroll());
856 }
857 
858 #if ENABLE(TILED_BACKING_STORE)
pageDidRequestScroll(const IntPoint & point)859 void WebPage::pageDidRequestScroll(const IntPoint& point)
860 {
861     send(Messages::WebPageProxy::PageDidRequestScroll(point));
862 }
863 #endif
864 
contextMenu()865 WebContextMenu* WebPage::contextMenu()
866 {
867     if (!m_contextMenu)
868         m_contextMenu = WebContextMenu::create(this);
869     return m_contextMenu.get();
870 }
871 
872 // Events
873 
874 static const WebEvent* g_currentEvent = 0;
875 
876 // FIXME: WebPage::currentEvent is used by the plug-in code to avoid having to convert from DOM events back to
877 // WebEvents. When we get the event handling sorted out, this should go away and the Widgets should get the correct
878 // platform events passed to the event handler code.
currentEvent()879 const WebEvent* WebPage::currentEvent()
880 {
881     return g_currentEvent;
882 }
883 
884 class CurrentEvent {
885 public:
CurrentEvent(const WebEvent & event)886     explicit CurrentEvent(const WebEvent& event)
887         : m_previousCurrentEvent(g_currentEvent)
888     {
889         g_currentEvent = &event;
890     }
891 
~CurrentEvent()892     ~CurrentEvent()
893     {
894         g_currentEvent = m_previousCurrentEvent;
895     }
896 
897 private:
898     const WebEvent* m_previousCurrentEvent;
899 };
900 
isContextClick(const PlatformMouseEvent & event)901 static bool isContextClick(const PlatformMouseEvent& event)
902 {
903     if (event.button() == WebCore::RightButton)
904         return true;
905 
906 #if PLATFORM(MAC)
907     // FIXME: this really should be about OSX-style UI, not about the Mac port
908     if (event.button() == WebCore::LeftButton && event.ctrlKey())
909         return true;
910 #endif
911 
912     return false;
913 }
914 
handleMouseEvent(const WebMouseEvent & mouseEvent,Page * page)915 static bool handleMouseEvent(const WebMouseEvent& mouseEvent, Page* page)
916 {
917     Frame* frame = page->mainFrame();
918     if (!frame->view())
919         return false;
920 
921     PlatformMouseEvent platformMouseEvent = platform(mouseEvent);
922 
923     switch (platformMouseEvent.eventType()) {
924         case WebCore::MouseEventPressed:
925         {
926             if (isContextClick(platformMouseEvent))
927                 page->contextMenuController()->clearContextMenu();
928 
929             bool handled = frame->eventHandler()->handleMousePressEvent(platformMouseEvent);
930 
931             if (isContextClick(platformMouseEvent)) {
932                 handled = frame->eventHandler()->sendContextMenuEvent(platformMouseEvent);
933                 if (handled)
934                     page->chrome()->showContextMenu();
935             }
936 
937             return handled;
938         }
939         case WebCore::MouseEventReleased:
940             return frame->eventHandler()->handleMouseReleaseEvent(platformMouseEvent);
941         case WebCore::MouseEventMoved:
942             return frame->eventHandler()->mouseMoved(platformMouseEvent);
943 
944         default:
945             ASSERT_NOT_REACHED();
946             return false;
947     }
948 }
949 
mouseEvent(const WebMouseEvent & mouseEvent)950 void WebPage::mouseEvent(const WebMouseEvent& mouseEvent)
951 {
952     // Don't try to handle any pending mouse events if a context menu is showing.
953     if (m_isShowingContextMenu) {
954         send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(mouseEvent.type()), false));
955         return;
956     }
957 
958     bool handled = false;
959 
960     if (m_pageOverlay) {
961         // Let the page overlay handle the event.
962         handled = m_pageOverlay->mouseEvent(mouseEvent);
963     }
964 
965     if (!handled) {
966         CurrentEvent currentEvent(mouseEvent);
967 
968         handled = handleMouseEvent(mouseEvent, m_page.get());
969     }
970 
971     send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(mouseEvent.type()), handled));
972 }
973 
handleWheelEvent(const WebWheelEvent & wheelEvent,Page * page)974 static bool handleWheelEvent(const WebWheelEvent& wheelEvent, Page* page)
975 {
976     Frame* frame = page->mainFrame();
977     if (!frame->view())
978         return false;
979 
980     PlatformWheelEvent platformWheelEvent = platform(wheelEvent);
981     return frame->eventHandler()->handleWheelEvent(platformWheelEvent);
982 }
983 
wheelEvent(const WebWheelEvent & wheelEvent)984 void WebPage::wheelEvent(const WebWheelEvent& wheelEvent)
985 {
986     CurrentEvent currentEvent(wheelEvent);
987 
988     bool handled = handleWheelEvent(wheelEvent, m_page.get());
989     send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(wheelEvent.type()), handled));
990 }
991 
handleKeyEvent(const WebKeyboardEvent & keyboardEvent,Page * page)992 static bool handleKeyEvent(const WebKeyboardEvent& keyboardEvent, Page* page)
993 {
994     if (!page->mainFrame()->view())
995         return false;
996 
997     if (keyboardEvent.type() == WebEvent::Char && keyboardEvent.isSystemKey())
998         return page->focusController()->focusedOrMainFrame()->eventHandler()->handleAccessKey(platform(keyboardEvent));
999     return page->focusController()->focusedOrMainFrame()->eventHandler()->keyEvent(platform(keyboardEvent));
1000 }
1001 
keyEvent(const WebKeyboardEvent & keyboardEvent)1002 void WebPage::keyEvent(const WebKeyboardEvent& keyboardEvent)
1003 {
1004     CurrentEvent currentEvent(keyboardEvent);
1005 
1006     bool handled = handleKeyEvent(keyboardEvent, m_page.get());
1007     // FIXME: Platform default behaviors should be performed during normal DOM event dispatch (in most cases, in default keydown event handler).
1008     if (!handled)
1009         handled = performDefaultBehaviorForKeyEvent(keyboardEvent);
1010 
1011     send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(keyboardEvent.type()), handled));
1012 }
1013 
1014 #if ENABLE(GESTURE_EVENTS)
handleGestureEvent(const WebGestureEvent & gestureEvent,Page * page)1015 static bool handleGestureEvent(const WebGestureEvent& gestureEvent, Page* page)
1016 {
1017     Frame* frame = page->mainFrame();
1018     if (!frame->view())
1019         return false;
1020 
1021     PlatformGestureEvent platformGestureEvent = platform(gestureEvent);
1022     return frame->eventHandler()->handleGestureEvent(platformGestureEvent);
1023 }
1024 
gestureEvent(const WebGestureEvent & gestureEvent)1025 void WebPage::gestureEvent(const WebGestureEvent& gestureEvent)
1026 {
1027     CurrentEvent currentEvent(gestureEvent);
1028 
1029     bool handled = handleGestureEvent(gestureEvent, m_page.get());
1030     send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(gestureEvent.type()), handled));
1031 }
1032 #endif
1033 
validateCommand(const String & commandName,uint64_t callbackID)1034 void WebPage::validateCommand(const String& commandName, uint64_t callbackID)
1035 {
1036     bool isEnabled = false;
1037     int32_t state = 0;
1038     Frame* frame = m_page->focusController()->focusedOrMainFrame();
1039     if (frame) {
1040         Editor::Command command = frame->editor()->command(commandName);
1041         state = command.state();
1042         isEnabled = command.isSupported() && command.isEnabled();
1043     }
1044 
1045     send(Messages::WebPageProxy::ValidateCommandCallback(commandName, isEnabled, state, callbackID));
1046 }
1047 
executeEditCommand(const String & commandName)1048 void WebPage::executeEditCommand(const String& commandName)
1049 {
1050     executeEditingCommand(commandName, String());
1051 }
1052 
restoreSession(const SessionState & sessionState)1053 uint64_t WebPage::restoreSession(const SessionState& sessionState)
1054 {
1055     const BackForwardListItemVector& list = sessionState.list();
1056     size_t size = list.size();
1057     uint64_t currentItemID = 0;
1058     for (size_t i = 0; i < size; ++i) {
1059         WebBackForwardListItem* webItem = list[i].get();
1060         DecoderAdapter decoder(webItem->backForwardData().data(), webItem->backForwardData().size());
1061 
1062         RefPtr<HistoryItem> item = HistoryItem::decodeBackForwardTree(webItem->url(), webItem->title(), webItem->originalURL(), decoder);
1063         if (!item) {
1064             LOG_ERROR("Failed to decode a HistoryItem from session state data.");
1065             return 0;
1066         }
1067 
1068         if (i == sessionState.currentIndex())
1069             currentItemID = webItem->itemID();
1070 
1071         WebBackForwardListProxy::addItemFromUIProcess(list[i]->itemID(), item.release());
1072     }
1073     ASSERT(currentItemID);
1074     return currentItemID;
1075 }
1076 
restoreSessionAndNavigateToCurrentItem(const SessionState & sessionState,const SandboxExtension::Handle & sandboxExtensionHandle)1077 void WebPage::restoreSessionAndNavigateToCurrentItem(const SessionState& sessionState, const SandboxExtension::Handle& sandboxExtensionHandle)
1078 {
1079     if (uint64_t currentItemID = restoreSession(sessionState))
1080         goToBackForwardItem(currentItemID, sandboxExtensionHandle);
1081 }
1082 
1083 #if ENABLE(TOUCH_EVENTS)
handleTouchEvent(const WebTouchEvent & touchEvent,Page * page)1084 static bool handleTouchEvent(const WebTouchEvent& touchEvent, Page* page)
1085 {
1086     Frame* frame = page->mainFrame();
1087     if (!frame->view())
1088         return false;
1089 
1090     return frame->eventHandler()->handleTouchEvent(platform(touchEvent));
1091 }
1092 
touchEvent(const WebTouchEvent & touchEvent)1093 void WebPage::touchEvent(const WebTouchEvent& touchEvent)
1094 {
1095     CurrentEvent currentEvent(touchEvent);
1096 
1097     bool handled = handleTouchEvent(touchEvent, m_page.get());
1098 
1099     send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(touchEvent.type()), handled));
1100 }
1101 #endif
1102 
scroll(Page * page,ScrollDirection direction,ScrollGranularity granularity)1103 void WebPage::scroll(Page* page, ScrollDirection direction, ScrollGranularity granularity)
1104 {
1105     page->focusController()->focusedOrMainFrame()->eventHandler()->scrollRecursively(direction, granularity);
1106 }
1107 
logicalScroll(Page * page,ScrollLogicalDirection direction,ScrollGranularity granularity)1108 void WebPage::logicalScroll(Page* page, ScrollLogicalDirection direction, ScrollGranularity granularity)
1109 {
1110     page->focusController()->focusedOrMainFrame()->eventHandler()->logicalScrollRecursively(direction, granularity);
1111 }
1112 
scrollBy(uint32_t scrollDirection,uint32_t scrollGranularity)1113 void WebPage::scrollBy(uint32_t scrollDirection, uint32_t scrollGranularity)
1114 {
1115     scroll(m_page.get(), static_cast<ScrollDirection>(scrollDirection), static_cast<ScrollGranularity>(scrollGranularity));
1116 }
1117 
setActive(bool isActive)1118 void WebPage::setActive(bool isActive)
1119 {
1120     m_page->focusController()->setActive(isActive);
1121 
1122 #if PLATFORM(MAC)
1123     // Tell all our plug-in views that the window focus changed.
1124     for (HashSet<PluginView*>::const_iterator it = m_pluginViews.begin(), end = m_pluginViews.end(); it != end; ++it)
1125         (*it)->setWindowIsFocused(isActive);
1126 #endif
1127 }
1128 
setDrawsBackground(bool drawsBackground)1129 void WebPage::setDrawsBackground(bool drawsBackground)
1130 {
1131     if (m_drawsBackground == drawsBackground)
1132         return;
1133 
1134     m_drawsBackground = drawsBackground;
1135 
1136     for (Frame* coreFrame = m_mainFrame->coreFrame(); coreFrame; coreFrame = coreFrame->tree()->traverseNext()) {
1137         if (FrameView* view = coreFrame->view())
1138             view->setTransparent(!drawsBackground);
1139     }
1140 
1141     m_drawingArea->pageBackgroundTransparencyChanged();
1142     m_drawingArea->setNeedsDisplay(IntRect(IntPoint(0, 0), m_viewSize));
1143 }
1144 
setDrawsTransparentBackground(bool drawsTransparentBackground)1145 void WebPage::setDrawsTransparentBackground(bool drawsTransparentBackground)
1146 {
1147     if (m_drawsTransparentBackground == drawsTransparentBackground)
1148         return;
1149 
1150     m_drawsTransparentBackground = drawsTransparentBackground;
1151 
1152     Color backgroundColor = drawsTransparentBackground ? Color::transparent : Color::white;
1153     for (Frame* coreFrame = m_mainFrame->coreFrame(); coreFrame; coreFrame = coreFrame->tree()->traverseNext()) {
1154         if (FrameView* view = coreFrame->view())
1155             view->setBaseBackgroundColor(backgroundColor);
1156     }
1157 
1158     m_drawingArea->pageBackgroundTransparencyChanged();
1159     m_drawingArea->setNeedsDisplay(IntRect(IntPoint(0, 0), m_viewSize));
1160 }
1161 
viewWillStartLiveResize()1162 void WebPage::viewWillStartLiveResize()
1163 {
1164     if (!m_page)
1165         return;
1166 
1167     // FIXME: This should propagate to all ScrollableAreas.
1168     if (Frame* frame = m_page->focusController()->focusedOrMainFrame()) {
1169         if (FrameView* view = frame->view())
1170             view->willStartLiveResize();
1171     }
1172 }
1173 
viewWillEndLiveResize()1174 void WebPage::viewWillEndLiveResize()
1175 {
1176     if (!m_page)
1177         return;
1178 
1179     // FIXME: This should propagate to all ScrollableAreas.
1180     if (Frame* frame = m_page->focusController()->focusedOrMainFrame()) {
1181         if (FrameView* view = frame->view())
1182             view->willEndLiveResize();
1183     }
1184 }
1185 
setFocused(bool isFocused)1186 void WebPage::setFocused(bool isFocused)
1187 {
1188     if (!isFocused && m_page->focusController()->focusedOrMainFrame()->editor()->behavior().shouldClearSelectionWhenLosingWebPageFocus())
1189         m_page->focusController()->focusedOrMainFrame()->selection()->clear();
1190 
1191     m_page->focusController()->setFocused(isFocused);
1192 }
1193 
setInitialFocus(bool forward)1194 void WebPage::setInitialFocus(bool forward)
1195 {
1196     if (!m_page || !m_page->focusController())
1197         return;
1198 
1199     Frame* frame = m_page->focusController()->focusedOrMainFrame();
1200     frame->document()->setFocusedNode(0);
1201     m_page->focusController()->setInitialFocus(forward ? FocusDirectionForward : FocusDirectionBackward, 0);
1202 }
1203 
setWindowResizerSize(const IntSize & windowResizerSize)1204 void WebPage::setWindowResizerSize(const IntSize& windowResizerSize)
1205 {
1206     if (m_windowResizerSize == windowResizerSize)
1207         return;
1208 
1209     m_windowResizerSize = windowResizerSize;
1210 
1211     for (Frame* coreFrame = m_mainFrame->coreFrame(); coreFrame; coreFrame = coreFrame->tree()->traverseNext()) {
1212         FrameView* view = coreFrame->view();
1213         if (view)
1214             view->windowResizerRectChanged();
1215     }
1216 }
1217 
setIsInWindow(bool isInWindow)1218 void WebPage::setIsInWindow(bool isInWindow)
1219 {
1220     if (!isInWindow) {
1221         m_page->setCanStartMedia(false);
1222         m_page->willMoveOffscreen();
1223     } else {
1224         m_page->setCanStartMedia(true);
1225         m_page->didMoveOnscreen();
1226     }
1227 }
1228 
didReceivePolicyDecision(uint64_t frameID,uint64_t listenerID,uint32_t policyAction,uint64_t downloadID)1229 void WebPage::didReceivePolicyDecision(uint64_t frameID, uint64_t listenerID, uint32_t policyAction, uint64_t downloadID)
1230 {
1231     WebFrame* frame = WebProcess::shared().webFrame(frameID);
1232     if (!frame)
1233         return;
1234     frame->didReceivePolicyDecision(listenerID, static_cast<PolicyAction>(policyAction), downloadID);
1235 }
1236 
show()1237 void WebPage::show()
1238 {
1239     send(Messages::WebPageProxy::ShowPage());
1240 }
1241 
setUserAgent(const String & userAgent)1242 void WebPage::setUserAgent(const String& userAgent)
1243 {
1244     m_userAgent = userAgent;
1245 }
1246 
windowToScreen(const IntRect & rect)1247 IntRect WebPage::windowToScreen(const IntRect& rect)
1248 {
1249     IntRect screenRect;
1250     sendSync(Messages::WebPageProxy::WindowToScreen(rect), Messages::WebPageProxy::WindowToScreen::Reply(screenRect));
1251     return screenRect;
1252 }
1253 
windowResizerRect() const1254 IntRect WebPage::windowResizerRect() const
1255 {
1256     if (m_windowResizerSize.isEmpty())
1257         return IntRect();
1258 
1259     IntSize frameViewSize;
1260     if (Frame* coreFrame = m_mainFrame->coreFrame()) {
1261         if (FrameView* view = coreFrame->view())
1262             frameViewSize = view->size();
1263     }
1264 
1265     return IntRect(frameViewSize.width() - m_windowResizerSize.width(), frameViewSize.height() - m_windowResizerSize.height(),
1266                    m_windowResizerSize.width(), m_windowResizerSize.height());
1267 }
1268 
keyboardUIMode()1269 KeyboardUIMode WebPage::keyboardUIMode()
1270 {
1271     bool fullKeyboardAccessEnabled = WebProcess::shared().fullKeyboardAccessEnabled();
1272     return static_cast<KeyboardUIMode>((fullKeyboardAccessEnabled ? KeyboardAccessFull : KeyboardAccessDefault) | (m_tabToLinks ? KeyboardAccessTabsToLinks : 0));
1273 }
1274 
runJavaScriptInMainFrame(const String & script,uint64_t callbackID)1275 void WebPage::runJavaScriptInMainFrame(const String& script, uint64_t callbackID)
1276 {
1277     // NOTE: We need to be careful when running scripts that the objects we depend on don't
1278     // disappear during script execution.
1279 
1280     // Retain the SerializedScriptValue at this level so it (and the internal data) lives
1281     // long enough for the DataReference to be encoded by the sent message.
1282     RefPtr<SerializedScriptValue> serializedResultValue;
1283     CoreIPC::DataReference dataReference;
1284 
1285     JSLock lock(SilenceAssertionsOnly);
1286     if (JSValue resultValue = m_mainFrame->coreFrame()->script()->executeScript(script, true).jsValue()) {
1287         if ((serializedResultValue = SerializedScriptValue::create(m_mainFrame->jsContext(),
1288             toRef(m_mainFrame->coreFrame()->script()->globalObject(mainThreadNormalWorld())->globalExec(), resultValue), 0)))
1289             dataReference = CoreIPC::DataReference(serializedResultValue->data().data(), serializedResultValue->data().size());
1290     }
1291 
1292     send(Messages::WebPageProxy::ScriptValueCallback(dataReference, callbackID));
1293 }
1294 
getContentsAsString(uint64_t callbackID)1295 void WebPage::getContentsAsString(uint64_t callbackID)
1296 {
1297     String resultString = m_mainFrame->contentsAsString();
1298     send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
1299 }
1300 
getRenderTreeExternalRepresentation(uint64_t callbackID)1301 void WebPage::getRenderTreeExternalRepresentation(uint64_t callbackID)
1302 {
1303     String resultString = renderTreeExternalRepresentation();
1304     send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
1305 }
1306 
getSelectionOrContentsAsString(uint64_t callbackID)1307 void WebPage::getSelectionOrContentsAsString(uint64_t callbackID)
1308 {
1309     String resultString = m_mainFrame->selectionAsString();
1310     if (resultString.isEmpty())
1311         resultString = m_mainFrame->contentsAsString();
1312     send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
1313 }
1314 
getSourceForFrame(uint64_t frameID,uint64_t callbackID)1315 void WebPage::getSourceForFrame(uint64_t frameID, uint64_t callbackID)
1316 {
1317     String resultString;
1318     if (WebFrame* frame = WebProcess::shared().webFrame(frameID))
1319        resultString = frame->source();
1320 
1321     send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
1322 }
1323 
getMainResourceDataOfFrame(uint64_t frameID,uint64_t callbackID)1324 void WebPage::getMainResourceDataOfFrame(uint64_t frameID, uint64_t callbackID)
1325 {
1326     CoreIPC::DataReference dataReference;
1327 
1328     RefPtr<SharedBuffer> buffer;
1329     if (WebFrame* frame = WebProcess::shared().webFrame(frameID)) {
1330         if (DocumentLoader* loader = frame->coreFrame()->loader()->documentLoader()) {
1331             if ((buffer = loader->mainResourceData()))
1332                 dataReference = CoreIPC::DataReference(reinterpret_cast<const uint8_t*>(buffer->data()), buffer->size());
1333         }
1334     }
1335 
1336     send(Messages::WebPageProxy::DataCallback(dataReference, callbackID));
1337 }
1338 
getResourceDataFromFrame(uint64_t frameID,const String & resourceURL,uint64_t callbackID)1339 void WebPage::getResourceDataFromFrame(uint64_t frameID, const String& resourceURL, uint64_t callbackID)
1340 {
1341     CoreIPC::DataReference dataReference;
1342 
1343     RefPtr<SharedBuffer> buffer;
1344     if (WebFrame* frame = WebProcess::shared().webFrame(frameID)) {
1345         if (DocumentLoader* loader = frame->coreFrame()->loader()->documentLoader()) {
1346             if (RefPtr<ArchiveResource> subresource = loader->subresource(KURL(KURL(), resourceURL))) {
1347                 if ((buffer = subresource->data()))
1348                     dataReference = CoreIPC::DataReference(reinterpret_cast<const uint8_t*>(buffer->data()), buffer->size());
1349             }
1350         }
1351     }
1352 
1353     send(Messages::WebPageProxy::DataCallback(dataReference, callbackID));
1354 }
1355 
getWebArchiveOfFrame(uint64_t frameID,uint64_t callbackID)1356 void WebPage::getWebArchiveOfFrame(uint64_t frameID, uint64_t callbackID)
1357 {
1358     CoreIPC::DataReference dataReference;
1359 
1360 #if PLATFORM(MAC) || PLATFORM(WIN)
1361     RetainPtr<CFDataRef> data;
1362     if (WebFrame* frame = WebProcess::shared().webFrame(frameID)) {
1363         if (RefPtr<LegacyWebArchive> archive = LegacyWebArchive::create(frame->coreFrame()->document())) {
1364             if ((data = archive->rawDataRepresentation()))
1365                 dataReference = CoreIPC::DataReference(CFDataGetBytePtr(data.get()), CFDataGetLength(data.get()));
1366         }
1367     }
1368 #endif
1369 
1370     send(Messages::WebPageProxy::DataCallback(dataReference, callbackID));
1371 }
1372 
forceRepaintWithoutCallback()1373 void WebPage::forceRepaintWithoutCallback()
1374 {
1375     m_drawingArea->forceRepaint();
1376 }
1377 
forceRepaint(uint64_t callbackID)1378 void WebPage::forceRepaint(uint64_t callbackID)
1379 {
1380     forceRepaintWithoutCallback();
1381     send(Messages::WebPageProxy::VoidCallback(callbackID));
1382 }
1383 
preferencesDidChange(const WebPreferencesStore & store)1384 void WebPage::preferencesDidChange(const WebPreferencesStore& store)
1385 {
1386     WebPreferencesStore::removeTestRunnerOverrides();
1387     updatePreferences(store);
1388 }
1389 
updatePreferences(const WebPreferencesStore & store)1390 void WebPage::updatePreferences(const WebPreferencesStore& store)
1391 {
1392     Settings* settings = m_page->settings();
1393 
1394     m_tabToLinks = store.getBoolValueForKey(WebPreferencesKey::tabsToLinksKey());
1395 
1396     // FIXME: This should be generated from macro expansion for all preferences,
1397     // but we currently don't match the naming of WebCore exactly so we are
1398     // handrolling the boolean and integer preferences until that is fixed.
1399 
1400 #define INITIALIZE_SETTINGS(KeyUpper, KeyLower, TypeName, Type, DefaultValue) settings->set##KeyUpper(store.get##TypeName##ValueForKey(WebPreferencesKey::KeyLower##Key()));
1401 
1402     FOR_EACH_WEBKIT_STRING_PREFERENCE(INITIALIZE_SETTINGS)
1403 
1404 #undef INITIALIZE_SETTINGS
1405 
1406     settings->setJavaScriptEnabled(store.getBoolValueForKey(WebPreferencesKey::javaScriptEnabledKey()));
1407     settings->setLoadsImagesAutomatically(store.getBoolValueForKey(WebPreferencesKey::loadsImagesAutomaticallyKey()));
1408     settings->setLoadsSiteIconsIgnoringImageLoadingSetting(store.getBoolValueForKey(WebPreferencesKey::loadsSiteIconsIgnoringImageLoadingPreferenceKey()));
1409     settings->setPluginsEnabled(store.getBoolValueForKey(WebPreferencesKey::pluginsEnabledKey()));
1410     settings->setJavaEnabled(store.getBoolValueForKey(WebPreferencesKey::javaEnabledKey()));
1411     settings->setOfflineWebApplicationCacheEnabled(store.getBoolValueForKey(WebPreferencesKey::offlineWebApplicationCacheEnabledKey()));
1412     settings->setLocalStorageEnabled(store.getBoolValueForKey(WebPreferencesKey::localStorageEnabledKey()));
1413     settings->setXSSAuditorEnabled(store.getBoolValueForKey(WebPreferencesKey::xssAuditorEnabledKey()));
1414     settings->setFrameFlatteningEnabled(store.getBoolValueForKey(WebPreferencesKey::frameFlatteningEnabledKey()));
1415     settings->setPrivateBrowsingEnabled(store.getBoolValueForKey(WebPreferencesKey::privateBrowsingEnabledKey()));
1416     settings->setDeveloperExtrasEnabled(store.getBoolValueForKey(WebPreferencesKey::developerExtrasEnabledKey()));
1417     settings->setTextAreasAreResizable(store.getBoolValueForKey(WebPreferencesKey::textAreasAreResizableKey()));
1418     settings->setNeedsSiteSpecificQuirks(store.getBoolValueForKey(WebPreferencesKey::needsSiteSpecificQuirksKey()));
1419     settings->setJavaScriptCanOpenWindowsAutomatically(store.getBoolValueForKey(WebPreferencesKey::javaScriptCanOpenWindowsAutomaticallyKey()));
1420     settings->setForceFTPDirectoryListings(store.getBoolValueForKey(WebPreferencesKey::forceFTPDirectoryListingsKey()));
1421     settings->setDNSPrefetchingEnabled(store.getBoolValueForKey(WebPreferencesKey::dnsPrefetchingEnabledKey()));
1422 #if ENABLE(WEB_ARCHIVE)
1423     settings->setWebArchiveDebugModeEnabled(store.getBoolValueForKey(WebPreferencesKey::webArchiveDebugModeEnabledKey()));
1424 #endif
1425     settings->setLocalFileContentSniffingEnabled(store.getBoolValueForKey(WebPreferencesKey::localFileContentSniffingEnabledKey()));
1426     settings->setUsesPageCache(store.getBoolValueForKey(WebPreferencesKey::usesPageCacheKey()));
1427     settings->setAuthorAndUserStylesEnabled(store.getBoolValueForKey(WebPreferencesKey::authorAndUserStylesEnabledKey()));
1428     settings->setPaginateDuringLayoutEnabled(store.getBoolValueForKey(WebPreferencesKey::paginateDuringLayoutEnabledKey()));
1429     settings->setDOMPasteAllowed(store.getBoolValueForKey(WebPreferencesKey::domPasteAllowedKey()));
1430     settings->setJavaScriptCanAccessClipboard(store.getBoolValueForKey(WebPreferencesKey::javaScriptCanAccessClipboardKey()));
1431     settings->setShouldPrintBackgrounds(store.getBoolValueForKey(WebPreferencesKey::shouldPrintBackgroundsKey()));
1432     settings->setWebSecurityEnabled(store.getBoolValueForKey(WebPreferencesKey::webSecurityEnabledKey()));
1433     settings->setAllowUniversalAccessFromFileURLs(store.getBoolValueForKey(WebPreferencesKey::allowUniversalAccessFromFileURLsKey()));
1434     settings->setAllowFileAccessFromFileURLs(store.getBoolValueForKey(WebPreferencesKey::allowFileAccessFromFileURLsKey()));
1435 
1436     settings->setMinimumFontSize(store.getUInt32ValueForKey(WebPreferencesKey::minimumFontSizeKey()));
1437     settings->setMinimumLogicalFontSize(store.getUInt32ValueForKey(WebPreferencesKey::minimumLogicalFontSizeKey()));
1438     settings->setDefaultFontSize(store.getUInt32ValueForKey(WebPreferencesKey::defaultFontSizeKey()));
1439     settings->setDefaultFixedFontSize(store.getUInt32ValueForKey(WebPreferencesKey::defaultFixedFontSizeKey()));
1440     settings->setEditableLinkBehavior(static_cast<WebCore::EditableLinkBehavior>(store.getUInt32ValueForKey(WebPreferencesKey::editableLinkBehaviorKey())));
1441 
1442     settings->setAcceleratedCompositingEnabled(store.getBoolValueForKey(WebPreferencesKey::acceleratedCompositingEnabledKey()) && LayerTreeHost::supportsAcceleratedCompositing());
1443     settings->setAcceleratedDrawingEnabled(store.getBoolValueForKey(WebPreferencesKey::acceleratedDrawingEnabledKey()) && LayerTreeHost::supportsAcceleratedCompositing());
1444     settings->setCanvasUsesAcceleratedDrawing(store.getBoolValueForKey(WebPreferencesKey::canvasUsesAcceleratedDrawingKey()) && LayerTreeHost::supportsAcceleratedCompositing());
1445     settings->setShowDebugBorders(store.getBoolValueForKey(WebPreferencesKey::compositingBordersVisibleKey()));
1446     settings->setShowRepaintCounter(store.getBoolValueForKey(WebPreferencesKey::compositingRepaintCountersVisibleKey()));
1447     settings->setWebGLEnabled(store.getBoolValueForKey(WebPreferencesKey::webGLEnabledKey()));
1448 
1449 #if ENABLE(DATABASE)
1450     AbstractDatabase::setIsAvailable(store.getBoolValueForKey(WebPreferencesKey::databasesEnabledKey()));
1451 #endif
1452 
1453 #if ENABLE(FULLSCREEN_API)
1454     settings->setFullScreenEnabled(store.getBoolValueForKey(WebPreferencesKey::fullScreenEnabledKey()));
1455 #endif
1456 
1457 #if ENABLE(DOM_STORAGE)
1458     settings->setLocalStorageDatabasePath(WebProcess::shared().localStorageDirectory());
1459 #endif
1460 
1461     platformPreferencesDidChange(store);
1462 }
1463 
1464 #if ENABLE(INSPECTOR)
inspector()1465 WebInspector* WebPage::inspector()
1466 {
1467     if (m_isClosed)
1468         return 0;
1469     if (!m_inspector)
1470         m_inspector = WebInspector::create(this);
1471     return m_inspector.get();
1472 }
1473 #endif
1474 
1475 #if ENABLE(FULLSCREEN_API)
fullScreenManager()1476 WebFullScreenManager* WebPage::fullScreenManager()
1477 {
1478     if (!m_fullScreenManager)
1479         m_fullScreenManager = WebFullScreenManager::create(this);
1480     return m_fullScreenManager.get();
1481 }
1482 #endif
1483 
1484 #if !PLATFORM(GTK) && !PLATFORM(MAC)
handleEditingKeyboardEvent(KeyboardEvent * evt)1485 bool WebPage::handleEditingKeyboardEvent(KeyboardEvent* evt)
1486 {
1487     Node* node = evt->target()->toNode();
1488     ASSERT(node);
1489     Frame* frame = node->document()->frame();
1490     ASSERT(frame);
1491 
1492     const PlatformKeyboardEvent* keyEvent = evt->keyEvent();
1493     if (!keyEvent)
1494         return false;
1495 
1496     Editor::Command command = frame->editor()->command(interpretKeyEvent(evt));
1497 
1498     if (keyEvent->type() == PlatformKeyboardEvent::RawKeyDown) {
1499         // WebKit doesn't have enough information about mode to decide how commands that just insert text if executed via Editor should be treated,
1500         // so we leave it upon WebCore to either handle them immediately (e.g. Tab that changes focus) or let a keypress event be generated
1501         // (e.g. Tab that inserts a Tab character, or Enter).
1502         return !command.isTextInsertion() && command.execute(evt);
1503     }
1504 
1505     if (command.execute(evt))
1506         return true;
1507 
1508     // Don't insert null or control characters as they can result in unexpected behaviour
1509     if (evt->charCode() < ' ')
1510         return false;
1511 
1512     return frame->editor()->insertText(evt->keyEvent()->text(), evt);
1513 }
1514 #endif
1515 
1516 #if PLATFORM(WIN)
performDragControllerAction(uint64_t action,WebCore::IntPoint clientPosition,WebCore::IntPoint globalPosition,uint64_t draggingSourceOperationMask,const WebCore::DragDataMap & dataMap,uint32_t flags)1517 void WebPage::performDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, const WebCore::DragDataMap& dataMap, uint32_t flags)
1518 {
1519     if (!m_page) {
1520         send(Messages::WebPageProxy::DidPerformDragControllerAction(DragOperationNone));
1521         return;
1522     }
1523 
1524     DragData dragData(dataMap, clientPosition, globalPosition, static_cast<DragOperation>(draggingSourceOperationMask), static_cast<DragApplicationFlags>(flags));
1525     switch (action) {
1526     case DragControllerActionEntered:
1527         send(Messages::WebPageProxy::DidPerformDragControllerAction(m_page->dragController()->dragEntered(&dragData)));
1528         break;
1529 
1530     case DragControllerActionUpdated:
1531         send(Messages::WebPageProxy::DidPerformDragControllerAction(m_page->dragController()->dragUpdated(&dragData)));
1532         break;
1533 
1534     case DragControllerActionExited:
1535         m_page->dragController()->dragExited(&dragData);
1536         break;
1537 
1538     case DragControllerActionPerformDrag:
1539         m_page->dragController()->performDrag(&dragData);
1540         break;
1541 
1542     default:
1543         ASSERT_NOT_REACHED();
1544     }
1545 }
1546 #else
performDragControllerAction(uint64_t action,WebCore::IntPoint clientPosition,WebCore::IntPoint globalPosition,uint64_t draggingSourceOperationMask,const String & dragStorageName,uint32_t flags,const SandboxExtension::Handle & sandboxExtensionHandle)1547 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)
1548 {
1549     if (!m_page) {
1550         send(Messages::WebPageProxy::DidPerformDragControllerAction(DragOperationNone));
1551         return;
1552     }
1553 
1554     DragData dragData(dragStorageName, clientPosition, globalPosition, static_cast<DragOperation>(draggingSourceOperationMask), static_cast<DragApplicationFlags>(flags));
1555     switch (action) {
1556     case DragControllerActionEntered:
1557         send(Messages::WebPageProxy::DidPerformDragControllerAction(m_page->dragController()->dragEntered(&dragData)));
1558         break;
1559 
1560     case DragControllerActionUpdated:
1561         send(Messages::WebPageProxy::DidPerformDragControllerAction(m_page->dragController()->dragUpdated(&dragData)));
1562         break;
1563 
1564     case DragControllerActionExited:
1565         m_page->dragController()->dragExited(&dragData);
1566         break;
1567 
1568     case DragControllerActionPerformDrag: {
1569         ASSERT(!m_pendingDropSandboxExtension);
1570 
1571         m_pendingDropSandboxExtension = SandboxExtension::create(sandboxExtensionHandle);
1572 
1573         m_page->dragController()->performDrag(&dragData);
1574 
1575         // If we started loading a local file, the sandbox extension tracker would have adopted this
1576         // pending drop sandbox extension. If not, we'll play it safe and invalidate it.
1577         if (m_pendingDropSandboxExtension) {
1578             m_pendingDropSandboxExtension->invalidate();
1579             m_pendingDropSandboxExtension = nullptr;
1580         }
1581 
1582         break;
1583     }
1584 
1585     default:
1586         ASSERT_NOT_REACHED();
1587     }
1588 }
1589 #endif
1590 
dragEnded(WebCore::IntPoint clientPosition,WebCore::IntPoint globalPosition,uint64_t operation)1591 void WebPage::dragEnded(WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t operation)
1592 {
1593     IntPoint adjustedClientPosition(clientPosition.x() + m_page->dragController()->dragOffset().x(), clientPosition.y() + m_page->dragController()->dragOffset().y());
1594     IntPoint adjustedGlobalPosition(globalPosition.x() + m_page->dragController()->dragOffset().x(), globalPosition.y() + m_page->dragController()->dragOffset().y());
1595 
1596     platformDragEnded();
1597     m_page->dragController()->dragEnded();
1598     FrameView* view = m_page->mainFrame()->view();
1599     if (!view)
1600         return;
1601     // FIXME: These are fake modifier keys here, but they should be real ones instead.
1602     PlatformMouseEvent event(adjustedClientPosition, adjustedGlobalPosition, LeftButton, MouseEventMoved, 0, false, false, false, false, currentTime());
1603     m_page->mainFrame()->eventHandler()->dragSourceEndedAt(event, (DragOperation)operation);
1604 }
1605 
willPerformLoadDragDestinationAction()1606 void WebPage::willPerformLoadDragDestinationAction()
1607 {
1608     m_sandboxExtensionTracker.willPerformLoadDragDestinationAction(m_pendingDropSandboxExtension.release());
1609 }
1610 
webEditCommand(uint64_t commandID)1611 WebEditCommand* WebPage::webEditCommand(uint64_t commandID)
1612 {
1613     return m_editCommandMap.get(commandID).get();
1614 }
1615 
addWebEditCommand(uint64_t commandID,WebEditCommand * command)1616 void WebPage::addWebEditCommand(uint64_t commandID, WebEditCommand* command)
1617 {
1618     m_editCommandMap.set(commandID, command);
1619 }
1620 
removeWebEditCommand(uint64_t commandID)1621 void WebPage::removeWebEditCommand(uint64_t commandID)
1622 {
1623     m_editCommandMap.remove(commandID);
1624 }
1625 
unapplyEditCommand(uint64_t commandID)1626 void WebPage::unapplyEditCommand(uint64_t commandID)
1627 {
1628     WebEditCommand* command = webEditCommand(commandID);
1629     if (!command)
1630         return;
1631 
1632     command->command()->unapply();
1633 }
1634 
reapplyEditCommand(uint64_t commandID)1635 void WebPage::reapplyEditCommand(uint64_t commandID)
1636 {
1637     WebEditCommand* command = webEditCommand(commandID);
1638     if (!command)
1639         return;
1640 
1641     m_isInRedo = true;
1642     command->command()->reapply();
1643     m_isInRedo = false;
1644 }
1645 
didRemoveEditCommand(uint64_t commandID)1646 void WebPage::didRemoveEditCommand(uint64_t commandID)
1647 {
1648     removeWebEditCommand(commandID);
1649 }
1650 
setActivePopupMenu(WebPopupMenu * menu)1651 void WebPage::setActivePopupMenu(WebPopupMenu* menu)
1652 {
1653     m_activePopupMenu = menu;
1654 }
1655 
setActiveOpenPanelResultListener(PassRefPtr<WebOpenPanelResultListener> openPanelResultListener)1656 void WebPage::setActiveOpenPanelResultListener(PassRefPtr<WebOpenPanelResultListener> openPanelResultListener)
1657 {
1658     m_activeOpenPanelResultListener = openPanelResultListener;
1659 }
1660 
findStringFromInjectedBundle(const String & target,FindOptions options)1661 bool WebPage::findStringFromInjectedBundle(const String& target, FindOptions options)
1662 {
1663     return m_page->findString(target, options);
1664 }
1665 
findString(const String & string,uint32_t options,uint32_t maxMatchCount)1666 void WebPage::findString(const String& string, uint32_t options, uint32_t maxMatchCount)
1667 {
1668     m_findController.findString(string, static_cast<FindOptions>(options), maxMatchCount);
1669 }
1670 
hideFindUI()1671 void WebPage::hideFindUI()
1672 {
1673     m_findController.hideFindUI();
1674 }
1675 
countStringMatches(const String & string,uint32_t options,uint32_t maxMatchCount)1676 void WebPage::countStringMatches(const String& string, uint32_t options, uint32_t maxMatchCount)
1677 {
1678     m_findController.countStringMatches(string, static_cast<FindOptions>(options), maxMatchCount);
1679 }
1680 
didChangeSelectedIndexForActivePopupMenu(int32_t newIndex)1681 void WebPage::didChangeSelectedIndexForActivePopupMenu(int32_t newIndex)
1682 {
1683     if (!m_activePopupMenu)
1684         return;
1685 
1686     m_activePopupMenu->didChangeSelectedIndex(newIndex);
1687     m_activePopupMenu = 0;
1688 }
1689 
didChooseFilesForOpenPanel(const Vector<String> & files)1690 void WebPage::didChooseFilesForOpenPanel(const Vector<String>& files)
1691 {
1692     if (!m_activeOpenPanelResultListener)
1693         return;
1694 
1695     m_activeOpenPanelResultListener->didChooseFiles(files);
1696     m_activeOpenPanelResultListener = 0;
1697 }
1698 
didCancelForOpenPanel()1699 void WebPage::didCancelForOpenPanel()
1700 {
1701     m_activeOpenPanelResultListener = 0;
1702 }
1703 
1704 #if ENABLE(WEB_PROCESS_SANDBOX)
extendSandboxForFileFromOpenPanel(const SandboxExtension::Handle & handle)1705 void WebPage::extendSandboxForFileFromOpenPanel(const SandboxExtension::Handle& handle)
1706 {
1707     SandboxExtension::create(handle)->consumePermanently();
1708 }
1709 #endif
1710 
didReceiveGeolocationPermissionDecision(uint64_t geolocationID,bool allowed)1711 void WebPage::didReceiveGeolocationPermissionDecision(uint64_t geolocationID, bool allowed)
1712 {
1713     m_geolocationPermissionRequestManager.didReceiveGeolocationPermissionDecision(geolocationID, allowed);
1714 }
1715 
advanceToNextMisspelling(bool startBeforeSelection)1716 void WebPage::advanceToNextMisspelling(bool startBeforeSelection)
1717 {
1718     Frame* frame = m_page->focusController()->focusedOrMainFrame();
1719     frame->editor()->advanceToNextMisspelling(startBeforeSelection);
1720 }
1721 
changeSpellingToWord(const String & word)1722 void WebPage::changeSpellingToWord(const String& word)
1723 {
1724     replaceSelectionWithText(m_page->focusController()->focusedOrMainFrame(), word);
1725 }
1726 
unmarkAllMisspellings()1727 void WebPage::unmarkAllMisspellings()
1728 {
1729     for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
1730         if (Document* document = frame->document())
1731             document->markers()->removeMarkers(DocumentMarker::Spelling);
1732     }
1733 }
1734 
unmarkAllBadGrammar()1735 void WebPage::unmarkAllBadGrammar()
1736 {
1737     for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
1738         if (Document* document = frame->document())
1739             document->markers()->removeMarkers(DocumentMarker::Grammar);
1740     }
1741 }
1742 
1743 #if PLATFORM(MAC)
uppercaseWord()1744 void WebPage::uppercaseWord()
1745 {
1746     m_page->focusController()->focusedOrMainFrame()->editor()->uppercaseWord();
1747 }
1748 
lowercaseWord()1749 void WebPage::lowercaseWord()
1750 {
1751     m_page->focusController()->focusedOrMainFrame()->editor()->lowercaseWord();
1752 }
1753 
capitalizeWord()1754 void WebPage::capitalizeWord()
1755 {
1756     m_page->focusController()->focusedOrMainFrame()->editor()->capitalizeWord();
1757 }
1758 #endif
1759 
setTextForActivePopupMenu(int32_t index)1760 void WebPage::setTextForActivePopupMenu(int32_t index)
1761 {
1762     if (!m_activePopupMenu)
1763         return;
1764 
1765     m_activePopupMenu->setTextForIndex(index);
1766 }
1767 
didSelectItemFromActiveContextMenu(const WebContextMenuItemData & item)1768 void WebPage::didSelectItemFromActiveContextMenu(const WebContextMenuItemData& item)
1769 {
1770     ASSERT(m_contextMenu);
1771     m_contextMenu->itemSelected(item);
1772     m_contextMenu = 0;
1773 }
1774 
replaceSelectionWithText(Frame * frame,const String & text)1775 void WebPage::replaceSelectionWithText(Frame* frame, const String& text)
1776 {
1777     if (frame->selection()->isNone())
1778         return;
1779 
1780     RefPtr<DocumentFragment> textFragment = createFragmentFromText(frame->selection()->toNormalizedRange().get(), text);
1781     applyCommand(ReplaceSelectionCommand::create(frame->document(), textFragment.release(), ReplaceSelectionCommand::SelectReplacement | ReplaceSelectionCommand::MatchStyle | ReplaceSelectionCommand::PreventNesting));
1782     frame->selection()->revealSelection(ScrollAlignment::alignToEdgeIfNeeded);
1783 }
1784 
mainFrameHasCustomRepresentation() const1785 bool WebPage::mainFrameHasCustomRepresentation() const
1786 {
1787     return static_cast<WebFrameLoaderClient*>(mainFrame()->coreFrame()->loader()->client())->frameHasCustomRepresentation();
1788 }
1789 
didChangeScrollOffsetForMainFrame()1790 void WebPage::didChangeScrollOffsetForMainFrame()
1791 {
1792     Frame* frame = m_page->mainFrame();
1793     IntPoint scrollPosition = frame->view()->scrollPosition();
1794     IntPoint maximumScrollPosition = frame->view()->maximumScrollPosition();
1795     IntPoint minimumScrollPosition = frame->view()->minimumScrollPosition();
1796 
1797     bool isPinnedToLeftSide = (scrollPosition.x() <= minimumScrollPosition.x());
1798     bool isPinnedToRightSide = (scrollPosition.x() >= maximumScrollPosition.x());
1799 
1800     if (isPinnedToLeftSide != m_cachedMainFrameIsPinnedToLeftSide || isPinnedToRightSide != m_cachedMainFrameIsPinnedToRightSide) {
1801         send(Messages::WebPageProxy::DidChangeScrollOffsetPinningForMainFrame(isPinnedToLeftSide, isPinnedToRightSide));
1802 
1803         m_cachedMainFrameIsPinnedToLeftSide = isPinnedToLeftSide;
1804         m_cachedMainFrameIsPinnedToRightSide = isPinnedToRightSide;
1805     }
1806 }
1807 
1808 #if PLATFORM(MAC)
1809 
addPluginView(PluginView * pluginView)1810 void WebPage::addPluginView(PluginView* pluginView)
1811 {
1812     ASSERT(!m_pluginViews.contains(pluginView));
1813 
1814     m_pluginViews.add(pluginView);
1815 }
1816 
removePluginView(PluginView * pluginView)1817 void WebPage::removePluginView(PluginView* pluginView)
1818 {
1819     ASSERT(m_pluginViews.contains(pluginView));
1820 
1821     m_pluginViews.remove(pluginView);
1822 }
1823 
setWindowIsVisible(bool windowIsVisible)1824 void WebPage::setWindowIsVisible(bool windowIsVisible)
1825 {
1826     m_windowIsVisible = windowIsVisible;
1827 
1828     // Tell all our plug-in views that the window visibility changed.
1829     for (HashSet<PluginView*>::const_iterator it = m_pluginViews.begin(), end = m_pluginViews.end(); it != end; ++it)
1830         (*it)->setWindowIsVisible(windowIsVisible);
1831 }
1832 
windowAndViewFramesChanged(const WebCore::IntRect & windowFrameInScreenCoordinates,const WebCore::IntRect & viewFrameInWindowCoordinates,const WebCore::IntPoint & accessibilityViewCoordinates)1833 void WebPage::windowAndViewFramesChanged(const WebCore::IntRect& windowFrameInScreenCoordinates, const WebCore::IntRect& viewFrameInWindowCoordinates, const WebCore::IntPoint& accessibilityViewCoordinates)
1834 {
1835     m_windowFrameInScreenCoordinates = windowFrameInScreenCoordinates;
1836     m_viewFrameInWindowCoordinates = viewFrameInWindowCoordinates;
1837     m_accessibilityPosition = accessibilityViewCoordinates;
1838 
1839     // Tell all our plug-in views that the window and view frames have changed.
1840     for (HashSet<PluginView*>::const_iterator it = m_pluginViews.begin(), end = m_pluginViews.end(); it != end; ++it)
1841         (*it)->windowAndViewFramesChanged(windowFrameInScreenCoordinates, viewFrameInWindowCoordinates);
1842 }
1843 
1844 #endif
1845 
windowIsFocused() const1846 bool WebPage::windowIsFocused() const
1847 {
1848     return m_page->focusController()->isActive();
1849 }
1850 
didReceiveMessage(CoreIPC::Connection * connection,CoreIPC::MessageID messageID,CoreIPC::ArgumentDecoder * arguments)1851 void WebPage::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments)
1852 {
1853     if (messageID.is<CoreIPC::MessageClassDrawingAreaLegacy>()) {
1854         if (m_drawingArea)
1855             m_drawingArea->didReceiveMessage(connection, messageID, arguments);
1856         return;
1857     }
1858 
1859 #if PLATFORM(MAC) || PLATFORM(WIN)
1860     if (messageID.is<CoreIPC::MessageClassDrawingArea>()) {
1861         if (m_drawingArea)
1862             m_drawingArea->didReceiveDrawingAreaMessage(connection, messageID, arguments);
1863         return;
1864     }
1865 #endif
1866 
1867 #if ENABLE(INSPECTOR)
1868     if (messageID.is<CoreIPC::MessageClassWebInspector>()) {
1869         if (WebInspector* inspector = this->inspector())
1870             inspector->didReceiveWebInspectorMessage(connection, messageID, arguments);
1871         return;
1872     }
1873 #endif
1874 
1875 #if ENABLE(FULLSCREEN_API)
1876     if (messageID.is<CoreIPC::MessageClassWebFullScreenManager>()) {
1877         fullScreenManager()->didReceiveMessage(connection, messageID, arguments);
1878         return;
1879     }
1880 #endif
1881 
1882     didReceiveWebPageMessage(connection, messageID, arguments);
1883 }
1884 
didReceiveSyncMessage(CoreIPC::Connection * connection,CoreIPC::MessageID messageID,CoreIPC::ArgumentDecoder * arguments,CoreIPC::ArgumentEncoder * reply)1885 CoreIPC::SyncReplyMode WebPage::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments, CoreIPC::ArgumentEncoder* reply)
1886 {
1887     return didReceiveSyncWebPageMessage(connection, messageID, arguments, reply);
1888 }
1889 
backForwardList()1890 InjectedBundleBackForwardList* WebPage::backForwardList()
1891 {
1892     if (!m_backForwardList)
1893         m_backForwardList = InjectedBundleBackForwardList::create(this);
1894     return m_backForwardList.get();
1895 }
1896 
1897 #if PLATFORM(QT)
findZoomableAreaForPoint(const WebCore::IntPoint & point)1898 void WebPage::findZoomableAreaForPoint(const WebCore::IntPoint& point)
1899 {
1900     const int minimumZoomTargetWidth = 100;
1901 
1902     Frame* mainframe = m_mainFrame->coreFrame();
1903     HitTestResult result = mainframe->eventHandler()->hitTestResultAtPoint(mainframe->view()->windowToContents(point), /*allowShadowContent*/ false, /*ignoreClipping*/ true);
1904 
1905     Node* node = result.innerNode();
1906     while (node && node->getRect().width() < minimumZoomTargetWidth)
1907         node = node->parentNode();
1908 
1909     IntRect zoomableArea;
1910     if (node)
1911         zoomableArea = node->getRect();
1912     send(Messages::WebPageProxy::DidFindZoomableArea(zoomableArea));
1913 }
1914 #endif
1915 
~SandboxExtensionTracker()1916 WebPage::SandboxExtensionTracker::~SandboxExtensionTracker()
1917 {
1918     invalidate();
1919 }
1920 
invalidate()1921 void WebPage::SandboxExtensionTracker::invalidate()
1922 {
1923     if (m_pendingProvisionalSandboxExtension) {
1924         m_pendingProvisionalSandboxExtension->invalidate();
1925         m_pendingProvisionalSandboxExtension = 0;
1926     }
1927 
1928     if (m_provisionalSandboxExtension) {
1929         m_provisionalSandboxExtension->invalidate();
1930         m_provisionalSandboxExtension = 0;
1931     }
1932 
1933     if (m_committedSandboxExtension) {
1934         m_committedSandboxExtension->invalidate();
1935         m_committedSandboxExtension = 0;
1936     }
1937 }
1938 
willPerformLoadDragDestinationAction(PassRefPtr<SandboxExtension> pendingDropSandboxExtension)1939 void WebPage::SandboxExtensionTracker::willPerformLoadDragDestinationAction(PassRefPtr<SandboxExtension> pendingDropSandboxExtension)
1940 {
1941     setPendingProvisionalSandboxExtension(pendingDropSandboxExtension);
1942 }
1943 
beginLoad(WebFrame * frame,const SandboxExtension::Handle & handle)1944 void WebPage::SandboxExtensionTracker::beginLoad(WebFrame* frame, const SandboxExtension::Handle& handle)
1945 {
1946     ASSERT(frame->isMainFrame());
1947 
1948     setPendingProvisionalSandboxExtension(SandboxExtension::create(handle));
1949 }
1950 
setPendingProvisionalSandboxExtension(PassRefPtr<SandboxExtension> pendingProvisionalSandboxExtension)1951 void WebPage::SandboxExtensionTracker::setPendingProvisionalSandboxExtension(PassRefPtr<SandboxExtension> pendingProvisionalSandboxExtension)
1952 {
1953     // If we get two beginLoad calls in succession, without a provisional load starting, then
1954     // m_pendingProvisionalSandboxExtension will be non-null. Invalidate and null out the extension if that is the case.
1955     if (m_pendingProvisionalSandboxExtension) {
1956         m_pendingProvisionalSandboxExtension->invalidate();
1957         m_pendingProvisionalSandboxExtension = nullptr;
1958     }
1959 
1960     m_pendingProvisionalSandboxExtension = pendingProvisionalSandboxExtension;
1961 }
1962 
shouldReuseCommittedSandboxExtension(WebFrame * frame)1963 static bool shouldReuseCommittedSandboxExtension(WebFrame* frame)
1964 {
1965     ASSERT(frame->isMainFrame());
1966 
1967     FrameLoader* frameLoader = frame->coreFrame()->loader();
1968     FrameLoadType frameLoadType = frameLoader->loadType();
1969 
1970     // If the page is being reloaded, it should reuse whatever extension is committed.
1971     if (frameLoadType == FrameLoadTypeReload || frameLoadType == FrameLoadTypeReloadFromOrigin)
1972         return true;
1973 
1974     DocumentLoader* documentLoader = frameLoader->documentLoader();
1975     DocumentLoader* provisionalDocumentLoader = frameLoader->provisionalDocumentLoader();
1976     if (!documentLoader || !provisionalDocumentLoader)
1977         return false;
1978 
1979     if (documentLoader->url().isLocalFile() && provisionalDocumentLoader->url().isLocalFile())
1980         return true;
1981 
1982     return false;
1983 }
1984 
didStartProvisionalLoad(WebFrame * frame)1985 void WebPage::SandboxExtensionTracker::didStartProvisionalLoad(WebFrame* frame)
1986 {
1987     if (!frame->isMainFrame())
1988         return;
1989 
1990     if (shouldReuseCommittedSandboxExtension(frame)) {
1991         m_pendingProvisionalSandboxExtension = m_committedSandboxExtension.release();
1992         ASSERT(!m_committedSandboxExtension);
1993     }
1994 
1995     ASSERT(!m_provisionalSandboxExtension);
1996 
1997     m_provisionalSandboxExtension = m_pendingProvisionalSandboxExtension.release();
1998     if (!m_provisionalSandboxExtension)
1999         return;
2000 
2001     m_provisionalSandboxExtension->consume();
2002 }
2003 
didCommitProvisionalLoad(WebFrame * frame)2004 void WebPage::SandboxExtensionTracker::didCommitProvisionalLoad(WebFrame* frame)
2005 {
2006     if (!frame->isMainFrame())
2007         return;
2008 
2009     ASSERT(!m_pendingProvisionalSandboxExtension);
2010 
2011     // The provisional load has been committed. Invalidate the currently committed sandbox
2012     // extension and make the provisional sandbox extension the committed sandbox extension.
2013     if (m_committedSandboxExtension)
2014         m_committedSandboxExtension->invalidate();
2015 
2016     m_committedSandboxExtension = m_provisionalSandboxExtension.release();
2017 }
2018 
didFailProvisionalLoad(WebFrame * frame)2019 void WebPage::SandboxExtensionTracker::didFailProvisionalLoad(WebFrame* frame)
2020 {
2021     if (!frame->isMainFrame())
2022         return;
2023 
2024     if (!m_provisionalSandboxExtension)
2025         return;
2026 
2027     m_provisionalSandboxExtension->invalidate();
2028     m_provisionalSandboxExtension = nullptr;
2029 }
2030 
hasLocalDataForURL(const KURL & url)2031 bool WebPage::hasLocalDataForURL(const KURL& url)
2032 {
2033     if (url.isLocalFile())
2034         return true;
2035 
2036     FrameLoader* frameLoader = m_page->mainFrame()->loader();
2037     DocumentLoader* documentLoader = frameLoader ? frameLoader->documentLoader() : 0;
2038     if (documentLoader && documentLoader->subresource(url))
2039         return true;
2040 
2041     return platformHasLocalDataForURL(url);
2042 }
2043 
setCustomTextEncodingName(const String & encoding)2044 void WebPage::setCustomTextEncodingName(const String& encoding)
2045 {
2046     m_page->mainFrame()->loader()->reloadWithOverrideEncoding(encoding);
2047 }
2048 
didRemoveBackForwardItem(uint64_t itemID)2049 void WebPage::didRemoveBackForwardItem(uint64_t itemID)
2050 {
2051     WebBackForwardListProxy::removeItem(itemID);
2052 }
2053 
2054 #if PLATFORM(MAC)
2055 
isSpeaking()2056 bool WebPage::isSpeaking()
2057 {
2058     bool result;
2059     return sendSync(Messages::WebPageProxy::GetIsSpeaking(), Messages::WebPageProxy::GetIsSpeaking::Reply(result)) && result;
2060 }
2061 
speak(const String & string)2062 void WebPage::speak(const String& string)
2063 {
2064     send(Messages::WebPageProxy::Speak(string));
2065 }
2066 
stopSpeaking()2067 void WebPage::stopSpeaking()
2068 {
2069     send(Messages::WebPageProxy::StopSpeaking());
2070 }
2071 
2072 #endif
2073 
beginPrinting(uint64_t frameID,const PrintInfo & printInfo)2074 void WebPage::beginPrinting(uint64_t frameID, const PrintInfo& printInfo)
2075 {
2076     WebFrame* frame = WebProcess::shared().webFrame(frameID);
2077     if (!frame)
2078         return;
2079 
2080     Frame* coreFrame = frame->coreFrame();
2081     if (!coreFrame)
2082         return;
2083 
2084     if (!m_printContext)
2085         m_printContext = adoptPtr(new PrintContext(coreFrame));
2086 
2087     m_printContext->begin(printInfo.availablePaperWidth, printInfo.availablePaperHeight);
2088 
2089     float fullPageHeight;
2090     m_printContext->computePageRects(FloatRect(0, 0, printInfo.availablePaperWidth, printInfo.availablePaperHeight), 0, 0, printInfo.pageSetupScaleFactor, fullPageHeight, true);
2091 }
2092 
endPrinting()2093 void WebPage::endPrinting()
2094 {
2095     m_printContext = nullptr;
2096 }
2097 
computePagesForPrinting(uint64_t frameID,const PrintInfo & printInfo,uint64_t callbackID)2098 void WebPage::computePagesForPrinting(uint64_t frameID, const PrintInfo& printInfo, uint64_t callbackID)
2099 {
2100     Vector<IntRect> resultPageRects;
2101     double resultTotalScaleFactorForPrinting = 1;
2102 
2103     beginPrinting(frameID, printInfo);
2104 
2105     if (m_printContext) {
2106         resultPageRects = m_printContext->pageRects();
2107         resultTotalScaleFactorForPrinting = m_printContext->computeAutomaticScaleFactor(FloatSize(printInfo.availablePaperWidth, printInfo.availablePaperHeight)) * printInfo.pageSetupScaleFactor;
2108     }
2109 
2110     // If we're asked to print, we should actually print at least a blank page.
2111     if (resultPageRects.isEmpty())
2112         resultPageRects.append(IntRect(0, 0, 1, 1));
2113 
2114     send(Messages::WebPageProxy::ComputedPagesCallback(resultPageRects, resultTotalScaleFactorForPrinting, callbackID));
2115 }
2116 
2117 #if PLATFORM(MAC) || PLATFORM(WIN)
drawRectToPDF(uint64_t frameID,const WebCore::IntRect & rect,uint64_t callbackID)2118 void WebPage::drawRectToPDF(uint64_t frameID, const WebCore::IntRect& rect, uint64_t callbackID)
2119 {
2120     WebFrame* frame = WebProcess::shared().webFrame(frameID);
2121     Frame* coreFrame = frame ? frame->coreFrame() : 0;
2122 
2123     RetainPtr<CFMutableDataRef> pdfPageData(AdoptCF, CFDataCreateMutable(0, 0));
2124 
2125     if (coreFrame) {
2126         ASSERT(coreFrame->document()->printing());
2127 
2128 #if USE(CG)
2129         // FIXME: Use CGDataConsumerCreate with callbacks to avoid copying the data.
2130         RetainPtr<CGDataConsumerRef> pdfDataConsumer(AdoptCF, CGDataConsumerCreateWithCFData(pdfPageData.get()));
2131 
2132         CGRect mediaBox = CGRectMake(0, 0, rect.width(), rect.height());
2133         RetainPtr<CGContextRef> context(AdoptCF, CGPDFContextCreate(pdfDataConsumer.get(), &mediaBox, 0));
2134         RetainPtr<CFDictionaryRef> pageInfo(AdoptCF, CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
2135         CGPDFContextBeginPage(context.get(), pageInfo.get());
2136 
2137         GraphicsContext ctx(context.get());
2138         ctx.scale(FloatSize(1, -1));
2139         ctx.translate(0, -rect.height());
2140         m_printContext->spoolRect(ctx, rect);
2141 
2142         CGPDFContextEndPage(context.get());
2143         CGPDFContextClose(context.get());
2144 #endif
2145     }
2146 
2147     send(Messages::WebPageProxy::DataCallback(CoreIPC::DataReference(CFDataGetBytePtr(pdfPageData.get()), CFDataGetLength(pdfPageData.get())), callbackID));
2148 }
2149 
drawPagesToPDF(uint64_t frameID,uint32_t first,uint32_t count,uint64_t callbackID)2150 void WebPage::drawPagesToPDF(uint64_t frameID, uint32_t first, uint32_t count, uint64_t callbackID)
2151 {
2152     WebFrame* frame = WebProcess::shared().webFrame(frameID);
2153     Frame* coreFrame = frame ? frame->coreFrame() : 0;
2154 
2155     RetainPtr<CFMutableDataRef> pdfPageData(AdoptCF, CFDataCreateMutable(0, 0));
2156 
2157     if (coreFrame) {
2158         ASSERT(coreFrame->document()->printing());
2159 
2160 #if USE(CG)
2161         // FIXME: Use CGDataConsumerCreate with callbacks to avoid copying the data.
2162         RetainPtr<CGDataConsumerRef> pdfDataConsumer(AdoptCF, CGDataConsumerCreateWithCFData(pdfPageData.get()));
2163 
2164         CGRect mediaBox = m_printContext->pageCount() ? m_printContext->pageRect(0) : CGRectMake(0, 0, 1, 1);
2165         RetainPtr<CGContextRef> context(AdoptCF, CGPDFContextCreate(pdfDataConsumer.get(), &mediaBox, 0));
2166         for (uint32_t page = first; page < first + count; ++page) {
2167             if (page >= m_printContext->pageCount())
2168                 break;
2169 
2170             RetainPtr<CFDictionaryRef> pageInfo(AdoptCF, CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
2171             CGPDFContextBeginPage(context.get(), pageInfo.get());
2172 
2173             GraphicsContext ctx(context.get());
2174             ctx.scale(FloatSize(1, -1));
2175             ctx.translate(0, -m_printContext->pageRect(page).height());
2176             m_printContext->spoolPage(ctx, page, m_printContext->pageRect(page).width());
2177 
2178             CGPDFContextEndPage(context.get());
2179         }
2180         CGPDFContextClose(context.get());
2181 #endif
2182     }
2183 
2184     send(Messages::WebPageProxy::DataCallback(CoreIPC::DataReference(CFDataGetBytePtr(pdfPageData.get()), CFDataGetLength(pdfPageData.get())), callbackID));
2185 }
2186 #endif
2187 
runModal()2188 void WebPage::runModal()
2189 {
2190     if (m_isClosed)
2191         return;
2192     if (m_isRunningModal)
2193         return;
2194 
2195     m_isRunningModal = true;
2196     send(Messages::WebPageProxy::RunModal());
2197     RunLoop::run();
2198     ASSERT(!m_isRunningModal);
2199 }
2200 
setMemoryCacheMessagesEnabled(bool memoryCacheMessagesEnabled)2201 void WebPage::setMemoryCacheMessagesEnabled(bool memoryCacheMessagesEnabled)
2202 {
2203     m_page->setMemoryCacheClientCallsEnabled(memoryCacheMessagesEnabled);
2204 }
2205 
2206 #if !PLATFORM(MAC)
platformDragEnded()2207 void WebPage::platformDragEnded()
2208 {
2209 }
2210 #endif
2211 
canHandleRequest(const WebCore::ResourceRequest & request)2212 bool WebPage::canHandleRequest(const WebCore::ResourceRequest& request)
2213 {
2214     if (SchemeRegistry::shouldLoadURLSchemeAsEmptyDocument(request.url().protocol()))
2215         return true;
2216     return platformCanHandleRequest(request);
2217 }
2218 
2219 #if PLATFORM(MAC) && !defined(BUILDING_ON_SNOW_LEOPARD)
handleCorrectionPanelResult(const String & result)2220 void WebPage::handleCorrectionPanelResult(const String& result)
2221 {
2222     Frame* frame = m_page->focusController()->focusedOrMainFrame();
2223     if (!frame)
2224         return;
2225     frame->editor()->handleCorrectionPanelResult(result);
2226 }
2227 #endif
2228 
simulateMouseDown(int button,WebCore::IntPoint position,int clickCount,WKEventModifiers modifiers,double time)2229 void WebPage::simulateMouseDown(int button, WebCore::IntPoint position, int clickCount, WKEventModifiers modifiers, double time)
2230 {
2231     mouseEvent(WebMouseEvent(WebMouseEvent::MouseDown, static_cast<WebMouseEvent::Button>(button), position, position, 0, 0, 0, clickCount, static_cast<WebMouseEvent::Modifiers>(modifiers), time));
2232 }
2233 
simulateMouseUp(int button,WebCore::IntPoint position,int clickCount,WKEventModifiers modifiers,double time)2234 void WebPage::simulateMouseUp(int button, WebCore::IntPoint position, int clickCount, WKEventModifiers modifiers, double time)
2235 {
2236     mouseEvent(WebMouseEvent(WebMouseEvent::MouseUp, static_cast<WebMouseEvent::Button>(button), position, position, 0, 0, 0, clickCount, static_cast<WebMouseEvent::Modifiers>(modifiers), time));
2237 }
2238 
simulateMouseMotion(WebCore::IntPoint position,double time)2239 void WebPage::simulateMouseMotion(WebCore::IntPoint position, double time)
2240 {
2241     mouseEvent(WebMouseEvent(WebMouseEvent::MouseMove, WebMouseEvent::NoButton, position, position, 0, 0, 0, 0, WebMouseEvent::Modifiers(), time));
2242 }
2243 
2244 } // namespace WebKit
2245