Diff
Added: branches/safari-612-branch/LayoutTests/editing/selection/ios/do-not-allow-text-selection-in-user-select-none-expected.txt (0 => 285518)
--- branches/safari-612-branch/LayoutTests/editing/selection/ios/do-not-allow-text-selection-in-user-select-none-expected.txt (rev 0)
+++ branches/safari-612-branch/LayoutTests/editing/selection/ios/do-not-allow-text-selection-in-user-select-none-expected.txt 2021-11-09 19:42:06 UTC (rev 285518)
@@ -0,0 +1,10 @@
+This test verifies that long pressing an element with -webkit-user-select: none; does not begin a text selection gesture. To manually run the test, long press the square below and verify that no text is selected.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS getSelection().toString() is ""
+PASS successfullyParsed is true
+
+TEST COMPLETE
+Hello world
Added: branches/safari-612-branch/LayoutTests/editing/selection/ios/do-not-allow-text-selection-in-user-select-none.html (0 => 285518)
--- branches/safari-612-branch/LayoutTests/editing/selection/ios/do-not-allow-text-selection-in-user-select-none.html (rev 0)
+++ branches/safari-612-branch/LayoutTests/editing/selection/ios/do-not-allow-text-selection-in-user-select-none.html 2021-11-09 19:42:06 UTC (rev 285518)
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+html, body {
+ font-size: 16px;
+}
+
+#target {
+ width: 150px;
+ height: 150px;
+ background-color: tomato;
+ -webkit-user-select: none;
+}
+</style>
+<script src=""
+<script src=""
+<script>
+jsTestIsAsync = true;
+description("This test verifies that long pressing an element with <code>-webkit-user-select: none;</code> does not begin a text selection gesture. To manually run the test, long press the square below and verify that no text is selected.");
+
+addEventListener("load", async () => {
+ if (!window.testRunner)
+ return;
+
+ await UIHelper.longPressElement(document.getElementById("target"));
+ shouldBeEqualToString("getSelection().toString()", "");
+ finishJSTest();
+});
+</script>
+</head>
+<body>
+<p>Hello world</p>
+<div id="target"></div>
+</body>
+</html>
\ No newline at end of file
Modified: branches/safari-612-branch/Source/WebKit/Shared/ios/InteractionInformationAtPosition.h (285517 => 285518)
--- branches/safari-612-branch/Source/WebKit/Shared/ios/InteractionInformationAtPosition.h 2021-11-09 19:42:03 UTC (rev 285517)
+++ branches/safari-612-branch/Source/WebKit/Shared/ios/InteractionInformationAtPosition.h 2021-11-09 19:42:06 UTC (rev 285518)
@@ -53,7 +53,15 @@
bool canBeValid { true };
std::optional<bool> nodeAtPositionHasDoubleClickHandler;
- bool isSelectable { false };
+
+ enum class Selectability : uint8_t {
+ Selectable,
+ UnselectableDueToFocusableElement,
+ UnselectableDueToLargeElementBounds,
+ UnselectableDueToUserSelectNone,
+ };
+ Selectability selectability { Selectability::Selectable };
+
bool isSelected { false };
bool prefersDraggingOverTextSelection { false };
bool isNearMarkedText { false };
@@ -107,10 +115,26 @@
// we can fetch the cheap information and copy the snapshots into the new response).
void mergeCompatibleOptionalInformation(const InteractionInformationAtPosition& oldInformation);
+ bool isSelectable() const { return selectability == Selectability::Selectable; }
+
void encode(IPC::Encoder&) const;
static WARN_UNUSED_RETURN bool decode(IPC::Decoder&, InteractionInformationAtPosition&);
};
-}
+} // namespace WebKit
+namespace WTF {
+
+template<> struct EnumTraits<WebKit::InteractionInformationAtPosition::Selectability> {
+ using values = EnumValues<
+ WebKit::InteractionInformationAtPosition::Selectability,
+ WebKit::InteractionInformationAtPosition::Selectability::Selectable,
+ WebKit::InteractionInformationAtPosition::Selectability::UnselectableDueToFocusableElement,
+ WebKit::InteractionInformationAtPosition::Selectability::UnselectableDueToLargeElementBounds,
+ WebKit::InteractionInformationAtPosition::Selectability::UnselectableDueToUserSelectNone
+ >;
+};
+
+} // namespace WTF
+
#endif // PLATFORM(IOS_FAMILY)
Modified: branches/safari-612-branch/Source/WebKit/Shared/ios/InteractionInformationAtPosition.mm (285517 => 285518)
--- branches/safari-612-branch/Source/WebKit/Shared/ios/InteractionInformationAtPosition.mm 2021-11-09 19:42:03 UTC (rev 285517)
+++ branches/safari-612-branch/Source/WebKit/Shared/ios/InteractionInformationAtPosition.mm 2021-11-09 19:42:06 UTC (rev 285518)
@@ -40,7 +40,7 @@
encoder << canBeValid;
encoder << nodeAtPositionHasDoubleClickHandler;
- encoder << isSelectable;
+ encoder << selectability;
encoder << isSelected;
encoder << prefersDraggingOverTextSelection;
encoder << isNearMarkedText;
@@ -99,7 +99,7 @@
if (!decoder.decode(result.nodeAtPositionHasDoubleClickHandler))
return false;
- if (!decoder.decode(result.isSelectable))
+ if (!decoder.decode(result.selectability))
return false;
if (!decoder.decode(result.isSelected))
Modified: branches/safari-612-branch/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (285517 => 285518)
--- branches/safari-612-branch/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm 2021-11-09 19:42:03 UTC (rev 285517)
+++ branches/safari-612-branch/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm 2021-11-09 19:42:06 UTC (rev 285518)
@@ -2902,7 +2902,7 @@
return YES;
#endif
- return _positionInformation.isSelectable;
+ return _positionInformation.isSelectable();
}
- (BOOL)pointIsNearMarkedText:(CGPoint)point
@@ -2970,6 +2970,9 @@
if (![self ensurePositionInformationIsUpToDate:request])
return NO;
+ if (gesture == UIWKGestureLoupe && _positionInformation.selectability == WebKit::InteractionInformationAtPosition::Selectability::UnselectableDueToUserSelectNone)
+ return NO;
+
#if ENABLE(DATALIST_ELEMENT)
if (_positionInformation.preventTextInteraction)
return NO;
@@ -5312,7 +5315,7 @@
#if PLATFORM(MACCATALYST)
WebKit::InteractionInformationRequest request(WebCore::roundedIntPoint(point));
[self requestAsynchronousPositionInformationUpdate:request];
- if ([self _currentPositionInformationIsApproximatelyValidForRequest:request radiusForApproximation:2] && _positionInformation.isSelectable)
+ if ([self _currentPositionInformationIsApproximatelyValidForRequest:request radiusForApproximation:2] && _positionInformation.isSelectable())
return [WKTextPosition textPositionWithRect:_positionInformation.caretRect];
#endif
return nil;
Modified: branches/safari-612-branch/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm (285517 => 285518)
--- branches/safari-612-branch/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm 2021-11-09 19:42:03 UTC (rev 285517)
+++ branches/safari-612-branch/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm 2021-11-09 19:42:06 UTC (rev 285518)
@@ -2913,10 +2913,31 @@
if (!hitNode || !hitNode->renderer())
return;
- RenderObject* renderer = hitNode->renderer();
- boundsPositionInformation(*renderer, info);
+ auto* renderer = hitNode->renderer();
+ info.selectability = ([&] {
+ if (renderer->style().userSelectIncludingInert() == UserSelect::None)
+ return InteractionInformationAtPosition::Selectability::UnselectableDueToUserSelectNone;
+
+ if (is<Element>(*hitNode)) {
+ if (isAssistableElement(downcast<Element>(*hitNode)))
+ return InteractionInformationAtPosition::Selectability::UnselectableDueToFocusableElement;
+
+ if (rectIsTooBigForSelection(info.bounds, *result.innerNodeFrame())) {
+ // We don't want to select blocks that are larger than 97% of the visible area of the document.
+ // FIXME: Is this heuristic still needed, now that block selection has been removed?
+ return InteractionInformationAtPosition::Selectability::UnselectableDueToLargeElementBounds;
+ }
+ }
+
+ return InteractionInformationAtPosition::Selectability::Selectable;
+ })();
info.isSelected = result.isSelected();
+
+ if (info.isLink || info.isImage)
+ return;
+
+ boundsPositionInformation(*renderer, info);
if (is<Element>(*hitNode)) {
Element& element = downcast<Element>(*hitNode);
@@ -2930,13 +2951,8 @@
linkIndicatorPositionInformation(page, attachment, request, info);
if (attachment.file())
info.url = ""
- } else {
- info.isSelectable = renderer->style().userSelect() != UserSelect::None;
- // We don't want to select blocks that are larger than 97% of the visible area of the document.
- // FIXME: Is this heuristic still needed, now that block selection has been removed?
- if (info.isSelectable && !hitNode->isTextNode())
- info.isSelectable = !isAssistableElement(*downcast<Element>(hitNode)) && !rectIsTooBigForSelection(info.bounds, *result.innerNodeFrame());
}
+
for (auto currentNode = makeRefPtr(hitNode); currentNode; currentNode = currentNode->parentOrShadowHostNode()) {
auto* renderer = currentNode->renderer();
if (!renderer)
@@ -3112,8 +3128,7 @@
if (!info.isImage && request.includeImageData && is<HTMLImageElement>(hitTestNode))
imagePositionInformation(*this, downcast<HTMLImageElement>(*hitTestNode), request, info);
- if (!(info.isLink || info.isImage))
- selectionPositionInformation(*this, request, info);
+ selectionPositionInformation(*this, request, info);
// Prevent the callout bar from showing when tapping on the datalist button.
#if ENABLE(DATALIST_ELEMENT)