Changeset 168744 in webkit
- Timestamp:
- May 13, 2014, 3:13:03 PM (11 years ago)
- Location:
- trunk/Source
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r168742 r168744 1 2014-05-13 Enrica Casucci <enrica@apple.com> 2 3 REGRESSION (WebKit2): Zooming to text field leaves it partially hidden by the form assistant. 4 https://bugs.webkit.org/show_bug.cgi?id=132879 5 <rdar://problem/16318049> 6 7 Reviewed by Benjamin Poulain. 8 9 Adding some exports. The fix to setScrollPosition is to avoid clamping the scroll 10 position when using delegate scrolling. 11 12 * WebCore.exp.in: 13 * platform/ScrollView.cpp: 14 (WebCore::ScrollView::setScrollPosition): 15 1 16 2014-05-13 Brady Eidson <beidson@apple.com> 2 17 -
trunk/Source/WebCore/WebCore.exp.in
r168680 r168744 1551 1551 __ZNK7WebCore11RenderLayer24needsCompositedScrollingEv 1552 1552 __ZNK7WebCore11RenderStyle11fontMetricsEv 1553 __ZNK7WebCore11RenderStyle15fontDescriptionEv 1553 1554 __ZNK7WebCore11RenderStyle21visitedDependentColorEi 1554 1555 __ZNK7WebCore11RenderStyle4fontEv -
trunk/Source/WebCore/platform/ScrollView.cpp
r168458 r168744 498 498 } 499 499 500 IntPoint newScrollPosition = adjustScrollPositionWithinRange(scrollPoint);500 IntPoint newScrollPosition = !delegatesScrolling() ? adjustScrollPositionWithinRange(scrollPoint) : scrollPoint; 501 501 502 502 if ((!delegatesScrolling() || !inProgrammaticScroll()) && newScrollPosition == scrollPosition()) -
trunk/Source/WebKit2/ChangeLog
r168740 r168744 1 2014-05-13 Enrica Casucci <enrica@apple.com> 2 3 REGRESSION (WebKit2): Zooming to text field leaves it partially hidden by the form assistant. 4 https://bugs.webkit.org/show_bug.cgi?id=132879 5 <rdar://problem/16318049> 6 7 Reviewed by Benjamin Poulain. 8 9 Adds the heuristics to zoom and scroll to ensure the element being focused 10 is fully visible and its text readable. 11 12 * Shared/AssistedNodeInformation.cpp: 13 (WebKit::AssistedNodeInformation::encode): 14 (WebKit::AssistedNodeInformation::decode): 15 * Shared/AssistedNodeInformation.h: 16 (WebKit::AssistedNodeInformation::AssistedNodeInformation): 17 * UIProcess/API/Cocoa/WKWebView.mm: 18 (-[WKWebView _zoomToFocusRect:WebCore::selectionRect:WebCore::fontSize:minimumScale:maximumScale:allowUserScaling:forceScroll:]): 19 (-[WKWebView _keyboardChangedWithInfo:adjustScrollView:]): 20 * UIProcess/API/Cocoa/WKWebViewInternal.h: 21 * UIProcess/ios/WKContentView.h: 22 * UIProcess/ios/WKContentView.mm: 23 (-[WKContentView _zoomToFocusRect:selectionRect:fontSize:minimumScale:maximumScale:allowUserScaling:forceScroll:]): 24 * UIProcess/ios/WKContentViewInteraction.mm: 25 (-[WKContentView _displayFormNodeInputView]): 26 (-[WKContentView _startAssistingNode:userIsInteracting:userObject:]): 27 * WebProcess/WebPage/ios/WebPageIOS.mm: 28 (WebKit::WebPage::getAssistedNodeInformation): 29 1 30 2014-05-13 Simon Fraser <simon.fraser@apple.com> 2 31 -
trunk/Source/WebKit2/Shared/AssistedNodeInformation.cpp
r165022 r168744 65 65 { 66 66 encoder << elementRect; 67 encoder << selectionRect; 67 68 encoder << minimumScaleFactor; 68 69 encoder << maximumScaleFactor; 70 encoder << nodeFontSize; 69 71 encoder << hasNextNode; 70 72 encoder << hasPreviousNode; … … 77 79 encoder << isMultiSelect; 78 80 encoder << isReadOnly; 81 encoder << allowsUserScaling; 79 82 encoder << value; 80 83 encoder << valueAsNumber; … … 87 90 return false; 88 91 92 if (!decoder.decode(result.selectionRect)) 93 return false; 94 89 95 if (!decoder.decode(result.minimumScaleFactor)) 90 96 return false; 91 97 92 98 if (!decoder.decode(result.maximumScaleFactor)) 99 return false; 100 101 if (!decoder.decode(result.nodeFontSize)) 93 102 return false; 94 103 … … 123 132 return false; 124 133 134 if (!decoder.decode(result.allowsUserScaling)) 135 return false; 136 125 137 if (!decoder.decode(result.value)) 126 138 return false; -
trunk/Source/WebKit2/Shared/AssistedNodeInformation.h
r165022 r168744 96 96 : minimumScaleFactor(-INFINITY) 97 97 , maximumScaleFactor(INFINITY) 98 , nodeFontSize(0) 98 99 , hasNextNode(false) 99 100 , hasPreviousNode(false) … … 101 102 , isMultiSelect(false) 102 103 , isReadOnly(false) 104 , allowsUserScaling(false) 103 105 , autocapitalizeType(WebAutocapitalizeTypeDefault) 104 106 , elementType(WKTypeNone) … … 109 111 110 112 WebCore::IntRect elementRect; 113 WebCore::IntRect selectionRect; 111 114 double minimumScaleFactor; 112 115 double maximumScaleFactor; 116 double nodeFontSize; 113 117 bool hasNextNode; 114 118 bool hasPreviousNode; … … 116 120 bool isMultiSelect; 117 121 bool isReadOnly; 122 bool allowsUserScaling; 118 123 WebAutocapitalizeType autocapitalizeType; 119 124 WKInputType elementType; -
trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm
r168689 r168744 84 84 - (CGFloat)getVerticalOverlapForView:(UIView *)view usingKeyboardInfo:(NSDictionary *)info; 85 85 @end 86 87 @interface UIView (UIViewInternal) 88 - (UIViewController *)_viewControllerForAncestor; 89 @end 90 91 @interface UIWindow (UIWindowInternal) 92 - (BOOL)_isHostedInAnotherProcess; 93 @end 94 95 @interface UIViewController (UIViewControllerInternal) 96 - (UIViewController *)_rootAncestorViewController; 97 - (UIViewController *)_viewControllerForSupportedInterfaceOrientations; 98 @end 86 99 #endif 87 100 … … 106 119 CGSize _minimumLayoutSizeOverride; 107 120 CGSize _minimumLayoutSizeOverrideForMinimalUI; 121 CGRect _inputViewBounds; 108 122 109 123 UIEdgeInsets _obscuredInsets; … … 120 134 RetainPtr<UIView> _resizeAnimationView; 121 135 CGFloat _lastAdjustmentForScroller; 122 CGFloat _keyboardVerticalOverlap;123 136 124 137 std::unique_ptr<WebKit::ViewGestureController> _gestureController; … … 617 630 } 618 631 632 // focusedElementRect and selectionRect are both in document coordinates. 633 - (void)_zoomToFocusRect:(WebCore::FloatRect)focusedElementRectInDocumentCoordinates selectionRect:(WebCore::FloatRect)selectionRectInDocumentCoordinates fontSize:(float)fontSize minimumScale:(double)minimumScale maximumScale:(double)maximumScale allowScaling:(BOOL)allowScaling forceScroll:(BOOL)forceScroll 634 { 635 const double WKWebViewStandardFontSize = 16; 636 const double kMinimumHeightToShowContentAboveKeyboard = 106; 637 const CFTimeInterval UIWebFormAnimationDuration = 0.25; 638 const double CaretOffsetFromWindowEdge = 20; 639 640 // Zoom around the element's bounding frame. We use a "standard" size to determine the proper frame. 641 double scale = allowScaling ? std::min(std::max(WKWebViewStandardFontSize / fontSize, minimumScale), maximumScale) : contentZoomScale(self); 642 CGFloat documentWidth = [_contentView bounds].size.width; 643 scale = CGRound(documentWidth * scale) / documentWidth; 644 645 UIWindow *window = [_scrollView window]; 646 647 WebCore::FloatRect focusedElementRectInNewScale = focusedElementRectInDocumentCoordinates; 648 focusedElementRectInNewScale.scale(scale); 649 focusedElementRectInNewScale.moveBy([_contentView frame].origin); 650 651 // Find the portion of the view that is visible on the screen. 652 UIViewController *topViewController = [[[_scrollView _viewControllerForAncestor] _rootAncestorViewController] _viewControllerForSupportedInterfaceOrientations]; 653 UIView *fullScreenView = topViewController.view; 654 if (!fullScreenView) 655 fullScreenView = window; 656 657 CGRect unobscuredScrollViewRectInWebViewCoordinates = UIEdgeInsetsInsetRect([self bounds], _obscuredInsets); 658 CGRect visibleScrollViewBoundsInWebViewCoordinates = CGRectIntersection(unobscuredScrollViewRectInWebViewCoordinates, [fullScreenView convertRect:[fullScreenView bounds] toView:self]); 659 CGRect formAssistantFrameInWebViewCoordinates = [window convertRect:_inputViewBounds toView:self]; 660 CGRect intersectionBetweenScrollViewAndFormAssistant = CGRectIntersection(visibleScrollViewBoundsInWebViewCoordinates, formAssistantFrameInWebViewCoordinates); 661 CGSize visibleSize = visibleScrollViewBoundsInWebViewCoordinates.size; 662 663 CGFloat visibleOffsetFromTop = 0; 664 if (!CGRectIsEmpty(intersectionBetweenScrollViewAndFormAssistant)) { 665 CGFloat heightVisibleAboveFormAssistant = CGRectGetMinY(intersectionBetweenScrollViewAndFormAssistant) - CGRectGetMinY(visibleScrollViewBoundsInWebViewCoordinates); 666 CGFloat heightVisibleBelowFormAssistant = CGRectGetMaxY(visibleScrollViewBoundsInWebViewCoordinates) - CGRectGetMaxY(intersectionBetweenScrollViewAndFormAssistant); 667 668 if (heightVisibleAboveFormAssistant >= kMinimumHeightToShowContentAboveKeyboard || heightVisibleBelowFormAssistant < heightVisibleAboveFormAssistant) 669 visibleSize.height = heightVisibleAboveFormAssistant; 670 else { 671 visibleSize.height = heightVisibleBelowFormAssistant; 672 visibleOffsetFromTop = CGRectGetMaxY(intersectionBetweenScrollViewAndFormAssistant) - CGRectGetMinY(visibleScrollViewBoundsInWebViewCoordinates); 673 } 674 } 675 676 BOOL selectionRectIsNotNull = !selectionRectInDocumentCoordinates.isZero(); 677 if (!forceScroll) { 678 CGRect currentlyVisibleRegionInWebViewCoordinates; 679 currentlyVisibleRegionInWebViewCoordinates.origin = unobscuredScrollViewRectInWebViewCoordinates.origin; 680 currentlyVisibleRegionInWebViewCoordinates.origin.y += visibleOffsetFromTop; 681 currentlyVisibleRegionInWebViewCoordinates.size = visibleSize; 682 683 // Don't bother scrolling if the entire node is already visible, whether or not we got a selectionRect. 684 if (CGRectContainsRect(currentlyVisibleRegionInWebViewCoordinates, [self convertRect:focusedElementRectInDocumentCoordinates fromView:_contentView.get()])) 685 return; 686 687 // Don't bother scrolling if we have a valid selectionRect and it is already visible. 688 if (selectionRectIsNotNull && CGRectContainsRect(currentlyVisibleRegionInWebViewCoordinates, [self convertRect:selectionRectInDocumentCoordinates fromView:_contentView.get()])) 689 return; 690 } 691 692 // We want to zoom to the left/top corner of the DOM node, with as much spacing on all sides as we 693 // can get based on the visible area after zooming (workingFrame). The spacing in either dimension is half the 694 // difference between the size of the DOM node and the size of the visible frame. 695 CGFloat horizontalSpaceInWebViewCoordinates = std::max((visibleSize.width - focusedElementRectInNewScale.width()) / 2.0, 0.0); 696 CGFloat verticalSpaceInWebViewCoordinates = std::max((visibleSize.height - focusedElementRectInNewScale.height()) / 2.0, 0.0); 697 698 CGPoint topLeft; 699 topLeft.x = focusedElementRectInNewScale.x() - horizontalSpaceInWebViewCoordinates; 700 topLeft.y = focusedElementRectInNewScale.y() - verticalSpaceInWebViewCoordinates - visibleOffsetFromTop; 701 702 CGFloat minimumAllowableHorizontalOffsetInWebViewCoordinates = -INFINITY; 703 CGFloat minimumAllowableVerticalOffsetInWebViewCoordinates = -INFINITY; 704 if (selectionRectIsNotNull) { 705 WebCore::FloatRect selectionRectInNewScale = selectionRectInDocumentCoordinates; 706 selectionRectInNewScale.scale(scale); 707 selectionRectInNewScale.moveBy([_contentView frame].origin); 708 minimumAllowableHorizontalOffsetInWebViewCoordinates = CGRectGetMaxX(selectionRectInNewScale) + CaretOffsetFromWindowEdge - visibleSize.width; 709 minimumAllowableVerticalOffsetInWebViewCoordinates = CGRectGetMaxY(selectionRectInNewScale) + CaretOffsetFromWindowEdge - visibleSize.height - visibleOffsetFromTop; 710 } 711 712 WebCore::FloatRect documentBoundsInNewScale = [_contentView bounds]; 713 documentBoundsInNewScale.scale(scale); 714 documentBoundsInNewScale.moveBy([_contentView frame].origin); 715 716 // Constrain the left edge in document coordinates so that: 717 // - it isn't so small that the scrollVisibleRect isn't visible on the screen 718 // - it isn't so great that the document's right edge is less than the right edge of the screen 719 if (selectionRectIsNotNull && topLeft.x < minimumAllowableHorizontalOffsetInWebViewCoordinates) 720 topLeft.x = minimumAllowableHorizontalOffsetInWebViewCoordinates; 721 else { 722 CGFloat maximumAllowableHorizontalOffset = CGRectGetMaxX(documentBoundsInNewScale) - visibleSize.width; 723 if (topLeft.x > maximumAllowableHorizontalOffset) 724 topLeft.x = maximumAllowableHorizontalOffset; 725 } 726 727 // Constrain the top edge in document coordinates so that: 728 // - it isn't so small that the scrollVisibleRect isn't visible on the screen 729 // - it isn't so great that the document's bottom edge is higher than the top of the form assistant 730 if (selectionRectIsNotNull && topLeft.y < minimumAllowableVerticalOffsetInWebViewCoordinates) 731 topLeft.y = minimumAllowableVerticalOffsetInWebViewCoordinates; 732 else { 733 CGFloat maximumAllowableVerticalOffset = CGRectGetMaxY(documentBoundsInNewScale) - visibleSize.height; 734 if (topLeft.y > maximumAllowableVerticalOffset) 735 topLeft.y = maximumAllowableVerticalOffset; 736 } 737 738 WebCore::FloatPoint newCenter = CGPointMake(topLeft.x + unobscuredScrollViewRectInWebViewCoordinates.size.width / 2.0, topLeft.y + unobscuredScrollViewRectInWebViewCoordinates.size.height / 2.0); 739 740 // The newCenter has been computed in the new scale, but _zoomToCenter expected the center to be in the original scale. 741 newCenter.scale(1 / scale, 1 / scale); 742 [_scrollView _zoomToCenter:newCenter 743 scale:scale 744 duration:UIWebFormAnimationDuration 745 force:YES]; 746 } 747 619 748 - (BOOL)_zoomToRect:(WebCore::FloatRect)targetRect withOrigin:(WebCore::FloatPoint)origin fitEntireRect:(BOOL)fitEntireRect minimumScale:(double)minimumScale maximumScale:(double)maximumScale minimumScrollDistance:(float)minimumScrollDistance 620 749 { … … 760 889 // FIXME: handle split keyboard. 761 890 UIEdgeInsets obscuredInsets = _obscuredInsets; 762 obscuredInsets.bottom = std::max(_obscuredInsets.bottom, _ keyboardVerticalOverlap);891 obscuredInsets.bottom = std::max(_obscuredInsets.bottom, _inputViewBounds.size.height); 763 892 CGRect unobscuredRect = UIEdgeInsetsInsetRect(self.bounds, obscuredInsets); 764 893 return [self convertRect:unobscuredRect toView:_contentView.get()]; … … 791 920 - (void)_keyboardChangedWithInfo:(NSDictionary *)keyboardInfo adjustScrollView:(BOOL)adjustScrollView 792 921 { 793 _keyboardVerticalOverlap = [[UIPeripheralHost sharedInstance] getVerticalOverlapForView:self usingKeyboardInfo:keyboardInfo]; 922 NSValue *endFrameValue = [keyboardInfo objectForKey:UIKeyboardFrameEndUserInfoKey]; 923 if (!endFrameValue) 924 return; 925 926 // The keyboard rect is always in screen coordinates. In the view services case the window does not 927 // have the interface orientation rotation transformation; its host does. So, it makes no sense to 928 // clip the keyboard rect against its screen. 929 if ([[self window] _isHostedInAnotherProcess]) 930 _inputViewBounds = [self.window convertRect:[endFrameValue CGRectValue] fromWindow:nil]; 931 else 932 _inputViewBounds = [self.window convertRect:CGRectIntersection([endFrameValue CGRectValue], self.window.screen.bounds) fromWindow:nil]; 933 794 934 [self _updateVisibleContentRects]; 795 935 -
trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewInternal.h
r168568 r168744 68 68 - (void)_scrollToContentOffset:(WebCore::FloatPoint)contentOffset; 69 69 - (BOOL)_scrollToRect:(WebCore::FloatRect)targetRect origin:(WebCore::FloatPoint)origin minimumScrollDistance:(float)minimumScrollDistance; 70 - (void)_zoomToFocusRect:(WebCore::FloatRect)focusedElementRect selectionRect:(WebCore::FloatRect)selectionRectInDocumentCoordinates fontSize:(float)fontSize minimumScale:(double)minimumScale maximumScale:(double)maximumScale allowScaling:(BOOL)allowScaling forceScroll:(BOOL)forceScroll; 70 71 - (BOOL)_zoomToRect:(WebCore::FloatRect)targetRect withOrigin:(WebCore::FloatPoint)origin fitEntireRect:(BOOL)fitEntireRect minimumScale:(double)minimumScale maximumScale:(double)maximumScale minimumScrollDistance:(float)minimumScrollDistance; 71 72 - (void)_zoomOutWithOrigin:(WebCore::FloatPoint)origin; -
trunk/Source/WebKit2/UIProcess/ios/WKContentView.h
r168560 r168744 85 85 86 86 - (BOOL)_scrollToRect:(CGRect)targetRect withOrigin:(CGPoint)origin minimumScrollDistance:(CGFloat)minimumScrollDistance; 87 - (void)_zoomToFocusRect:(CGRect)rectToFocus selectionRect:(CGRect)selectionRect fontSize:(float)fontSize minimumScale:(double)minimumScale maximumScale:(double)maximumScale allowScaling:(BOOL)allowScaling forceScroll:(BOOL)forceScroll; 87 88 - (BOOL)_zoomToRect:(CGRect)targetRect withOrigin:(CGPoint)origin fitEntireRect:(BOOL)fitEntireRect minimumScale:(double)minimumScale maximumScale:(double)maximumScale minimumScrollDistance:(CGFloat)minimumScrollDistance; 88 89 - (void)_zoomOutWithOrigin:(CGPoint)origin; -
trunk/Source/WebKit2/UIProcess/ios/WKContentView.mm
r168568 r168744 477 477 } 478 478 479 - (void)_zoomToFocusRect:(CGRect)rectToFocus selectionRect:(CGRect)selectionRect fontSize:(float)fontSize minimumScale:(double)minimumScale maximumScale:(double)maximumScale allowScaling:(BOOL)allowScaling forceScroll:(BOOL)forceScroll 480 { 481 [_webView _zoomToFocusRect:rectToFocus 482 selectionRect:selectionRect 483 fontSize:fontSize 484 minimumScale:minimumScale 485 maximumScale:maximumScale 486 allowScaling:allowScaling 487 forceScroll:forceScroll]; 488 } 489 479 490 - (BOOL)_zoomToRect:(CGRect)targetRect withOrigin:(CGPoint)origin fitEntireRect:(BOOL)fitEntireRect minimumScale:(double)minimumScale maximumScale:(double)maximumScale minimumScrollDistance:(CGFloat)minimumScrollDistance 480 491 { -
trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm
r168563 r168744 496 496 - (void)_displayFormNodeInputView 497 497 { 498 if (UICurrentUserInterfaceIdiomIsPad()) 499 [self _scrollToRect:_assistedNodeInformation.elementRect withOrigin:_page->editorState().caretRectAtStart.location() minimumScrollDistance:0]; 500 else 501 [self _zoomToRect:_assistedNodeInformation.elementRect 502 withOrigin:_page->editorState().caretRectAtStart.location() 503 fitEntireRect:YES minimumScale:_assistedNodeInformation.minimumScaleFactor 504 maximumScale:_assistedNodeInformation.maximumScaleFactor 505 minimumScrollDistance:0]; 506 498 [self _zoomToFocusRect:_assistedNodeInformation.elementRect 499 selectionRect:_assistedNodeInformation.selectionRect 500 fontSize:_assistedNodeInformation.nodeFontSize 501 minimumScale:_assistedNodeInformation.minimumScaleFactor 502 maximumScale:_assistedNodeInformation.maximumScaleFactor 503 allowScaling:(_assistedNodeInformation.allowsUserScaling && !UICurrentUserInterfaceIdiomIsPad()) 504 forceScroll:[self requiresAccessoryView]]; 507 505 [self _updateAccessory]; 508 506 } … … 2127 2125 return; 2128 2126 2127 // FIXME: We should remove this check when we manage to send StartAssistingNode from the WebProcess 2128 // only when it is truly time to show the keyboard. 2129 if (_assistedNodeInformation.elementType == information.elementType && _assistedNodeInformation.elementRect == information.elementRect) 2130 return; 2131 2129 2132 _isEditable = YES; 2130 2133 _assistedNodeInformation = information; -
trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm
r168572 r168744 1777 1777 layoutIfNeeded(); 1778 1778 1779 if (RenderObject* renderer = m_assistedNode->renderer()) 1779 if (RenderObject* renderer = m_assistedNode->renderer()) { 1780 1780 information.elementRect = m_page->focusController().focusedOrMainFrame().view()->contentsToRootView(renderer->absoluteBoundingBoxRect()); 1781 else 1781 information.nodeFontSize = renderer->style().fontDescription().computedSize(); 1782 } else 1782 1783 information.elementRect = IntRect(); 1784 // FIXME: This should return the selection rect, but when this is called at focus time 1785 // we don't have a selection yet. Using the last interaction location is a reasonable approximation for now. 1786 information.selectionRect = IntRect(m_lastInteractionLocation, IntSize(1, 1)); 1783 1787 information.minimumScaleFactor = m_viewportConfiguration.minimumScale(); 1784 1788 information.maximumScaleFactor = m_viewportConfiguration.maximumScale(); 1789 information.allowsUserScaling = m_viewportConfiguration.allowsUserScaling(); 1785 1790 information.hasNextNode = hasFocusableElement(m_assistedNode.get(), m_page.get(), true); 1786 1791 information.hasPreviousNode = hasFocusableElement(m_assistedNode.get(), m_page.get(), false);
Note:
See TracChangeset
for help on using the changeset viewer.