Changeset 249339 in webkit
- Timestamp:
- Aug 30, 2019 12:28:57 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r249338 r249339 1 2019-08-30 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 Caret does not appear in text field inside a transformed, overflow: hidden container 4 https://bugs.webkit.org/show_bug.cgi?id=201317 5 <rdar://problem/54859264> 6 7 Reviewed by Simon Fraser. 8 9 Add a new layout test that covers this scenario. See WebCore ChangeLog for additional detail. 10 11 * editing/selection/ios/show-selection-in-transformed-container-2-expected.txt: Added. 12 * editing/selection/ios/show-selection-in-transformed-container-2.html: Added. 13 1 14 2019-08-30 Chris Dumez <cdumez@apple.com> 2 15 -
trunk/Source/WebCore/ChangeLog
r249338 r249339 1 2019-08-30 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 Caret does not appear in text field inside a transformed, overflow: hidden container 4 https://bugs.webkit.org/show_bug.cgi?id=201317 5 <rdar://problem/54859264> 6 7 Reviewed by Simon Fraser. 8 9 This patch refactors the heuristic for determining whether to suppress selection gestures and UI in a way that 10 fixes the corner case encountered in this bug. To understand why this test case fails with our existing 11 heuristic, consider the below test case. 12 13 Let's say we have an input field inside an "overflow: hidden;" container, which is positioned in such a way that 14 it is completely clipped by its enclosing container which is also "overflow: hidden". Our existing logic would 15 appropriately identify this as a hidden editable element. 16 17 However, let's now apply a transform to the input field's closest "overflow: hidden" ancestor, such that the 18 field is now visible. Since RenderLayer::offsetFromAncestor doesn't take transforms into account when we try to 19 find the offset of the "overflow: hidden" layer relative to the root view, we end up passing an offsetFromRoot 20 of (0, 100vw) to RenderLayer::calculateClipRects, which computes a background clip rect of (0, 0, 100vw, 100vh). 21 22 This means that at the end of RenderLayer::calculateClipRects, we end up intersecting the background clip rect 23 (0, 0, 100vw, 100vh) against (100vw, 0, 100vw, 100vh), which results in the empty rect, and subsequently makes 24 us believe we're editing a hidden editable element. 25 26 Instead of tacking on more logic to isTransparentOrFullyClippedRespectingParentFrames, we can fix this by using 27 RenderObject::computeVisibleRectInContainer instead, performing a similar walk up the render tree to compute the 28 visible rect of each focused element or subframe relative to its root. This is capable of taking transforms into 29 account. See comments below for more details. 30 31 Test: editing/selection/ios/show-selection-in-transformed-container-2.html 32 33 * rendering/RenderLayer.cpp: 34 (WebCore::RenderLayer::isTransparentRespectingParentFrames const): 35 36 Split out isTransparentOrFullyClippedRespectingParentFrames into two methods: RenderLayer's 37 isTransparentRespectingParentFrames, and RenderObject's hasNonEmptyVisibleRectRespectingParentFrames. The 38 transparency check starts at the enclosing layer and walks up the layer tree, while the non-empty visible rect 39 check looks for renderers that are completely empty relative to their root views. 40 41 * rendering/RenderLayer.h: 42 * rendering/RenderObject.cpp: 43 (WebCore::RenderObject::hasNonEmptyVisibleRectRespectingParentFrames const): 44 45 Rewrite logic for detecting completely clipped editable areas (that formerly lived in 46 isTransparentOrFullyClippedRespectingParentFrames) to use computeVisibleRectInContainer instead. 47 48 * rendering/RenderObject.h: 49 1 50 2019-08-30 Chris Dumez <cdumez@apple.com> 2 51 -
trunk/Source/WebCore/rendering/RenderLayer.cpp
r249309 r249339 6836 6836 } 6837 6837 6838 bool RenderLayer::isTransparent OrFullyClippedRespectingParentFrames() const6838 bool RenderLayer::isTransparentRespectingParentFrames() const 6839 6839 { 6840 6840 static const double minimumVisibleOpacity = 0.01; … … 6844 6844 currentOpacity *= layer->renderer().style().opacity(); 6845 6845 if (currentOpacity < minimumVisibleOpacity) 6846 return true;6847 }6848 6849 auto hasEmptyClipRect = [] (const RenderLayer& layer) -> bool {6850 auto* frameView = layer.renderer().document().view();6851 if (!frameView)6852 return false;6853 6854 auto* renderView = frameView->renderView();6855 if (!renderView)6856 return false;6857 6858 auto* renderViewLayer = renderView->layer();6859 if (!renderViewLayer)6860 return false;6861 6862 if (is<HTMLFrameOwnerElement>(layer.renderer().element()) && layer.visibleSize().isEmpty())6863 return true;6864 6865 LayoutRect layerBounds;6866 ClipRect backgroundRect;6867 ClipRect foregroundRect;6868 layer.calculateRects({ renderViewLayer, TemporaryClipRects }, LayoutRect::infiniteRect(), layerBounds, backgroundRect, foregroundRect, layer.offsetFromAncestor(renderViewLayer));6869 return backgroundRect.isEmpty();6870 };6871 6872 for (auto* layer = this; layer; layer = enclosingFrameRenderLayer(*layer)) {6873 if (hasEmptyClipRect(*layer))6874 6846 return true; 6875 6847 } -
trunk/Source/WebCore/rendering/RenderLayer.h
r249091 r249339 898 898 bool paintingFrequently() const { return m_paintFrequencyTracker.paintingFrequently(); } 899 899 900 WEBCORE_EXPORT bool isTransparent OrFullyClippedRespectingParentFrames() const;900 WEBCORE_EXPORT bool isTransparentRespectingParentFrames() const; 901 901 902 902 void invalidateEventRegion(); -
trunk/Source/WebCore/rendering/RenderObject.cpp
r248846 r249339 1903 1903 } 1904 1904 1905 bool RenderObject::hasNonEmptyVisibleRectRespectingParentFrames() const 1906 { 1907 auto enclosingFrameRenderer = [] (const RenderObject& renderer) { 1908 auto* ownerElement = renderer.document().ownerElement(); 1909 return ownerElement ? ownerElement->renderer() : nullptr; 1910 }; 1911 1912 auto hasEmptyVisibleRect = [] (const RenderObject& renderer) { 1913 VisibleRectContext context { false, false, { VisibleRectContextOption::UseEdgeInclusiveIntersection, VisibleRectContextOption::ApplyCompositedClips }}; 1914 auto& box = renderer.enclosingBoxModelObject(); 1915 auto clippedBounds = box.computeVisibleRectInContainer(box.borderBoundingBox(), &box.view(), context); 1916 return !clippedBounds || clippedBounds->isEmpty(); 1917 }; 1918 1919 for (auto* renderer = this; renderer; renderer = enclosingFrameRenderer(*renderer)) { 1920 if (hasEmptyVisibleRect(*renderer)) 1921 return true; 1922 } 1923 1924 return false; 1925 } 1926 1905 1927 #if ENABLE(TREE_DEBUGGING) 1906 1928 -
trunk/Source/WebCore/rendering/RenderObject.h
r248807 r249339 684 684 virtual Optional<LayoutRect> computeVisibleRectInContainer(const LayoutRect&, const RenderLayerModelObject* repaintContainer, VisibleRectContext) const; 685 685 virtual Optional<FloatRect> computeFloatVisibleRectInContainer(const FloatRect&, const RenderLayerModelObject* repaintContainer, VisibleRectContext) const; 686 687 WEBCORE_EXPORT bool hasNonEmptyVisibleRectRespectingParentFrames() const; 686 688 687 689 virtual unsigned int length() const { return 1; } -
trunk/Source/WebKit/ChangeLog
r249336 r249339 1 2019-08-30 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 Caret does not appear in text field inside a transformed, overflow: hidden container 4 https://bugs.webkit.org/show_bug.cgi?id=201317 5 <rdar://problem/54859264> 6 7 Reviewed by Simon Fraser. 8 9 Adjust isTransparentOrFullyClipped to use the new methods in RenderLayer and RenderObject. See WebCore ChangeLog 10 for more details. 11 12 * WebProcess/WebPage/ios/WebPageIOS.mm: 13 (WebKit::WebPage::isTransparentOrFullyClipped const): 14 1 15 2019-08-30 Simon Fraser <simon.fraser@apple.com> 2 16 -
trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm
r249296 r249339 198 198 199 199 auto* enclosingLayer = renderer->enclosingLayer(); 200 return enclosingLayer && enclosingLayer->isTransparentOrFullyClippedRespectingParentFrames(); 200 if (enclosingLayer && enclosingLayer->isTransparentRespectingParentFrames()) 201 return true; 202 203 return renderer->hasNonEmptyVisibleRectRespectingParentFrames(); 201 204 } 202 205
Note: See TracChangeset
for help on using the changeset viewer.