Skip to content
Permalink
Browse files
<model> should be draggable, similar to <img>
https://bugs.webkit.org/show_bug.cgi?id=229246

Reviewed by Wenson Hsieh.

Source/WebCore:

* page/DragActions.h:
(WebCore::anyDragSourceAction):
* page/DragController.cpp:
(WebCore::DragController::draggableElement const):
(WebCore::DragController::startDrag):
* page/EventHandler.cpp:
(WebCore::EventHandler::dragHysteresisExceeded const):
Make <model> draggable, vending a PasteboardImage with the model data and correct MIME type.
We currently make a DragImage from a node snapshot, but later will want a richer DragImage.

Source/WebKit:

* UIProcess/ios/DragDropInteractionState.mm:
(WebKit::shouldUseDragImageToCreatePreviewForDragSource):
For now, use the Web-Content-process-painted node-snapshot DragImage for the targeted preview on iOS.

Source/WebKitLegacy/mac:

* WebView/WebView.mm:
(kit):
Do nothing for <model> drags in legacy WebKit.

Tools:

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKit/cube.usdz: Added.
* TestWebKitAPI/Tests/ios/DragAndDropTestsIOS.mm:
(-[ModelLoadingMessageHandler userContentController:didReceiveScriptMessage:]):
(TestWebKitAPI::TEST):
Add a test that ensures that dragging a <model> works.


Canonical link: https://commits.webkit.org/242528@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@283563 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
hortont424 committed Oct 5, 2021
1 parent 3b7a8c4 commit e9393d2b7018f96082bf55359e18b151485b2d7c
Showing 13 changed files with 177 additions and 6 deletions.
@@ -1,3 +1,20 @@
2021-10-05 Tim Horton <timothy_horton@apple.com>

<model> should be draggable, similar to <img>
https://bugs.webkit.org/show_bug.cgi?id=229246

Reviewed by Wenson Hsieh.

* page/DragActions.h:
(WebCore::anyDragSourceAction):
* page/DragController.cpp:
(WebCore::DragController::draggableElement const):
(WebCore::DragController::startDrag):
* page/EventHandler.cpp:
(WebCore::EventHandler::dragHysteresisExceeded const):
Make <model> draggable, vending a PasteboardImage with the model data and correct MIME type.
We currently make a DragImage from a node snapshot, but later will want a richer DragImage.

2021-10-05 Gabriel Nava Marino <gnavamarino@apple.com>

Unsupported blending of mixed length types leads to nullptr deref when accessing m_value.calc in CSSPrimitiveValue::primitiveType()
@@ -73,6 +73,8 @@ class HTMLModelElement final : public HTMLElement, private CachedRawResourceClie

void enterFullscreen();

bool isDraggableIgnoringAttributes() const final { return true; }

private:
HTMLModelElement(const QualifiedName&, Document&);

@@ -46,15 +46,18 @@ constexpr OptionSet<DragDestinationAction> anyDragDestinationAction()

// See WebDragSourceAction.
enum class DragSourceAction : uint8_t {
DHTML = 1,
Image = 2,
Link = 4,
Selection = 8,
DHTML = 1 << 0,
Image = 1 << 1,
Link = 1 << 2,
Selection = 1 << 3,
#if ENABLE(ATTACHMENT_ELEMENT)
Attachment = 16,
Attachment = 1 << 4,
#endif
#if ENABLE(INPUT_TYPE_COLOR)
Color = 32,
Color = 1 << 5,
#endif
#if ENABLE(MODEL_ELEMENT)
Model = 1 << 6,
#endif
};

@@ -70,6 +73,9 @@ constexpr OptionSet<DragSourceAction> anyDragSourceAction()
#endif
#if ENABLE(INPUT_TYPE_COLOR)
, DragSourceAction::Color
#endif
#if ENABLE(MODEL_ELEMENT)
, DragSourceAction::Model
#endif
};
}
@@ -143,6 +149,9 @@ template<> struct EnumTraits<WebCore::DragSourceAction> {
#endif
#if ENABLE(INPUT_TYPE_COLOR)
, WebCore::DragSourceAction::Color
#endif
#if ENABLE(MODEL_ELEMENT)
, WebCore::DragSourceAction::Model
#endif
>;
};
@@ -58,12 +58,14 @@
#include "HTMLAttachmentElement.h"
#include "HTMLImageElement.h"
#include "HTMLInputElement.h"
#include "HTMLModelElement.h"
#include "HTMLParserIdioms.h"
#include "HTMLPlugInElement.h"
#include "HitTestRequest.h"
#include "HitTestResult.h"
#include "Image.h"
#include "ImageOrientation.h"
#include "Model.h"
#include "MoveSelectionCommand.h"
#include "Page.h"
#include "Pasteboard.h"
@@ -752,6 +754,15 @@ static bool imageElementIsDraggable(const HTMLImageElement& image, const Frame&
return cachedImage && !cachedImage->errorOccurred() && cachedImage->imageForRenderer(renderer);
}

