diff options
Diffstat (limited to 'Source/WebCore/page')
-rw-r--r-- | Source/WebCore/page/TouchAdjustment.cpp | 94 | ||||
-rw-r--r-- | Source/WebCore/page/scrolling/chromium/ScrollingCoordinatorChromium.cpp | 90 | ||||
-rw-r--r-- | Source/WebCore/page/win/EventHandlerWin.cpp | 6 |
3 files changed, 125 insertions, 65 deletions
diff --git a/Source/WebCore/page/TouchAdjustment.cpp b/Source/WebCore/page/TouchAdjustment.cpp index 42fe2c135..ddf2ab563 100644 --- a/Source/WebCore/page/TouchAdjustment.cpp +++ b/Source/WebCore/page/TouchAdjustment.cpp @@ -35,7 +35,10 @@ #include "RenderBox.h" #include "RenderObject.h" #include "RenderStyle.h" +#include "RenderText.h" #include "ShadowRoot.h" +#include "Text.h" +#include "TextBreakIterator.h" namespace WebCore { @@ -62,6 +65,7 @@ private: typedef Vector<SubtargetGeometry> SubtargetGeometryList; typedef bool (*NodeFilter)(Node*); +typedef void (*AppendSubtargetsForNode)(Node*, SubtargetGeometryList&); typedef float (*DistanceFunction)(const IntPoint&, const IntRect&, const SubtargetGeometry&); // Takes non-const Node* because isContentEditable is a non-const function. @@ -101,20 +105,26 @@ bool providesContextMenuItems(Node* node) if (node->renderer()->isMedia()) return true; if (node->renderer()->canBeSelectionLeaf()) { - // If the context menu gesture will trigger a selection all selectable nodes are targets. - // FIXME: To improve the adjusted point, each individual word should be a separate subtarget, - // see for example FatFingers::checkForText() in WebKit/blackberry. + // If the context menu gesture will trigger a selection all selectable nodes are valid targets. if (node->renderer()->frame()->editor()->behavior().shouldSelectOnContextualMenuClick()) return true; - // FIXME: A selected text might only be partially selected, and we should only append - // the selected subtargets of it in appendSubtargetsForNodeToList(). + // Only the selected part of the renderer is a valid target, but this will be corrected in + // appendContextSubtargetsForNode. if (node->renderer()->selectionState() != RenderObject::SelectionNone) return true; } return false; } -static inline void appendSubtargetsForNodeToList(Node* node, SubtargetGeometryList& subtargets) +static inline void appendQuadsToSubtargetList(Vector<FloatQuad>& quads, Node* node, SubtargetGeometryList& subtargets) +{ + Vector<FloatQuad>::const_iterator it = quads.begin(); + const Vector<FloatQuad>::const_iterator end = quads.end(); + for (; it != end; ++it) + subtargets.append(SubtargetGeometry(node, *it)); +} + +static inline void appendBasicSubtargetsForNode(Node* node, SubtargetGeometryList& subtargets) { // Since the node is a result of a hit test, we are already ensured it has a renderer. ASSERT(node->renderer()); @@ -122,10 +132,66 @@ static inline void appendSubtargetsForNodeToList(Node* node, SubtargetGeometryLi Vector<FloatQuad> quads; node->renderer()->absoluteQuads(quads); - Vector<FloatQuad>::const_iterator it = quads.begin(); - const Vector<FloatQuad>::const_iterator end = quads.end(); - for (; it != end; ++it) - subtargets.append(SubtargetGeometry(node, *it)); + appendQuadsToSubtargetList(quads, node, subtargets); +} + +static inline void appendContextSubtargetsForNode(Node* node, SubtargetGeometryList& subtargets) +{ + // This is a variant of appendBasicSubtargetsForNode that adds special subtargets for + // selected or auto-selectable parts of text nodes. + ASSERT(node->renderer()); + + if (!node->isTextNode()) + return appendBasicSubtargetsForNode(node, subtargets); + + Text* textNode = static_cast<WebCore::Text*>(node); + RenderText* textRenderer = static_cast<RenderText*>(textNode->renderer()); + + if (textRenderer->frame()->editor()->behavior().shouldSelectOnContextualMenuClick()) { + // Make subtargets out of every word. + String textValue = textNode->data(); + TextBreakIterator* wordIterator = wordBreakIterator(textValue.characters(), textValue.length()); + int lastOffset = textBreakFirst(wordIterator); + if (lastOffset == -1) + return; + int offset; + while ((offset = textBreakNext(wordIterator)) != -1) { + if (isWordTextBreak(wordIterator)) { + Vector<FloatQuad> quads; + textRenderer->absoluteQuadsForRange(quads, lastOffset, offset); + appendQuadsToSubtargetList(quads, textNode, subtargets); + } + lastOffset = offset; + } + } else { + if (textRenderer->selectionState() == RenderObject::SelectionNone) + return appendBasicSubtargetsForNode(node, subtargets); + // If selected, make subtargets out of only the selected part of the text. + int startPos, endPos; + switch (textRenderer->selectionState()) { + case RenderObject::SelectionInside: + startPos = 0; + endPos = textRenderer->textLength(); + break; + case RenderObject::SelectionStart: + textRenderer->selectionStartEnd(startPos, endPos); + endPos = textRenderer->textLength(); + break; + case RenderObject::SelectionEnd: + textRenderer->selectionStartEnd(startPos, endPos); + startPos = 0; + break; + case RenderObject::SelectionBoth: + textRenderer->selectionStartEnd(startPos, endPos); + break; + default: + ASSERT_NOT_REACHED(); + return; + } + Vector<FloatQuad> quads; + textRenderer->absoluteQuadsForRange(quads, startPos, endPos); + appendQuadsToSubtargetList(quads, textNode, subtargets); + } } static inline void appendZoomableSubtargets(Node* node, SubtargetGeometryList& subtargets) @@ -148,7 +214,7 @@ static inline void appendZoomableSubtargets(Node* node, SubtargetGeometryList& s } // Compiles a list of subtargets of all the relevant target nodes. -void compileSubtargetList(const NodeList& intersectedNodes, SubtargetGeometryList& subtargets, NodeFilter nodeFilter) +void compileSubtargetList(const NodeList& intersectedNodes, SubtargetGeometryList& subtargets, NodeFilter nodeFilter, AppendSubtargetsForNode appendSubtargetsForNode) { // Find candidates responding to tap gesture events in O(n) time. HashMap<Node*, Node*> responderMap; @@ -201,7 +267,7 @@ void compileSubtargetList(const NodeList& intersectedNodes, SubtargetGeometryLis ASSERT(respondingNode); if (ancestorsToRespondersSet.contains(respondingNode)) continue; - appendSubtargetsForNodeToList(candidate, subtargets); + appendSubtargetsForNode(candidate, subtargets); } } @@ -408,7 +474,7 @@ bool findBestClickableCandidate(Node*& targetNode, IntPoint &targetPoint, const { IntRect targetArea; TouchAdjustment::SubtargetGeometryList subtargets; - TouchAdjustment::compileSubtargetList(nodeList, subtargets, TouchAdjustment::nodeRespondsToTapGesture); + TouchAdjustment::compileSubtargetList(nodeList, subtargets, TouchAdjustment::nodeRespondsToTapGesture, TouchAdjustment::appendBasicSubtargetsForNode); return TouchAdjustment::findNodeWithLowestDistanceMetric(targetNode, targetPoint, targetArea, touchHotspot, touchArea, subtargets, TouchAdjustment::hybridDistanceFunction); } @@ -416,7 +482,7 @@ bool findBestContextMenuCandidate(Node*& targetNode, IntPoint &targetPoint, cons { IntRect targetArea; TouchAdjustment::SubtargetGeometryList subtargets; - TouchAdjustment::compileSubtargetList(nodeList, subtargets, TouchAdjustment::providesContextMenuItems); + TouchAdjustment::compileSubtargetList(nodeList, subtargets, TouchAdjustment::providesContextMenuItems, TouchAdjustment::appendContextSubtargetsForNode); return TouchAdjustment::findNodeWithLowestDistanceMetric(targetNode, targetPoint, targetArea, touchHotspot, touchArea, subtargets, TouchAdjustment::hybridDistanceFunction); } diff --git a/Source/WebCore/page/scrolling/chromium/ScrollingCoordinatorChromium.cpp b/Source/WebCore/page/scrolling/chromium/ScrollingCoordinatorChromium.cpp index e256bde1a..1db759404 100644 --- a/Source/WebCore/page/scrolling/chromium/ScrollingCoordinatorChromium.cpp +++ b/Source/WebCore/page/scrolling/chromium/ScrollingCoordinatorChromium.cpp @@ -29,12 +29,12 @@ #include "Frame.h" #include "FrameView.h" -#include "Page.h" #include "Region.h" #include "RenderLayerCompositor.h" #include "RenderView.h" #include "ScrollbarThemeComposite.h" #include "WebScrollbarThemeGeometryNative.h" +#include <public/WebScrollableLayer.h> #include <public/WebScrollbar.h> #include <public/WebScrollbarLayer.h> #include <public/WebScrollbarThemeGeometry.h> @@ -42,6 +42,7 @@ using WebKit::WebLayer; using WebKit::WebRect; +using WebKit::WebScrollableLayer; using WebKit::WebScrollbarLayer; using WebKit::WebVector; @@ -50,39 +51,36 @@ namespace WebCore { class ScrollingCoordinatorPrivate { WTF_MAKE_NONCOPYABLE(ScrollingCoordinatorPrivate); public: - ScrollingCoordinatorPrivate() - : m_scrollLayer(0) - { - } - + ScrollingCoordinatorPrivate() { } ~ScrollingCoordinatorPrivate() { } - void setScrollLayer(WebLayer* layer) + void setScrollLayer(WebScrollableLayer layer) { m_scrollLayer = layer; - if (m_horizontalScrollbarLayer) - m_horizontalScrollbarLayer->setScrollLayer(layer); - if (m_verticalScrollbarLayer) - m_verticalScrollbarLayer->setScrollLayer(layer); + if (!m_horizontalScrollbarLayer.isNull()) + m_horizontalScrollbarLayer.setScrollLayer(layer); + if (!m_verticalScrollbarLayer.isNull()) + m_verticalScrollbarLayer.setScrollLayer(layer); } - void setHorizontalScrollbarLayer(PassOwnPtr<WebScrollbarLayer> layer) + void setHorizontalScrollbarLayer(WebScrollbarLayer layer) { m_horizontalScrollbarLayer = layer; } - void setVerticalScrollbarLayer(PassOwnPtr<WebScrollbarLayer> layer) + void setVerticalScrollbarLayer(WebScrollbarLayer layer) { m_verticalScrollbarLayer = layer; } - WebLayer* scrollLayer() const { return m_scrollLayer; } + bool hasScrollLayer() const { return !m_scrollLayer.isNull(); } + WebScrollableLayer scrollLayer() const { return m_scrollLayer; } private: - WebLayer* m_scrollLayer; - OwnPtr<WebScrollbarLayer> m_horizontalScrollbarLayer; - OwnPtr<WebScrollbarLayer> m_verticalScrollbarLayer; + WebScrollableLayer m_scrollLayer; + WebScrollbarLayer m_horizontalScrollbarLayer; + WebScrollbarLayer m_verticalScrollbarLayer; }; PassRefPtr<ScrollingCoordinator> ScrollingCoordinator::create(Page* page) @@ -114,20 +112,15 @@ static GraphicsLayer* scrollLayerForFrameView(FrameView* frameView) #endif } -static WebLayer* scrollableLayerForGraphicsLayer(GraphicsLayer* layer) -{ - return layer->platformLayer(); -} - -static PassOwnPtr<WebScrollbarLayer> createScrollbarLayer(Scrollbar* scrollbar, WebLayer* scrollLayer, GraphicsLayer* scrollbarGraphicsLayer, FrameView* frameView) +static WebScrollbarLayer createScrollbarLayer(Scrollbar* scrollbar, WebScrollableLayer scrollLayer, GraphicsLayer* scrollbarGraphicsLayer, FrameView* frameView) { ASSERT(scrollbar); ASSERT(scrollbarGraphicsLayer); - if (!scrollLayer) { + if (scrollLayer.isNull()) { // FIXME: sometimes we get called before setScrollLayer, workaround by finding the scroll layout ourselves. - scrollLayer = scrollableLayerForGraphicsLayer(scrollLayerForFrameView(frameView)); - ASSERT(scrollLayer); + scrollLayer = scrollLayerForFrameView(frameView)->platformLayer()->to<WebScrollableLayer>(); + ASSERT(!scrollLayer.isNull()); } // Root layer non-overlay scrollbars should be marked opaque to disable @@ -145,7 +138,7 @@ static PassOwnPtr<WebScrollbarLayer> createScrollbarLayer(Scrollbar* scrollbar, if (!platformSupported || scrollbar->isCustomScrollbar()) { scrollbarGraphicsLayer->setContentsToMedia(0); scrollbarGraphicsLayer->setDrawsContent(true); - return nullptr; + return WebScrollbarLayer(); } // All Chromium scrollbar themes derive from ScrollbarThemeComposite. @@ -153,14 +146,14 @@ static PassOwnPtr<WebScrollbarLayer> createScrollbarLayer(Scrollbar* scrollbar, WebKit::WebScrollbarThemePainter painter(themeComposite, scrollbar); OwnPtr<WebKit::WebScrollbarThemeGeometry> geometry(WebKit::WebScrollbarThemeGeometryNative::create(themeComposite)); - OwnPtr<WebScrollbarLayer> scrollbarLayer = adoptPtr(WebScrollbarLayer::create(scrollbar, painter, geometry.release())); - scrollbarLayer->setScrollLayer(scrollLayer); + WebScrollbarLayer scrollbarLayer = WebScrollbarLayer::create(scrollbar, painter, geometry.release()); + scrollbarLayer.setScrollLayer(scrollLayer); - scrollbarGraphicsLayer->setContentsToMedia(scrollbarLayer->layer()); + scrollbarGraphicsLayer->setContentsToMedia(&scrollbarLayer); scrollbarGraphicsLayer->setDrawsContent(false); - scrollbarLayer->layer()->setOpaque(scrollbarGraphicsLayer->contentsOpaque()); + scrollbarLayer.setOpaque(scrollbarGraphicsLayer->contentsOpaque()); - return scrollbarLayer.release(); + return scrollbarLayer; } void ScrollingCoordinator::frameViewHorizontalScrollbarLayerDidChange(FrameView* frameView, GraphicsLayer* horizontalScrollbarLayer) @@ -168,7 +161,6 @@ void ScrollingCoordinator::frameViewHorizontalScrollbarLayerDidChange(FrameView* if (!horizontalScrollbarLayer || !coordinatesScrollingForFrameView(frameView)) return; - setScrollLayer(scrollLayerForFrameView(m_page->mainFrame()->view())); m_private->setHorizontalScrollbarLayer(createScrollbarLayer(frameView->horizontalScrollbar(), m_private->scrollLayer(), horizontalScrollbarLayer, frameView)); } @@ -177,25 +169,25 @@ void ScrollingCoordinator::frameViewVerticalScrollbarLayerDidChange(FrameView* f if (!verticalScrollbarLayer || !coordinatesScrollingForFrameView(frameView)) return; - setScrollLayer(scrollLayerForFrameView(m_page->mainFrame()->view())); m_private->setVerticalScrollbarLayer(createScrollbarLayer(frameView->verticalScrollbar(), m_private->scrollLayer(), verticalScrollbarLayer, frameView)); } void ScrollingCoordinator::setScrollLayer(GraphicsLayer* scrollLayer) { - m_private->setScrollLayer(scrollLayer ? scrollableLayerForGraphicsLayer(scrollLayer) : 0); + WebScrollableLayer layer; + if (scrollLayer) + layer = scrollLayer->platformLayer()->to<WebScrollableLayer>(); + m_private->setScrollLayer(layer); } void ScrollingCoordinator::setNonFastScrollableRegion(const Region& region) { - // We won't necessarily get a setScrollLayer() call before this one, so grab the root ourselves. - setScrollLayer(scrollLayerForFrameView(m_page->mainFrame()->view())); - if (m_private->scrollLayer()) { + if (m_private->hasScrollLayer()) { Vector<IntRect> rects = region.rects(); WebVector<WebRect> webRects(rects.size()); for (size_t i = 0; i < rects.size(); ++i) webRects[i] = rects[i]; - m_private->scrollLayer()->setNonFastScrollableRegion(webRects); + m_private->scrollLayer().setNonFastScrollableRegion(webRects); } } @@ -206,18 +198,14 @@ void ScrollingCoordinator::setScrollParameters(const ScrollParameters&) void ScrollingCoordinator::setWheelEventHandlerCount(unsigned wheelEventHandlerCount) { - // We won't necessarily get a setScrollLayer() call before this one, so grab the root ourselves. - setScrollLayer(scrollLayerForFrameView(m_page->mainFrame()->view())); - if (m_private->scrollLayer()) - m_private->scrollLayer()->setHaveWheelEventHandlers(wheelEventHandlerCount > 0); + if (m_private->hasScrollLayer()) + m_private->scrollLayer().setHaveWheelEventHandlers(wheelEventHandlerCount > 0); } void ScrollingCoordinator::setShouldUpdateScrollLayerPositionOnMainThread(bool should) { - // We won't necessarily get a setScrollLayer() call before this one, so grab the root ourselves. - setScrollLayer(scrollLayerForFrameView(m_page->mainFrame()->view())); - if (m_private->scrollLayer()) - m_private->scrollLayer()->setShouldScrollOnMainThread(should); + if (m_private->hasScrollLayer()) + m_private->scrollLayer().setShouldScrollOnMainThread(should); } bool ScrollingCoordinator::supportsFixedPositionLayers() const @@ -227,14 +215,14 @@ bool ScrollingCoordinator::supportsFixedPositionLayers() const void ScrollingCoordinator::setLayerIsContainerForFixedPositionLayers(GraphicsLayer* layer, bool enable) { - if (WebLayer* scrollableLayer = scrollableLayerForGraphicsLayer(layer)) - scrollableLayer->setIsContainerForFixedPositionLayers(enable); + if (WebLayer* platformLayer = layer->platformLayer()) + platformLayer->to<WebScrollableLayer>().setIsContainerForFixedPositionLayers(enable); } void ScrollingCoordinator::setLayerIsFixedToContainerLayer(GraphicsLayer* layer, bool enable) { - if (WebLayer* scrollableLayer = scrollableLayerForGraphicsLayer(layer)) - scrollableLayer->setFixedToContainerLayer(enable); + if (WebLayer* platformLayer = layer->platformLayer()) + platformLayer->to<WebScrollableLayer>().setFixedToContainerLayer(enable); } } diff --git a/Source/WebCore/page/win/EventHandlerWin.cpp b/Source/WebCore/page/win/EventHandlerWin.cpp index 9393efa55..e391b7765 100644 --- a/Source/WebCore/page/win/EventHandlerWin.cpp +++ b/Source/WebCore/page/win/EventHandlerWin.cpp @@ -51,7 +51,9 @@ namespace WebCore { +#if ENABLE(DRAG_SUPPORT) const double EventHandler::TextDragDelay = 0.0; +#endif bool EventHandler::passMousePressEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe) { @@ -61,8 +63,10 @@ bool EventHandler::passMousePressEventToSubframe(MouseEventWithHitTestResults& m bool EventHandler::passMouseMoveEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe, HitTestResult* hoveredNode) { +#if ENABLE(DRAG_SUPPORT) if (m_mouseDownMayStartDrag && !m_mouseDownWasInSubframe) return false; +#endif subframe->eventHandler()->handleMouseMoveEvent(mev.event(), hoveredNode); return true; } @@ -91,6 +95,7 @@ bool EventHandler::eventActivatedView(const PlatformMouseEvent& event) const return event.didActivateWebView(); } +#if ENABLE(DRAG_SUPPORT) PassRefPtr<Clipboard> EventHandler::createDraggingClipboard() const { #if OS(WINCE) @@ -101,6 +106,7 @@ PassRefPtr<Clipboard> EventHandler::createDraggingClipboard() const return ClipboardWin::create(Clipboard::DragAndDrop, dataObject.get(), ClipboardWritable, m_frame); #endif } +#endif void EventHandler::focusDocumentView() { |