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