#if ENABLE(MODEL_ELEMENT)

static bool modelElementIsDraggable(const HTMLModelElement& modelElement)
{
return !!modelElement.model();
}

#endif

#if ENABLE(ATTACHMENT_ELEMENT)

static RefPtr<HTMLAttachmentElement> enclosingAttachmentElement(Element& element)
@@ -823,6 +834,12 @@ Element* DragController::draggableElement(const Frame* sourceFrame, Element* sta
state.type.add(DragSourceAction::Color);
return element;
}
#endif
#if ENABLE(MODEL_ELEMENT)
if (m_dragSourceAction.contains(DragSourceAction::Model) && is<HTMLModelElement>(*element) && modelElementIsDraggable(downcast<HTMLModelElement>(*element))) {
state.type.add(DragSourceAction::Model);
return element;
}
#endif
}
}
@@ -1239,6 +1256,27 @@ bool DragController::startDrag(Frame& src, const DragState& state, OptionSet<Dra
}
#endif

#if ENABLE(MODEL_ELEMENT)
bool isModel = is<HTMLModelElement>(state.source);
if (isModel && m_dragSourceAction.contains(DragSourceAction::Model)) {
auto& modelElement = downcast<HTMLModelElement>(*state.source);
dragImage = DragImage { createDragImageForNode(src, modelElement) };

PasteboardImage pasteboardImage;
pasteboardImage.suggestedName = modelElement.currentSrc().lastPathComponent().toString();
pasteboardImage.resourceMIMEType = modelElement.model()->mimeType();
pasteboardImage.resourceData = modelElement.model()->data();
dataTransfer.pasteboard().write(pasteboardImage);

dragImageOffset = IntPoint { dragImageSize(dragImage.get()) };
dragLoc = dragLocForDHTMLDrag(mouseDraggedPoint, dragOrigin, dragImageOffset, false);

client().willPerformDragSourceAction(DragSourceAction::Model, dragOrigin, dataTransfer);
doSystemDrag(WTFMove(dragImage), dragLoc, dragOrigin, src, state, { });
return true;
}
#endif

