Changeset 284766 in webkit
- Timestamp:
- Oct 24, 2021, 1:39:35 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 6 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/editing/selection/ios/do-not-allow-text-selection-in-user-select-none-expected.txt (added)
-
LayoutTests/editing/selection/ios/do-not-allow-text-selection-in-user-select-none.html (added)
-
Source/WebKit/ChangeLog (modified) (1 diff)
-
Source/WebKit/Shared/ios/InteractionInformationAtPosition.h (modified) (2 diffs)
-
Source/WebKit/Shared/ios/InteractionInformationAtPosition.mm (modified) (2 diffs)
-
Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (modified) (3 diffs)
-
Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r284758 r284766 1 2021-10-24 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 REGRESSION (iOS 15): Safari shows zoom callout even if -webkit-user-select is none 4 https://bugs.webkit.org/show_bug.cgi?id=231161 5 rdar://83863266 6 7 Reviewed by Darin Adler. 8 9 See Source/WebKit/ChangeLog for more details. 10 11 * editing/selection/ios/do-not-allow-text-selection-in-user-select-none-expected.txt: Added. 12 * editing/selection/ios/do-not-allow-text-selection-in-user-select-none.html: Added. 13 1 14 2021-10-24 Alexey Shvayka <shvaikalesh@gmail.com> 2 15 -
trunk/Source/WebKit/ChangeLog
r284763 r284766 1 2021-10-24 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 REGRESSION (iOS 15): Safari shows zoom callout even if -webkit-user-select is none 4 https://bugs.webkit.org/show_bug.cgi?id=231161 5 rdar://83863266 6 7 Reviewed by Darin Adler. 8 9 Make several minor tweaks to prevent the text interaction assistant's loupe gesture from beginning when long 10 pressing inside content with `-webkit-user-select: none;`. Importantly, this prevents both the text 11 interaction's haptic feedback and the text selection magnifier UI (introduced in iOS 15) from showing up. See 12 comments below for more details. 13 14 Test: editing/selection/ios/do-not-allow-text-selection-in-user-select-none.html 15 16 * Shared/ios/InteractionInformationAtPosition.h: 17 (WebKit::InteractionInformationAtPosition::isSelectable const): 18 19 Add a helper method to return whether the `selectability` flag is equal to `Selectable`, and use this in places 20 where we current check the `isSelectable` flag. 21 22 * Shared/ios/InteractionInformationAtPosition.mm: 23 (WebKit::InteractionInformationAtPosition::encode const): 24 (WebKit::InteractionInformationAtPosition::decode): 25 26 Break the current `isSelectable` flag out into different enum types, which enumerate the reasons why we might 27 need to treat hit-tested content as non-user-selectable. Importantly, this allows us to only early return inside 28 `-textInteractionGesture:shouldBeginAtPoint:` below if the element has an explicit `-webkit-user-select: none;`, 29 and not because of the other reasons (i.e. large element bounds or the fact that we're long pressing editable 30 text while not editing). 31 32 This nuance is important in order to continue allowing the loupe gesture (which manifests as a floating caret) 33 to begin when long pressing inside a focused a text field. 34 35 * UIProcess/ios/WKContentViewInteraction.mm: 36 (-[WKContentView hasSelectablePositionAtPoint:]): 37 (-[WKContentView textInteractionGesture:shouldBeginAtPoint:]): 38 39 Return NO here in the case where we're recognizing a loupe gesture (i.e. long press) inside content with 40 `-webkit-user-select: none;` (by consulting the new `selectability` enumeration). This allows us to prevent both 41 haptic feedback as well as the new magnifier UI from triggering when long pressing inside content that has 42 explicitly disabled text selection. 43 44 (-[WKContentView closestPositionToPoint:]): 45 * WebProcess/WebPage/ios/WebPageIOS.mm: 46 (WebKit::selectionPositionInformation): 47 (WebKit::WebPage::positionInformation): 48 49 Additionally populate the `selectability` flag even when long pressing inside images and links. Instead of 50 putting the call to `selectionPositionInformation` behind the `isLink`/`isImage` check, move that condition into 51 `selectionPositionInformation` in the form of an early return, and always populate `selectability` in either 52 case. 53 1 54 2021-10-24 Darin Adler <darin@apple.com> 2 55 -
trunk/Source/WebKit/Shared/ios/InteractionInformationAtPosition.h
r280098 r284766 54 54 bool canBeValid { true }; 55 55 std::optional<bool> nodeAtPositionHasDoubleClickHandler; 56 bool isSelectable { false }; 56 57 enum class Selectability : uint8_t { 58 Selectable, 59 UnselectableDueToFocusableElement, 60 UnselectableDueToLargeElementBounds, 61 UnselectableDueToUserSelectNone, 62 }; 63 Selectability selectability { Selectability::Selectable }; 64 57 65 bool isSelected { false }; 58 66 bool prefersDraggingOverTextSelection { false }; … … 108 116 void mergeCompatibleOptionalInformation(const InteractionInformationAtPosition& oldInformation); 109 117 118 bool isSelectable() const { return selectability == Selectability::Selectable; } 119 110 120 void encode(IPC::Encoder&) const; 111 121 static WARN_UNUSED_RETURN bool decode(IPC::Decoder&, InteractionInformationAtPosition&); 112 122 }; 113 123 114 } 124 } // namespace WebKit 125 126 namespace WTF { 127 128 template<> struct EnumTraits<WebKit::InteractionInformationAtPosition::Selectability> { 129 using values = EnumValues< 130 WebKit::InteractionInformationAtPosition::Selectability, 131 WebKit::InteractionInformationAtPosition::Selectability::Selectable, 132 WebKit::InteractionInformationAtPosition::Selectability::UnselectableDueToFocusableElement, 133 WebKit::InteractionInformationAtPosition::Selectability::UnselectableDueToLargeElementBounds, 134 WebKit::InteractionInformationAtPosition::Selectability::UnselectableDueToUserSelectNone 135 >; 136 }; 137 138 } // namespace WTF 115 139 116 140 #endif // PLATFORM(IOS_FAMILY) -
trunk/Source/WebKit/Shared/ios/InteractionInformationAtPosition.mm
r280098 r284766 41 41 encoder << canBeValid; 42 42 encoder << nodeAtPositionHasDoubleClickHandler; 43 encoder << isSelectable;43 encoder << selectability; 44 44 encoder << isSelected; 45 45 encoder << prefersDraggingOverTextSelection; … … 100 100 return false; 101 101 102 if (!decoder.decode(result. isSelectable))102 if (!decoder.decode(result.selectability)) 103 103 return false; 104 104 -
trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm
r284630 r284766 2887 2887 #endif 2888 2888 2889 return _positionInformation.isSelectable ;2889 return _positionInformation.isSelectable(); 2890 2890 } 2891 2891 … … 2953 2953 WebKit::InteractionInformationRequest request(WebCore::roundedIntPoint(point)); 2954 2954 if (![self ensurePositionInformationIsUpToDate:request]) 2955 return NO; 2956 2957 if (gesture == UIWKGestureLoupe && _positionInformation.selectability == WebKit::InteractionInformationAtPosition::Selectability::UnselectableDueToUserSelectNone) 2955 2958 return NO; 2956 2959 … … 5255 5258 WebKit::InteractionInformationRequest request(WebCore::roundedIntPoint(point)); 5256 5259 [self requestAsynchronousPositionInformationUpdate:request]; 5257 if ([self _currentPositionInformationIsApproximatelyValidForRequest:request radiusForApproximation:2] && _positionInformation.isSelectable )5260 if ([self _currentPositionInformationIsApproximatelyValidForRequest:request radiusForApproximation:2] && _positionInformation.isSelectable()) 5258 5261 return [WKTextPosition textPositionWithRect:_positionInformation.caretRect]; 5259 5262 #endif -
trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm
r284628 r284766 2889 2889 return; 2890 2890 2891 RenderObject* renderer = hitNode->renderer(); 2891 auto* renderer = hitNode->renderer(); 2892 2893 info.selectability = ([&] { 2894 if (renderer->style().userSelectIncludingInert() == UserSelect::None) 2895 return InteractionInformationAtPosition::Selectability::UnselectableDueToUserSelectNone; 2896 2897 if (is<Element>(*hitNode)) { 2898 if (isAssistableElement(downcast<Element>(*hitNode))) 2899 return InteractionInformationAtPosition::Selectability::UnselectableDueToFocusableElement; 2900 2901 if (rectIsTooBigForSelection(info.bounds, *result.innerNodeFrame())) { 2902 // We don't want to select blocks that are larger than 97% of the visible area of the document. 2903 // FIXME: Is this heuristic still needed, now that block selection has been removed? 2904 return InteractionInformationAtPosition::Selectability::UnselectableDueToLargeElementBounds; 2905 } 2906 } 2907 2908 return InteractionInformationAtPosition::Selectability::Selectable; 2909 })(); 2910 info.isSelected = result.isSelected(); 2911 2912 if (info.isLink || info.isImage) 2913 return; 2914 2892 2915 boundsPositionInformation(*renderer, info); 2893 2894 info.isSelected = result.isSelected();2895 2916 2896 2917 if (is<Element>(*hitNode)) { … … 2906 2927 if (attachment.file()) 2907 2928 info.url = URL::fileURLWithFileSystemPath(downcast<HTMLAttachmentElement>(*hitNode).file()->path()); 2908 } else { 2909 info.isSelectable = renderer->style().userSelectIncludingInert() != UserSelect::None; 2910 // We don't want to select blocks that are larger than 97% of the visible area of the document. 2911 // FIXME: Is this heuristic still needed, now that block selection has been removed? 2912 if (info.isSelectable && !hitNode->isTextNode()) 2913 info.isSelectable = !isAssistableElement(*downcast<Element>(hitNode)) && !rectIsTooBigForSelection(info.bounds, *result.innerNodeFrame()); 2914 } 2929 } 2930 2915 2931 for (RefPtr currentNode = hitNode; currentNode; currentNode = currentNode->parentOrShadowHostNode()) { 2916 2932 auto* renderer = currentNode->renderer(); … … 3088 3104 imagePositionInformation(*this, downcast<HTMLImageElement>(*hitTestNode), request, info); 3089 3105 3090 if (!(info.isLink || info.isImage)) 3091 selectionPositionInformation(*this, request, info); 3106 selectionPositionInformation(*this, request, info); 3092 3107 3093 3108 // Prevent the callout bar from showing when tapping on the datalist button.
Note:
See TracChangeset
for help on using the changeset viewer.