WebKit2 snapshots should contain accelerated content
[WebKit-https.git] / WebKit2 / WebProcess / WebPage / WebPage.cpp
1 /*
2  * Copyright (C) 2010 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 "WebPage.h"
27
28 #include "Arguments.h"
29 #include "DataReference.h"
30 #include "DrawingArea.h"
31 #include "InjectedBundle.h"
32 #include "InjectedBundleBackForwardList.h"
33 #include "MessageID.h"
34 #include "NetscapePlugin.h"
35 #include "PageOverlay.h"
36 #include "PluginProxy.h"
37 #include "PluginView.h"
38 #include "WebBackForwardListProxy.h"
39 #include "WebChromeClient.h"
40 #include "WebContextMenu.h"
41 #include "WebContextMenuClient.h"
42 #include "WebContextMessages.h"
43 #include "WebCoreArgumentCoders.h"
44 #include "WebDragClient.h"
45 #include "WebEditorClient.h"
46 #include "WebEvent.h"
47 #include "WebEventConversion.h"
48 #include "WebFrame.h"
49 #include "WebImage.h"
50 #include "WebInspector.h"
51 #include "WebInspectorClient.h"
52 #include "WebOpenPanelResultListener.h"
53 #include "WebPageCreationParameters.h"
54 #include "WebPageGroupProxy.h"
55 #include "WebPageProxyMessages.h"
56 #include "WebPopupMenu.h"
57 #include "WebPreferencesStore.h"
58 #include "WebProcess.h"
59 #include "WebProcessProxyMessageKinds.h"
60 #include "WebProcessProxyMessages.h"
61 #include <WebCore/AbstractDatabase.h>
62 #include <WebCore/ArchiveResource.h>
63 #include <WebCore/Chrome.h>
64 #include <WebCore/ContextMenuController.h>
65 #include <WebCore/DocumentLoader.h>
66 #include <WebCore/EventHandler.h>
67 #include <WebCore/FocusController.h>
68 #include <WebCore/Frame.h>
69 #include <WebCore/FrameLoaderTypes.h>
70 #include <WebCore/FrameView.h>
71 #include <WebCore/HistoryItem.h>
72 #include <WebCore/KeyboardEvent.h>
73 #include <WebCore/Page.h>
74 #include <WebCore/PlatformKeyboardEvent.h>
75 #include <WebCore/RenderTreeAsText.h>
76 #include <WebCore/ResourceRequest.h>
77 #include <WebCore/Settings.h>
78 #include <WebCore/SharedBuffer.h>
79 #include <WebCore/SubstituteData.h>
80 #include <WebCore/TextIterator.h>
81 #include <runtime/JSLock.h>
82 #include <runtime/JSValue.h>
83
84 #if PLATFORM(MAC) || PLATFORM(WIN)
85 #include <WebCore/LegacyWebArchive.h>
86 #endif
87
88 #if ENABLE(PLUGIN_PROCESS)
89 // FIXME: This is currently Mac-specific!
90 #include "MachPort.h"
91 #endif
92
93 #if PLATFORM(QT)
94 #include "HitTestResult.h"
95 #endif
96
97 #ifndef NDEBUG
98 #include <wtf/RefCountedLeakCounter.h>
99 #endif
100
101 using namespace JSC;
102 using namespace WebCore;
103
104 namespace WebKit {
105
106 #ifndef NDEBUG
107 static WTF::RefCountedLeakCounter webPageCounter("WebPage");
108 #endif
109
110 PassRefPtr<WebPage> WebPage::create(uint64_t pageID, const WebPageCreationParameters& parameters)
111 {
112     RefPtr<WebPage> page = adoptRef(new WebPage(pageID, parameters));
113
114     if (page->pageGroup()->isVisibleToInjectedBundle() && WebProcess::shared().injectedBundle())
115         WebProcess::shared().injectedBundle()->didCreatePage(page.get());
116
117     return page.release();
118 }
119
120 WebPage::WebPage(uint64_t pageID, const WebPageCreationParameters& parameters)
121     : m_viewSize(parameters.viewSize)
122     , m_drawsBackground(true)
123     , m_drawsTransparentBackground(false)
124     , m_isInRedo(false)
125     , m_isClosed(false)
126     , m_tabToLinks(false)
127 #if PLATFORM(MAC)
128     , m_windowIsVisible(false)
129 #elif PLATFORM(WIN)
130     , m_nativeWindow(parameters.nativeWindow)
131 #endif
132     , m_findController(this)
133     , m_pageID(pageID)
134 {
135     ASSERT(m_pageID);
136
137     Page::PageClients pageClients;
138     pageClients.chromeClient = new WebChromeClient(this);
139     pageClients.contextMenuClient = new WebContextMenuClient(this);
140     pageClients.editorClient = new WebEditorClient(this);
141     pageClients.dragClient = new WebDragClient(this);
142 #if ENABLE(INSPECTOR)
143     pageClients.inspectorClient = new WebInspectorClient(this);
144 #endif
145     pageClients.backForwardClient = WebBackForwardListProxy::create(this);
146     m_page = adoptPtr(new Page(pageClients));
147
148     // Qt does not yet call setIsInWindow. Until it does, just leave
149     // this line out so plug-ins and video will work. Eventually all platforms
150     // should call setIsInWindow and this comment and #if should be removed,
151     // leaving behind the setCanStartMedia call.
152 #if !PLATFORM(QT)
153     m_page->setCanStartMedia(false);
154 #endif
155
156     updatePreferences(parameters.store);
157
158     m_pageGroup = WebProcess::shared().webPageGroup(parameters.pageGroupData);
159     m_page->setGroupName(m_pageGroup->identifier());
160
161     platformInitialize();
162     Settings::setMinDOMTimerInterval(0.004);
163
164     m_drawingArea = DrawingArea::create(parameters.drawingAreaInfo.type, parameters.drawingAreaInfo.identifier, this);
165     m_mainFrame = WebFrame::createMainFrame(this);
166
167     setDrawsBackground(parameters.drawsBackground);
168     setDrawsTransparentBackground(parameters.drawsTransparentBackground);
169
170     m_userAgent = parameters.userAgent;
171
172 #ifndef NDEBUG
173     webPageCounter.increment();
174 #endif
175 }
176
177 WebPage::~WebPage()
178 {
179     if (m_backForwardList)
180         m_backForwardList->detach();
181
182     ASSERT(!m_page);
183
184     m_sandboxExtensionTracker.invalidate();
185
186 #if PLATFORM(MAC)
187     ASSERT(m_pluginViews.isEmpty());
188 #endif
189
190 #ifndef NDEBUG
191     webPageCounter.decrement();
192 #endif
193 }
194
195 void WebPage::dummy(bool&)
196 {
197 }
198
199 CoreIPC::Connection* WebPage::connection() const
200 {
201     return WebProcess::shared().connection();
202 }
203
204 void WebPage::initializeInjectedBundleContextMenuClient(WKBundlePageContextMenuClient* client)
205 {
206     m_contextMenuClient.initialize(client);
207 }
208
209 void WebPage::initializeInjectedBundleEditorClient(WKBundlePageEditorClient* client)
210 {
211     m_editorClient.initialize(client);
212 }
213
214 void WebPage::initializeInjectedBundleFormClient(WKBundlePageFormClient* client)
215 {
216     m_formClient.initialize(client);
217 }
218
219 void WebPage::initializeInjectedBundleLoaderClient(WKBundlePageLoaderClient* client)
220 {
221     m_loaderClient.initialize(client);
222 }
223
224 void WebPage::initializeInjectedBundleUIClient(WKBundlePageUIClient* client)
225 {
226     m_uiClient.initialize(client);
227 }
228
229 PassRefPtr<Plugin> WebPage::createPlugin(const Plugin::Parameters& parameters)
230 {
231     String pluginPath;
232
233     if (!WebProcess::shared().connection()->sendSync(
234             Messages::WebContext::GetPluginPath(parameters.mimeType, parameters.url.string()), 
235             Messages::WebContext::GetPluginPath::Reply(pluginPath), 0)) {
236         return 0;
237     }
238
239     if (pluginPath.isNull())
240         return 0;
241
242 #if ENABLE(PLUGIN_PROCESS)
243     return PluginProxy::create(pluginPath);
244 #else
245     return NetscapePlugin::create(NetscapePluginModule::getOrCreate(pluginPath));
246 #endif
247 }
248
249 String WebPage::renderTreeExternalRepresentation() const
250 {
251     return externalRepresentation(m_mainFrame->coreFrame(), RenderAsTextBehaviorNormal);
252 }
253
254 void WebPage::executeEditingCommand(const String& commandName, const String& argument)
255 {
256     Frame* frame = m_page->focusController()->focusedOrMainFrame();
257     if (!frame)
258         return;
259     frame->editor()->command(commandName).execute(argument);
260 }
261
262 bool WebPage::isEditingCommandEnabled(const String& commandName)
263 {
264     Frame* frame = m_page->focusController()->focusedOrMainFrame();
265     if (!frame)
266         return false;
267     
268     Editor::Command command = frame->editor()->command(commandName);
269     return command.isSupported() && command.isEnabled();
270 }
271     
272 void WebPage::clearMainFrameName()
273 {
274     mainFrame()->coreFrame()->tree()->clearName();
275 }
276
277 #if USE(ACCELERATED_COMPOSITING)
278 void WebPage::changeAcceleratedCompositingMode(WebCore::GraphicsLayer* layer)
279 {
280     if (m_isClosed)
281         return;
282
283     bool compositing = layer;
284     
285     // Tell the UI process that accelerated compositing changed. It may respond by changing
286     // drawing area types.
287     DrawingAreaInfo newDrawingAreaInfo;
288
289     if (!sendSync(Messages::WebPageProxy::DidChangeAcceleratedCompositing(compositing), Messages::WebPageProxy::DidChangeAcceleratedCompositing::Reply(newDrawingAreaInfo)))
290         return;
291     
292     if (newDrawingAreaInfo.type != drawingArea()->info().type) {
293         m_drawingArea = 0;
294         if (newDrawingAreaInfo.type != DrawingAreaInfo::None) {
295             m_drawingArea = DrawingArea::create(newDrawingAreaInfo.type, newDrawingAreaInfo.identifier, this);
296             m_drawingArea->setNeedsDisplay(IntRect(IntPoint(0, 0), m_viewSize));
297         }
298     }
299 }
300
301 void WebPage::enterAcceleratedCompositingMode(GraphicsLayer* layer)
302 {
303     changeAcceleratedCompositingMode(layer);
304     m_drawingArea->setRootCompositingLayer(layer);
305 }
306
307 void WebPage::exitAcceleratedCompositingMode()
308 {
309     changeAcceleratedCompositingMode(0);
310 }
311 #endif
312
313 void WebPage::close()
314 {
315     if (m_isClosed)
316         return;
317
318     m_isClosed = true;
319
320     if (pageGroup()->isVisibleToInjectedBundle() && WebProcess::shared().injectedBundle())
321         WebProcess::shared().injectedBundle()->willDestroyPage(this);
322
323 #if ENABLE(INSPECTOR)
324     m_inspector = 0;
325 #endif
326
327     if (m_activePopupMenu) {
328         m_activePopupMenu->disconnectFromPage();
329         m_activePopupMenu = 0;
330     }
331
332     if (m_activeOpenPanelResultListener) {
333         m_activeOpenPanelResultListener->disconnectFromPage();
334         m_activeOpenPanelResultListener = 0;
335     }
336
337     m_sandboxExtensionTracker.invalidate();
338
339     m_mainFrame->coreFrame()->loader()->detachFromParent();
340     m_page.clear();
341
342     m_drawingArea->onPageClose();
343     m_drawingArea.clear();
344
345     WebProcess::shared().removeWebPage(m_pageID);
346 }
347
348 void WebPage::tryClose()
349 {
350     if (!m_mainFrame->coreFrame()->loader()->shouldClose())
351         return;
352
353     sendClose();
354 }
355
356 void WebPage::sendClose()
357 {
358     send(Messages::WebPageProxy::ClosePage());
359 }
360
361 void WebPage::loadURL(const String& url, const SandboxExtension::Handle& sandboxExtensionHandle)
362 {
363     loadURLRequest(ResourceRequest(KURL(KURL(), url)), sandboxExtensionHandle);
364 }
365
366 void WebPage::loadURLRequest(const ResourceRequest& request, const SandboxExtension::Handle& sandboxExtensionHandle)
367 {
368     m_sandboxExtensionTracker.beginLoad(m_mainFrame.get(), sandboxExtensionHandle);
369     m_mainFrame->coreFrame()->loader()->load(request, false);
370 }
371
372 void WebPage::loadData(PassRefPtr<SharedBuffer> sharedBuffer, const String& MIMEType, const String& encodingName, const KURL& baseURL, const KURL& unreachableURL)
373 {
374     ResourceRequest request(baseURL);
375     SubstituteData substituteData(sharedBuffer, MIMEType, encodingName, unreachableURL);
376     m_mainFrame->coreFrame()->loader()->load(request, substituteData, false);
377 }
378
379 void WebPage::loadHTMLString(const String& htmlString, const String& baseURLString)
380 {
381     RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(htmlString.characters()), htmlString.length() * sizeof(UChar));
382     KURL baseURL = baseURLString.isEmpty() ? blankURL() : KURL(KURL(), baseURLString);
383     loadData(sharedBuffer, "text/html", "utf-16", baseURL, KURL());
384 }
385
386 void WebPage::loadAlternateHTMLString(const String& htmlString, const String& baseURLString, const String& unreachableURLString)
387 {
388     RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(htmlString.characters()), htmlString.length() * sizeof(UChar));
389     KURL baseURL = baseURLString.isEmpty() ? blankURL() : KURL(KURL(), baseURLString);
390     KURL unreachableURL = unreachableURLString.isEmpty() ? KURL() : KURL(KURL(), unreachableURLString)  ;
391     loadData(sharedBuffer, "text/html", "utf-16", baseURL, unreachableURL);
392 }
393
394 void WebPage::loadPlainTextString(const String& string)
395 {
396     RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(string.characters()), string.length() * sizeof(UChar));
397     loadData(sharedBuffer, "text/plain", "utf-16", blankURL(), KURL());
398 }
399
400 void WebPage::stopLoading()
401 {
402     m_mainFrame->coreFrame()->loader()->stopForUserCancel();
403 }
404
405 void WebPage::reload(bool reloadFromOrigin)
406 {
407     m_mainFrame->coreFrame()->loader()->reload(reloadFromOrigin);
408 }
409
410 void WebPage::goForward(uint64_t backForwardItemID)
411 {
412     HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID);
413     m_page->goToItem(item, FrameLoadTypeForward);
414 }
415
416 void WebPage::goBack(uint64_t backForwardItemID)
417 {
418     HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID);
419     m_page->goToItem(item, FrameLoadTypeBack);
420 }
421
422 void WebPage::goToBackForwardItem(uint64_t backForwardItemID)
423 {
424     HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID);
425     m_page->goToItem(item, FrameLoadTypeIndexedBackForward);
426 }
427
428 void WebPage::layoutIfNeeded()
429 {
430     if (m_mainFrame->coreFrame()->view())
431         m_mainFrame->coreFrame()->view()->updateLayoutAndStyleIfNeededRecursive();
432 }
433
434 void WebPage::setSize(const WebCore::IntSize& viewSize)
435 {
436 #if ENABLE(TILED_BACKING_STORE)
437     // If we are resizing to content ignore external attempts.
438     if (!m_resizesToContentsLayoutSize.isEmpty())
439         return;
440 #endif
441
442     if (m_viewSize == viewSize)
443         return;
444
445     Frame* frame = m_page->mainFrame();
446     
447     frame->view()->resize(viewSize);
448     frame->view()->setNeedsLayout();
449     m_drawingArea->setNeedsDisplay(IntRect(IntPoint(0, 0), viewSize));
450     
451     m_viewSize = viewSize;
452 }
453
454 #if ENABLE(TILED_BACKING_STORE)
455 void WebPage::setActualVisibleContentRect(const IntRect& rect)
456 {
457     Frame* frame = m_page->mainFrame();
458
459     frame->view()->setActualVisibleContentRect(rect);
460 }
461
462 void WebPage::setResizesToContentsUsingLayoutSize(const IntSize& targetLayoutSize)
463 {
464     if (m_resizesToContentsLayoutSize == targetLayoutSize)
465         return;
466
467     m_resizesToContentsLayoutSize = targetLayoutSize;
468
469     Frame* frame = m_page->mainFrame();
470     if (m_resizesToContentsLayoutSize.isEmpty()) {
471         frame->view()->setDelegatesScrolling(false);
472         frame->view()->setUseFixedLayout(false);
473         frame->view()->setPaintsEntireContents(false);
474     } else {
475         frame->view()->setDelegatesScrolling(true);
476         frame->view()->setUseFixedLayout(true);
477         frame->view()->setPaintsEntireContents(true);
478         frame->view()->setFixedLayoutSize(m_resizesToContentsLayoutSize);
479     }
480     frame->view()->forceLayout();
481 }
482
483 void WebPage::resizeToContentsIfNeeded()
484 {
485     if (m_resizesToContentsLayoutSize.isEmpty())
486         return;
487
488     Frame* frame = m_page->mainFrame();
489
490     IntSize contentSize = frame->view()->contentsSize();
491     if (contentSize == m_viewSize)
492         return;
493
494     m_viewSize = contentSize;
495     frame->view()->resize(m_viewSize);
496     frame->view()->setNeedsLayout();
497 }
498 #endif
499
500 void WebPage::drawRect(GraphicsContext& graphicsContext, const IntRect& rect)
501 {
502     graphicsContext.save();
503     graphicsContext.clip(rect);
504     m_mainFrame->coreFrame()->view()->paint(&graphicsContext, rect);
505     graphicsContext.restore();
506
507     if (m_pageOverlay) {
508         graphicsContext.save();
509         graphicsContext.clip(rect);
510         m_pageOverlay->drawRect(graphicsContext, rect);
511         graphicsContext.restore();
512     }
513 }
514
515 double WebPage::textZoomFactor() const
516 {
517     Frame* frame = m_mainFrame->coreFrame();
518     if (!frame)
519         return 1;
520     return frame->textZoomFactor();
521 }
522
523 void WebPage::setTextZoomFactor(double zoomFactor)
524 {
525     Frame* frame = m_mainFrame->coreFrame();
526     if (!frame)
527         return;
528     frame->setTextZoomFactor(static_cast<float>(zoomFactor));
529 }
530
531 double WebPage::pageZoomFactor() const
532 {
533     Frame* frame = m_mainFrame->coreFrame();
534     if (!frame)
535         return 1;
536     return frame->pageZoomFactor();
537 }
538
539 void WebPage::setPageZoomFactor(double zoomFactor)
540 {
541     Frame* frame = m_mainFrame->coreFrame();
542     if (!frame)
543         return;
544     frame->setPageZoomFactor(static_cast<float>(zoomFactor));
545 }
546
547 void WebPage::setPageAndTextZoomFactors(double pageZoomFactor, double textZoomFactor)
548 {
549     Frame* frame = m_mainFrame->coreFrame();
550     if (!frame)
551         return;
552     return frame->setPageAndTextZoomFactors(static_cast<float>(pageZoomFactor), static_cast<float>(textZoomFactor));
553 }
554
555 void WebPage::scaleWebView(double scale, const IntPoint& origin)
556 {
557     Frame* frame = m_mainFrame->coreFrame();
558     if (!frame)
559         return;
560     frame->scalePage(scale, origin);
561 }
562
563 double WebPage::viewScaleFactor() const
564 {
565     Frame* frame = m_mainFrame->coreFrame();
566     if (!frame)
567         return 1;
568     return frame->pageScaleFactor();
569 }
570
571 void WebPage::installPageOverlay(PassRefPtr<PageOverlay> pageOverlay)
572 {
573     if (m_pageOverlay)
574         pageOverlay->setPage(0);
575
576     m_pageOverlay = pageOverlay;
577     m_pageOverlay->setPage(this);
578     m_pageOverlay->setNeedsDisplay();
579 }
580
581 void WebPage::uninstallPageOverlay(PageOverlay* pageOverlay)
582 {
583     if (pageOverlay != m_pageOverlay)
584         return;
585
586     m_pageOverlay->setPage(0);
587     m_pageOverlay = nullptr;
588     m_drawingArea->setNeedsDisplay(IntRect(IntPoint(0, 0), m_viewSize));
589 }
590
591 PassRefPtr<WebImage> WebPage::snapshotInViewCoordinates(const IntRect& rect, ImageOptions options)
592 {
593     FrameView* frameView = m_mainFrame->coreFrame()->view();
594     if (!frameView)
595         return 0;
596
597     frameView->updateLayoutAndStyleIfNeededRecursive();
598
599     PaintBehavior oldBehavior = frameView->paintBehavior();
600     frameView->setPaintBehavior(oldBehavior | PaintBehaviorFlattenCompositingLayers);
601
602     RefPtr<WebImage> snapshot = WebImage::create(rect.size(), options);
603     OwnPtr<WebCore::GraphicsContext> graphicsContext = snapshot->backingStore()->createGraphicsContext();
604
605     graphicsContext->save();
606     graphicsContext->translate(-rect.x(), -rect.y());
607     frameView->paint(graphicsContext.get(), rect);
608     graphicsContext->restore();
609
610     frameView->setPaintBehavior(oldBehavior);
611
612     return snapshot.release();
613 }
614
615 PassRefPtr<WebImage> WebPage::snapshotInDocumentCoordinates(const IntRect& rect, ImageOptions options)
616 {
617     FrameView* frameView = m_mainFrame->coreFrame()->view();
618     if (!frameView)
619         return 0;
620
621     frameView->updateLayoutAndStyleIfNeededRecursive();
622
623     PaintBehavior oldBehavior = frameView->paintBehavior();
624     frameView->setPaintBehavior(oldBehavior | PaintBehaviorFlattenCompositingLayers);
625
626     RefPtr<WebImage> snapshot = WebImage::create(rect.size(), options);
627     OwnPtr<WebCore::GraphicsContext> graphicsContext = snapshot->backingStore()->createGraphicsContext();
628
629     graphicsContext->save();
630     graphicsContext->translate(-rect.x(), -rect.y());
631     frameView->paintContents(graphicsContext.get(), rect);
632     graphicsContext->restore();
633
634     frameView->setPaintBehavior(oldBehavior);
635
636     return snapshot.release();
637 }
638
639 void WebPage::pageDidScroll()
640 {
641     // Hide the find indicator.
642     m_findController.hideFindIndicator();
643
644     m_uiClient.pageDidScroll(this);
645
646     send(Messages::WebPageProxy::PageDidScroll());
647 }
648
649 #if ENABLE(TILED_BACKING_STORE)
650 void WebPage::pageDidRequestScroll(const IntSize& delta)
651 {
652     send(Messages::WebPageProxy::PageDidRequestScroll(delta));
653 }
654 #endif
655
656 WebContextMenu* WebPage::contextMenu()
657 {
658     if (!m_contextMenu)
659         m_contextMenu = WebContextMenu::create(this);
660     return m_contextMenu.get();
661 }
662
663 void WebPage::getLocationAndLengthFromRange(Range* range, uint64_t& location, uint64_t& length)
664 {
665     location = notFound;
666     length = 0;
667
668     if (!range || !range->startContainer())
669         return;
670
671     Element* selectionRoot = range->ownerDocument()->frame()->selection()->rootEditableElement();
672     Element* scope = selectionRoot ? selectionRoot : range->ownerDocument()->documentElement();
673     
674     // Mouse events may cause TSM to attempt to create an NSRange for a portion of the view
675     // that is not inside the current editable region.  These checks ensure we don't produce
676     // potentially invalid data when responding to such requests.
677     if (range->startContainer() != scope && !range->startContainer()->isDescendantOf(scope))
678         return;
679     if (range->endContainer() != scope && !range->endContainer()->isDescendantOf(scope))
680         return;
681
682     RefPtr<Range> testRange = Range::create(scope->document(), scope, 0, range->startContainer(), range->startOffset());
683     ASSERT(testRange->startContainer() == scope);
684     location = TextIterator::rangeLength(testRange.get());
685     
686     ExceptionCode ec;
687     testRange->setEnd(range->endContainer(), range->endOffset(), ec);
688     ASSERT(testRange->startContainer() == scope);
689     length = TextIterator::rangeLength(testRange.get()) - location;
690 }
691
692 // Events 
693
694 static const WebEvent* g_currentEvent = 0;
695
696 // FIXME: WebPage::currentEvent is used by the plug-in code to avoid having to convert from DOM events back to
697 // WebEvents. When we get the event handling sorted out, this should go away and the Widgets should get the correct
698 // platform events passed to the event handler code.
699 const WebEvent* WebPage::currentEvent()
700 {
701     return g_currentEvent;
702 }
703
704 class CurrentEvent {
705 public:
706     explicit CurrentEvent(const WebEvent& event)
707         : m_previousCurrentEvent(g_currentEvent)
708     {
709         g_currentEvent = &event;
710     }
711
712     ~CurrentEvent()
713     {
714         g_currentEvent = m_previousCurrentEvent;
715     }
716
717 private:
718     const WebEvent* m_previousCurrentEvent;
719 };
720
721 static bool isContextClick(const PlatformMouseEvent& event)
722 {
723     if (event.button() == WebCore::RightButton)
724         return true;
725
726 #if PLATFORM(MAC)
727     // FIXME: this really should be about OSX-style UI, not about the Mac port
728     if (event.button() == WebCore::LeftButton && event.ctrlKey())
729         return true;
730 #endif
731
732     return false;
733 }
734
735 static bool handleMouseEvent(const WebMouseEvent& mouseEvent, Page* page)
736 {
737     Frame* frame = page->mainFrame();
738     if (!frame->view())
739         return false;
740
741     PlatformMouseEvent platformMouseEvent = platform(mouseEvent);
742
743     switch (platformMouseEvent.eventType()) {
744         case WebCore::MouseEventPressed:
745         {
746             if (isContextClick(platformMouseEvent))
747                 page->contextMenuController()->clearContextMenu();
748             
749             bool handled = frame->eventHandler()->handleMousePressEvent(platformMouseEvent);
750             
751             if (isContextClick(platformMouseEvent)) {
752                 handled = frame->eventHandler()->sendContextMenuEvent(platformMouseEvent);
753                 if (handled)
754                     page->chrome()->showContextMenu();
755             }
756
757             return handled;
758         }
759         case WebCore::MouseEventReleased:
760             return frame->eventHandler()->handleMouseReleaseEvent(platformMouseEvent);
761         case WebCore::MouseEventMoved:
762             return frame->eventHandler()->mouseMoved(platformMouseEvent);
763         default:
764             ASSERT_NOT_REACHED();
765             return false;
766     }
767 }
768
769 void WebPage::mouseEvent(const WebMouseEvent& mouseEvent)
770 {
771     bool handled = false;
772     
773     if (m_pageOverlay) {
774         // Let the page overlay handle the event.
775         handled = m_pageOverlay->mouseEvent(mouseEvent);
776     }
777
778     if (!handled) {
779         CurrentEvent currentEvent(mouseEvent);
780
781         handled = handleMouseEvent(mouseEvent, m_page.get());
782     }
783
784     send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(mouseEvent.type()), handled));
785 }
786
787 static bool handleWheelEvent(const WebWheelEvent& wheelEvent, Page* page)
788 {
789     Frame* frame = page->mainFrame();
790     if (!frame->view())
791         return false;
792
793     PlatformWheelEvent platformWheelEvent = platform(wheelEvent);
794     return frame->eventHandler()->handleWheelEvent(platformWheelEvent);
795 }
796
797 void WebPage::wheelEvent(const WebWheelEvent& wheelEvent)
798 {
799     CurrentEvent currentEvent(wheelEvent);
800
801     bool handled = handleWheelEvent(wheelEvent, m_page.get());
802     send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(wheelEvent.type()), handled));
803 }
804
805 static bool handleKeyEvent(const WebKeyboardEvent& keyboardEvent, Page* page)
806 {
807     if (!page->mainFrame()->view())
808         return false;
809
810     if (keyboardEvent.type() == WebEvent::Char && keyboardEvent.isSystemKey())
811         return page->focusController()->focusedOrMainFrame()->eventHandler()->handleAccessKey(platform(keyboardEvent));
812     return page->focusController()->focusedOrMainFrame()->eventHandler()->keyEvent(platform(keyboardEvent));
813 }
814
815 void WebPage::keyEvent(const WebKeyboardEvent& keyboardEvent)
816 {
817     CurrentEvent currentEvent(keyboardEvent);
818
819     bool handled = handleKeyEvent(keyboardEvent, m_page.get());
820     if (!handled)
821         handled = performDefaultBehaviorForKeyEvent(keyboardEvent);
822
823     send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(keyboardEvent.type()), handled));
824 }
825
826 void WebPage::validateMenuItem(const String& commandName)
827 {
828     bool isEnabled = false;
829     int32_t state = 0;
830     Frame* frame = m_page->focusController()->focusedOrMainFrame();
831     if (frame) {
832         Editor::Command command = frame->editor()->command(commandName);
833         state = command.state();
834         isEnabled = command.isSupported() && command.isEnabled();
835     }
836
837     send(Messages::WebPageProxy::DidValidateMenuItem(commandName, isEnabled, state));
838 }
839
840 void WebPage::executeEditCommand(const String& commandName)
841 {
842     executeEditingCommand(commandName, String());
843 }
844
845 #if ENABLE(TOUCH_EVENTS)
846 static bool handleTouchEvent(const WebTouchEvent& touchEvent, Page* page)
847 {
848     Frame* frame = page->mainFrame();
849     if (!frame->view())
850         return false;
851
852     return frame->eventHandler()->handleTouchEvent(platform(touchEvent));
853 }
854
855 void WebPage::touchEvent(const WebTouchEvent& touchEvent)
856 {
857     CurrentEvent currentEvent(touchEvent);
858
859     bool handled = handleTouchEvent(touchEvent, m_page.get());
860
861     send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(touchEvent.type()), handled));
862 }
863 #endif
864
865 void WebPage::setActive(bool isActive)
866 {
867     m_page->focusController()->setActive(isActive);
868
869 #if PLATFORM(MAC)    
870     // Tell all our plug-in views that the window focus changed.
871     for (HashSet<PluginView*>::const_iterator it = m_pluginViews.begin(), end = m_pluginViews.end(); it != end; ++it)
872         (*it)->setWindowIsFocused(isActive);
873 #endif
874 }
875
876 void WebPage::setDrawsBackground(bool drawsBackground)
877 {
878     if (m_drawsBackground == drawsBackground)
879         return;
880
881     m_drawsBackground = drawsBackground;
882
883     for (Frame* coreFrame = m_mainFrame->coreFrame(); coreFrame; coreFrame = coreFrame->tree()->traverseNext()) {
884         if (FrameView* view = coreFrame->view())
885             view->setTransparent(!drawsBackground);
886     }
887
888     m_drawingArea->pageBackgroundTransparencyChanged();
889     m_drawingArea->setNeedsDisplay(IntRect(IntPoint(0, 0), m_viewSize));
890 }
891
892 void WebPage::setDrawsTransparentBackground(bool drawsTransparentBackground)
893 {
894     if (m_drawsTransparentBackground == drawsTransparentBackground)
895         return;
896
897     m_drawsTransparentBackground = drawsTransparentBackground;
898
899     Color backgroundColor = drawsTransparentBackground ? Color::transparent : Color::white;
900     for (Frame* coreFrame = m_mainFrame->coreFrame(); coreFrame; coreFrame = coreFrame->tree()->traverseNext()) {
901         if (FrameView* view = coreFrame->view())
902             view->setBaseBackgroundColor(backgroundColor);
903     }
904
905     m_drawingArea->pageBackgroundTransparencyChanged();
906     m_drawingArea->setNeedsDisplay(IntRect(IntPoint(0, 0), m_viewSize));
907 }
908
909 void WebPage::setFocused(bool isFocused)
910 {
911     m_page->focusController()->setFocused(isFocused);
912 }
913
914 void WebPage::setInitialFocus(bool forward)
915 {
916     if (!m_page || !m_page->focusController())
917         return;
918
919     Frame* frame = m_page->focusController()->focusedOrMainFrame();
920     frame->document()->setFocusedNode(0);
921     m_page->focusController()->setInitialFocus(forward ? FocusDirectionForward : FocusDirectionBackward, 0);
922 }
923
924 void WebPage::setWindowResizerSize(const IntSize& windowResizerSize)
925 {
926     if (m_windowResizerSize == windowResizerSize)
927         return;
928
929     m_windowResizerSize = windowResizerSize;
930
931     for (Frame* coreFrame = m_mainFrame->coreFrame(); coreFrame; coreFrame = coreFrame->tree()->traverseNext()) {
932         FrameView* view = coreFrame->view();
933         if (view)
934             view->windowResizerRectChanged();
935     }
936 }
937
938 void WebPage::setIsInWindow(bool isInWindow)
939 {
940     if (!isInWindow) {
941         m_page->setCanStartMedia(false);
942         m_page->willMoveOffscreen();
943     } else {
944         m_page->setCanStartMedia(true);
945         m_page->didMoveOnscreen();
946     }
947 }
948
949 void WebPage::didReceivePolicyDecision(uint64_t frameID, uint64_t listenerID, uint32_t policyAction, uint64_t downloadID)
950 {
951     WebFrame* frame = WebProcess::shared().webFrame(frameID);
952     if (!frame)
953         return;
954     frame->didReceivePolicyDecision(listenerID, static_cast<PolicyAction>(policyAction), downloadID);
955 }
956
957 void WebPage::show()
958 {
959     send(Messages::WebPageProxy::ShowPage());
960 }
961
962 void WebPage::setUserAgent(const String& userAgent)
963 {
964     m_userAgent = userAgent;
965 }
966
967 IntRect WebPage::windowResizerRect() const
968 {
969     if (m_windowResizerSize.isEmpty())
970         return IntRect();
971
972     IntSize frameViewSize;
973     if (Frame* coreFrame = m_mainFrame->coreFrame()) {
974         if (FrameView* view = coreFrame->view())
975             frameViewSize = view->size();
976     }
977
978     return IntRect(frameViewSize.width() - m_windowResizerSize.width(), frameViewSize.height() - m_windowResizerSize.height(), 
979                    m_windowResizerSize.width(), m_windowResizerSize.height());
980 }
981
982 void WebPage::runJavaScriptInMainFrame(const String& script, uint64_t callbackID)
983 {
984     // NOTE: We need to be careful when running scripts that the objects we depend on don't
985     // disappear during script execution.
986
987     JSLock lock(SilenceAssertionsOnly);
988     JSValue resultValue = m_mainFrame->coreFrame()->script()->executeScript(script, true).jsValue();
989     String resultString;
990     if (resultValue)
991         resultString = ustringToString(resultValue.toString(m_mainFrame->coreFrame()->script()->globalObject(mainThreadNormalWorld())->globalExec()));
992
993     send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
994 }
995
996 void WebPage::getContentsAsString(uint64_t callbackID)
997 {
998     String resultString = m_mainFrame->contentsAsString();
999     send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
1000 }
1001
1002 void WebPage::getRenderTreeExternalRepresentation(uint64_t callbackID)
1003 {
1004     String resultString = renderTreeExternalRepresentation();
1005     send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
1006 }
1007
1008 void WebPage::getSelectionOrContentsAsString(uint64_t callbackID)
1009 {
1010     String resultString = m_mainFrame->selectionAsString();
1011     if (resultString.isEmpty())
1012         resultString = m_mainFrame->contentsAsString();
1013     send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
1014 }
1015
1016 void WebPage::getSourceForFrame(uint64_t frameID, uint64_t callbackID)
1017 {
1018     String resultString;
1019     if (WebFrame* frame = WebProcess::shared().webFrame(frameID))
1020        resultString = frame->source();
1021
1022     send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
1023 }
1024
1025 void WebPage::getMainResourceDataOfFrame(uint64_t frameID, uint64_t callbackID)
1026 {
1027     CoreIPC::DataReference dataReference;
1028
1029     RefPtr<SharedBuffer> buffer;
1030     if (WebFrame* frame = WebProcess::shared().webFrame(frameID)) {
1031         if (DocumentLoader* loader = frame->coreFrame()->loader()->documentLoader()) {
1032             if ((buffer = loader->mainResourceData()))
1033                 dataReference = CoreIPC::DataReference(reinterpret_cast<const uint8_t*>(buffer->data()), buffer->size());
1034         }
1035     }
1036
1037     send(Messages::WebPageProxy::DataCallback(dataReference, callbackID));
1038 }
1039
1040 void WebPage::getWebArchiveOfFrame(uint64_t frameID, uint64_t callbackID)
1041 {
1042     CoreIPC::DataReference dataReference;
1043
1044 #if PLATFORM(MAC) || PLATFORM(WIN)
1045     RetainPtr<CFDataRef> data;
1046     if (WebFrame* frame = WebProcess::shared().webFrame(frameID)) {
1047         if (RefPtr<LegacyWebArchive> archive = LegacyWebArchive::create(frame->coreFrame())) {
1048             if ((data = archive->rawDataRepresentation()))
1049                 dataReference = CoreIPC::DataReference(CFDataGetBytePtr(data.get()), CFDataGetLength(data.get()));
1050         }
1051     }
1052 #endif
1053
1054     send(Messages::WebPageProxy::DataCallback(dataReference, callbackID));
1055 }
1056
1057 void WebPage::preferencesDidChange(const WebPreferencesStore& store)
1058 {
1059     WebPreferencesStore::removeTestRunnerOverrides();
1060     updatePreferences(store);
1061 }
1062
1063 void WebPage::updatePreferences(const WebPreferencesStore& store)
1064 {
1065     Settings* settings = m_page->settings();
1066
1067     m_tabToLinks = store.getBoolValueForKey(WebPreferencesKey::tabsToLinksKey());
1068
1069     // FIXME: This should be generated from macro expansion for all preferences,
1070     // but we currently don't match the naming of WebCore exactly so we are
1071     // handrolling the boolean and integer preferences until that is fixed.
1072
1073 #define INITIALIZE_SETTINGS(KeyUpper, KeyLower, TypeName, Type, DefaultValue) settings->set##KeyUpper(store.get##TypeName##ValueForKey(WebPreferencesKey::KeyLower##Key()));
1074
1075     FOR_EACH_WEBKIT_STRING_PREFERENCE(INITIALIZE_SETTINGS)
1076
1077 #undef INITIALIZE_SETTINGS
1078
1079     settings->setJavaScriptEnabled(store.getBoolValueForKey(WebPreferencesKey::javaScriptEnabledKey()));
1080     settings->setLoadsImagesAutomatically(store.getBoolValueForKey(WebPreferencesKey::loadsImagesAutomaticallyKey()));
1081     settings->setPluginsEnabled(store.getBoolValueForKey(WebPreferencesKey::pluginsEnabledKey()));
1082     settings->setJavaEnabled(store.getBoolValueForKey(WebPreferencesKey::javaEnabledKey()));
1083     settings->setOfflineWebApplicationCacheEnabled(store.getBoolValueForKey(WebPreferencesKey::offlineWebApplicationCacheEnabledKey()));
1084     settings->setLocalStorageEnabled(store.getBoolValueForKey(WebPreferencesKey::localStorageEnabledKey()));
1085     settings->setXSSAuditorEnabled(store.getBoolValueForKey(WebPreferencesKey::xssAuditorEnabledKey()));
1086     settings->setFrameFlatteningEnabled(store.getBoolValueForKey(WebPreferencesKey::frameFlatteningEnabledKey()));
1087     settings->setPrivateBrowsingEnabled(store.getBoolValueForKey(WebPreferencesKey::privateBrowsingEnabledKey()));
1088     settings->setDeveloperExtrasEnabled(store.getBoolValueForKey(WebPreferencesKey::developerExtrasEnabledKey()));
1089     settings->setTextAreasAreResizable(store.getBoolValueForKey(WebPreferencesKey::textAreasAreResizableKey()));
1090     settings->setNeedsSiteSpecificQuirks(store.getBoolValueForKey(WebPreferencesKey::needsSiteSpecificQuirksKey()));
1091     settings->setJavaScriptCanOpenWindowsAutomatically(store.getBoolValueForKey(WebPreferencesKey::javaScriptCanOpenWindowsAutomaticallyKey()));
1092     settings->setForceFTPDirectoryListings(store.getBoolValueForKey(WebPreferencesKey::forceFTPDirectoryListingsKey()));
1093     settings->setDNSPrefetchingEnabled(store.getBoolValueForKey(WebPreferencesKey::dnsPrefetchingEnabledKey()));
1094     settings->setWebArchiveDebugModeEnabled(store.getBoolValueForKey(WebPreferencesKey::webArchiveDebugModeEnabledKey()));
1095     settings->setLocalFileContentSniffingEnabled(store.getBoolValueForKey(WebPreferencesKey::localFileContentSniffingEnabledKey()));
1096     settings->setUsesPageCache(store.getBoolValueForKey(WebPreferencesKey::usesPageCacheKey()));
1097     settings->setAuthorAndUserStylesEnabled(store.getBoolValueForKey(WebPreferencesKey::authorAndUserStylesEnabledKey()));
1098     settings->setPaginateDuringLayoutEnabled(store.getBoolValueForKey(WebPreferencesKey::paginateDuringLayoutEnabledKey()));
1099     settings->setDOMPasteAllowed(store.getBoolValueForKey(WebPreferencesKey::domPasteAllowedKey()));
1100
1101     settings->setMinimumFontSize(store.getUInt32ValueForKey(WebPreferencesKey::minimumFontSizeKey()));
1102     settings->setMinimumLogicalFontSize(store.getUInt32ValueForKey(WebPreferencesKey::minimumLogicalFontSizeKey()));
1103     settings->setDefaultFontSize(store.getUInt32ValueForKey(WebPreferencesKey::defaultFontSizeKey()));
1104     settings->setDefaultFixedFontSize(store.getUInt32ValueForKey(WebPreferencesKey::defaultFixedFontSizeKey()));
1105
1106 #if PLATFORM(WIN)
1107     // Temporarily turn off accelerated compositing until we have a good solution for rendering it.
1108     settings->setAcceleratedCompositingEnabled(false);
1109 #else
1110     settings->setAcceleratedCompositingEnabled(store.getBoolValueForKey(WebPreferencesKey::acceleratedCompositingEnabledKey()));
1111 #endif
1112     settings->setShowDebugBorders(store.getBoolValueForKey(WebPreferencesKey::compositingBordersVisibleKey()));
1113     settings->setShowRepaintCounter(store.getBoolValueForKey(WebPreferencesKey::compositingRepaintCountersVisibleKey()));
1114
1115 #if ENABLE(DATABASE)
1116     AbstractDatabase::setIsAvailable(store.getBoolValueForKey(WebPreferencesKey::databasesEnabledKey()));
1117 #endif
1118
1119     platformPreferencesDidChange(store);
1120 }
1121
1122 #if ENABLE(INSPECTOR)
1123 WebInspector* WebPage::inspector()
1124 {
1125     if (m_isClosed)
1126         return 0;
1127     if (!m_inspector)
1128         m_inspector = adoptPtr(new WebInspector(this));
1129     return m_inspector.get();
1130 }
1131 #endif
1132
1133 #if !PLATFORM(MAC)
1134 bool WebPage::handleEditingKeyboardEvent(KeyboardEvent* evt)
1135 {
1136     Node* node = evt->target()->toNode();
1137     ASSERT(node);
1138     Frame* frame = node->document()->frame();
1139     ASSERT(frame);
1140
1141     const PlatformKeyboardEvent* keyEvent = evt->keyEvent();
1142     if (!keyEvent)
1143         return false;
1144
1145     Editor::Command command = frame->editor()->command(interpretKeyEvent(evt));
1146
1147     if (keyEvent->type() == PlatformKeyboardEvent::RawKeyDown) {
1148         // WebKit doesn't have enough information about mode to decide how commands that just insert text if executed via Editor should be treated,
1149         // so we leave it upon WebCore to either handle them immediately (e.g. Tab that changes focus) or let a keypress event be generated
1150         // (e.g. Tab that inserts a Tab character, or Enter).
1151         return !command.isTextInsertion() && command.execute(evt);
1152     }
1153
1154     if (command.execute(evt))
1155         return true;
1156
1157     // Don't insert null or control characters as they can result in unexpected behaviour
1158     if (evt->charCode() < ' ')
1159         return false;
1160
1161     return frame->editor()->insertText(evt->keyEvent()->text(), evt);
1162 }
1163 #endif
1164
1165 WebEditCommand* WebPage::webEditCommand(uint64_t commandID)
1166 {
1167     return m_editCommandMap.get(commandID).get();
1168 }
1169
1170 void WebPage::addWebEditCommand(uint64_t commandID, WebEditCommand* command)
1171 {
1172     m_editCommandMap.set(commandID, command);
1173 }
1174
1175 void WebPage::removeWebEditCommand(uint64_t commandID)
1176 {
1177     m_editCommandMap.remove(commandID);
1178 }
1179
1180 void WebPage::unapplyEditCommand(uint64_t commandID)
1181 {
1182     WebEditCommand* command = webEditCommand(commandID);
1183     if (!command)
1184         return;
1185
1186     command->command()->unapply();
1187 }
1188
1189 void WebPage::reapplyEditCommand(uint64_t commandID)
1190 {
1191     WebEditCommand* command = webEditCommand(commandID);
1192     if (!command)
1193         return;
1194
1195     m_isInRedo = true;
1196     command->command()->reapply();
1197     m_isInRedo = false;
1198 }
1199
1200 void WebPage::didRemoveEditCommand(uint64_t commandID)
1201 {
1202     removeWebEditCommand(commandID);
1203 }
1204
1205 void WebPage::setActivePopupMenu(WebPopupMenu* menu)
1206 {
1207     m_activePopupMenu = menu;
1208 }
1209
1210 void WebPage::setActiveOpenPanelResultListener(PassRefPtr<WebOpenPanelResultListener> openPanelResultListener)
1211 {
1212     m_activeOpenPanelResultListener = openPanelResultListener;
1213 }
1214
1215 bool WebPage::findStringFromInjectedBundle(const String& target, FindOptions options)
1216 {
1217     return m_page->findString(target, options);
1218 }
1219
1220 void WebPage::findString(const String& string, uint32_t options, uint32_t maxMatchCount)
1221 {
1222     m_findController.findString(string, static_cast<FindOptions>(options), maxMatchCount);
1223 }
1224
1225 void WebPage::hideFindUI()
1226 {
1227     m_findController.hideFindUI();
1228 }
1229
1230 void WebPage::countStringMatches(const String& string, uint32_t options, uint32_t maxMatchCount)
1231 {
1232     m_findController.countStringMatches(string, static_cast<FindOptions>(options), maxMatchCount);
1233 }
1234
1235 void WebPage::didChangeSelectedIndexForActivePopupMenu(int32_t newIndex)
1236 {
1237     if (!m_activePopupMenu)
1238         return;
1239
1240     m_activePopupMenu->didChangeSelectedIndex(newIndex);
1241     m_activePopupMenu = 0;
1242 }
1243
1244 void WebPage::didChooseFilesForOpenPanel(const Vector<String>& files)
1245 {
1246     if (!m_activeOpenPanelResultListener)
1247         return;
1248
1249     m_activeOpenPanelResultListener->didChooseFiles(files);
1250     m_activeOpenPanelResultListener = 0;
1251 }
1252
1253 void WebPage::didCancelForOpenPanel()
1254 {
1255     m_activeOpenPanelResultListener = 0;
1256 }
1257
1258 void WebPage::unmarkAllMisspellings()
1259 {
1260     for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
1261         if (Document* document = frame->document())
1262             document->markers()->removeMarkers(DocumentMarker::Spelling);
1263     }
1264 }
1265
1266 void WebPage::unmarkAllBadGrammar()
1267 {
1268     for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
1269         if (Document* document = frame->document())
1270             document->markers()->removeMarkers(DocumentMarker::Grammar);
1271     }
1272 }
1273
1274 void WebPage::setTextForActivePopupMenu(int32_t index)
1275 {
1276     if (!m_activePopupMenu)
1277         return;
1278
1279     m_activePopupMenu->setTextForIndex(index);
1280 }
1281
1282 void WebPage::didSelectItemFromActiveContextMenu(const WebContextMenuItemData& item)
1283 {
1284     ASSERT(m_contextMenu);
1285     m_contextMenu->itemSelected(item);
1286     m_contextMenu = 0;
1287 }
1288
1289 #if PLATFORM(MAC)
1290
1291 void WebPage::addPluginView(PluginView* pluginView)
1292 {
1293     ASSERT(!m_pluginViews.contains(pluginView));
1294
1295     m_pluginViews.add(pluginView);
1296 }
1297
1298 void WebPage::removePluginView(PluginView* pluginView)
1299 {
1300     ASSERT(m_pluginViews.contains(pluginView));
1301
1302     m_pluginViews.remove(pluginView);
1303 }
1304
1305 void WebPage::setWindowIsVisible(bool windowIsVisible)
1306 {
1307     m_windowIsVisible = windowIsVisible;
1308
1309     // Tell all our plug-in views that the window visibility changed.
1310     for (HashSet<PluginView*>::const_iterator it = m_pluginViews.begin(), end = m_pluginViews.end(); it != end; ++it)
1311         (*it)->setWindowIsVisible(windowIsVisible);
1312 }
1313
1314 void WebPage::windowAndViewFramesChanged(const WebCore::IntRect& windowFrameInScreenCoordinates, const WebCore::IntRect& viewFrameInWindowCoordinates)
1315 {
1316     m_windowFrameInScreenCoordinates = windowFrameInScreenCoordinates;
1317     m_viewFrameInWindowCoordinates = viewFrameInWindowCoordinates;
1318
1319     // Tell all our plug-in views that the window and view frames have changed.
1320     for (HashSet<PluginView*>::const_iterator it = m_pluginViews.begin(), end = m_pluginViews.end(); it != end; ++it)
1321         (*it)->windowAndViewFramesChanged(windowFrameInScreenCoordinates, viewFrameInWindowCoordinates);
1322 }
1323
1324 bool WebPage::windowIsFocused() const
1325 {
1326     return m_page->focusController()->isActive();
1327 }
1328
1329 #endif
1330
1331 void WebPage::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments)
1332 {
1333     if (messageID.is<CoreIPC::MessageClassDrawingAreaLegacy>()) {
1334         if (m_drawingArea)
1335             m_drawingArea->didReceiveMessage(connection, messageID, arguments);
1336         return;
1337     }
1338
1339 #if ENABLE(INSPECTOR)
1340     if (messageID.is<CoreIPC::MessageClassWebInspector>()) {
1341         if (WebInspector* inspector = this->inspector())
1342             inspector->didReceiveWebInspectorMessage(connection, messageID, arguments);
1343         return;
1344     }
1345 #endif
1346
1347     didReceiveWebPageMessage(connection, messageID, arguments);
1348 }
1349
1350 CoreIPC::SyncReplyMode WebPage::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments, CoreIPC::ArgumentEncoder* reply)
1351 {   
1352     return didReceiveSyncWebPageMessage(connection, messageID, arguments, reply);
1353 }
1354     
1355 InjectedBundleBackForwardList* WebPage::backForwardList()
1356 {
1357     if (!m_backForwardList)
1358         m_backForwardList = InjectedBundleBackForwardList::create(this);
1359     return m_backForwardList.get();
1360 }
1361
1362 #if PLATFORM(QT)
1363 void WebPage::findZoomableAreaForPoint(const WebCore::IntPoint& point)
1364 {
1365     const int minimumZoomTargetWidth = 100;
1366
1367     Frame* mainframe = m_mainFrame->coreFrame();
1368     HitTestResult result = mainframe->eventHandler()->hitTestResultAtPoint(mainframe->view()->windowToContents(point), /*allowShadowContent*/ false, /*ignoreClipping*/ true);
1369
1370     Node* node = result.innerNode();
1371     while (node && node->getRect().width() < minimumZoomTargetWidth)
1372         node = node->parentNode();
1373
1374     IntRect zoomableArea;
1375     if (node)
1376         zoomableArea = node->getRect();
1377     send(Messages::WebPageProxy::DidFindZoomableArea(zoomableArea));
1378 }
1379 #endif
1380
1381 WebPage::SandboxExtensionTracker::~SandboxExtensionTracker()
1382 {
1383     invalidate();
1384 }
1385
1386 void WebPage::SandboxExtensionTracker::invalidate()
1387 {
1388     if (m_pendingProvisionalSandboxExtension) {
1389         m_pendingProvisionalSandboxExtension->invalidate();
1390         m_pendingProvisionalSandboxExtension = 0;
1391     }
1392
1393     if (m_provisionalSandboxExtension) {
1394         m_provisionalSandboxExtension->invalidate();
1395         m_provisionalSandboxExtension = 0;
1396     }
1397
1398     if (m_committedSandboxExtension) {
1399         m_committedSandboxExtension->invalidate();
1400         m_committedSandboxExtension = 0;
1401     }
1402 }
1403
1404 void WebPage::SandboxExtensionTracker::beginLoad(WebFrame* frame, const SandboxExtension::Handle& handle)
1405 {
1406     ASSERT(frame->isMainFrame());
1407
1408     ASSERT(!m_pendingProvisionalSandboxExtension);
1409     m_pendingProvisionalSandboxExtension = SandboxExtension::create(handle);
1410 }
1411
1412 void WebPage::SandboxExtensionTracker::didStartProvisionalLoad(WebFrame* frame)
1413 {
1414     if (!frame->isMainFrame())
1415         return;
1416
1417     ASSERT(!m_provisionalSandboxExtension);
1418
1419     m_provisionalSandboxExtension = m_pendingProvisionalSandboxExtension.release();
1420     if (!m_provisionalSandboxExtension)
1421         return;
1422
1423     m_provisionalSandboxExtension->consume();
1424 }
1425
1426 void WebPage::SandboxExtensionTracker::didCommitProvisionalLoad(WebFrame* frame)
1427 {
1428     if (!frame->isMainFrame())
1429         return;
1430     
1431     ASSERT(!m_pendingProvisionalSandboxExtension);
1432
1433     // The provisional load has been committed. Invalidate the currently committed sandbox
1434     // extension and make the provisional sandbox extension the committed sandbox extension.
1435     if (m_committedSandboxExtension)
1436         m_committedSandboxExtension->invalidate();
1437
1438     m_committedSandboxExtension = m_provisionalSandboxExtension.release();
1439 }
1440
1441 void WebPage::SandboxExtensionTracker::didFailProvisionalLoad(WebFrame* frame)
1442 {
1443     if (!frame->isMainFrame())
1444         return;
1445
1446     ASSERT(!m_pendingProvisionalSandboxExtension);
1447     if (!m_provisionalSandboxExtension)
1448         return;
1449
1450     m_provisionalSandboxExtension->invalidate();
1451     m_provisionalSandboxExtension = 0;
1452 }
1453
1454 bool WebPage::hasLocalDataForURL(const KURL& url)
1455 {
1456     if (url.isLocalFile())
1457         return true;
1458
1459     FrameLoader* frameLoader = m_page->mainFrame()->loader();
1460     DocumentLoader* documentLoader = frameLoader ? frameLoader->documentLoader() : 0;
1461     if (documentLoader && documentLoader->subresource(url))
1462         return true;
1463
1464     return platformHasLocalDataForURL(url);
1465 }
1466
1467 void WebPage::setCustomTextEncodingName(const String& encoding)
1468 {
1469     m_page->mainFrame()->loader()->reloadWithOverrideEncoding(encoding);
1470 }
1471
1472 #if PLATFORM(MAC)
1473
1474 bool WebPage::isSpeaking()
1475 {
1476     bool result;
1477     return sendSync(Messages::WebPageProxy::GetIsSpeaking(), Messages::WebPageProxy::GetIsSpeaking::Reply(result)) && result;
1478 }
1479
1480 void WebPage::speak(const String& string)
1481 {
1482     send(Messages::WebPageProxy::Speak(string));
1483 }
1484
1485 void WebPage::stopSpeaking()
1486 {
1487     send(Messages::WebPageProxy::StopSpeaking());
1488 }
1489
1490 #endif
1491
1492 } // namespace WebKit