if (state.type == DragSourceAction::DHTML && dragImage) {
ASSERT(m_dragSourceAction.contains(DragSourceAction::DHTML));
client().willPerformDragSourceAction(DragSourceAction::DHTML, dragOrigin, dataTransfer);
@@ -3885,6 +3885,9 @@ bool EventHandler::dragHysteresisExceeded(const FloatPoint& dragViewportLocation
case DragSourceAction::Image:
#if ENABLE(ATTACHMENT_ELEMENT)
case DragSourceAction::Attachment:
#endif
#if ENABLE(MODEL_ELEMENT)
case DragSourceAction::Model:
#endif
threshold = ImageDragHysteresis;
break;
@@ -1,3 +1,14 @@
2021-10-05 Tim Horton <timothy_horton@apple.com>

<model> should be draggable, similar to <img>
https://bugs.webkit.org/show_bug.cgi?id=229246

Reviewed by Wenson Hsieh.

* UIProcess/ios/DragDropInteractionState.mm:
(WebKit::shouldUseDragImageToCreatePreviewForDragSource):
For now, use the Web-Content-process-painted node-snapshot DragImage for the targeted preview on iOS.

2021-10-05 Tim Horton <timothy_horton@apple.com>

Add an alternate style for form controls, and implement it for checkboxes and radio buttons
@@ -103,6 +103,11 @@ static bool shouldUseDragImageToCreatePreviewForDragSource(const DragSourceState
return true;
#endif

#if ENABLE(MODEL_ELEMENT)
if (source.action.contains(DragSourceAction::Model))
return true;
#endif

return source.action.containsAny({ DragSourceAction::DHTML, DragSourceAction::Image });
}

@@ -1,3 +1,14 @@
2021-10-05 Tim Horton <timothy_horton@apple.com>

<model> should be draggable, similar to <img>
https://bugs.webkit.org/show_bug.cgi?id=229246

Reviewed by Wenson Hsieh.

* WebView/WebView.mm:
(kit):
Do nothing for <model> drags in legacy WebKit.

2021-10-03 David Kilzer <ddkilzer@apple.com>

WTF::RetainPtr<> allows assignment of two pointer types that are not assignable
@@ -718,6 +718,10 @@ WebDragSourceAction kit(std::optional<WebCore::DragSourceAction> action)
#if ENABLE(INPUT_TYPE_COLOR)
case WebCore::DragSourceAction::Color:
break;
#endif
#if ENABLE(MODEL_ELEMENT)
case WebCore::DragSourceAction::Model:
break;
#endif
}

@@ -1,3 +1,17 @@
2021-10-05 Tim Horton <timothy_horton@apple.com>

<model> should be draggable, similar to <img>
https://bugs.webkit.org/show_bug.cgi?id=229246

Reviewed by Wenson Hsieh.

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKit/cube.usdz: Added.
* TestWebKitAPI/Tests/ios/DragAndDropTestsIOS.mm:
(-[ModelLoadingMessageHandler userContentController:didReceiveScriptMessage:]):
(TestWebKitAPI::TEST):
Add a test that ensures that dragging a <model> works.

2021-10-05 Alex Christensen <achristensen@webkit.org>

Implement missing functions in PrivateClickMeasurementDaemonClient
@@ -175,6 +175,7 @@
2DC9451724D8AC0200430376 /* WebThreadLock.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2DC9451624D8AC0200430376 /* WebThreadLock.mm */; };
2DD7D3AF178227B30026E1E3 /* lots-of-text-vertical-lr.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2DD7D3AE178227AC0026E1E3 /* lots-of-text-vertical-lr.html */; };
2DD87145265F23B4005F997C /* BifurcatedGraphicsContextTestsCG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2DD87144265F23B4005F997C /* BifurcatedGraphicsContextTestsCG.cpp */; };
2DDD4DA4270B8B3500659A61 /* cube.usdz in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2DDD4DA3270B8B3300659A61 /* cube.usdz */; };
2DE71AFE1D49C0BD00904094 /* AnimatedResize.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2DE71AFD1D49C0BD00904094 /* AnimatedResize.mm */; };
2DE71B001D49C3ED00904094 /* blinking-div.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2DE71AFF1D49C2F000904094 /* blinking-div.html */; };
2DFF7B6D1DA487AF00814614 /* SnapshotStore.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2DFF7B6C1DA487AF00814614 /* SnapshotStore.mm */; };
@@ -1459,6 +1460,7 @@
9B62630C1F8C25C8007EE29B /* copy-url.html in Copy Resources */,
7AEAD4811E20122700416EFE /* CrossPartitionFileSchemeAccess.html in Copy Resources */,
4995A6F025E8772000E5F0A9 /* csp-document-uri-report.html in Copy Resources */,
2DDD4DA4270B8B3500659A61 /* cube.usdz in Copy Resources */,
F4AB578A1F65165400DB0DA1 /* custom-draggable-div.html in Copy Resources */,
290F4275172A221C00939FF0 /* custom-protocol-sync-xhr.html in Copy Resources */,
1CF59AE521E6977D006E37EC /* dark-mode.html in Copy Resources */,
@@ -1986,6 +1988,7 @@
2DD7D3A9178205D00026E1E3 /* ResizeReversePaginatedWebView.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ResizeReversePaginatedWebView.cpp; sourceTree = "<group>"; };
2DD7D3AE178227AC0026E1E3 /* lots-of-text-vertical-lr.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "lots-of-text-vertical-lr.html"; sourceTree = "<group>"; };
2DD87144265F23B4005F997C /* BifurcatedGraphicsContextTestsCG.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BifurcatedGraphicsContextTestsCG.cpp; path = cg/BifurcatedGraphicsContextTestsCG.cpp; sourceTree = "<group>"; };
2DDD4DA3270B8B3300659A61 /* cube.usdz */ = {isa = PBXFileReference; lastKnownFileType = file.usdz; path = cube.usdz; sourceTree = "<group>"; };
2DE71AFD1D49C0BD00904094 /* AnimatedResize.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AnimatedResize.mm; sourceTree = "<group>"; };
2DE71AFF1D49C2F000904094 /* blinking-div.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "blinking-div.html"; sourceTree = "<group>"; };
2DFF7B6C1DA487AF00814614 /* SnapshotStore.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SnapshotStore.mm; sourceTree = "<group>"; };
@@ -4628,6 +4631,7 @@
1A50AA1F1A2A4EA500F4C345 /* close-from-within-create-page.html */,
9B270FED1DDC25FD002D53F3 /* closed-shadow-tree-test.html */,
5C9E56861DF9148E00C9EE33 /* contentBlockerCheck.html */,
2DDD4DA3270B8B3300659A61 /* cube.usdz */,
290F4274172A1FDE00939FF0 /* custom-protocol-sync-xhr.html */,
118153432208B7AC00B2CCD2 /* deferred-script-load.html */,
118153452208B7E500B2CCD2 /* deferred-script.js */,
Binary file not shown.
@@ -31,6 +31,7 @@
#import "DragAndDropSimulator.h"
#import "NSItemProviderAdditions.h"
#import "PlatformUtilities.h"
#import "TestURLSchemeHandler.h"
#import "TestWKWebView.h"
#import "UIKitSPI.h"
#import "WKWebViewConfigurationExtras.h"
@@ -43,6 +44,7 @@
#import <WebKit/WKProcessPoolPrivate.h>
#import <WebKit/WKWebViewConfigurationPrivate.h>
#import <WebKit/WebItemProviderPasteboard.h>
#import <WebKit/_WKExperimentalFeature.h>
#import <WebKit/_WKProcessPoolConfiguration.h>
#import <wtf/Seconds.h>
#import <wtf/SoftLinking.h>
@@ -92,6 +94,21 @@ - (NSString *)editorValue

