summaryrefslogtreecommitdiff
path: root/Source/WebKit/chromium/src/WebViewImpl.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2012-10-17 16:21:14 +0200
committerSimon Hausmann <simon.hausmann@digia.com>2012-10-17 16:21:14 +0200
commit8995b83bcbfbb68245f779b64e5517627c6cc6ea (patch)
tree17985605dab9263cc2444bd4d45f189e142cca7c /Source/WebKit/chromium/src/WebViewImpl.cpp
parentb9c9652036d5e9f1e29c574f40bc73a35c81ace6 (diff)
downloadqtwebkit-8995b83bcbfbb68245f779b64e5517627c6cc6ea.tar.gz
Imported WebKit commit cf4f8fc6f19b0629f51860cb2d4b25e139d07e00 (http://svn.webkit.org/repository/webkit/trunk@131592)
New snapshot that includes the build fixes for Mac OS X 10.6 and earlier as well as the previously cherry-picked changes
Diffstat (limited to 'Source/WebKit/chromium/src/WebViewImpl.cpp')
-rw-r--r--Source/WebKit/chromium/src/WebViewImpl.cpp400
1 files changed, 250 insertions, 150 deletions
diff --git a/Source/WebKit/chromium/src/WebViewImpl.cpp b/Source/WebKit/chromium/src/WebViewImpl.cpp
index 261f7c357..d6bf94b96 100644
--- a/Source/WebKit/chromium/src/WebViewImpl.cpp
+++ b/Source/WebKit/chromium/src/WebViewImpl.cpp
@@ -92,7 +92,6 @@
#include "PageGroupLoadDeferrer.h"
#include "PagePopupClient.h"
#include "PageWidgetDelegate.h"
-#include "Pasteboard.h"
#include "PlatformContextSkia.h"
#include "PlatformKeyboardEvent.h"
#include "PlatformMouseEvent.h"
@@ -192,13 +191,19 @@ using namespace std;
// (such as due to a double tap gesture or find in page etc.). These are
// experimentally determined.
static const int touchPointPadding = 32;
+static const int nonUserInitiatedPointPadding = 11;
static const float minScaleDifference = 0.01f;
static const float doubleTapZoomContentDefaultMargin = 5;
static const float doubleTapZoomContentMinimumMargin = 2;
static const double doubleTapZoomAnimationDurationInSeconds = 0.25;
+static const float doubleTapZoomAlreadyLegibleRatio = 1.2f;
// Constants for zooming in on a focused text field.
static const double scrollAndScaleAnimationDurationInSeconds = 0.2;
+static const int minReadableCaretHeight = 18;
+static const float minScaleChangeToTriggerZoom = 1.05f;
+static const float leftBoxRatio = 0.3f;
+static const int caretPadding = 10;
namespace WebKit {
@@ -209,8 +214,8 @@ namespace WebKit {
const double WebView::textSizeMultiplierRatio = 1.2;
const double WebView::minTextSizeMultiplier = 0.5;
const double WebView::maxTextSizeMultiplier = 3.0;
-const float WebView::minPageScaleFactor = 0.25;
-const float WebView::maxPageScaleFactor = 4.0;
+const float WebView::minPageScaleFactor = 0.25f;
+const float WebView::maxPageScaleFactor = 4.0f;
// The group name identifies a namespace of pages. Page group is used on PLATFORM(MAC)
@@ -392,6 +397,8 @@ WebViewImpl::WebViewImpl(WebViewClient* client)
, m_ignoreViewportTagMaximumScale(false)
, m_pageScaleFactorIsSet(false)
, m_savedPageScaleFactor(0)
+ , m_doubleTapZoomInEffect(false)
+ , m_shouldUseDoubleTapTimeZero(false)
, m_contextMenuAllowed(false)
, m_doingDragAndDrop(false)
, m_ignoreInputEvents(false)
@@ -622,39 +629,6 @@ void WebViewImpl::mouseContextMenu(const WebMouseEvent& event)
void WebViewImpl::handleMouseUp(Frame& mainFrame, const WebMouseEvent& event)
{
-#if OS(UNIX) && !OS(DARWIN)
- // If the event was a middle click, attempt to copy text into the focused
- // frame. We execute this before we let the page have a go at the event
- // because the page may change what is focused during in its event handler.
- //
- // This code is in the mouse up handler. There is some debate about putting
- // this here, as opposed to the mouse down handler.
- // xterm: pastes on up.
- // GTK: pastes on down.
- // Firefox: pastes on up.
- // Midori: couldn't paste at all with 0.1.2
- //
- // There is something of a webcompat angle to this well, as highlighted by
- // crbug.com/14608. Pages can clear text boxes 'onclick' and, if we paste on
- // down then the text is pasted just before the onclick handler runs and
- // clears the text box. So it's important this happens after the
- // handleMouseReleaseEvent() earlier in this function
- if (event.button == WebMouseEvent::ButtonMiddle) {
- Frame* focused = focusedWebCoreFrame();
- FrameView* view = m_page->mainFrame()->view();
- IntPoint clickPoint(m_lastMouseDownPoint.x, m_lastMouseDownPoint.y);
- IntPoint contentPoint = view->windowToContents(clickPoint);
- HitTestResult hitTestResult = focused->eventHandler()->hitTestResultAtPoint(contentPoint, false, false, ShouldHitTestScrollbars);
- // We don't want to send a paste when middle clicking a scroll bar or a
- // link (which will navigate later in the code). The main scrollbars
- // have to be handled separately.
- if (!hitTestResult.scrollbar() && !hitTestResult.isLiveLink() && focused && !view->scrollbarAtPoint(clickPoint)) {
- Editor* editor = focused->editor();
- editor->command(AtomicString("PasteGlobalSelection")).execute();
- }
- }
-#endif
-
PageWidgetEventHandler::handleMouseUp(mainFrame, event);
#if OS(WINDOWS)
@@ -689,6 +663,29 @@ void WebViewImpl::scrollBy(const WebCore::IntPoint& delta)
bool WebViewImpl::handleGestureEvent(const WebGestureEvent& event)
{
bool eventSwallowed = false;
+
+ // Handle link highlighting outside the main switch to avoid getting lost in the
+ // complicated set of cases handled below.
+ switch (event.type) {
+ case WebInputEvent::GestureTapDown:
+ // Queue a highlight animation, then hand off to regular handler.
+#if OS(LINUX)
+ if (settingsImpl()->gestureTapHighlightEnabled())
+ enableTouchHighlight(IntPoint(event.x, event.y));
+#endif
+ break;
+ case WebInputEvent::GestureTapCancel:
+ if (m_linkHighlight)
+ m_linkHighlight->startHighlightAnimationIfNeeded();
+ break;
+ case WebInputEvent::GestureTap:
+ // If a link highlight is active, kill it.
+ m_linkHighlight.clear();
+ break;
+ default:
+ break;
+ }
+
switch (event.type) {
case WebInputEvent::GestureFlingStart: {
m_client->cancelScheduledContentIntents();
@@ -710,7 +707,7 @@ bool WebViewImpl::handleGestureEvent(const WebGestureEvent& event)
break;
case WebInputEvent::GestureTap: {
m_client->cancelScheduledContentIntents();
- if (detectContentOnTouch(WebPoint(event.x, event.y), event.type)) {
+ if (detectContentOnTouch(WebPoint(event.x, event.y))) {
eventSwallowed = true;
break;
}
@@ -745,37 +742,42 @@ bool WebViewImpl::handleGestureEvent(const WebGestureEvent& event)
break;
}
- case WebInputEvent::GestureTwoFingerTap:
- case WebInputEvent::GestureLongPress: {
+ case WebInputEvent::GestureTwoFingerTap: {
if (!mainFrameImpl() || !mainFrameImpl()->frameView())
break;
- m_client->cancelScheduledContentIntents();
- if (detectContentOnTouch(WebPoint(event.x, event.y), event.type)) {
- eventSwallowed = true;
+ m_page->contextMenuController()->clearContextMenu();
+ m_contextMenuAllowed = true;
+ PlatformGestureEventBuilder platformEvent(mainFrameImpl()->frameView(), event);
+ eventSwallowed = mainFrameImpl()->frame()->eventHandler()->sendContextMenuEventForGesture(platformEvent);
+ m_contextMenuAllowed = false;
+
+ break;
+ }
+ case WebInputEvent::GestureLongPress: {
+ if (!mainFrameImpl() || !mainFrameImpl()->frameView())
break;
- }
+ m_client->cancelScheduledContentIntents();
m_page->contextMenuController()->clearContextMenu();
m_contextMenuAllowed = true;
PlatformGestureEventBuilder platformEvent(mainFrameImpl()->frameView(), event);
- eventSwallowed = mainFrameImpl()->frame()->eventHandler()->sendContextMenuEventForGesture(platformEvent);
+ eventSwallowed = mainFrameImpl()->frame()->eventHandler()->handleGestureEvent(platformEvent);
m_contextMenuAllowed = false;
break;
}
case WebInputEvent::GestureTapDown: {
m_client->cancelScheduledContentIntents();
- // Queue a highlight animation, then hand off to regular handler.
-#if OS(LINUX)
- if (settingsImpl()->gestureTapHighlightEnabled())
- enableTouchHighlight(IntPoint(event.x, event.y));
-#endif
PlatformGestureEventBuilder platformEvent(mainFrameImpl()->frameView(), event);
eventSwallowed = mainFrameImpl()->frame()->eventHandler()->handleGestureEvent(platformEvent);
break;
}
case WebInputEvent::GestureDoubleTap:
+ m_client->cancelScheduledContentIntents();
+ animateZoomAroundPoint(WebPoint(event.x, event.y), DoubleTap);
+ eventSwallowed = true;
+ break;
case WebInputEvent::GestureScrollBegin:
case WebInputEvent::GesturePinchBegin:
m_client->cancelScheduledContentIntents();
@@ -815,17 +817,15 @@ void WebViewImpl::renderingStats(WebRenderingStats& stats) const
void WebViewImpl::startPageScaleAnimation(const IntPoint& targetPosition, bool useAnchor, float newScale, double durationInSeconds)
{
- if (!m_layerTreeView)
- return;
-
- IntPoint clampedPoint = targetPosition;
+ WebPoint clampedPoint = targetPosition;
if (!useAnchor)
clampedPoint = clampOffsetAtScale(targetPosition, newScale);
-
- if (!durationInSeconds && !useAnchor) {
+ if ((!durationInSeconds && !useAnchor) || m_shouldUseDoubleTapTimeZero) {
setPageScaleFactor(newScale, clampedPoint);
return;
}
+ if (!m_layerTreeView)
+ return;
m_layerTreeView->startPageScaleAnimation(targetPosition, useAnchor, newScale, durationInSeconds);
}
@@ -1075,24 +1075,37 @@ WebRect WebViewImpl::widenRectWithinPageBounds(const WebRect& source, int target
return WebRect(newX, source.y, newWidth, source.height);
}
-void WebViewImpl::computeScaleAndScrollForHitRect(const WebRect& hitRect, AutoZoomType zoomType, float& scale, WebPoint& scroll)
+void WebViewImpl::shouldUseAnimateDoubleTapTimeZeroForTesting(bool setToZero)
+{
+ m_shouldUseDoubleTapTimeZero = setToZero;
+}
+
+void WebViewImpl::computeScaleAndScrollForHitRect(const WebRect& hitRect, AutoZoomType zoomType, float& scale, WebPoint& scroll, bool& isAnchor)
{
scale = pageScaleFactor();
scroll.x = scroll.y = 0;
WebRect targetRect = hitRect;
+ // Padding only depends on page scale when triggered by manually tapping
+ int padding = (zoomType == DoubleTap) ? touchPointPadding : nonUserInitiatedPointPadding;
if (targetRect.isEmpty())
- targetRect.width = targetRect.height = touchPointPadding;
-
+ targetRect.width = targetRect.height = padding;
WebRect rect = computeBlockBounds(targetRect, zoomType);
+ if (zoomType == FindInPage && rect.isEmpty()) {
+ // Keep current scale (no need to scroll as x,y will normally already
+ // be visible). FIXME: Revisit this if it isn't always true.
+ return;
+ }
- const float overviewScale = m_minimumPageScaleFactor;
bool scaleUnchanged = true;
if (!rect.isEmpty()) {
// Pages should be as legible as on desktop when at dpi scale, so no
// need to zoom in further when automatically determining zoom level
// (after double tap, find in page, etc), though the user should still
// be allowed to manually pinch zoom in further if they desire.
- const float maxScale = deviceScaleFactor();
+ const float defaultScaleWhenAlreadyLegible = m_minimumPageScaleFactor * doubleTapZoomAlreadyLegibleRatio;
+ float legibleScale = deviceScaleFactor();
+ if (legibleScale < defaultScaleWhenAlreadyLegible)
+ legibleScale = (scale == m_minimumPageScaleFactor) ? defaultScaleWhenAlreadyLegible : m_minimumPageScaleFactor;
const float defaultMargin = doubleTapZoomContentDefaultMargin * deviceScaleFactor();
const float minimumMargin = doubleTapZoomContentMinimumMargin * deviceScaleFactor();
@@ -1105,55 +1118,61 @@ void WebViewImpl::computeScaleAndScrollForHitRect(const WebRect& hitRect, AutoZo
rect = widenRectWithinPageBounds(rect,
static_cast<int>(defaultMargin * rect.width / m_size.width),
static_cast<int>(minimumMargin * rect.width / m_size.width));
-
// Fit block to screen, respecting limits.
scale *= static_cast<float>(m_size.width) / rect.width;
- scale = min(scale, maxScale);
+ scale = min(scale, legibleScale);
scale = clampPageScaleFactorToLimits(scale);
scaleUnchanged = fabs(pageScaleFactor() - scale) < minScaleDifference;
}
- if (zoomType == DoubleTap) {
- if (rect.isEmpty() || scaleUnchanged) {
- // Zoom out to overview mode.
- if (overviewScale)
- scale = overviewScale;
- return;
- }
- } else if (rect.isEmpty()) {
- // Keep current scale (no need to scroll as x,y will normally already
- // be visible). FIXME: Revisit this if it isn't always true.
- return;
- }
-
- // FIXME: If this is being called for auto zoom during find in page,
- // then if the user manually zooms in it'd be nice to preserve the relative
- // increase in zoom they caused (if they zoom out then it's ok to zoom
- // them back in again). This isn't compatible with our current double-tap
- // zoom strategy (fitting the containing block to the screen) though.
-
- float screenHeight = m_size.height / scale * pageScaleFactor();
- float screenWidth = m_size.width / scale * pageScaleFactor();
-
- // Scroll to vertically align the block.
- if (rect.height < screenHeight) {
- // Vertically center short blocks.
- rect.y -= 0.5 * (screenHeight - rect.height);
+ if (zoomType == DoubleTap && (rect.isEmpty() || scaleUnchanged || m_doubleTapZoomInEffect)) {
+ // Zoom out to minimum scale.
+ scale = m_minimumPageScaleFactor;
+ scroll = WebPoint(hitRect.x, hitRect.y);
+ isAnchor = true;
+ m_doubleTapZoomInEffect = false;
} else {
- // Ensure position we're zooming to (+ padding) isn't off the bottom of
- // the screen.
- rect.y = max<float>(rect.y, hitRect.y + touchPointPadding - screenHeight);
- } // Otherwise top align the block.
-
- // Do the same thing for horizontal alignment.
- if (rect.width < screenWidth)
- rect.x -= 0.5 * (screenWidth - rect.width);
- else
- rect.x = max<float>(rect.x, hitRect.x + touchPointPadding - screenWidth);
+ if (zoomType == DoubleTap && scale != m_minimumPageScaleFactor)
+ m_doubleTapZoomInEffect = true;
+ else
+ m_doubleTapZoomInEffect = false;
+ // FIXME: If this is being called for auto zoom during find in page,
+ // then if the user manually zooms in it'd be nice to preserve the
+ // relative increase in zoom they caused (if they zoom out then it's ok
+ // to zoom them back in again). This isn't compatible with our current
+ // double-tap zoom strategy (fitting the containing block to the screen)
+ // though.
+
+ float screenHeight = m_size.height / scale * pageScaleFactor();
+ float screenWidth = m_size.width / scale * pageScaleFactor();
+
+ // Scroll to vertically align the block.
+ if (rect.height < screenHeight) {
+ // Vertically center short blocks.
+ rect.y -= 0.5 * (screenHeight - rect.height);
+ } else {
+ // Ensure position we're zooming to (+ padding) isn't off the bottom of
+ // the screen.
+ rect.y = max<float>(rect.y, hitRect.y + padding - screenHeight);
+ } // Otherwise top align the block.
+
+ // Do the same thing for horizontal alignment.
+ if (rect.width < screenWidth)
+ rect.x -= 0.5 * (screenWidth - rect.width);
+ else
+ rect.x = max<float>(rect.x, hitRect.x + padding - screenWidth);
+ scroll.x = rect.x;
+ scroll.y = rect.y;
+ isAnchor = false;
+ }
- scroll.x = rect.x;
- scroll.y = rect.y;
+ scale = clampPageScaleFactorToLimits(scale);
+ scroll = mainFrameImpl()->frameView()->windowToContents(scroll);
+ float scaleDelta = scale / pageScaleFactor();
+ scroll = WebPoint(scroll.x * scaleDelta, scroll.y * scaleDelta);
+ if (!isAnchor)
+ scroll = clampOffsetAtScale(scroll, scale);
}
static bool highlightConditions(Node* node)
@@ -1179,10 +1198,10 @@ Node* WebViewImpl::bestTouchLinkNode(IntPoint touchEventLocation)
while (bestTouchNode && !highlightConditions(bestTouchNode))
bestTouchNode = bestTouchNode->parentNode();
- // If the document has click handlers installed, we don't want to default to applying the highlight to the entire RenderView, or the
- // entire body. Also, if the node has non-auto Z-index, we cannot be sure of it's ordering with respect to other possible target nodes.
+ // If the document/body have click handlers installed, we don't want to default to applying the highlight to the entire RenderView, or the
+ // entire body.
RenderObject* touchNodeRenderer = bestTouchNode ? bestTouchNode->renderer() : 0;
- if (bestTouchNode && (!touchNodeRenderer || touchNodeRenderer->isRenderView() || touchNodeRenderer->isBody() || !touchNodeRenderer->style()->hasAutoZIndex()))
+ if (bestTouchNode && (!touchNodeRenderer || touchNodeRenderer->isRenderView() || touchNodeRenderer->isBody()))
return 0;
return bestTouchNode;
@@ -1206,7 +1225,6 @@ void WebViewImpl::enableTouchHighlight(IntPoint touchEventLocation)
return;
m_linkHighlight = LinkHighlight::create(touchNode, this);
- m_linkHighlight->startHighlightAnimation();
}
#endif
@@ -1219,11 +1237,13 @@ void WebViewImpl::animateZoomAroundPoint(const IntPoint& point, AutoZoomType zoo
float scale;
WebPoint scroll;
- computeScaleAndScrollForHitRect(WebRect(point.x(), point.y(), 0, 0), zoomType, scale, scroll);
+ bool isAnchor;
+ WebPoint webPoint = point;
+ computeScaleAndScrollForHitRect(WebRect(webPoint.x, webPoint.y, 0, 0), zoomType, scale, scroll, isAnchor);
bool isDoubleTap = (zoomType == DoubleTap);
- double durationInSeconds = isDoubleTap ? doubleTapZoomAnimationDurationInSeconds : 0;
- startPageScaleAnimation(scroll, isDoubleTap, scale, durationInSeconds);
+ double durationInSeconds = (isDoubleTap && !m_shouldUseDoubleTapTimeZero) ? doubleTapZoomAnimationDurationInSeconds : 0;
+ startPageScaleAnimation(scroll, isAnchor, scale, durationInSeconds);
#endif
}
@@ -1555,9 +1575,9 @@ void WebViewImpl::resize(const WebSize& newSize)
#endif
WebDevToolsAgentPrivate* agentPrivate = devToolsAgentPrivate();
- if (agentPrivate && agentPrivate->metricsOverridden())
- agentPrivate->webViewResized();
- else {
+ if (agentPrivate)
+ agentPrivate->webViewResized(newSize);
+ if (!agentPrivate || !agentPrivate->metricsOverridden()) {
WebFrameImpl* webFrame = mainFrameImpl();
if (webFrame->frameView())
webFrame->frameView()->resize(newSize.width, newSize.height);
@@ -1723,13 +1743,6 @@ void WebViewImpl::updateAnimations(double monotonicFrameBeginTime)
#if ENABLE(REQUEST_ANIMATION_FRAME)
TRACE_EVENT0("webkit", "WebViewImpl::updateAnimations");
- WebFrameImpl* webframe = mainFrameImpl();
- if (!webframe)
- return;
- FrameView* view = webframe->frameView();
- if (!view)
- return;
-
// Create synthetic wheel events as necessary for fling.
if (m_gestureAnimation) {
if (m_gestureAnimation->animate(monotonicFrameBeginTime))
@@ -1738,6 +1751,9 @@ void WebViewImpl::updateAnimations(double monotonicFrameBeginTime)
m_gestureAnimation.clear();
}
+ if (!m_page)
+ return;
+
PageWidgetDelegate::animate(m_page.get(), monotonicFrameBeginTime);
#endif
}
@@ -2628,8 +2644,78 @@ void WebViewImpl::scrollFocusedNodeIntoRect(const WebRect& rect)
Node* focusedNode = focusedWebCoreNode();
if (!frame || !frame->view() || !focusedNode || !focusedNode->isElementNode())
return;
- Element* elementNode = static_cast<Element*>(focusedNode);
- frame->view()->scrollElementToRect(elementNode, IntRect(rect.x, rect.y, rect.width, rect.height));
+
+ if (!m_webSettings->autoZoomFocusedNodeToLegibleScale()) {
+ Element* elementNode = static_cast<Element*>(focusedNode);
+ frame->view()->scrollElementToRect(elementNode, IntRect(rect.x, rect.y, rect.width, rect.height));
+ return;
+ }
+
+#if ENABLE(GESTURE_EVENTS)
+ focusedNode->document()->updateLayoutIgnorePendingStylesheets();
+
+ // 'caret' is rect encompassing the blinking cursor.
+ IntRect textboxRect = focusedNode->document()->view()->contentsToWindow(pixelSnappedIntRect(focusedNode->Node::boundingBox()));
+ WebRect caret, end;
+ selectionBounds(caret, end);
+
+ // Pick a scale which is reasonably readable. This is the scale at which
+ // the caret height will become minReadableCaretHeight (adjusted for dpi
+ // and font scale factor).
+ float targetScale = deviceScaleFactor();
+#if ENABLE(TEXT_AUTOSIZING)
+ if (page() && page()->settings())
+ targetScale *= page()->settings()->textAutosizingFontScaleFactor();
+#endif
+ const float newScale = clampPageScaleFactorToLimits(pageScaleFactor() * minReadableCaretHeight * targetScale / caret.height);
+ const float deltaScale = newScale / pageScaleFactor();
+
+ // Convert the rects to absolute space in the new scale.
+ IntRect textboxRectInDocumentCoordinates = textboxRect;
+ textboxRectInDocumentCoordinates.move(mainFrame()->scrollOffset());
+ textboxRectInDocumentCoordinates.scale(deltaScale);
+ IntRect caretInDocumentCoordinates = caret;
+ caretInDocumentCoordinates.move(mainFrame()->scrollOffset());
+ caretInDocumentCoordinates.scale(deltaScale);
+
+ IntPoint newOffset;
+ if (textboxRectInDocumentCoordinates.width() <= m_size.width) {
+ // Field is narrower than screen. Try to leave padding on left so field's
+ // label is visible, but it's more important to ensure entire field is
+ // onscreen.
+ int idealLeftPadding = m_size.width * leftBoxRatio;
+ int maxLeftPaddingKeepingBoxOnscreen = m_size.width - textboxRectInDocumentCoordinates.width();
+ newOffset.setX(textboxRectInDocumentCoordinates.x() - min<int>(idealLeftPadding, maxLeftPaddingKeepingBoxOnscreen));
+ } else {
+ // Field is wider than screen. Try to left-align field, unless caret would
+ // be offscreen, in which case right-align the caret.
+ newOffset.setX(max<int>(textboxRectInDocumentCoordinates.x(), caretInDocumentCoordinates.x() + caretInDocumentCoordinates.width() + caretPadding - m_size.width));
+ }
+ if (textboxRectInDocumentCoordinates.height() <= m_size.height) {
+ // Field is shorter than screen. Vertically center it.
+ newOffset.setY(textboxRectInDocumentCoordinates.y() - (m_size.height - textboxRectInDocumentCoordinates.height()) / 2);
+ } else {
+ // Field is taller than screen. Try to top align field, unless caret would
+ // be offscreen, in which case bottom-align the caret.
+ newOffset.setY(max<int>(textboxRectInDocumentCoordinates.y(), caretInDocumentCoordinates.y() + caretInDocumentCoordinates.height() + caretPadding - m_size.height));
+ }
+
+ bool needAnimation = false;
+ // If we are at less than the target zoom level, zoom in.
+ if (deltaScale > minScaleChangeToTriggerZoom)
+ needAnimation = true;
+ // If the caret is offscreen, then animate.
+ IntRect sizeRect(0, 0, m_size.width, m_size.height);
+ if (!sizeRect.contains(caret))
+ needAnimation = true;
+ // If the box is partially offscreen and it's possible to bring it fully
+ // onscreen, then animate.
+ if (sizeRect.contains(textboxRectInDocumentCoordinates.width(), textboxRectInDocumentCoordinates.height()) && !sizeRect.contains(textboxRect))
+ needAnimation = true;
+
+ if (needAnimation)
+ startPageScaleAnimation(newOffset, false, newScale, scrollAndScaleAnimationDurationInSeconds);
+#endif
}
void WebViewImpl::advanceFocus(bool reverse)
@@ -2756,8 +2842,20 @@ void WebViewImpl::setPageScaleFactor(float scaleFactor, const WebPoint& origin)
}
scaleFactor = clampPageScaleFactorToLimits(scaleFactor);
- WebPoint clampedOrigin = clampOffsetAtScale(origin, scaleFactor);
- page()->setPageScaleFactor(scaleFactor, clampedOrigin);
+ WebPoint scrollOffset;
+ if (!m_page->settings()->applyPageScaleFactorInCompositor()) {
+ // If page scale is not applied in the compositor, then the scroll offsets should
+ // be modified by the scale factor.
+ scrollOffset = clampOffsetAtScale(origin, scaleFactor);
+ } else {
+ IntPoint offset = origin;
+ WebSize contentSize = mainFrame()->contentsSize();
+ offset.shrunkTo(IntPoint(contentSize.width - m_size.width, contentSize.height - m_size.height));
+ offset.clampNegativeToZero();
+ scrollOffset = offset;
+ }
+
+ page()->setPageScaleFactor(scaleFactor, scrollOffset);
m_pageScaleFactorIsSet = true;
}
@@ -3195,6 +3293,8 @@ void WebViewImpl::sendResizeEventAndRepaint()
m_client->didInvalidateRect(damagedRect);
}
}
+ if (m_pageOverlays)
+ m_pageOverlays->update();
}
void WebViewImpl::configureAutoResizeMode()
@@ -3412,13 +3512,13 @@ void WebView::addUserScript(const WebString& sourceCode,
WebView::UserScriptInjectAt injectAt,
WebView::UserContentInjectIn injectIn)
{
- OwnPtr<Vector<String> > patterns = adoptPtr(new Vector<String>);
+ Vector<String> patterns;
for (size_t i = 0; i < patternsIn.size(); ++i)
- patterns->append(patternsIn[i]);
+ patterns.append(patternsIn[i]);
PageGroup* pageGroup = PageGroup::pageGroup(pageGroupName);
RefPtr<DOMWrapperWorld> world(DOMWrapperWorld::createUninitializedWorld());
- pageGroup->addUserScriptToWorld(world.get(), sourceCode, WebURL(), patterns.release(), nullptr,
+ pageGroup->addUserScriptToWorld(world.get(), sourceCode, WebURL(), patterns, Vector<String>(),
static_cast<UserScriptInjectionTime>(injectAt),
static_cast<UserContentInjectedFrames>(injectIn));
}
@@ -3428,9 +3528,9 @@ void WebView::addUserStyleSheet(const WebString& sourceCode,
WebView::UserContentInjectIn injectIn,
WebView::UserStyleInjectionTime injectionTime)
{
- OwnPtr<Vector<String> > patterns = adoptPtr(new Vector<String>);
+ Vector<String> patterns;
for (size_t i = 0; i < patternsIn.size(); ++i)
- patterns->append(patternsIn[i]);
+ patterns.append(patternsIn[i]);
PageGroup* pageGroup = PageGroup::pageGroup(pageGroupName);
RefPtr<DOMWrapperWorld> world(DOMWrapperWorld::createUninitializedWorld());
@@ -3439,7 +3539,7 @@ void WebView::addUserStyleSheet(const WebString& sourceCode,
// callers specify this though, since in other cases the caller will probably want "user" level.
//
// FIXME: It would be nice to populate the URL correctly, instead of passing an empty URL.
- pageGroup->addUserStyleSheetToWorld(world.get(), sourceCode, WebURL(), patterns.release(), nullptr,
+ pageGroup->addUserStyleSheetToWorld(world.get(), sourceCode, WebURL(), patterns, Vector<String>(),
static_cast<UserContentInjectedFrames>(injectIn),
UserStyleAuthorLevel,
static_cast<WebCore::UserStyleInjectionTime>(injectionTime));
@@ -3462,8 +3562,10 @@ void WebViewImpl::didCommitLoad(bool* isNewNavigation, bool isNavigationWithinPa
m_newNavigationLoader = 0;
#endif
m_observedNewNavigation = false;
- if (*isNewNavigation && !isNavigationWithinPage)
+ if (*isNewNavigation && !isNavigationWithinPage) {
m_pageScaleFactorIsSet = false;
+ m_doubleTapZoomInEffect = false;
+ }
// Make sure link highlight from previous page is cleared.
m_linkHighlight.clear();
@@ -3757,6 +3859,8 @@ void WebViewImpl::paintRootLayer(GraphicsContext& context, const IntRect& conten
if (!page())
return;
FrameView* view = page()->mainFrame()->view();
+ if (context.platformContext())
+ context.platformContext()->setDeviceScaleFactor(page()->deviceScaleFactor());
view->paintContents(&context, contentRect);
double paintEnd = currentTime();
double pixelsPerSec = (contentRect.width() * contentRect.height()) / (paintEnd - paintStart);
@@ -3776,8 +3880,9 @@ void WebViewImpl::setIsAcceleratedCompositingActive(bool active)
if (!active) {
m_isAcceleratedCompositingActive = false;
// We need to finish all GL rendering before sending didDeactivateCompositor() to prevent
- // flickering when compositing turns off.
- if (m_layerTreeView)
+ // flickering when compositing turns off. This is only necessary if we're not in
+ // force-compositing-mode.
+ if (m_layerTreeView && !page()->settings()->forceCompositingMode())
m_layerTreeView->finishAllRendering();
m_client->didDeactivateCompositor();
} else if (m_layerTreeView) {
@@ -3921,15 +4026,22 @@ void WebViewImpl::applyScrollAndScale(const WebSize& scrollDelta, float pageScal
mainFrameImpl()->frameView()->scrollBy(scrollDelta);
} else {
// The page scale changed, so apply a scale and scroll in a single
- // operation. The old scroll offset (and passed-in delta) are
- // in the old coordinate space, so we first need to multiply them
- // by the page scale delta.
+ // operation.
WebSize scrollOffset = mainFrame()->scrollOffset();
scrollOffset.width += scrollDelta.width;
scrollOffset.height += scrollDelta.height;
- WebPoint scaledScrollOffset(scrollOffset.width * pageScaleDelta,
- scrollOffset.height * pageScaleDelta);
- setPageScaleFactor(pageScaleFactor() * pageScaleDelta, scaledScrollOffset);
+
+ WebPoint scrollPoint(scrollOffset.width, scrollOffset.height);
+ if (!m_page->settings()->applyPageScaleFactorInCompositor()) {
+ // The old scroll offset (and passed-in delta) are in the old
+ // coordinate space, so we first need to multiply them by the page
+ // scale delta.
+ scrollPoint.x = scrollPoint.x * pageScaleDelta;
+ scrollPoint.y = scrollPoint.y * pageScaleDelta;
+ }
+
+ setPageScaleFactor(pageScaleFactor() * pageScaleDelta, scrollPoint);
+ m_doubleTapZoomInEffect = false;
}
}
@@ -4020,12 +4132,8 @@ void WebViewImpl::selectAutofillSuggestionAtIndex(unsigned listIndex)
m_autofillPopupClient->valueChanged(listIndex);
}
-bool WebViewImpl::detectContentOnTouch(const WebPoint& position, WebInputEvent::Type touchType)
+bool WebViewImpl::detectContentOnTouch(const WebPoint& position)
{
- ASSERT(touchType == WebInputEvent::GestureTap
- || touchType == WebInputEvent::GestureTwoFingerTap
- || touchType == WebInputEvent::GestureLongPress);
-
HitTestResult touchHit = hitTestResultForWindowPos(position);
if (touchHit.isContentEditable())
@@ -4038,22 +4146,14 @@ bool WebViewImpl::detectContentOnTouch(const WebPoint& position, WebInputEvent::
// Ignore when tapping on links or nodes listening to click events, unless the click event is on the
// body element, in which case it's unlikely that the original node itself was intended to be clickable.
for (; node && !node->hasTagName(HTMLNames::bodyTag); node = node->parentNode()) {
- if (node->isLink() || (touchType == WebInputEvent::GestureTap
- && (node->willRespondToTouchEvents() || node->willRespondToMouseClickEvents()))) {
+ if (node->isLink() || node->willRespondToTouchEvents() || node->willRespondToMouseClickEvents())
return false;
- }
}
WebContentDetectionResult content = m_client->detectContentAround(touchHit);
if (!content.isValid())
return false;
- if (touchType != WebInputEvent::GestureTap) {
- // Select the detected content as a block.
- focusedFrame()->selectRange(content.range());
- return true;
- }
-
m_client->scheduleContentIntent(content.intent());
return true;
}