diff options
author | Teng-Hui Zhu <ztenghui@google.com> | 2010-11-10 15:31:59 -0800 |
---|---|---|
committer | Teng-Hui Zhu <ztenghui@google.com> | 2010-11-17 13:35:59 -0800 |
commit | 28040489d744e0c5d475a88663056c9040ed5320 (patch) | |
tree | c463676791e4a63e452a95f0a12b2a8519730693 /WebKit/qt/Api | |
parent | eff9be92c41913c92fb1d3b7983c071f3e718678 (diff) | |
download | external_webkit-28040489d744e0c5d475a88663056c9040ed5320.zip external_webkit-28040489d744e0c5d475a88663056c9040ed5320.tar.gz external_webkit-28040489d744e0c5d475a88663056c9040ed5320.tar.bz2 |
Merge WebKit at r71558: Initial merge by git.
Change-Id: Ib345578fa29df7e4bc72b4f00e4a6fddcb754c4c
Diffstat (limited to 'WebKit/qt/Api')
-rw-r--r-- | WebKit/qt/Api/qgraphicswebview.cpp | 3 | ||||
-rw-r--r-- | WebKit/qt/Api/qwebelement.cpp | 10 | ||||
-rw-r--r-- | WebKit/qt/Api/qwebframe.cpp | 46 | ||||
-rw-r--r-- | WebKit/qt/Api/qwebframe_p.h | 8 | ||||
-rw-r--r-- | WebKit/qt/Api/qwebkitplatformplugin.h | 18 | ||||
-rw-r--r-- | WebKit/qt/Api/qwebpage.cpp | 207 | ||||
-rw-r--r-- | WebKit/qt/Api/qwebpage_p.h | 20 | ||||
-rw-r--r-- | WebKit/qt/Api/qwebsettings.cpp | 2 |
8 files changed, 271 insertions, 43 deletions
diff --git a/WebKit/qt/Api/qgraphicswebview.cpp b/WebKit/qt/Api/qgraphicswebview.cpp index df28626..f026827 100644 --- a/WebKit/qt/Api/qgraphicswebview.cpp +++ b/WebKit/qt/Api/qgraphicswebview.cpp @@ -140,6 +140,7 @@ void QGraphicsWebViewPrivate::updateResizesToContentsForPage() QObject::disconnect(page->mainFrame(), SIGNAL(contentsSizeChanged(QSize)), q, SLOT(_q_contentsSizeChanged(const QSize&))); } + page->d->page->settings()->setShouldDelegateScrolling(resizesToContents); } void QGraphicsWebViewPrivate::_q_contentsSizeChanged(const QSize& size) @@ -411,6 +412,8 @@ void QGraphicsWebViewPrivate::detachCurrentPage() if (!page) return; + page->d->page->settings()->setShouldDelegateScrolling(false); + page->d->view.clear(); // The client has always to be deleted. diff --git a/WebKit/qt/Api/qwebelement.cpp b/WebKit/qt/Api/qwebelement.cpp index 68fa17a..8121111 100644 --- a/WebKit/qt/Api/qwebelement.cpp +++ b/WebKit/qt/Api/qwebelement.cpp @@ -311,6 +311,11 @@ void QWebElement::setOuterXml(const QString &markup) \note This is currently implemented for (X)HTML elements only. + \note The format of the markup returned will obey the namespace of the + document containing the element. This means the return value will obey XML + formatting rules, such as self-closing tags, only if the document is + 'text/xhtml+xml'. + \sa setOuterXml(), setInnerXml(), toInnerXml() */ QString QWebElement::toOuterXml() const @@ -345,6 +350,11 @@ void QWebElement::setInnerXml(const QString &markup) \note This is currently implemented for (X)HTML elements only. + \note The format of the markup returned will obey the namespace of the + document containing the element. This means the return value will obey XML + formatting rules, such as self-closing tags, only if the document is + 'text/xhtml+xml'. + \sa setInnerXml(), setOuterXml(), toOuterXml() */ QString QWebElement::toInnerXml() const diff --git a/WebKit/qt/Api/qwebframe.cpp b/WebKit/qt/Api/qwebframe.cpp index 39e74d9..7d423d5 100644 --- a/WebKit/qt/Api/qwebframe.cpp +++ b/WebKit/qt/Api/qwebframe.cpp @@ -97,6 +97,7 @@ #include "runtime_root.h" #endif #if USE(TEXTURE_MAPPER) +#include "texmap/TextureMapper.h" #include "texmap/TextureMapperPlatformLayer.h" #endif #include "wtf/HashMap.h" @@ -294,19 +295,38 @@ void QWebFramePrivate::renderFromTiledBackingStore(GraphicsContext* context, con painter->restore(); } -#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER) - // TextureMapper might use raw OpenGL or some other backend that requires native painting. On raster this doesn't have any effect. - if (rootGraphicsLayer) { - painter->beginNativePainting(); - rootGraphicsLayer->paint(context, view->size(), view->frameRect(), IntRect(clip.boundingRect()), TransformationMatrix(), painter->opacity()); - painter->endNativePainting(); - } +#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER) + renderCompositedLayers(context, IntRect(clip.boundingRect())); renderRelativeCoords(context, (QWebFrame::RenderLayer)(QWebFrame::ScrollBarLayer | QWebFrame::PanIconLayer), clip); #endif } #endif +#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER) +void QWebFramePrivate::renderCompositedLayers(GraphicsContext* context, const IntRect& clip) +{ + if (!rootGraphicsLayer) + return; + + textureMapper->setGraphicsContext(context); + textureMapper->setImageInterpolationQuality(context->imageInterpolationQuality()); + textureMapper->setTextDrawingMode(context->textDrawingMode()); + QPainter* painter = context->platformContext(); + FrameView* view = frame->view(); + painter->save(); + painter->beginNativePainting(); + TextureMapperContentLayer::PaintOptions options; + options.visibleRect = clip; + options.targetRect = view->frameRect(); + options.viewportSize = view->size(); + options.opacity = painter->opacity(); + rootGraphicsLayer->paint(textureMapper.get(), options); + painter->endNativePainting(); + painter->restore(); +} +#endif + void QWebFramePrivate::renderRelativeCoords(GraphicsContext* context, QWebFrame::RenderLayer layer, const QRegion& clip) { if (!frame->view() || !frame->contentRenderer()) @@ -349,16 +369,8 @@ void QWebFramePrivate::renderRelativeCoords(GraphicsContext* context, QWebFrame: context->restore(); } painter->restore(); - #if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER) - if (rootGraphicsLayer) { - painter->save(); - painter->beginNativePainting(); - rootGraphicsLayer->paint(context, view->size(), view->frameRect(), IntRect(clip.boundingRect()), - TransformationMatrix(), context->platformContext()->opacity()); - painter->endNativePainting(); - painter->restore(); - } + renderCompositedLayers(context, IntRect(clip.boundingRect())); #endif } if (layer & (QWebFrame::PanIconLayer | QWebFrame::ScrollBarLayer)) { @@ -758,7 +770,7 @@ QIcon QWebFrame::icon() const */ QString QWebFrame::frameName() const { - return d->frame->tree()->name(); + return d->frame->tree()->uniqueName(); } /*! diff --git a/WebKit/qt/Api/qwebframe_p.h b/WebKit/qt/Api/qwebframe_p.h index 5660bd1..7c0d235 100644 --- a/WebKit/qt/Api/qwebframe_p.h +++ b/WebKit/qt/Api/qwebframe_p.h @@ -33,6 +33,10 @@ #include "Frame.h" #include "ViewportArguments.h" +#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER) +#include "texmap/TextureMapper.h" +#endif + namespace WebCore { class FrameLoaderClientQt; class FrameView; @@ -94,6 +98,9 @@ public: void renderFromTiledBackingStore(WebCore::GraphicsContext*, const QRegion& clip); #endif +#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER) + void renderCompositedLayers(WebCore::GraphicsContext* context, const WebCore::IntRect& clip); +#endif QWebFrame *q; Qt::ScrollBarPolicy horizontalScrollBarPolicy; Qt::ScrollBarPolicy verticalScrollBarPolicy; @@ -106,6 +113,7 @@ public: int marginHeight; #if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER) WebCore::TextureMapperContentLayer* rootGraphicsLayer; + OwnPtr<WebCore::TextureMapper> textureMapper; #endif bool zoomTextOnly; }; diff --git a/WebKit/qt/Api/qwebkitplatformplugin.h b/WebKit/qt/Api/qwebkitplatformplugin.h index a851d56..2ceaac1 100644 --- a/WebKit/qt/Api/qwebkitplatformplugin.h +++ b/WebKit/qt/Api/qwebkitplatformplugin.h @@ -102,6 +102,19 @@ public: virtual void playHapticFeedback(const HapticEvent, const QString& hapticType, const HapticStrength) = 0; }; +class QWebTouchModifier : public QObject +{ + Q_OBJECT +public: + virtual ~QWebTouchModifier() {} + + enum PaddingDirection { + Up, Right, Down, Left + }; + + virtual unsigned hitTestPaddingForTouch(const PaddingDirection) const = 0; +}; + class QWebKitPlatformPlugin { public: @@ -110,13 +123,14 @@ public: enum Extension { MultipleSelections, Notifications, - Haptics + Haptics, + TouchInteraction }; virtual bool supportsExtension(Extension extension) const = 0; virtual QObject* createExtension(Extension extension) const = 0; }; -Q_DECLARE_INTERFACE(QWebKitPlatformPlugin, "com.nokia.Qt.WebKit.PlatformPlugin/1.5"); +Q_DECLARE_INTERFACE(QWebKitPlatformPlugin, "com.nokia.Qt.WebKit.PlatformPlugin/1.6"); #endif // QWEBKITPLATFORMPLUGIN_H diff --git a/WebKit/qt/Api/qwebpage.cpp b/WebKit/qt/Api/qwebpage.cpp index 40f41c5..a6ca65a 100644 --- a/WebKit/qt/Api/qwebpage.cpp +++ b/WebKit/qt/Api/qwebpage.cpp @@ -31,13 +31,17 @@ #include "qwebinspector.h" #include "qwebinspector_p.h" #include "qwebsettings.h" +#include "qwebkitplatformplugin.h" #include "qwebkitversion.h" +#include "CSSComputedStyleDeclaration.h" +#include "CSSParser.h" #include "ApplicationCacheStorage.h" #include "BackForwardListImpl.h" -#include "Cache.h" +#include "MemoryCache.h" #include "Chrome.h" #include "ChromeClientQt.h" +#include "ClientRect.h" #include "ContextMenu.h" #include "ContextMenuClientQt.h" #include "ContextMenuController.h" @@ -60,6 +64,7 @@ #include "FrameView.h" #include "GeolocationPermissionClientQt.h" #include "HTMLFormElement.h" +#include "HTMLFrameOwnerElement.h" #include "HTMLInputElement.h" #include "HTMLNames.h" #include "HashMap.h" @@ -74,7 +79,9 @@ #include "MIMETypeRegistry.h" #include "NavigationAction.h" #include "NetworkingContext.h" +#include "NodeList.h" #include "NotificationPresenterClientQt.h" +#include "NotImplemented.h" #include "Page.h" #include "PageClientQt.h" #include "PageGroup.h" @@ -86,6 +93,7 @@ #include "PluginDatabase.h" #include "PluginPackage.h" #include "ProgressTracker.h" +#include "QtPlatformPlugin.h" #include "RefPtr.h" #include "RenderTextControl.h" #include "SchemeRegistry.h" @@ -657,6 +665,7 @@ void QWebPagePrivate::mousePressEvent(T* ev) } bool accepted = false; + adjustPointForClicking(ev); PlatformMouseEvent mev(ev, 1); // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton if (mev.button() != NoButton) @@ -736,6 +745,7 @@ void QWebPagePrivate::mouseReleaseEvent(T *ev) return; bool accepted = false; + adjustPointForClicking(ev); PlatformMouseEvent mev(ev, 0); // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton if (mev.button() != NoButton) @@ -1024,9 +1034,9 @@ void QWebPagePrivate::inputMethodEvent(QInputMethodEvent *ev) return; } - RenderObject* renderer = 0; + Node* node = 0; if (frame->selection()->rootEditableElement()) - renderer = frame->selection()->rootEditableElement()->shadowAncestorNode()->renderer(); + node = frame->selection()->rootEditableElement()->shadowAncestorNode(); Vector<CompositionUnderline> underlines; bool hasSelection = false; @@ -1054,8 +1064,8 @@ void QWebPagePrivate::inputMethodEvent(QInputMethodEvent *ev) case QInputMethodEvent::Selection: { hasSelection = true; // A selection in the inputMethodEvent is always reflected in the visible text - if (renderer && renderer->node()) - setSelectionRange(renderer->node(), qMin(a.start, (a.start + a.length)), qMax(a.start, (a.start + a.length))); + if (node) + setSelectionRange(node, qMin(a.start, (a.start + a.length)), qMax(a.start, (a.start + a.length))); if (!ev->preeditString().isEmpty()) { editor->setComposition(ev->preeditString(), underlines, @@ -1263,6 +1273,42 @@ bool QWebPagePrivate::handleScrolling(QKeyEvent *ev, Frame *frame) return frame->eventHandler()->scrollRecursively(direction, granularity); } +void QWebPagePrivate::adjustPointForClicking(QMouseEvent*) +{ + notImplemented(); +} + +void QWebPagePrivate::adjustPointForClicking(QGraphicsSceneMouseEvent* ev) +{ + QtPlatformPlugin platformPlugin; + QWebTouchModifier* touchModifier = platformPlugin.createTouchModifier(); + if (!touchModifier) + return; + + unsigned topPadding = touchModifier->hitTestPaddingForTouch(QWebTouchModifier::Up); + unsigned rightPadding = touchModifier->hitTestPaddingForTouch(QWebTouchModifier::Right); + unsigned bottomPadding = touchModifier->hitTestPaddingForTouch(QWebTouchModifier::Down); + unsigned leftPadding = touchModifier->hitTestPaddingForTouch(QWebTouchModifier::Left); + + delete touchModifier; + touchModifier = 0; + + if (!topPadding && !rightPadding && !bottomPadding && !leftPadding) + return; + + Document* startingDocument = page->mainFrame()->document(); + if (!startingDocument) + return; + + IntPoint originalPoint(QPointF(ev->pos()).toPoint()); + TouchAdjuster touchAdjuster(topPadding, rightPadding, bottomPadding, leftPadding); + IntPoint adjustedPoint = touchAdjuster.findCandidatePointForTouch(originalPoint, startingDocument); + if (adjustedPoint == IntPoint::zero()) + return; + + ev->setPos(QPointF(adjustedPoint)); +} + bool QWebPagePrivate::touchEvent(QTouchEvent* event) { WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); @@ -1319,14 +1365,11 @@ QVariant QWebPage::inputMethodQuery(Qt::InputMethodQuery property) const return QVariant(QFont()); } case Qt::ImCursorPosition: { - if (renderTextControl) { - if (editor->hasComposition()) { - RefPtr<Range> range = editor->compositionRange(); - return QVariant(renderTextControl->selectionEnd() - TextIterator::rangeLength(range.get())); - } - return QVariant(frame->selection()->extent().offsetInContainerNode()); + if (editor->hasComposition()) { + RefPtr<Range> range = editor->compositionRange(); + return QVariant(frame->selection()->end().offsetInContainerNode() - TextIterator::rangeLength(range.get())); } - return QVariant(); + return QVariant(frame->selection()->extent().offsetInContainerNode()); } case Qt::ImSurroundingText: { if (renderTextControl) { @@ -1340,23 +1383,20 @@ QVariant QWebPage::inputMethodQuery(Qt::InputMethodQuery property) const } case Qt::ImCurrentSelection: { if (renderTextControl) { - int start = renderTextControl->selectionStart(); - int end = renderTextControl->selectionEnd(); + int start = frame->selection()->start().offsetInContainerNode(); + int end = frame->selection()->end().offsetInContainerNode(); if (end > start) - return QVariant(QString(renderTextControl->text()).mid(start,end-start)); + return QVariant(QString(renderTextControl->text()).mid(start, end - start)); } return QVariant(); } case Qt::ImAnchorPosition: { - if (renderTextControl) { - if (editor->hasComposition()) { - RefPtr<Range> range = editor->compositionRange(); - return QVariant(renderTextControl->selectionStart() - TextIterator::rangeLength(range.get())); - } - return QVariant(frame->selection()->base().offsetInContainerNode()); + if (editor->hasComposition()) { + RefPtr<Range> range = editor->compositionRange(); + return QVariant(frame->selection()->start().offsetInContainerNode() - TextIterator::rangeLength(range.get())); } - return QVariant(); + return QVariant(frame->selection()->base().offsetInContainerNode()); } case Qt::ImMaximumTextLength: { if (frame->selection()->isContentEditable()) { @@ -1435,6 +1475,124 @@ quint16 QWebPagePrivate::inspectorServerPort() return 0; } +static bool hasMouseListener(Element* element) +{ + ASSERT(element); + return element->hasEventListeners(eventNames().clickEvent) + || element->hasEventListeners(eventNames().mousedownEvent) + || element->hasEventListeners(eventNames().mouseupEvent); +} + +static bool isClickableElement(Element* element, RefPtr<NodeList> list) +{ + ASSERT(element); + bool isClickable = hasMouseListener(element); + if (!isClickable && list) { + Element* parent = element->parentElement(); + unsigned count = list->length(); + for (unsigned i = 0; i < count && parent; i++) { + if (list->item(i) != parent) + continue; + + isClickable = hasMouseListener(parent); + if (isClickable) + break; + + parent = parent->parentElement(); + } + } + + ExceptionCode ec = 0; + return isClickable + || element->webkitMatchesSelector("a,*:link,*:visited,*[role=button],button,input,select,label", ec) + || computedStyle(element)->getPropertyValue(cssPropertyID("cursor")) == "pointer"; +} + +static bool isValidFrameOwner(Element* element) +{ + ASSERT(element); + return element->isFrameOwnerElement() && static_cast<HTMLFrameOwnerElement*>(element)->contentFrame(); +} + +static Element* nodeToElement(Node* node) +{ + if (node && node->isElementNode()) + return static_cast<Element*>(node); + return 0; +} + +QWebPagePrivate::TouchAdjuster::TouchAdjuster(unsigned topPadding, unsigned rightPadding, unsigned bottomPadding, unsigned leftPadding) + : m_topPadding(topPadding) + , m_rightPadding(rightPadding) + , m_bottomPadding(bottomPadding) + , m_leftPadding(leftPadding) +{ +} + +IntPoint QWebPagePrivate::TouchAdjuster::findCandidatePointForTouch(const IntPoint& touchPoint, Document* document) const +{ + if (!document) + return IntPoint(); + + int x = touchPoint.x(); + int y = touchPoint.y(); + + RefPtr<NodeList> intersectedNodes = document->nodesFromRect(x, y, m_topPadding, m_rightPadding, m_bottomPadding, m_leftPadding, false); + if (!intersectedNodes) + return IntPoint(); + + Element* closestClickableElement = 0; + IntRect largestIntersectionRect; + FrameView* view = document->frame()->view(); + + // Touch rect in contents coordinates. + IntRect touchRect(HitTestResult::rectForPoint(view->windowToContents(IntPoint(x, y)), m_topPadding, m_rightPadding, m_bottomPadding, m_leftPadding)); + + // Iterate over the list of nodes hit looking for the one whose bounding area + // has largest intersection with the touch area (point + padding). + for (unsigned i = 0; i < intersectedNodes->length(); i++) { + Node* currentNode = intersectedNodes->item(i); + + Element* currentElement = nodeToElement(currentNode); + if (!currentElement || (!isClickableElement(currentElement, 0) && !isValidFrameOwner(currentElement))) + continue; + + IntRect currentElementBoundingRect = currentElement->getRect(); + currentElementBoundingRect.intersect(touchRect); + + if (currentElementBoundingRect.isEmpty()) + continue; + + int currentIntersectionRectArea = currentElementBoundingRect.width() * currentElementBoundingRect.height(); + int largestIntersectionRectArea = largestIntersectionRect.width() * largestIntersectionRect.height(); + if (currentIntersectionRectArea > largestIntersectionRectArea) { + closestClickableElement = currentElement; + largestIntersectionRect = currentElementBoundingRect; + } + } + + if (largestIntersectionRect.isEmpty()) + return IntPoint(); + + // Handle the case when user taps a inner frame. It is done in three steps: + // 1) Transform the original touch point to the inner document coordinates; + // 1) Call nodesFromRect for the inner document in case; + // 3) Re-add the inner frame offset (location) before passing the new clicking + // position to WebCore. + if (closestClickableElement->isFrameOwnerElement()) { + // Adjust client coordinates' origin to be top left of inner frame viewport. + PassRefPtr<ClientRect> rect = closestClickableElement->getBoundingClientRect(); + IntPoint newTouchPoint = touchPoint; + IntSize offset = IntSize(rect->left(), rect->top()); + newTouchPoint -= offset; + + HTMLFrameOwnerElement* owner = static_cast<HTMLFrameOwnerElement*>(closestClickableElement); + Document* childDocument = owner->contentFrame()->document(); + return findCandidatePointForTouch(newTouchPoint, childDocument); + } + return view->contentsToWindow(largestIntersectionRect).center(); +} + /*! \enum QWebPage::FindFlag @@ -2424,7 +2582,10 @@ bool QWebPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest & QString QWebPage::selectedText() const { d->createMainFrame(); - return d->page->focusController()->focusedOrMainFrame()->editor()->selectedText(); + WebCore::Frame* frame = d->page->focusController()->focusedOrMainFrame(); + if (frame->selection()->selection().selectionType() == VisibleSelection::NoSelection) + return QString(); + return frame->editor()->selectedText(); } #ifndef QT_NO_ACTION diff --git a/WebKit/qt/Api/qwebpage_p.h b/WebKit/qt/Api/qwebpage_p.h index 1f70293..1b9cd66 100644 --- a/WebKit/qt/Api/qwebpage_p.h +++ b/WebKit/qt/Api/qwebpage_p.h @@ -31,6 +31,7 @@ #include "qwebhistory.h" #include "qwebframe.h" +#include "IntPoint.h" #include "KURL.h" #include "PlatformString.h" @@ -43,10 +44,13 @@ namespace WebCore { class ContextMenuClientQt; class ContextMenuItem; class ContextMenu; + class Document; class EditorClientQt; class Element; class InspectorController; + class IntRect; class Node; + class NodeList; class Page; class Frame; } @@ -126,6 +130,22 @@ public: // Returns whether the default action was cancelled in the JS event handler bool touchEvent(QTouchEvent*); + class TouchAdjuster { + public: + TouchAdjuster(unsigned topPadding, unsigned rightPadding, unsigned bottomPadding, unsigned leftPadding); + + WebCore::IntPoint findCandidatePointForTouch(const WebCore::IntPoint&, WebCore::Document*) const; + + private: + unsigned m_topPadding; + unsigned m_rightPadding; + unsigned m_bottomPadding; + unsigned m_leftPadding; + }; + + void adjustPointForClicking(QMouseEvent*); + void adjustPointForClicking(QGraphicsSceneMouseEvent*); + void setInspector(QWebInspector*); QWebInspector* getOrCreateInspector(); WebCore::InspectorController* inspectorController(); diff --git a/WebKit/qt/Api/qwebsettings.cpp b/WebKit/qt/Api/qwebsettings.cpp index 3cd36f2..ed425c2 100644 --- a/WebKit/qt/Api/qwebsettings.cpp +++ b/WebKit/qt/Api/qwebsettings.cpp @@ -25,7 +25,7 @@ #include "qwebplugindatabase_p.h" #include "AbstractDatabase.h" -#include "Cache.h" +#include "MemoryCache.h" #include "CrossOriginPreflightResultCache.h" #include "FontCache.h" #include "Page.h" |