@end

@interface ModelLoadingMessageHandler : NSObject <WKScriptMessageHandler>

@property (nonatomic) BOOL didLoadModel;

@end

@implementation ModelLoadingMessageHandler
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
{
EXPECT_WK_STREQ(@"READY", [message body]);
_didLoadModel = true;
}
@end


static void loadTestPageAndEnsureInputSession(DragAndDropSimulator *simulator, NSString *testPageName)
{
TestWKWebView *webView = [simulator webView];
@@ -2156,6 +2173,42 @@ static BOOL isCompletelyWhite(UIImage *image)
EXPECT_WK_STREQ("one.foo.png (image/png)\ntwo.foo.PNG (image/png)", [webView stringByEvaluatingJavaScript:@"output.innerText"]);
}

TEST(DragAndDropTests, CanStartDragOnModel)
{
auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
for (_WKExperimentalFeature *feature in [WKPreferences _experimentalFeatures]) {
if ([feature.key isEqualToString:@"ModelElementEnabled"])
[[configuration preferences] _setEnabled:YES forFeature:feature];
}

// FIXME: Remove this after <rdar://problem/83863149> is fixed.
// It should not be necessary to use WKURLSchemeHandler here, but CFNetwork does not correctly identify USDZ files.
auto handler = adoptNS([TestURLSchemeHandler new]);
RetainPtr<NSData> modelData = [NSData dataWithContentsOfURL:[NSBundle.mainBundle URLForResource:@"cube" withExtension:@"usdz" subdirectory:@"TestWebKitAPI.resources"]];
[handler setStartURLSchemeTaskHandler:^(WKWebView *, id<WKURLSchemeTask> task) {
NSURLResponse *response = [[[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:@"model/vnd.usdz+zip" expectedContentLength:[modelData length] textEncodingName:nil] autorelease];
[task didReceiveResponse:response];
[task didReceiveData:modelData.get()];
[task didFinish];
}];

auto messageHandler = adoptNS([[ModelLoadingMessageHandler alloc] init]);
[[configuration userContentController] addScriptMessageHandler:messageHandler.get() name:@"modelLoading"];
[configuration setURLSchemeHandler:handler.get() forURLScheme:@"model"];

auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500) configuration:configuration.get()]);
[webView synchronouslyLoadHTMLString:@"<model><source src='model://cube.usdz'></model><script>document.getElementsByTagName('model')[0].ready.then(() => { window.webkit.messageHandlers.modelLoading.postMessage('READY') });</script>"];

while (![messageHandler didLoadModel])
Util::spinRunLoop();

auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebView:webView.get()]);
[simulator runFrom:CGPointMake(20, 20) to:CGPointMake(100, 100)];

NSArray *registeredTypes = [[simulator sourceItemProviders].firstObject registeredTypeIdentifiers];
EXPECT_WK_STREQ("com.pixar.universal-scene-description-mobile", [registeredTypes firstObject]);
}

} // namespace TestWebKitAPI

#endif // ENABLE(DRAG_SUPPORT) && PLATFORM(IOS_FAMILY) && !PLATFORM(MACCATALYST)

0 comments on commit e9393d2

Please sign in to comment.