Changeset 230171 in webkit
- Timestamp:
- Apr 2, 2018, 12:06:44 PM (7 years ago)
- Location:
- trunk/Source/WebKit
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit/ChangeLog
r230169 r230171 1 2018-04-02 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 [Extra zoom mode] Zoom level is sometimes excessive when zooming to focused form controls 4 https://bugs.webkit.org/show_bug.cgi?id=184222 5 <rdar://problem/39063886> 6 7 Reviewed by Timothy Hatcher. 8 9 Upon interactively focusing an element, we zoom and scroll to reveal that element. The heuristics introduced in 10 <https://trac.webkit.org/r168744> work by computing a target scale, and then a point to zoom to given that 11 scale. Currently, this scale is dependent on the computed font size of the form control, such that the form 12 control would be scaled to have an effective font size of 16. 13 14 However, in extra zoom mode, applying these same heuristics (ironically) results in excessive zoom levels, since 15 scaling the font up to 16 would cause most form controls to zoom so far in that we lose context of surrounding 16 elements such as labels and other form controls; the fact that the element is highlighted by the focused form 17 control overlay makes this even more confusing, since part of the focus overlay highlight rect often ends up 18 outside the viewport. 19 20 To fix this, we make a couple of tweaks to focus rect zooming in extra zoom mode. (1) Instead of computing 21 target zoom level based on font size, try to zoom such that the focused element rect fills up most of the 22 viewport (similar to double-tap zooming). This ensures that the focused form control overlay's highlight rect 23 makes sense in most cases, with few exceptions (e.g. the element frame is larger than the viewport). (2) 24 Introduce a minimum legible font size of 11, and compute the minimium scale needed such that the form control 25 font would appear to be at least this legible font size. Then, clamp the target scale chosen by (1) to this 26 minimum scale. 27 28 One additional consideration for (1) is that naively scaling to fit the element rect to the viewport (with some 29 fixed margins) would cause the viewport scale to always change when moving focus between form controls of 30 different dimensions, even if the current scale is more or less appropriate for all the focusable elements. To 31 address this, instead of computing a single target zoom scale for an element rect, compute a range of possible 32 target zoom scales (where the minimum and maximum values depend on the margin we add around the element rect). 33 If the current scale already falls within this target scale range, then we won't bother adjusting the scale at 34 all (unless the font size is too small — see (2)). If the current scale falls outside the target scale range, we 35 then make the minimal adjustment needed to ensure that the element rect fits well within the viewport without 36 being too small. 37 38 * UIProcess/API/Cocoa/WKWebView.mm: 39 (-[WKWebView _zoomToFocusRect:selectionRect:insideFixed:fontSize:minimumScale:maximumScale:allowScaling:forceScroll:]): 40 41 Move some logic around so that the target scale is computed after computing the visible size. Also renames some 42 constants local to this function (WKWebViewStandardFontSize, kMinimumHeightToShowContentAboveKeyboard, 43 UIWebFormAnimationDuration, CaretOffsetFromWindowEdge) such that they now share a consistent naming style. 44 1 45 2018-04-02 Jer Noble <jer.noble@apple.com> 2 46 -
trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm
r230041 r230171 2121 2121 UNUSED_PARAM(insideFixed); 2122 2122 2123 const double WKWebViewStandardFontSize = 16; 2124 const double kMinimumHeightToShowContentAboveKeyboard = 106; 2125 const CFTimeInterval UIWebFormAnimationDuration = 0.25; 2126 const double CaretOffsetFromWindowEdge = 20; 2127 2128 // Zoom around the element's bounding frame. We use a "standard" size to determine the proper frame. 2129 double scale = allowScaling ? std::min(std::max(WKWebViewStandardFontSize / fontSize, minimumScale), maximumScale) : contentZoomScale(self); 2130 CGFloat documentWidth = [_contentView bounds].size.width; 2131 scale = CGRound(documentWidth * scale) / documentWidth; 2123 const double minimumHeightToShowContentAboveKeyboard = 106; 2124 const CFTimeInterval formControlZoomAnimationDuration = 0.25; 2125 const double caretOffsetFromWindowEdge = 20; 2132 2126 2133 2127 UIWindow *window = [_scrollView window]; 2134 2135 WebCore::FloatRect focusedElementRectInNewScale = focusedElementRectInDocumentCoordinates;2136 focusedElementRectInNewScale.scale(scale);2137 focusedElementRectInNewScale.moveBy([_contentView frame].origin);2138 2128 2139 2129 // Find the portion of the view that is visible on the screen. … … 2154 2144 CGFloat heightVisibleBelowFormAssistant = CGRectGetMaxY(visibleScrollViewBoundsInWebViewCoordinates) - CGRectGetMaxY(intersectionBetweenScrollViewAndFormAssistant); 2155 2145 2156 if (heightVisibleAboveFormAssistant >= kMinimumHeightToShowContentAboveKeyboard || heightVisibleBelowFormAssistant < heightVisibleAboveFormAssistant)2146 if (heightVisibleAboveFormAssistant >= minimumHeightToShowContentAboveKeyboard || heightVisibleBelowFormAssistant < heightVisibleAboveFormAssistant) 2157 2147 visibleSize.height = heightVisibleAboveFormAssistant; 2158 2148 else { … … 2161 2151 } 2162 2152 } 2153 2154 // Zoom around the element's bounding frame. We use a "standard" size to determine the proper frame. 2155 double currentScale = contentZoomScale(self); 2156 double scale = currentScale; 2157 if (allowScaling) { 2158 #if ENABLE(EXTRA_ZOOM_MODE) 2159 const double minimumLegibleFontSize = 11; 2160 const CGFloat minimumMarginForZoomingToEntireFocusRectInWebViewCoordinates = 10; 2161 const CGFloat maximumMarginForZoomingToEntireFocusRectInWebViewCoordinates = 35; 2162 2163 CGRect minimumTargetRectInDocumentCoordinates = UIRectInsetEdges(focusedElementRectInDocumentCoordinates, UIRectEdgeAll, -minimumMarginForZoomingToEntireFocusRectInWebViewCoordinates / currentScale); 2164 CGRect maximumTargetRectInDocumentCoordinates = UIRectInsetEdges(focusedElementRectInDocumentCoordinates, UIRectEdgeAll, -maximumMarginForZoomingToEntireFocusRectInWebViewCoordinates / currentScale); 2165 2166 double clampedMaximumTargetScale = clampTo<double>(std::min(visibleSize.width / CGRectGetWidth(minimumTargetRectInDocumentCoordinates), visibleSize.height / CGRectGetHeight(minimumTargetRectInDocumentCoordinates)), minimumScale, maximumScale); 2167 double clampedMinimumTargetScale = clampTo<double>(std::min(visibleSize.width / CGRectGetWidth(maximumTargetRectInDocumentCoordinates), visibleSize.height / CGRectGetHeight(maximumTargetRectInDocumentCoordinates)), minimumScale, maximumScale); 2168 double targetScaleIgnoringFontSizeConstraints = clampTo<double>(currentScale, clampedMinimumTargetScale, clampedMaximumTargetScale); 2169 scale = std::max<double>(minimumLegibleFontSize / fontSize, targetScaleIgnoringFontSizeConstraints); 2170 #else 2171 const double webViewStandardFontSize = 16; 2172 scale = clampTo<double>(webViewStandardFontSize / fontSize, minimumScale, maximumScale); 2173 #endif 2174 } 2175 2176 CGFloat documentWidth = [_contentView bounds].size.width; 2177 scale = CGRound(documentWidth * scale) / documentWidth; 2178 2179 WebCore::FloatRect focusedElementRectInNewScale = focusedElementRectInDocumentCoordinates; 2180 focusedElementRectInNewScale.scale(scale); 2181 focusedElementRectInNewScale.moveBy([_contentView frame].origin); 2163 2182 2164 2183 BOOL selectionRectIsNotNull = !selectionRectInDocumentCoordinates.isZero(); … … 2194 2213 selectionRectInNewScale.scale(scale); 2195 2214 selectionRectInNewScale.moveBy([_contentView frame].origin); 2196 minimumAllowableHorizontalOffsetInWebViewCoordinates = CGRectGetMaxX(selectionRectInNewScale) + CaretOffsetFromWindowEdge - visibleSize.width;2197 minimumAllowableVerticalOffsetInWebViewCoordinates = CGRectGetMaxY(selectionRectInNewScale) + CaretOffsetFromWindowEdge - visibleSize.height - visibleOffsetFromTop;2215 minimumAllowableHorizontalOffsetInWebViewCoordinates = CGRectGetMaxX(selectionRectInNewScale) + caretOffsetFromWindowEdge - visibleSize.width; 2216 minimumAllowableVerticalOffsetInWebViewCoordinates = CGRectGetMaxY(selectionRectInNewScale) + caretOffsetFromWindowEdge - visibleSize.height - visibleOffsetFromTop; 2198 2217 } 2199 2218 … … 2226 2245 WebCore::FloatPoint newCenter = CGPointMake(topLeft.x + unobscuredScrollViewRectInWebViewCoordinates.size.width / 2.0, topLeft.y + unobscuredScrollViewRectInWebViewCoordinates.size.height / 2.0); 2227 2246 2228 if (scale != c ontentZoomScale(self))2247 if (scale != currentScale) 2229 2248 _page->willStartUserTriggeredZooming(); 2230 2249 … … 2233 2252 // The newCenter has been computed in the new scale, but _zoomToCenter expected the center to be in the original scale. 2234 2253 newCenter.scale(1 / scale); 2235 [_scrollView _zoomToCenter:newCenter 2236 scale:scale 2237 duration:UIWebFormAnimationDuration 2238 force:YES]; 2254 [_scrollView _zoomToCenter:newCenter scale:scale duration:formControlZoomAnimationDuration force:YES]; 2239 2255 } 2240 2256
Note:
See TracChangeset
for help on using the changeset viewer.