1 /*
2  * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public License
15  * along with this program; see the file COPYING.LIB.  If not, write to
16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  *
19  */
20 
21 #include "config.h"
22 #include "qwkpage.h"
23 #include "qwkpage_p.h"
24 
25 #include "qwkpreferences_p.h"
26 
27 #include "ChunkedUpdateDrawingAreaProxy.h"
28 #include "ClientImpl.h"
29 #include "DrawingAreaProxyImpl.h"
30 #include "qgraphicswkview.h"
31 #include "qwkcontext.h"
32 #include "qwkcontext_p.h"
33 #include "qwkhistory.h"
34 #include "qwkhistory_p.h"
35 #include "FindIndicator.h"
36 #include "LocalizedStrings.h"
37 #include "NativeWebKeyboardEvent.h"
38 #include "NativeWebMouseEvent.h"
39 #include "NativeWebWheelEvent.h"
40 #include "NotImplemented.h"
41 #include "Region.h"
42 #include "TiledDrawingAreaProxy.h"
43 #include "WebContext.h"
44 #include "WebContextMenuProxyQt.h"
45 #include "WebEventFactoryQt.h"
46 #include "WebPopupMenuProxyQt.h"
47 #include "WKStringQt.h"
48 #include "WKURLQt.h"
49 #include "ViewportArguments.h"
50 #include <QAction>
51 #include <QApplication>
52 #include <QGraphicsSceneMouseEvent>
53 #include <QStyle>
54 #include <QTouchEvent>
55 #include <QtDebug>
56 #include <WebCore/Cursor.h>
57 #include <WebCore/FloatRect.h>
58 #include <WebCore/NotImplemented.h>
59 #include <WebKit2/WKFrame.h>
60 #include <WebKit2/WKPageGroup.h>
61 #include <WebKit2/WKRetainPtr.h>
62 
63 using namespace WebKit;
64 using namespace WebCore;
65 
contextMenuActionForWebAction(QWKPage::WebAction action)66 static WebCore::ContextMenuAction contextMenuActionForWebAction(QWKPage::WebAction action)
67 {
68     switch (action) {
69     case QWKPage::OpenLink:
70         return WebCore::ContextMenuItemTagOpenLink;
71     case QWKPage::OpenLinkInNewWindow:
72         return WebCore::ContextMenuItemTagOpenLinkInNewWindow;
73     case QWKPage::CopyLinkToClipboard:
74         return WebCore::ContextMenuItemTagCopyLinkToClipboard;
75     case QWKPage::OpenImageInNewWindow:
76         return WebCore::ContextMenuItemTagOpenImageInNewWindow;
77     case QWKPage::Cut:
78         return WebCore::ContextMenuItemTagCut;
79     case QWKPage::Copy:
80         return WebCore::ContextMenuItemTagCopy;
81     case QWKPage::Paste:
82         return WebCore::ContextMenuItemTagPaste;
83     case QWKPage::SelectAll:
84         return WebCore::ContextMenuItemTagSelectAll;
85     default:
86         ASSERT(false);
87         break;
88     }
89     return WebCore::ContextMenuItemTagNoAction;
90 }
91 
QWKPagePrivate(QWKPage * qq,QWKContext * c)92 QWKPagePrivate::QWKPagePrivate(QWKPage* qq, QWKContext* c)
93     : q(qq)
94     , view(0)
95     , context(c)
96     , preferences(0)
97     , createNewPageFn(0)
98     , backingStoreType(QGraphicsWKView::Simple)
99     , isConnectedToEngine(true)
100 {
101     memset(actions, 0, sizeof(actions));
102     page = context->d->context->createWebPage(this, 0);
103     history = QWKHistoryPrivate::createHistory(page->backForwardList());
104 }
105 
~QWKPagePrivate()106 QWKPagePrivate::~QWKPagePrivate()
107 {
108     page->close();
109     delete history;
110 }
111 
init(QGraphicsItem * view,QGraphicsWKView::BackingStoreType backingStoreType)112 void QWKPagePrivate::init(QGraphicsItem* view, QGraphicsWKView::BackingStoreType backingStoreType)
113 {
114     this->view = view;
115     this->backingStoreType = backingStoreType;
116     page->initializeWebPage();
117 }
118 
setCursor(const WebCore::Cursor & cursor)119 void QWKPagePrivate::setCursor(const WebCore::Cursor& cursor)
120 {
121 #ifndef QT_NO_CURSOR
122     emit q->cursorChanged(*cursor.platformCursor());
123 #endif
124 }
125 
setViewportArguments(const ViewportArguments & args)126 void QWKPagePrivate::setViewportArguments(const ViewportArguments& args)
127 {
128     viewportArguments = args;
129     emit q->viewportChangeRequested();
130 }
131 
createDrawingAreaProxy()132 PassOwnPtr<DrawingAreaProxy> QWKPagePrivate::createDrawingAreaProxy()
133 {
134     // FIXME: We should avoid this cast by decoupling the view from the page.
135     QGraphicsWKView* wkView = static_cast<QGraphicsWKView*>(view);
136 
137 #if ENABLE(TILED_BACKING_STORE)
138     if (backingStoreType == QGraphicsWKView::Tiled)
139         return TiledDrawingAreaProxy::create(wkView, page.get());
140 #endif
141     if (backingStoreType == QGraphicsWKView::Impl)
142         return DrawingAreaProxyImpl::create(page.get());
143     return ChunkedUpdateDrawingAreaProxy::create(wkView, page.get());
144 }
145 
setViewNeedsDisplay(const WebCore::IntRect & rect)146 void QWKPagePrivate::setViewNeedsDisplay(const WebCore::IntRect& rect)
147 {
148     view->update(QRect(rect));
149 }
150 
displayView()151 void QWKPagePrivate::displayView()
152 {
153     // FIXME: Implement.
154 }
155 
scrollView(const WebCore::IntRect & scrollRect,const WebCore::IntSize & scrollOffset)156 void QWKPagePrivate::scrollView(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollOffset)
157 {
158     // FIXME: Implement.
159 }
160 
viewSize()161 WebCore::IntSize QWKPagePrivate::viewSize()
162 {
163     return view ? WebCore::IntSize(view->boundingRect().size().toSize()) : WebCore::IntSize();
164 }
165 
isViewWindowActive()166 bool QWKPagePrivate::isViewWindowActive()
167 {
168     return view && view->isActive();
169 }
170 
isViewFocused()171 bool QWKPagePrivate::isViewFocused()
172 {
173     return view && view->hasFocus();
174 }
175 
isViewVisible()176 bool QWKPagePrivate::isViewVisible()
177 {
178     return view && view->isVisible();
179 }
180 
isViewInWindow()181 bool QWKPagePrivate::isViewInWindow()
182 {
183     // FIXME: Implement.
184     return true;
185 }
186 
enterAcceleratedCompositingMode(const LayerTreeContext &)187 void QWKPagePrivate::enterAcceleratedCompositingMode(const LayerTreeContext&)
188 {
189     // FIXME: Implement.
190 }
191 
exitAcceleratedCompositingMode()192 void QWKPagePrivate::exitAcceleratedCompositingMode()
193 {
194     // FIXME: Implement.
195 }
196 
pageDidRequestScroll(const IntPoint & point)197 void QWKPagePrivate::pageDidRequestScroll(const IntPoint& point)
198 {
199     emit q->scrollRequested(point.x(), point.y());
200 }
201 
didChangeContentsSize(const IntSize & newSize)202 void QWKPagePrivate::didChangeContentsSize(const IntSize& newSize)
203 {
204     emit q->contentsSizeChanged(QSize(newSize));
205 }
206 
toolTipChanged(const String &,const String & newTooltip)207 void QWKPagePrivate::toolTipChanged(const String&, const String& newTooltip)
208 {
209     emit q->toolTipChanged(QString(newTooltip));
210 }
211 
registerEditCommand(PassRefPtr<WebEditCommandProxy>,WebPageProxy::UndoOrRedo)212 void QWKPagePrivate::registerEditCommand(PassRefPtr<WebEditCommandProxy>, WebPageProxy::UndoOrRedo)
213 {
214 }
215 
clearAllEditCommands()216 void QWKPagePrivate::clearAllEditCommands()
217 {
218 }
219 
canUndoRedo(WebPageProxy::UndoOrRedo)220 bool QWKPagePrivate::canUndoRedo(WebPageProxy::UndoOrRedo)
221 {
222     return false;
223 }
224 
executeUndoRedo(WebPageProxy::UndoOrRedo)225 void QWKPagePrivate::executeUndoRedo(WebPageProxy::UndoOrRedo)
226 {
227 }
228 
convertToDeviceSpace(const FloatRect & rect)229 FloatRect QWKPagePrivate::convertToDeviceSpace(const FloatRect& rect)
230 {
231     return rect;
232 }
233 
windowToScreen(const IntRect & rect)234 IntRect QWKPagePrivate::windowToScreen(const IntRect& rect)
235 {
236     return rect;
237 }
238 
convertToUserSpace(const FloatRect & rect)239 FloatRect QWKPagePrivate::convertToUserSpace(const FloatRect& rect)
240 {
241     return rect;
242 }
243 
selectionChanged(bool,bool,bool,bool)244 void QWKPagePrivate::selectionChanged(bool, bool, bool, bool)
245 {
246 }
247 
doneWithKeyEvent(const NativeWebKeyboardEvent &,bool)248 void QWKPagePrivate::doneWithKeyEvent(const NativeWebKeyboardEvent&, bool)
249 {
250 }
251 
createPopupMenuProxy(WebPageProxy *)252 PassRefPtr<WebPopupMenuProxy> QWKPagePrivate::createPopupMenuProxy(WebPageProxy*)
253 {
254     return WebPopupMenuProxyQt::create();
255 }
256 
createContextMenuProxy(WebPageProxy *)257 PassRefPtr<WebContextMenuProxy> QWKPagePrivate::createContextMenuProxy(WebPageProxy*)
258 {
259     return WebContextMenuProxyQt::create(q);
260 }
261 
setFindIndicator(PassRefPtr<FindIndicator>,bool fadeOut)262 void QWKPagePrivate::setFindIndicator(PassRefPtr<FindIndicator>, bool fadeOut)
263 {
264 }
265 
didCommitLoadForMainFrame(bool useCustomRepresentation)266 void QWKPagePrivate::didCommitLoadForMainFrame(bool useCustomRepresentation)
267 {
268 }
269 
didFinishLoadingDataForCustomRepresentation(const String & suggestedFilename,const CoreIPC::DataReference &)270 void QWKPagePrivate::didFinishLoadingDataForCustomRepresentation(const String& suggestedFilename, const CoreIPC::DataReference&)
271 {
272 }
273 
flashBackingStoreUpdates(const Vector<IntRect> &)274 void QWKPagePrivate::flashBackingStoreUpdates(const Vector<IntRect>&)
275 {
276     notImplemented();
277 }
278 
paint(QPainter * painter,QRect area)279 void QWKPagePrivate::paint(QPainter* painter, QRect area)
280 {
281     if (page->isValid() && page->drawingArea()) {
282         if (page->drawingArea()->type() == DrawingAreaTypeImpl) {
283             // FIXME: Do something with the unpainted region?
284             WebKit::Region unpaintedRegion;
285             static_cast<DrawingAreaProxyImpl*>(page->drawingArea())->paint(painter, area, unpaintedRegion);
286         } else
287             page->drawingArea()->paint(IntRect(area), painter);
288     } else
289         painter->fillRect(area, Qt::white);
290 }
291 
keyPressEvent(QKeyEvent * ev)292 void QWKPagePrivate::keyPressEvent(QKeyEvent* ev)
293 {
294     page->handleKeyboardEvent(NativeWebKeyboardEvent(ev));
295 }
296 
keyReleaseEvent(QKeyEvent * ev)297 void QWKPagePrivate::keyReleaseEvent(QKeyEvent* ev)
298 {
299     page->handleKeyboardEvent(NativeWebKeyboardEvent(ev));
300 }
301 
mouseMoveEvent(QGraphicsSceneMouseEvent * ev)302 void QWKPagePrivate::mouseMoveEvent(QGraphicsSceneMouseEvent* ev)
303 {
304     // For some reason mouse press results in mouse hover (which is
305     // converted to mouse move for WebKit). We ignore these hover
306     // events by comparing lastPos with newPos.
307     // NOTE: lastPos from the event always comes empty, so we work
308     // around that here.
309     static QPointF lastPos = QPointF();
310     if (lastPos == ev->pos())
311         return;
312     lastPos = ev->pos();
313 
314     page->handleMouseEvent(NativeWebMouseEvent(ev, 0));
315 }
316 
mousePressEvent(QGraphicsSceneMouseEvent * ev)317 void QWKPagePrivate::mousePressEvent(QGraphicsSceneMouseEvent* ev)
318 {
319     if (tripleClickTimer.isActive() && (ev->pos() - tripleClick).manhattanLength() < QApplication::startDragDistance()) {
320         page->handleMouseEvent(NativeWebMouseEvent(ev, 3));
321         return;
322     }
323 
324     page->handleMouseEvent(NativeWebMouseEvent(ev, 1));
325 }
326 
mouseReleaseEvent(QGraphicsSceneMouseEvent * ev)327 void QWKPagePrivate::mouseReleaseEvent(QGraphicsSceneMouseEvent* ev)
328 {
329     page->handleMouseEvent(NativeWebMouseEvent(ev, 0));
330 }
331 
mouseDoubleClickEvent(QGraphicsSceneMouseEvent * ev)332 void QWKPagePrivate::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* ev)
333 {
334     page->handleMouseEvent(NativeWebMouseEvent(ev, 2));
335 
336     tripleClickTimer.start(QApplication::doubleClickInterval(), q);
337     tripleClick = ev->pos().toPoint();
338 }
339 
wheelEvent(QGraphicsSceneWheelEvent * ev)340 void QWKPagePrivate::wheelEvent(QGraphicsSceneWheelEvent* ev)
341 {
342     page->handleWheelEvent(NativeWebWheelEvent(ev));
343 }
344 
updateAction(QWKPage::WebAction action)345 void QWKPagePrivate::updateAction(QWKPage::WebAction action)
346 {
347 #ifdef QT_NO_ACTION
348     Q_UNUSED(action)
349 #else
350     QAction* a = actions[action];
351     if (!a)
352         return;
353 
354     RefPtr<WebKit::WebFrameProxy> mainFrame = page->mainFrame();
355     if (!mainFrame)
356         return;
357 
358     bool enabled = a->isEnabled();
359     bool checked = a->isChecked();
360 
361     switch (action) {
362     case QWKPage::Back:
363         enabled = page->canGoBack();
364         break;
365     case QWKPage::Forward:
366         enabled = page->canGoForward();
367         break;
368     case QWKPage::Stop:
369         enabled = !(WebFrameProxy::LoadStateFinished == mainFrame->loadState());
370         break;
371     case QWKPage::Reload:
372         enabled = (WebFrameProxy::LoadStateFinished == mainFrame->loadState());
373         break;
374     default:
375         break;
376     }
377 
378     a->setEnabled(enabled);
379 
380     if (a->isCheckable())
381         a->setChecked(checked);
382 #endif // QT_NO_ACTION
383 }
384 
updateNavigationActions()385 void QWKPagePrivate::updateNavigationActions()
386 {
387     updateAction(QWKPage::Back);
388     updateAction(QWKPage::Forward);
389     updateAction(QWKPage::Stop);
390     updateAction(QWKPage::Reload);
391 }
392 
393 #ifndef QT_NO_ACTION
_q_webActionTriggered(bool checked)394 void QWKPagePrivate::_q_webActionTriggered(bool checked)
395 {
396     QAction* a = qobject_cast<QAction*>(q->sender());
397     if (!a)
398         return;
399     QWKPage::WebAction action = static_cast<QWKPage::WebAction>(a->data().toInt());
400     q->triggerAction(action, checked);
401 }
402 #endif // QT_NO_ACTION
403 
touchEvent(QTouchEvent * event)404 void QWKPagePrivate::touchEvent(QTouchEvent* event)
405 {
406 #if ENABLE(TOUCH_EVENTS)
407     WebTouchEvent touchEvent = WebEventFactory::createWebTouchEvent(event);
408     page->handleTouchEvent(touchEvent);
409 #else
410     event->ignore();
411 #endif
412 }
413 
didRelaunchProcess()414 void QWKPagePrivate::didRelaunchProcess()
415 {
416     QGraphicsWKView* wkView = static_cast<QGraphicsWKView*>(view);
417     if (wkView)
418         q->setViewportSize(wkView->size().toSize());
419 
420     isConnectedToEngine = true;
421     emit q->engineConnectionChanged(true);
422 }
423 
processDidCrash()424 void QWKPagePrivate::processDidCrash()
425 {
426     isConnectedToEngine = false;
427     emit q->engineConnectionChanged(false);
428 }
429 
QWKPage(QWKContext * context)430 QWKPage::QWKPage(QWKContext* context)
431     : d(new QWKPagePrivate(this, context))
432 {
433     WKPageLoaderClient loadClient = {
434         0,      /* version */
435         this,   /* clientInfo */
436         qt_wk_didStartProvisionalLoadForFrame,
437         qt_wk_didReceiveServerRedirectForProvisionalLoadForFrame,
438         qt_wk_didFailProvisionalLoadWithErrorForFrame,
439         qt_wk_didCommitLoadForFrame,
440         qt_wk_didFinishDocumentLoadForFrame,
441         qt_wk_didFinishLoadForFrame,
442         qt_wk_didFailLoadWithErrorForFrame,
443         qt_wk_didSameDocumentNavigationForFrame,
444         qt_wk_didReceiveTitleForFrame,
445         qt_wk_didFirstLayoutForFrame,
446         qt_wk_didFirstVisuallyNonEmptyLayoutForFrame,
447         qt_wk_didRemoveFrameFromHierarchy,
448         0, /* didDisplayInsecureContentForFrame */
449         0, /* didRunInsecureContentForFrame */
450         0, /* canAuthenticateAgainstProtectionSpaceInFrame */
451         0, /* didReceiveAuthenticationChallengeInFrame */
452         qt_wk_didStartProgress,
453         qt_wk_didChangeProgress,
454         qt_wk_didFinishProgress,
455         qt_wk_didBecomeUnresponsive,
456         qt_wk_didBecomeResponsive,
457         0,  /* processDidCrash */
458         0,  /* didChangeBackForwardList */
459         0,  /* shouldGoToBackForwardListItem */
460         0   /* didFailToInitializePlugin */
461     };
462     WKPageSetPageLoaderClient(pageRef(), &loadClient);
463 
464     WKPageUIClient uiClient = {
465         0,      /* version */
466         this,   /* clientInfo */
467         qt_wk_createNewPage,
468         qt_wk_showPage,
469         qt_wk_close,
470         qt_wk_takeFocus,
471         0,  /* focus */
472         0,  /* unfocus */
473         qt_wk_runJavaScriptAlert,
474         0,  /* runJavaScriptConfirm */
475         0,  /* runJavaScriptPrompt */
476         qt_wk_setStatusText,
477         0,  /* mouseDidMoveOverElement */
478         0,  /* missingPluginButtonClicked */
479         0,  /* didNotHandleKeyEvent */
480         0,  /* toolbarsAreVisible */
481         0,  /* setToolbarsAreVisible */
482         0,  /* menuBarIsVisible */
483         0,  /* setMenuBarIsVisible */
484         0,  /* statusBarIsVisible */
485         0,  /* setStatusBarIsVisible */
486         0,  /* isResizable */
487         0,  /* setIsResizable */
488         0,  /* getWindowFrame */
489         0,  /* setWindowFrame */
490         0,  /* runBeforeUnloadConfirmPanel */
491         0,  /* didDraw */
492         0,  /* pageDidScroll */
493         0,  /* exceededDatabaseQuota */
494         0,  /* runOpenPanel */
495         0,  /* decidePolicyForGeolocationPermissionRequest */
496         0,  /* headerHeight */
497         0,  /* footerHeight */
498         0,  /* drawHeader */
499         0,  /* drawFooter */
500         0,  /* printFrame */
501         0,  /* runModal */
502         0,  /* didCompleteRubberBandForMainFrame */
503         0,  /* saveDataToFileInDownloadsFolder */
504         0,  /* shouldInterruptJavaScript */
505     };
506     WKPageSetPageUIClient(pageRef(), &uiClient);
507 }
508 
~QWKPage()509 QWKPage::~QWKPage()
510 {
511     delete d;
512 }
513 
ViewportAttributes()514 QWKPage::ViewportAttributes::ViewportAttributes()
515     : d(0)
516     , m_initialScaleFactor(-1.0)
517     , m_minimumScaleFactor(-1.0)
518     , m_maximumScaleFactor(-1.0)
519     , m_devicePixelRatio(-1.0)
520     , m_isUserScalable(true)
521     , m_isValid(false)
522 {
523 
524 }
525 
ViewportAttributes(const QWKPage::ViewportAttributes & other)526 QWKPage::ViewportAttributes::ViewportAttributes(const QWKPage::ViewportAttributes& other)
527     : d(other.d)
528     , m_initialScaleFactor(other.m_initialScaleFactor)
529     , m_minimumScaleFactor(other.m_minimumScaleFactor)
530     , m_maximumScaleFactor(other.m_maximumScaleFactor)
531     , m_devicePixelRatio(other.m_devicePixelRatio)
532     , m_isUserScalable(other.m_isUserScalable)
533     , m_isValid(other.m_isValid)
534     , m_size(other.m_size)
535 {
536 
537 }
538 
~ViewportAttributes()539 QWKPage::ViewportAttributes::~ViewportAttributes()
540 {
541 
542 }
543 
operator =(const QWKPage::ViewportAttributes & other)544 QWKPage::ViewportAttributes& QWKPage::ViewportAttributes::operator=(const QWKPage::ViewportAttributes& other)
545 {
546     if (this != &other) {
547         d = other.d;
548         m_initialScaleFactor = other.m_initialScaleFactor;
549         m_minimumScaleFactor = other.m_minimumScaleFactor;
550         m_maximumScaleFactor = other.m_maximumScaleFactor;
551         m_devicePixelRatio = other.m_devicePixelRatio;
552         m_isUserScalable = other.m_isUserScalable;
553         m_isValid = other.m_isValid;
554         m_size = other.m_size;
555     }
556 
557     return *this;
558 }
559 
viewportAttributesForSize(const QSize & availableSize) const560 QWKPage::ViewportAttributes QWKPage::viewportAttributesForSize(const QSize& availableSize) const
561 {
562     static int desktopWidth = 980;
563     static int deviceDPI = 160;
564 
565     ViewportAttributes result;
566 
567      if (availableSize.isEmpty())
568          return result; // Returns an invalid instance.
569 
570     // FIXME: Add a way to get these data via the platform plugin and fall back
571     // to the size of the view.
572     int deviceWidth = 480;
573     int deviceHeight = 864;
574 
575     WebCore::ViewportAttributes conf = WebCore::computeViewportAttributes(d->viewportArguments, desktopWidth, deviceWidth, deviceHeight, deviceDPI, availableSize);
576 
577     result.m_isValid = true;
578     result.m_size = conf.layoutSize;
579     result.m_initialScaleFactor = conf.initialScale;
580     result.m_minimumScaleFactor = conf.minimumScale;
581     result.m_maximumScaleFactor = conf.maximumScale;
582     result.m_devicePixelRatio = conf.devicePixelRatio;
583     result.m_isUserScalable = static_cast<bool>(conf.userScalable);
584 
585     return result;
586 }
587 
setActualVisibleContentsRect(const QRect & rect) const588 void QWKPage::setActualVisibleContentsRect(const QRect& rect) const
589 {
590 #if ENABLE(TILED_BACKING_STORE)
591     d->page->setActualVisibleContentRect(rect);
592 #endif
593 }
594 
timerEvent(QTimerEvent * ev)595 void QWKPage::timerEvent(QTimerEvent* ev)
596 {
597     int timerId = ev->timerId();
598     if (timerId == d->tripleClickTimer.timerId())
599         d->tripleClickTimer.stop();
600     else
601         QObject::timerEvent(ev);
602 }
603 
pageRef() const604 WKPageRef QWKPage::pageRef() const
605 {
606     return toAPI(d->page.get());
607 }
608 
context() const609 QWKContext* QWKPage::context() const
610 {
611     return d->context;
612 }
613 
preferences() const614 QWKPreferences* QWKPage::preferences() const
615 {
616     if (!d->preferences) {
617         WKPageGroupRef pageGroupRef = WKPageGetPageGroup(pageRef());
618         d->preferences = QWKPreferencesPrivate::createPreferences(pageGroupRef);
619     }
620 
621     return d->preferences;
622 }
623 
setCreateNewPageFunction(CreateNewPageFn function)624 void QWKPage::setCreateNewPageFunction(CreateNewPageFn function)
625 {
626     d->createNewPageFn = function;
627 }
628 
setCustomUserAgent(const QString & userAgent)629 void QWKPage::setCustomUserAgent(const QString& userAgent)
630 {
631     WKRetainPtr<WKStringRef> wkUserAgent(WKStringCreateWithQString(userAgent));
632     WKPageSetCustomUserAgent(pageRef(), wkUserAgent.get());
633 }
634 
customUserAgent() const635 QString QWKPage::customUserAgent() const
636 {
637     return WKStringCopyQString(WKPageCopyCustomUserAgent(pageRef()));
638 }
639 
load(const QUrl & url)640 void QWKPage::load(const QUrl& url)
641 {
642     WKRetainPtr<WKURLRef> wkurl(WKURLCreateWithQUrl(url));
643     WKPageLoadURL(pageRef(), wkurl.get());
644 }
645 
setUrl(const QUrl & url)646 void QWKPage::setUrl(const QUrl& url)
647 {
648     load(url);
649 }
650 
url() const651 QUrl QWKPage::url() const
652 {
653     WKRetainPtr<WKFrameRef> frame = WKPageGetMainFrame(pageRef());
654     if (!frame)
655         return QUrl();
656     return WKURLCopyQUrl(WKFrameCopyURL(frame.get()));
657 }
658 
title() const659 QString QWKPage::title() const
660 {
661     return WKStringCopyQString(WKPageCopyTitle(pageRef()));
662 }
663 
setViewportSize(const QSize & size)664 void QWKPage::setViewportSize(const QSize& size)
665 {
666     if (d->page->drawingArea())
667         d->page->drawingArea()->setSize(IntSize(size), IntSize());
668 }
669 
textZoomFactor() const670 qreal QWKPage::textZoomFactor() const
671 {
672     return WKPageGetTextZoomFactor(pageRef());
673 }
674 
setTextZoomFactor(qreal zoomFactor)675 void QWKPage::setTextZoomFactor(qreal zoomFactor)
676 {
677     WKPageSetTextZoomFactor(pageRef(), zoomFactor);
678 }
679 
pageZoomFactor() const680 qreal QWKPage::pageZoomFactor() const
681 {
682     return WKPageGetPageZoomFactor(pageRef());
683 }
684 
setPageZoomFactor(qreal zoomFactor)685 void QWKPage::setPageZoomFactor(qreal zoomFactor)
686 {
687     WKPageSetPageZoomFactor(pageRef(), zoomFactor);
688 }
689 
setPageAndTextZoomFactors(qreal pageZoomFactor,qreal textZoomFactor)690 void QWKPage::setPageAndTextZoomFactors(qreal pageZoomFactor, qreal textZoomFactor)
691 {
692     WKPageSetPageAndTextZoomFactors(pageRef(), pageZoomFactor, textZoomFactor);
693 }
694 
history() const695 QWKHistory* QWKPage::history() const
696 {
697     return d->history;
698 }
699 
setResizesToContentsUsingLayoutSize(const QSize & targetLayoutSize)700 void QWKPage::setResizesToContentsUsingLayoutSize(const QSize& targetLayoutSize)
701 {
702 #if ENABLE(TILED_BACKING_STORE)
703     d->page->setResizesToContentsUsingLayoutSize(targetLayoutSize);
704 #endif
705 }
706 
707 #ifndef QT_NO_ACTION
triggerAction(WebAction webAction,bool)708 void QWKPage::triggerAction(WebAction webAction, bool)
709 {
710     switch (webAction) {
711     case Back:
712         d->page->goBack();
713         return;
714     case Forward:
715         d->page->goForward();
716         return;
717     case Stop:
718         d->page->stopLoading();
719         return;
720     case Reload:
721         d->page->reload(/* reloadFromOrigin */ true);
722         return;
723     default:
724         break;
725     }
726 
727     QAction* qtAction = action(webAction);
728     WebKit::WebContextMenuItemData menuItemData(ActionType, contextMenuActionForWebAction(webAction), qtAction->text(), qtAction->isEnabled(), qtAction->isChecked());
729     d->page->contextMenuItemSelected(menuItemData);
730 }
731 #endif // QT_NO_ACTION
732 
733 #ifndef QT_NO_ACTION
action(WebAction action) const734 QAction* QWKPage::action(WebAction action) const
735 {
736     if (action == QWKPage::NoWebAction || action >= WebActionCount)
737         return 0;
738 
739     if (d->actions[action])
740         return d->actions[action];
741 
742     QString text;
743     QIcon icon;
744     QStyle* style = qobject_cast<QApplication*>(QCoreApplication::instance())->style();
745     bool checkable = false;
746 
747     switch (action) {
748     case OpenLink:
749         text = contextMenuItemTagOpenLink();
750         break;
751     case OpenLinkInNewWindow:
752         text = contextMenuItemTagOpenLinkInNewWindow();
753         break;
754     case CopyLinkToClipboard:
755         text = contextMenuItemTagCopyLinkToClipboard();
756         break;
757     case OpenImageInNewWindow:
758         text = contextMenuItemTagOpenImageInNewWindow();
759         break;
760     case Back:
761         text = contextMenuItemTagGoBack();
762         icon = style->standardIcon(QStyle::SP_ArrowBack);
763         break;
764     case Forward:
765         text = contextMenuItemTagGoForward();
766         icon = style->standardIcon(QStyle::SP_ArrowForward);
767         break;
768     case Stop:
769         text = contextMenuItemTagStop();
770         icon = style->standardIcon(QStyle::SP_BrowserStop);
771         break;
772     case Reload:
773         text = contextMenuItemTagReload();
774         icon = style->standardIcon(QStyle::SP_BrowserReload);
775         break;
776     case Cut:
777         text = contextMenuItemTagCut();
778         break;
779     case Copy:
780         text = contextMenuItemTagCopy();
781         break;
782     case Paste:
783         text = contextMenuItemTagPaste();
784         break;
785     case SelectAll:
786         text = contextMenuItemTagSelectAll();
787         break;
788     default:
789         return 0;
790         break;
791     }
792 
793     if (text.isEmpty())
794         return 0;
795 
796     QAction* a = new QAction(d->q);
797     a->setText(text);
798     a->setData(action);
799     a->setCheckable(checkable);
800     a->setIcon(icon);
801 
802     connect(a, SIGNAL(triggered(bool)), this, SLOT(_q_webActionTriggered(bool)));
803 
804     d->actions[action] = a;
805     d->updateAction(action);
806     return a;
807 }
808 #endif // QT_NO_ACTION
809 
findZoomableAreaForPoint(const QPoint & point)810 void QWKPage::findZoomableAreaForPoint(const QPoint& point)
811 {
812     d->page->findZoomableAreaForPoint(point);
813 }
814 
didFindZoomableArea(const IntRect & area)815 void QWKPagePrivate::didFindZoomableArea(const IntRect& area)
816 {
817     emit q->zoomableAreaFound(QRect(area));
818 }
819 
isConnectedToEngine() const820 bool QWKPage::isConnectedToEngine() const
821 {
822     return d->isConnectedToEngine;
823 }
824 
825 #include "moc_qwkpage.cpp"
826