WebPageProxy.cpp 74.9 KB
Newer Older
1
/*
2
 * Copyright (C) 2010, 2011 Apple Inc. All rights reserved.
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "WebPageProxy.h"

28
29
#include "AuthenticationChallengeProxy.h"
#include "AuthenticationDecisionListener.h"
30
#include "DataReference.h"
31
#include "DrawingAreaProxy.h"
andersca@apple.com's avatar
andersca@apple.com committed
32
#include "FindIndicator.h"
33
#include "MessageID.h"
34
#include "NativeWebKeyboardEvent.h"
35
#include "PageClient.h"
36
#include "PrintInfo.h"
37
#include "SessionState.h"
38
#include "StringPairVector.h"
39
#include "TextChecker.h"
40
#include "TextCheckerState.h"
41
#include "WKContextPrivate.h"
42
#include "WebBackForwardList.h"
43
#include "WebBackForwardListItem.h"
44
#include "WebCertificateInfo.h"
45
#include "WebContext.h"
46
#include "WebContextMenuProxy.h"
47
#include "WebContextUserMessageCoders.h"
48
#include "WebCoreArgumentCoders.h"
49
#include "WebData.h"
weinig@apple.com's avatar
weinig@apple.com committed
50
#include "WebEditCommandProxy.h"
51
#include "WebEvent.h"
52
53
#include "WebFormSubmissionListenerProxy.h"
#include "WebFramePolicyListenerProxy.h"
54
#include "WebOpenPanelResultListenerProxy.h"
55
#include "WebPageCreationParameters.h"
56
57
#include "WebPageGroup.h"
#include "WebPageGroupData.h"
58
#include "WebPageMessages.h"
59
60
#include "WebPopupItem.h"
#include "WebPopupMenuProxy.h"
61
62
#include "WebPreferences.h"
#include "WebProcessManager.h"
63
#include "WebProcessMessages.h"
64
#include "WebProcessProxy.h"
65
#include "WebProtectionSpace.h"
66
#include "WebSecurityOrigin.h"
67
#include "WebURLRequest.h"
68
#include <WebCore/DragData.h>
69
#include <WebCore/FloatRect.h>
andersca@apple.com's avatar
andersca@apple.com committed
70
#include <WebCore/MIMETypeRegistry.h>
71
#include <WebCore/WindowFeatures.h>
72
#include <stdio.h>
73

74
75
76
77
#ifndef NDEBUG
#include <wtf/RefCountedLeakCounter.h>
#endif

78
79
80
// This controls what strategy we use for mouse wheel coalesing.
#define MERGE_WHEEL_EVENTS 0

81
82
#define MESSAGE_CHECK(assertion) MESSAGE_CHECK_BASE(assertion, process()->connection())

83
84
85
86
87
88
89
90
using namespace WebCore;

namespace WebKit {

#ifndef NDEBUG
static WTF::RefCountedLeakCounter webPageProxyCounter("WebPageProxy");
#endif

91
PassRefPtr<WebPageProxy> WebPageProxy::create(PageClient* pageClient, WebContext* context, WebPageGroup* pageGroup, uint64_t pageID)
92
{
93
    return adoptRef(new WebPageProxy(pageClient, context, pageGroup, pageID));
94
95
}

96
97
WebPageProxy::WebPageProxy(PageClient* pageClient, WebContext* context, WebPageGroup* pageGroup, uint64_t pageID)
    : m_pageClient(pageClient)
98
    , m_context(context)
99
    , m_pageGroup(pageGroup)
100
    , m_mainFrame(0)
101
    , m_userAgent(standardUserAgent())
weinig@apple.com's avatar
weinig@apple.com committed
102
    , m_geolocationPermissionRequestManager(this)
103
    , m_estimatedProgress(0)
104
105
    , m_isInWindow(m_pageClient->isViewInWindow())
    , m_isVisible(m_pageClient->isViewVisible())
106
    , m_backForwardList(WebBackForwardList::create(this))
107
108
    , m_textZoomFactor(1)
    , m_pageZoomFactor(1)
109
    , m_viewScaleFactor(1)
110
111
    , m_drawsBackground(true)
    , m_drawsTransparentBackground(false)
112
    , m_useFixedLayout(false)
113
114
    , m_isValid(true)
    , m_isClosed(false)
115
    , m_isInPrintingMode(false)
116
117
118
119
    , m_inDecidePolicyForMIMEType(false)
    , m_syncMimeTypePolicyActionIsValid(false)
    , m_syncMimeTypePolicyAction(PolicyUse)
    , m_syncMimeTypePolicyDownloadID(0)
120
    , m_processingWheelEvent(false)
121
    , m_processingMouseMoveEvent(false)
122
    , m_pageID(pageID)
123
124
125
#if PLATFORM(MAC)
    , m_isSmartInsertDeleteEnabled(TextChecker::isSmartInsertDeleteEnabled())
#endif
126
127
    , m_spellDocumentTag(0)
    , m_hasSpellDocumentTag(false)
128
    , m_pendingLearnOrIgnoreWordMessageCount(0)
129
    , m_mainFrameHasCustomRepresentation(false)
130
    , m_currentDragOperation(DragOperationNone)
131
132
133
134
{
#ifndef NDEBUG
    webPageProxyCounter.increment();
#endif
135

136
137
    WebContext::statistics().wkPageCount++;

138
    m_pageGroup->addPage(this);
139
140
141
142
}

WebPageProxy::~WebPageProxy()
{
143
144
    WebContext::statistics().wkPageCount--;

145
146
147
    if (m_hasSpellDocumentTag)
        TextChecker::closeSpellDocumentWithTag(m_spellDocumentTag);

148
149
    m_pageGroup->removePage(this);

150
151
152
153
154
155
156
#ifndef NDEBUG
    webPageProxyCounter.decrement();
#endif
}

WebProcessProxy* WebPageProxy::process() const
{
157
    return m_context->process();
158
159
}

160
161
bool WebPageProxy::isValid()
{
162
163
164
165
166
    // A page that has been explicitly closed is never valid.
    if (m_isClosed)
        return false;

    return m_isValid;
167
168
}

169
170
171
172
173
174
175
176
void WebPageProxy::setDrawingArea(PassOwnPtr<DrawingAreaProxy> drawingArea)
{
    if (drawingArea == m_drawingArea)
        return;

    m_drawingArea = drawingArea;
}

177
void WebPageProxy::initializeLoaderClient(const WKPageLoaderClient* loadClient)
178
179
180
181
{
    m_loaderClient.initialize(loadClient);
}

182
void WebPageProxy::initializePolicyClient(const WKPagePolicyClient* policyClient)
183
184
185
186
{
    m_policyClient.initialize(policyClient);
}

187
188
189
190
191
void WebPageProxy::initializeFormClient(const WKPageFormClient* formClient)
{
    m_formClient.initialize(formClient);
}

192
193
194
195
196
void WebPageProxy::initializeResourceLoadClient(const WKPageResourceLoadClient* client)
{
    m_resourceLoadClient.initialize(client);
}

197
void WebPageProxy::initializeUIClient(const WKPageUIClient* client)
198
199
200
201
{
    m_uiClient.initialize(client);
}

202
203
204
205
206
void WebPageProxy::initializeFindClient(const WKPageFindClient* client)
{
    m_findClient.initialize(client);
}

207
208
209
210
211
void WebPageProxy::initializeContextMenuClient(const WKPageContextMenuClient* client)
{
    m_contextMenuClient.initialize(client);
}

212
void WebPageProxy::reattachToWebProcess()
213
{
214
    m_isValid = true;
215

216
217
    context()->relaunchProcessIfNecessary();
    process()->addExistingWebPage(this, m_pageID);
218

219
220
    initializeWebPage();

221
    m_pageClient->didRelaunchProcess();
222
223
}

224
225
226
227
228
229
void WebPageProxy::reattachToWebProcessWithItem(WebBackForwardListItem* item)
{
    if (item && item != m_backForwardList->currentItem())
        m_backForwardList->goToItem(item);
    
    reattachToWebProcess();
230
231
232
    
    if (item)
        process()->send(Messages::WebPage::GoToBackForwardItem(item->itemID()), m_pageID);
233
234
}

235
void WebPageProxy::initializeWebPage()
236
{
237
    ASSERT(isValid());
238

239
240
241
242
    BackForwardListItemVector items = m_backForwardList->entries();
    for (size_t i = 0; i < items.size(); ++i)
        process()->registerNewWebBackForwardListItem(items[i].get());

243
    m_drawingArea = m_pageClient->createDrawingAreaProxy();
244
    ASSERT(m_drawingArea);
245

246
    process()->send(Messages::WebProcess::CreateWebPage(m_pageID, creationParameters()), 0);
247
248
249
250
251
252
253
}

void WebPageProxy::close()
{
    if (!isValid())
        return;

254
    m_isClosed = true;
255

256
257
    m_backForwardList->pageClosed();

ap@apple.com's avatar
ap@apple.com committed
258
    process()->disconnectFramesFromPage(this);
259
    m_mainFrame = 0;
260

261
#if ENABLE(INSPECTOR)
262
263
264
265
    if (m_inspector) {
        m_inspector->invalidate();
        m_inspector = 0;
    }
266
#endif
267

268
269
270
271
272
    if (m_openPanelResultListener) {
        m_openPanelResultListener->invalidate();
        m_openPanelResultListener = 0;
    }

weinig@apple.com's avatar
weinig@apple.com committed
273
274
    m_geolocationPermissionRequestManager.invalidateRequests();

275
276
    m_toolTip = String();

277
278
    invalidateCallbackMap(m_dataCallbacks);
    invalidateCallbackMap(m_stringCallbacks);
279

weinig@apple.com's avatar
weinig@apple.com committed
280
281
282
283
284
285
    Vector<WebEditCommandProxy*> editCommandVector;
    copyToVector(m_editCommandSet, editCommandVector);
    m_editCommandSet.clear();
    for (size_t i = 0, size = editCommandVector.size(); i < size; ++i)
        editCommandVector[i]->invalidate();

286
287
    m_activePopupMenu = 0;

288
289
    m_estimatedProgress = 0.0;
    
290
291
292
293
294
295
    m_loaderClient.initialize(0);
    m_policyClient.initialize(0);
    m_uiClient.initialize(0);

    m_drawingArea.clear();

296
    process()->send(Messages::WebPage::Close(), m_pageID);
297
298
299
300
301
302
303
304
    process()->removeWebPage(m_pageID);
}

bool WebPageProxy::tryClose()
{
    if (!isValid())
        return true;

305
    process()->send(Messages::WebPage::TryClose(), m_pageID);
306
307
308
    return false;
}

309
310
311
312
313
314
315
316
static void initializeSandboxExtensionHandle(const KURL& url, SandboxExtension::Handle& sandboxExtensionHandle)
{
    if (!url.isLocalFile())
        return;

    SandboxExtension::createHandle("/", SandboxExtension::ReadOnly, sandboxExtensionHandle);
}

317
void WebPageProxy::loadURL(const String& url)
318
{
319
    if (!isValid())
320
        reattachToWebProcess();
321

322
323
324
    SandboxExtension::Handle sandboxExtensionHandle;
    initializeSandboxExtensionHandle(KURL(KURL(), url), sandboxExtensionHandle);
    process()->send(Messages::WebPage::LoadURL(url, sandboxExtensionHandle), m_pageID);
325
326
}

327
328
void WebPageProxy::loadURLRequest(WebURLRequest* urlRequest)
{
329
    if (!isValid())
330
        reattachToWebProcess();
331

332
333
334
    SandboxExtension::Handle sandboxExtensionHandle;
    initializeSandboxExtensionHandle(urlRequest->resourceRequest().url(), sandboxExtensionHandle);
    process()->send(Messages::WebPage::LoadURLRequest(urlRequest->resourceRequest(), sandboxExtensionHandle), m_pageID);
335
336
}

337
338
339
340
void WebPageProxy::loadHTMLString(const String& htmlString, const String& baseURL)
{
    if (!isValid())
        return;
341
    process()->send(Messages::WebPage::LoadHTMLString(htmlString, baseURL), m_pageID);
342
343
}

344
345
346
347
348
349
350
351
352
353
354
355
void WebPageProxy::loadAlternateHTMLString(const String& htmlString, const String& baseURL, const String& unreachableURL)
{
    if (!isValid())
        return;

    if (!m_mainFrame)
        return;

    m_mainFrame->setUnreachableURL(unreachableURL);
    process()->send(Messages::WebPage::LoadAlternateHTMLString(htmlString, baseURL, unreachableURL), m_pageID);
}

356
357
358
359
void WebPageProxy::loadPlainTextString(const String& string)
{
    if (!isValid())
        return;
360
    process()->send(Messages::WebPage::LoadPlainTextString(string), m_pageID);
361
362
}

363
364
365
366
void WebPageProxy::stopLoading()
{
    if (!isValid())
        return;
367
    process()->send(Messages::WebPage::StopLoading(), m_pageID);
368
369
}

370
void WebPageProxy::reload(bool reloadFromOrigin)
371
{
372
373
    if (!isValid()) {
        reattachToWebProcessWithItem(m_backForwardList->currentItem());
374
        return;
375
376
    }

377
    process()->send(Messages::WebPage::Reload(reloadFromOrigin), m_pageID);
378
379
380
381
}

void WebPageProxy::goForward()
{
382
383
    if (!isValid()) {
        reattachToWebProcessWithItem(m_backForwardList->forwardItem());
384
        return;
385
    }
weinig@apple.com's avatar
weinig@apple.com committed
386
387
388
389

    if (!canGoForward())
        return;

390
    process()->send(Messages::WebPage::GoForward(m_backForwardList->forwardItem()->itemID()), m_pageID);
391
392
}

393
394
395
396
397
bool WebPageProxy::canGoForward() const
{
    return m_backForwardList->forwardItem();
}

398
399
void WebPageProxy::goBack()
{
400
401
    if (!isValid()) {
        reattachToWebProcessWithItem(m_backForwardList->backItem());
402
        return;
403
    }
weinig@apple.com's avatar
weinig@apple.com committed
404
405
406
407

    if (!canGoBack())
        return;

408
    process()->send(Messages::WebPage::GoBack(m_backForwardList->backItem()->itemID()), m_pageID);
409
410
}

411
412
413
414
415
416
417
bool WebPageProxy::canGoBack() const
{
    return m_backForwardList->backItem();
}

void WebPageProxy::goToBackForwardItem(WebBackForwardListItem* item)
{
418
419
    if (!isValid()) {
        reattachToWebProcessWithItem(item);
420
        return;
421
    }
weinig@apple.com's avatar
weinig@apple.com committed
422

423
    process()->send(Messages::WebPage::GoToBackForwardItem(item->itemID()), m_pageID);
424
425
}

426
427
428
429
430
void WebPageProxy::didChangeBackForwardList()
{
    m_loaderClient.didChangeBackForwardList(this);
}

andersca@apple.com's avatar
andersca@apple.com committed
431
432
433
434
435
436
437
438
439
440
    
bool WebPageProxy::canShowMIMEType(const String& mimeType) const
{
    if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType))
        return true;

    if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType))
        return true;
    
    String newMimeType = mimeType;
441
    PluginInfoStore::Plugin plugin = context()->pluginInfoStore()->findPlugin(newMimeType, KURL());
andersca@apple.com's avatar
andersca@apple.com committed
442
443
444
445
446
447
    if (!plugin.path.isNull())
        return true;

    return false;
}

448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
void WebPageProxy::setDrawsBackground(bool drawsBackground)
{
    if (m_drawsBackground == drawsBackground)
        return;

    m_drawsBackground = drawsBackground;

    if (isValid())
        process()->send(Messages::WebPage::SetDrawsBackground(drawsBackground), m_pageID);
}

void WebPageProxy::setDrawsTransparentBackground(bool drawsTransparentBackground)
{
    if (m_drawsTransparentBackground == drawsTransparentBackground)
        return;

    m_drawsTransparentBackground = drawsTransparentBackground;

    if (isValid())
        process()->send(Messages::WebPage::SetDrawsTransparentBackground(drawsTransparentBackground), m_pageID);
}

470
471
472
473
474
void WebPageProxy::setViewNeedsDisplay(const IntRect& rect)
{
    m_pageClient->setViewNeedsDisplay(rect);
}

475
476
477
478
479
void WebPageProxy::displayView()
{
    m_pageClient->displayView();
}

480
481
482
483
484
void WebPageProxy::scrollView(const IntRect& scrollRect, const IntSize& scrollOffset)
{
    m_pageClient->scrollView(scrollRect, scrollOffset);
}

485
void WebPageProxy::viewStateDidChange(ViewStateFlags flags)
486
487
488
{
    if (!isValid())
        return;
489
490
491
492
493
494
495
496
497
498
499

    if (flags & ViewIsFocused)
        process()->send(Messages::WebPage::SetFocused(m_pageClient->isViewFocused()), m_pageID);

    if (flags & ViewWindowIsActive)
        process()->send(Messages::WebPage::SetActive(m_pageClient->isViewWindowActive()), m_pageID);

    if (flags & ViewIsVisible) {
        bool isVisible = m_pageClient->isViewVisible();
        if (isVisible != m_isVisible) {
            m_isVisible = isVisible;
500
            m_drawingArea->visibilityDidChange();
501
502
503
504
505
506
507
508
509
510
511
            m_drawingArea->setPageIsVisible(isVisible);
        }
    }

    if (flags & ViewIsInWindow) {
        bool isInWindow = m_pageClient->isViewInWindow();
        if (m_isInWindow != isInWindow) {
            m_isInWindow = isInWindow;
            process()->send(Messages::WebPage::SetIsInWindow(isInWindow), m_pageID);
        }
    }
512
513
}

514
515
516
517
518
IntSize WebPageProxy::viewSize() const
{
    return m_pageClient->viewSize();
}

519
520
521
522
523
524
525
void WebPageProxy::setInitialFocus(bool forward)
{
    if (!isValid())
        return;
    process()->send(Messages::WebPage::SetInitialFocus(forward), m_pageID);
}

526
527
528
529
530
531
532
void WebPageProxy::setWindowResizerSize(const IntSize& windowResizerSize)
{
    if (!isValid())
        return;
    process()->send(Messages::WebPage::SetWindowResizerSize(windowResizerSize), m_pageID);
}

533
void WebPageProxy::validateMenuItem(const String& commandName)
534
535
536
{
    if (!isValid())
        return;
537
    process()->send(Messages::WebPage::ValidateMenuItem(commandName), m_pageID);
538
}
539
540
    
void WebPageProxy::executeEditCommand(const String& commandName)
541
542
543
544
{
    if (!isValid())
        return;

545
    process()->send(Messages::WebPage::ExecuteEditCommand(commandName), m_pageID);
546
547
}
    
548
#if PLATFORM(MAC)
549
void WebPageProxy::updateWindowIsVisible(bool windowIsVisible)
550
551
552
{
    if (!isValid())
        return;
553
    process()->send(Messages::WebPage::SetWindowIsVisible(windowIsVisible), m_pageID);
554
555
}

556
void WebPageProxy::windowAndViewFramesChanged(const IntRect& windowFrameInScreenCoordinates, const IntRect& viewFrameInWindowCoordinates, const IntPoint& accessibilityViewCoordinates)
557
558
559
{
    if (!isValid())
        return;
560

561
    process()->send(Messages::WebPage::WindowAndViewFramesChanged(windowFrameInScreenCoordinates, viewFrameInWindowCoordinates, accessibilityViewCoordinates), m_pageID);
562
}
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580

void WebPageProxy::getMarkedRange(uint64_t& location, uint64_t& length)
{
    process()->sendSync(Messages::WebPage::GetMarkedRange(), Messages::WebPage::GetMarkedRange::Reply(location, length), m_pageID);
}
    
uint64_t WebPageProxy::characterIndexForPoint(const IntPoint point)
{
    uint64_t result;
    process()->sendSync(Messages::WebPage::CharacterIndexForPoint(point), Messages::WebPage::CharacterIndexForPoint::Reply(result), m_pageID);
    return result;
}

WebCore::IntRect WebPageProxy::firstRectForCharacterRange(uint64_t location, uint64_t length)
{
    IntRect resultRect;
    process()->sendSync(Messages::WebPage::FirstRectForCharacterRange(location, length), Messages::WebPage::FirstRectForCharacterRange::Reply(resultRect), m_pageID);
    return resultRect;
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
}
#elif PLATFORM(WIN)
WebCore::IntRect WebPageProxy::firstRectForCharacterInSelectedRange(int characterPosition)
{
    IntRect resultRect;
    process()->sendSync(Messages::WebPage::FirstRectForCharacterInSelectedRange(characterPosition), Messages::WebPage::FirstRectForCharacterInSelectedRange::Reply(resultRect), m_pageID);
    return resultRect;
}

String WebPageProxy::getSelectedText()
{
    String text;
    process()->sendSync(Messages::WebPage::GetSelectedText(), Messages::WebPage::GetSelectedText::Reply(text), m_pageID);
    return text;
}
596
597
#endif

598
599
600
601
602
603
604
605
606
607
#if ENABLE(TILED_BACKING_STORE)
void WebPageProxy::setActualVisibleContentRect(const IntRect& rect)
{
    if (!isValid())
        return;

    process()->send(Messages::WebPage::SetActualVisibleContentRect(rect), m_pageID);
}
#endif

608
609
610
611
612
613
614
615
616
617
618
619
void WebPageProxy::performDragControllerAction(DragControllerAction action, WebCore::DragData* dragData, const String& dragStorageName)
{
    if (!isValid())
        return;
    process()->send(Messages::WebPage::PerformDragControllerAction(action, dragData->clientPosition(), dragData->globalPosition(), dragData->draggingSourceOperationMask(), dragStorageName, dragData->flags()), m_pageID);
}

void WebPageProxy::didPerformDragControllerAction(uint64_t resultOperation)
{
    m_currentDragOperation = static_cast<DragOperation>(resultOperation);
}

620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
#if PLATFORM(MAC)
void WebPageProxy::setDragImage(const WebCore::IntPoint& clientPosition, const IntSize& imageSize, const SharedMemory::Handle& dragImageHandle, bool isLinkDrag)
{
    RefPtr<ShareableBitmap> dragImage = ShareableBitmap::create(imageSize, dragImageHandle);
    if (!dragImage)
        return;
    
    m_pageClient->setDragImage(clientPosition, imageSize, dragImage.release(), isLinkDrag);
}
#endif

void WebPageProxy::dragEnded(const WebCore::IntPoint& clientPosition, const WebCore::IntPoint& globalPosition, uint64_t operation)
{
    if (!isValid())
        return;
    process()->send(Messages::WebPage::DragEnded(clientPosition, globalPosition, operation), m_pageID);
}

638
void WebPageProxy::handleMouseEvent(const WebMouseEvent& event)
639
640
641
642
643
644
645
{
    if (!isValid())
        return;

    // NOTE: This does not start the responsiveness timer because mouse move should not indicate interaction.
    if (event.type() != WebEvent::MouseMove)
        process()->responsivenessTimer()->start();
646
647
648
649
650
651
652
653
654
    else {
        if (m_processingMouseMoveEvent) {
            m_nextMouseMoveEvent = adoptPtr(new WebMouseEvent(event));
            return;
        }

        m_processingMouseMoveEvent = true;
    }

655
    process()->send(Messages::WebPage::MouseEvent(event), m_pageID);
656
657
}

658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
static PassOwnPtr<WebWheelEvent> coalesceWheelEvents(WebWheelEvent* oldNextWheelEvent, const WebWheelEvent& newWheelEvent)
{
#if MERGE_WHEEL_EVENTS
    // Merge model: Combine wheel event deltas (and wheel ticks) into a single wheel event.
    if (!oldNextWheelEvent)
        return adoptPtr(new WebWheelEvent(newWheelEvent));

    if (oldNextWheelEvent->position() != newWheelEvent.position() || oldNextWheelEvent->modifiers() != newWheelEvent.modifiers() || oldNextWheelEvent->granularity() != newWheelEvent.granularity())
        return adoptPtr(new WebWheelEvent(newWheelEvent));

    FloatSize mergedDelta = oldNextWheelEvent->delta() + newWheelEvent.delta();
    FloatSize mergedWheelTicks = oldNextWheelEvent->wheelTicks() + newWheelEvent.wheelTicks();

    return adoptPtr(new WebWheelEvent(WebEvent::Wheel, newWheelEvent.position(), newWheelEvent.globalPosition(), mergedDelta, mergedWheelTicks, newWheelEvent.granularity(), newWheelEvent.modifiers(), newWheelEvent.timestamp()));
#else
    // Simple model: Just keep the last event, dropping all interim events.
    return adoptPtr(new WebWheelEvent(newWheelEvent));
#endif
}

678
void WebPageProxy::handleWheelEvent(const WebWheelEvent& event)
679
680
681
682
{
    if (!isValid())
        return;

683
684
685
686
687
    if (m_processingWheelEvent) {
        m_nextWheelEvent = coalesceWheelEvents(m_nextWheelEvent.get(), event);
        return;
    }

688
    process()->responsivenessTimer()->start();
689
    process()->send(Messages::WebPage::WheelEvent(event), m_pageID);
690
    m_processingWheelEvent = true;
691
692
}

693
void WebPageProxy::handleKeyboardEvent(const NativeWebKeyboardEvent& event)
694
695
696
697
{
    if (!isValid())
        return;

698
699
    m_keyEventQueue.append(event);

700
    process()->responsivenessTimer()->start();
701
    process()->send(Messages::WebPage::KeyEvent(event), m_pageID);
702
703
}

704
#if ENABLE(TOUCH_EVENTS)
705
void WebPageProxy::handleTouchEvent(const WebTouchEvent& event)
706
707
708
{
    if (!isValid())
        return;
709
    process()->send(Messages::WebPage::TouchEvent(event), m_pageID); 
710
711
712
}
#endif

713
void WebPageProxy::receivedPolicyDecision(PolicyAction action, WebFrameProxy* frame, uint64_t listenerID)
714
715
716
717
{
    if (!isValid())
        return;

718
    uint64_t downloadID = 0;
andersca@apple.com's avatar
andersca@apple.com committed
719
720
    if (action == PolicyDownload) {
        // Create a download proxy.
721
        downloadID = context()->createDownloadProxy();
andersca@apple.com's avatar
andersca@apple.com committed
722
    }
723

724
725
726
727
728
729
730
731
732
    // If we received a policy decision while in decidePolicyForMIMEType the decision will 
    // be sent back to the web process by decidePolicyForMIMEType. 
    if (m_inDecidePolicyForMIMEType) {
        m_syncMimeTypePolicyActionIsValid = true;
        m_syncMimeTypePolicyAction = action;
        m_syncMimeTypePolicyDownloadID = downloadID;
        return;
    }

733
    process()->send(Messages::WebPage::DidReceivePolicyDecision(frame->frameID(), listenerID, action, downloadID), m_pageID);
734
735
}

736
737
738
739
740
741
742
743
744
745
String WebPageProxy::pageTitle() const
{
    // Return the null string if there is no main frame (e.g. nothing has been loaded in the page yet, WebProcess has
    // crashed, page has been closed).
    if (!m_mainFrame)
        return String();

    return m_mainFrame->title();
}

746
void WebPageProxy::setUserAgent(const String& userAgent)
747
{
748
749
750
751
    if (m_userAgent == userAgent)
        return;
    m_userAgent = userAgent;

752
753
    if (!isValid())
        return;
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
    process()->send(Messages::WebPage::SetUserAgent(m_userAgent), m_pageID);
}

void WebPageProxy::setApplicationNameForUserAgent(const String& applicationName)
{
    if (m_applicationNameForUserAgent == applicationName)
        return;

    m_applicationNameForUserAgent = applicationName;
    if (!m_customUserAgent.isEmpty())
        return;

    setUserAgent(standardUserAgent(m_applicationNameForUserAgent));
}

void WebPageProxy::setCustomUserAgent(const String& customUserAgent)
{
    if (m_customUserAgent == customUserAgent)
        return;
773

774
775
776
777
    m_customUserAgent = customUserAgent;

    if (m_customUserAgent.isEmpty()) {
        setUserAgent(standardUserAgent(m_applicationNameForUserAgent));
778
        return;
779
    }
780

781
    setUserAgent(m_customUserAgent);
782
783
}

784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
bool WebPageProxy::supportsTextEncoding() const
{
    return !m_mainFrameHasCustomRepresentation && m_mainFrame && !m_mainFrame->isDisplayingStandaloneImageDocument();
}

void WebPageProxy::setCustomTextEncodingName(const String& encodingName)
{
    if (m_customTextEncodingName == encodingName)
        return;
    m_customTextEncodingName = encodingName;

    if (!isValid())
        return;
    process()->send(Messages::WebPage::SetCustomTextEncodingName(encodingName), m_pageID);
}

800
801
802
803
804
805
806
807
void WebPageProxy::terminateProcess()
{
    if (!isValid())
        return;

    process()->terminate();
}

808
#if !PLATFORM(CF) || defined(BUILDING_QT__)
809
PassRefPtr<WebData> WebPageProxy::sessionStateData(WebPageProxySessionStateFilterCallback, void* context) const
810
811
812
813
814
{
    // FIXME: Return session state data for saving Page state.
    return 0;
}

815
void WebPageProxy::restoreFromSessionStateData(WebData*)
816
817
818
{
    // FIXME: Restore the Page from the passed in session state data.
}
819
#endif
820

821
822
823
824
825
826
827
828
829
830
831
832
bool WebPageProxy::supportsTextZoom() const
{
    if (m_mainFrameHasCustomRepresentation)
        return false;

    // FIXME: This should also return false for standalone media and plug-in documents.
    if (!m_mainFrame || m_mainFrame->isDisplayingStandaloneImageDocument())
        return false;

    return true;
}
 
833
834
835
836
837
void WebPageProxy::setTextZoomFactor(double zoomFactor)
{
    if (!isValid())
        return;

838
839
840
    if (m_mainFrameHasCustomRepresentation)
        return;

841
842
843
844
    if (m_textZoomFactor == zoomFactor)
        return;

    m_textZoomFactor = zoomFactor;
845
    process()->send(Messages::WebPage::SetTextZoomFactor(m_textZoomFactor), m_pageID); 
846
847
}

848
849
850
851
852
double WebPageProxy::pageZoomFactor() const
{
    return m_mainFrameHasCustomRepresentation ? m_pageClient->customRepresentationZoomFactor() : m_pageZoomFactor;
}

853
854
855
856
857
void WebPageProxy::setPageZoomFactor(double zoomFactor)
{
    if (!isValid())
        return;

858
859
860
861
862
    if (m_mainFrameHasCustomRepresentation) {
        m_pageClient->setCustomRepresentationZoomFactor(zoomFactor);
        return;
    }

863
864
865
866
    if (m_pageZoomFactor == zoomFactor)
        return;

    m_pageZoomFactor = zoomFactor;
867
    process()->send(Messages::WebPage::SetPageZoomFactor(m_pageZoomFactor), m_pageID); 
868
869
870
871
872
873
874
}

void WebPageProxy::setPageAndTextZoomFactors(double pageZoomFactor, double textZoomFactor)
{
    if (!isValid())
        return;

875
876
877
878
879
    if (m_mainFrameHasCustomRepresentation) {
        m_pageClient->setCustomRepresentationZoomFactor(pageZoomFactor);
        return;
    }

880
881
882
883
884
    if (m_pageZoomFactor == pageZoomFactor && m_textZoomFactor == textZoomFactor)
        return;

    m_pageZoomFactor = pageZoomFactor;
    m_textZoomFactor = textZoomFactor;
885
    process()->send(Messages::WebPage::SetPageAndTextZoomFactors(m_pageZoomFactor, m_textZoomFactor), m_pageID); 
886
887
}

888
void WebPageProxy::scaleWebView(double scale, const IntPoint& origin)
889
890
891
892
{
    if (!isValid())
        return;

893
    process()->send(Messages::WebPage::ScaleWebView(scale, origin), m_pageID);
894
895
}

896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
void WebPageProxy::setUseFixedLayout(bool fixed)
{
    if (!isValid())
        return;

    if (fixed == m_useFixedLayout)
        return;

    m_useFixedLayout = fixed;
    if (!fixed)
        m_fixedLayoutSize = IntSize();
    process()->send(Messages::WebPage::SetUseFixedLayout(fixed), m_pageID);
}

void WebPageProxy::setFixedLayoutSize(const IntSize& size)
{
    if (!isValid())
        return;

    if (size == m_fixedLayoutSize)
        return;

    m_fixedLayoutSize = size;
    process()->send(Messages::WebPage::SetFixedLayoutSize(size), m_pageID);
}

922
923
924
925
926
void WebPageProxy::viewScaleFactorDidChange(double scaleFactor)
{
    m_viewScaleFactor = scaleFactor;
}

927
void WebPageProxy::findString(const String& string, FindOptions options, unsigned maxMatchCount)
928
{
929
    process()->send(Messages::WebPage::FindString(string, options, maxMatchCount), m_pageID);
930
931
932
933
}

void WebPageProxy::hideFindUI()
{
934
    process()->send(Messages::WebPage::HideFindUI(), m_pageID);
935
936
}

937
void WebPageProxy::countStringMatches(const String& string, FindOptions options, unsigned maxMatchCount)
938
{
939
    process()->send(Messages::WebPage::CountStringMatches(string, options, maxMatchCount), m_pageID);
940
941
}
    
942
void WebPageProxy::runJavaScriptInMainFrame(const String& script, PassRefPtr<StringCallback> prpCallback)
943
{
944
    RefPtr<StringCallback> callback = prpCallback;
945
    uint64_t callbackID = callback->callbackID();
946
    m_stringCallbacks.set(callbackID, callback.get());
947
    process()->send(Messages::WebPage::RunJavaScriptInMainFrame(script, callbackID), m_pageID);
948
949
}

950
void WebPageProxy::getRenderTreeExternalRepresentation(PassRefPtr<StringCallback> prpCallback)
951
{
952
    RefPtr<StringCallback> callback = prpCallback;
953
    uint64_t callbackID = callback->callbackID();
954
    m_stringCallbacks.set(callbackID, callback.get());
955
    process()->send(Messages::WebPage::GetRenderTreeExternalRepresentation(callbackID), m_pageID);
956
957
}

958
void WebPageProxy::getSourceForFrame(WebFrameProxy* frame, PassRefPtr<StringCallback> prpCallback)
959
{
960
    RefPtr<StringCallback> callback = prpCallback;
961
    uint64_t callbackID = callback->callbackID();
962
    m_stringCallbacks.set(callbackID, callback.get());
963
    process()->send(Messages::WebPage::GetSourceForFrame(frame->frameID(), callbackID), m_pageID);
964
965
}

966
void WebPageProxy::getContentsAsString(PassRefPtr<StringCallback> prpCallback)
967
{
968
    RefPtr<StringCallback> callback = prpCallback;
969
    uint64_t callbackID = callback->callbackID();
970
    m_stringCallbacks.set(callbackID, callback.get());
971
972
973
    process()->send(Messages::WebPage::GetContentsAsString(callbackID), m_pageID);
}

974
void WebPageProxy::getSelectionOrContentsAsString(PassRefPtr<StringCallback> prpCallback)
975
{
976
    RefPtr<StringCallback> callback = prpCallback;
977
    uint64_t callbackID = callback->callbackID();
978
979
980
981
    m_stringCallbacks.set(callbackID, callback.get());
    process()->send(Messages::WebPage::GetSelectionOrContentsAsString(callbackID), m_pageID);
}

982
983
984
985
986
987
988
989
void WebPageProxy::getMainResourceDataOfFrame(WebFrameProxy* frame, PassRefPtr<DataCallback> prpCallback)
{
    RefPtr<DataCallback> callback = prpCallback;
    uint64_t callbackID = callback->callbackID();
    m_dataCallbacks.set(callbackID, callback.get());
    process()->send(Messages::WebPage::GetMainResourceDataOfFrame(frame->frameID(), callbackID), m_pageID);
}

990
991
992
993
994
995
996
997
void WebPageProxy::getResourceDataFromFrame(WebFrameProxy* frame, WebURL* resourceURL, PassRefPtr<DataCallback> prpCallback)
{
    RefPtr<DataCallback> callback = prpCallback;
    uint64_t callbackID = callback->callbackID();
    m_dataCallbacks.set(callbackID, callback.get());
    process()->send(Messages::WebPage::GetResourceDataFromFrame(frame->frameID(), resourceURL->string(), callbackID), m_pageID);
}

998
999
1000
void WebPageProxy::getWebArchiveOfFrame(WebFrameProxy* frame, PassRefPtr<DataCallback> prpCallback)
{
    RefPtr<DataCallback> callback = prpCallback;
For faster browsing, not all history is shown. View entire blame