WebKit Bugzilla
Attachment 347225 Details for
Bug 188464
: Support drag-and-drop for input[type=color]
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-188464-20180815165132.patch (text/plain), 74.83 KB, created by
Aditya Keerthi
on 2018-08-15 16:51:33 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Aditya Keerthi
Created:
2018-08-15 16:51:33 PDT
Size:
74.83 KB
patch
obsolete
>Subversion Revision: 234818 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 069efc572d3ca1d9cd484eef1fdee358a0fa55f9..70ff8518783d85b8160e44c65a1cb078faffa87d 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,75 @@ >+2018-08-15 Aditya Keerthi <akeerthi@apple.com> >+ >+ Support drag-and-drop for input[type=color] >+ https://bugs.webkit.org/show_bug.cgi?id=188464 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ input[type=color] should support native drag and drop on both macOS and iOS. >+ >+ Added methods to Pasteboard and PlatformPasteboard to enable colors to be read >+ from and written to the pasteboard. On macOS, colors are managed through the >+ NSColorPboardType, whereas on iOS, colors are managed through the >+ 'com.apple.uikit.color' identifier. >+ >+ DragSourceActionColor was added to the list of DragSourceActions to identify >+ when a color input is being dragged. >+ >+ Tests: editing/pasteboard/drag-and-drop-color-input-events.html >+ editing/pasteboard/drag-and-drop-color-input.html >+ >+ * page/DragActions.h: >+ * page/DragController.cpp: >+ (WebCore::DragController::dragEnteredOrUpdated): >+ (WebCore::isEnabledColorInput): >+ (WebCore::DragController::concludeEditDrag): >+ (WebCore::DragController::canProcessDrag): >+ (WebCore::DragController::draggableElement const): >+ (WebCore::DragController::startDrag): >+ * page/EventHandler.cpp: >+ (WebCore::EventHandler::dragHysteresisExceeded const): >+ (WebCore::EventHandler::handleDrag): >+ * page/EventHandler.h: >+ * page/mac/DragControllerMac.mm: >+ (WebCore::DragController::updateSupportedTypeIdentifiersForDragHandlingMethod const): >+ * platform/DragData.h: >+ * platform/DragImage.cpp: >+ (WebCore::DragImage::operator=): >+ * platform/DragImage.h: Added the visiblePath property to DragImage, in order for >+ us to be able to clip images in the UITargetedDragPreview on iOS. >+ * platform/DragItem.h: >+ (WebCore::DragItem::encode const): >+ (WebCore::DragItem::decode): >+ * platform/Pasteboard.h: >+ * platform/PasteboardStrategy.h: >+ * platform/PlatformPasteboard.h: >+ * platform/gtk/DragImageGtk.cpp: >+ (WebCore::createDragImageForColor): >+ * platform/gtk/PasteboardGtk.cpp: >+ (WebCore::Pasteboard::write): >+ * platform/ios/DragImageIOS.mm: >+ (WebCore::createDragImageForColor): >+ * platform/ios/PasteboardIOS.mm: >+ (WebCore::Pasteboard::write): >+ * platform/ios/PlatformPasteboardIOS.mm: >+ (WebCore::PlatformPasteboard::color): >+ (WebCore::PlatformPasteboard::setColor): >+ * platform/mac/DragDataMac.mm: >+ (WebCore::colorPasteboardType): >+ (WebCore::DragData::containsCompatibleContent const): >+ * platform/mac/DragImageMac.mm: >+ (WebCore::createDragImageForColor): Draw a rounded rectangle with a fill color >+ matching the value of the dragged color input. The rendered image is designed to >+ mimic the preview shown when dragging an NSColorWell. >+ * platform/mac/PasteboardMac.mm: >+ (WebCore::Pasteboard::write): >+ * platform/mac/PlatformPasteboardMac.mm: >+ (WebCore::PlatformPasteboard::setColor): >+ * platform/win/PasteboardWin.cpp: >+ (WebCore::Pasteboard::write): >+ * platform/wpe/PasteboardWPE.cpp: >+ (WebCore::Pasteboard::write): >+ > 2018-08-13 Ali Juma <ajuma@chromium.org> > > [IntersectionObserver] Validate threshold values >diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog >index 91b71f7bfc9b73f757f8b74ae88fbfcb4b4f3d2a..f5bab1350409d962956c12a9aa50d366f5bf29b2 100644 >--- a/Source/WebKit/ChangeLog >+++ b/Source/WebKit/ChangeLog >@@ -1,3 +1,44 @@ >+2018-08-15 Aditya Keerthi <akeerthi@apple.com> >+ >+ Support drag-and-drop for input[type=color] >+ https://bugs.webkit.org/show_bug.cgi?id=188464 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ On iOS, the drag preview for the color input is a rounded rectangle. In order to >+ ensure that the corners appear transparent, the visiblePath property of the >+ UIDragPreviewParameters was set to match the preview's shape. This also required >+ the creation of an additional ArgumentCoder for Path. >+ >+ When beginning the drag session, the preview should appear centered about the >+ color input. This is managed in createTargetedDragPreview. However, once the >+ preview is dragged, the preview should be at the center of the touch location. >+ Consequently, DragSourceActionColor was added to the list of sources that could >+ update the drag preview after lifting. >+ >+ * Shared/WebCoreArgumentCoders.cpp: >+ (IPC::ArgumentCoder<Path>::decode): >+ * Shared/WebCoreArgumentCoders.h: >+ * UIProcess/Cocoa/WebPasteboardProxyCocoa.mm: >+ (WebKit::WebPasteboardProxy::setPasteboardColor): >+ * UIProcess/WebPasteboardProxy.h: >+ * UIProcess/WebPasteboardProxy.messages.in: >+ * UIProcess/ios/DragDropInteractionState.h: >+ * UIProcess/ios/DragDropInteractionState.mm: >+ (WebKit::createTargetedDragPreview): >+ (WebKit::shouldUseDragImageToCreatePreviewForDragSource): >+ (WebKit::shouldUseVisiblePathToCreatePreviewForDragSource): >+ (WebKit::canUpdatePreviewForActiveDragSource): >+ (WebKit::DragDropInteractionState::previewForDragItem const): >+ (WebKit::DragDropInteractionState::stageDragItem): >+ (WebKit::DragDropInteractionState::updatePreviewsForActiveDragSources): >+ * UIProcess/ios/forms/WKFormColorPicker.mm: >+ (-[WKColorPicker initWithView:]): >+ * UIProcess/mac/WebColorPickerMac.h: >+ * WebProcess/WebCoreSupport/WebPlatformStrategies.cpp: >+ (WebKit::WebPlatformStrategies::setColor): >+ * WebProcess/WebCoreSupport/WebPlatformStrategies.h: >+ > 2018-08-13 Wenson Hsieh <wenson_hsieh@apple.com> > > [WK2] [macOS] Implement a mechanism to test drag and drop >diff --git a/Source/WebKitLegacy/mac/ChangeLog b/Source/WebKitLegacy/mac/ChangeLog >index 77093f102445849d564e90ff87bad866f1a160df..b51bf978b5823e9f54826c0112f84e01fde4d4d0 100644 >--- a/Source/WebKitLegacy/mac/ChangeLog >+++ b/Source/WebKitLegacy/mac/ChangeLog >@@ -1,3 +1,14 @@ >+2018-08-15 Aditya Keerthi <akeerthi@apple.com> >+ >+ Support drag-and-drop for input[type=color] >+ https://bugs.webkit.org/show_bug.cgi?id=188464 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * WebCoreSupport/WebPlatformStrategies.h: >+ * WebCoreSupport/WebPlatformStrategies.mm: >+ (WebPlatformStrategies::setColor): >+ > 2018-08-13 Alex Christensen <achristensen@webkit.org> > > Use a 1-byte enum class for TextDirection >diff --git a/Source/WebCore/page/DragActions.h b/Source/WebCore/page/DragActions.h >index 2c1a37a6e0be5273c2c550e4849f26fe3525875e..c3d4a41767de373b3b14cd73e437a0880cf98bdd 100644 >--- a/Source/WebCore/page/DragActions.h >+++ b/Source/WebCore/page/DragActions.h >@@ -47,6 +47,9 @@ namespace WebCore { > DragSourceActionSelection = 8, > #if ENABLE(ATTACHMENT_ELEMENT) > DragSourceActionAttachment = 16, >+#endif >+#if ENABLE(INPUT_TYPE_COLOR) >+ DragSourceActionColor = 32, > #endif > DragSourceActionAny = UINT_MAX > } DragSourceAction; >diff --git a/Source/WebCore/page/DragController.cpp b/Source/WebCore/page/DragController.cpp >index 6c49e66983452dfdd8d7064dda461290f559a2a7..e4bc381187b696a2e27e6c0547afee972ac99ff0 100644 >--- a/Source/WebCore/page/DragController.cpp >+++ b/Source/WebCore/page/DragController.cpp >@@ -321,7 +321,8 @@ DragOperation DragController::dragEnteredOrUpdated(const DragData& dragData) > dragOperation = operationForLoad(dragData); > if (dragOperation != DragOperationNone) > m_dragHandlingMethod = DragHandlingMethod::PageLoad; >- } >+ } else if (m_dragHandlingMethod == DragHandlingMethod::SetColor) >+ dragOperation = DragOperationCopy; > > updateSupportedTypeIdentifiersForDragHandlingMethod(m_dragHandlingMethod, dragData); > return dragOperation; >@@ -343,6 +344,20 @@ static HTMLInputElement* asFileInput(Node& node) > return inputElement && inputElement->isFileUpload() ? inputElement : nullptr; > } > >+#if ENABLE(INPUT_TYPE_COLOR) >+static bool isEnabledColorInput(Node& node, bool setToShadowAncestor) >+{ >+ Node* candidate = setToShadowAncestor ? node.deprecatedShadowAncestorNode() : &node; >+ if (is<HTMLInputElement>(*candidate)) { >+ auto& input = downcast<HTMLInputElement>(*candidate); >+ if (input.isColorControl() && !input.isDisabledFormControl()) >+ return true; >+ } >+ >+ return false; >+} >+#endif >+ > // This can return null if an empty document is loaded. > static Element* elementUnderMouse(Document* documentUnderMouse, const IntPoint& p) > { >@@ -539,6 +554,13 @@ bool DragController::concludeEditDrag(const DragData& dragData) > Color color = dragData.asColor(); > if (!color.isValid()) > return false; >+#if ENABLE(INPUT_TYPE_COLOR) >+ if (isEnabledColorInput(*element, false)) { >+ auto& input = downcast<HTMLInputElement>(*element); >+ input.setValue(color.serialized(), DispatchInputAndChangeEvent); >+ return true; >+ } >+#endif > auto innerRange = innerFrame->selection().toNormalizedRange(); > if (!innerRange) > return false; >@@ -643,6 +665,10 @@ bool DragController::canProcessDrag(const DragData& dragData) > DragData::DraggingPurpose dragPurpose = DragData::DraggingPurpose::ForEditing; > if (asFileInput(*result.innerNonSharedNode())) > dragPurpose = DragData::DraggingPurpose::ForFileUpload; >+#if ENABLE(INPUT_TYPE_COLOR) >+ else if (isEnabledColorInput(*result.innerNonSharedNode(), true)) >+ dragPurpose = DragData::DraggingPurpose::ForColorControl; >+#endif > > if (!dragData.containsCompatibleContent(dragPurpose)) > return false; >@@ -650,6 +676,11 @@ bool DragController::canProcessDrag(const DragData& dragData) > if (dragPurpose == DragData::DraggingPurpose::ForFileUpload) > return true; > >+#if ENABLE(INPUT_TYPE_COLOR) >+ if (dragPurpose == DragData::DraggingPurpose::ForColorControl) >+ return true; >+#endif >+ > if (is<HTMLPlugInElement>(*result.innerNonSharedNode())) { > if (!downcast<HTMLPlugInElement>(result.innerNonSharedNode())->canProcessDrag() && !result.innerNonSharedNode()->hasEditableStyle()) > return false; >@@ -784,6 +815,13 @@ Element* DragController::draggableElement(const Frame* sourceFrame, Element* sta > state.type = static_cast<DragSourceAction>(state.type | DragSourceActionAttachment); > return element; > } >+#endif >+#if ENABLE(INPUT_TYPE_COLOR) >+ if ((m_dragSourceAction & DragSourceActionColor) >+ && isEnabledColorInput(*element, false)) { >+ state.type = static_cast<DragSourceAction>(state.type | DragSourceActionColor); >+ return element; >+ } > #endif > } > } >@@ -874,6 +912,10 @@ bool DragController::startDrag(Frame& src, const DragState& state, DragOperation > #endif > #if ENABLE(ATTACHMENT_ELEMENT) > includeShadowDOM = includeShadowDOM || is<HTMLAttachmentElement>(state.source.get()); >+#endif >+#if ENABLE(INPUT_TYPE_COLOR) >+ bool isColorControl = is<HTMLInputElement>(state.source) && downcast<HTMLInputElement>(*state.source).isColorControl(); >+ includeShadowDOM = includeShadowDOM || isColorControl; > #endif > bool sourceContainsHitNode; > if (!includeShadowDOM) >@@ -1130,6 +1172,24 @@ bool DragController::startDrag(Frame& src, const DragState& state, DragOperation > } > #endif > >+#if ENABLE(INPUT_TYPE_COLOR) >+ if (isColorControl && m_dragSourceAction & DragSourceActionColor) { >+ auto& input = downcast<HTMLInputElement>(*state.source); >+ auto color = input.valueAsColor(); >+ >+ Path visiblePath; >+ dragImage = DragImage { createDragImageForColor(color, input.boundsInRootViewSpace(), input.document().page()->pageScaleFactor(), visiblePath) }; >+ dragImage.setVisiblePath(visiblePath); >+ dataTransfer.pasteboard().write(color); >+ dragImageOffset = IntPoint { dragImageSize(dragImage.get()) }; >+ dragLoc = dragLocForDHTMLDrag(mouseDraggedPoint, dragOrigin, dragImageOffset, false); >+ >+ m_client.willPerformDragSourceAction(DragSourceActionColor, dragOrigin, dataTransfer); >+ doSystemDrag(WTFMove(dragImage), dragLoc, dragOrigin, src, state, { }); >+ return true; >+ } >+#endif >+ > if (state.type == DragSourceActionDHTML && dragImage) { > ASSERT(m_dragSourceAction & DragSourceActionDHTML); > m_client.willPerformDragSourceAction(DragSourceActionDHTML, dragOrigin, dataTransfer); >diff --git a/Source/WebCore/page/EventHandler.cpp b/Source/WebCore/page/EventHandler.cpp >index 15bce50c7b2af8466b3279fb71259ec12abb7ea7..28605ea4d8dcdc85d981bff3d06ec4e2d7729a08 100644 >--- a/Source/WebCore/page/EventHandler.cpp >+++ b/Source/WebCore/page/EventHandler.cpp >@@ -134,6 +134,7 @@ using namespace HTMLNames; > const int LinkDragHysteresis = 40; > const int ImageDragHysteresis = 5; > const int TextDragHysteresis = 3; >+const int ColorDragHystersis = 3; > const int GeneralDragHysteresis = 3; > #if PLATFORM(COCOA) > const Seconds EventHandler::TextDragDelay { 150_ms }; >@@ -3510,6 +3511,11 @@ bool EventHandler::dragHysteresisExceeded(const FloatPoint& dragViewportLocation > case DragSourceActionLink: > threshold = LinkDragHysteresis; > break; >+#if ENABLE(INPUT_TYPE_COLOR) >+ case DragSourceActionColor: >+ threshold = ColorDragHystersis; >+ break; >+#endif > case DragSourceActionDHTML: > break; > case DragSourceActionNone: >@@ -3690,16 +3696,16 @@ bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event, CheckDr > > if (!ExactlyOneBitSet(dragState().type)) { > ASSERT((dragState().type & DragSourceActionSelection)); >-#if ENABLE(ATTACHMENT_ELEMENT) >- ASSERT((dragState().type & ~DragSourceActionSelection) == DragSourceActionDHTML >- || (dragState().type & ~DragSourceActionSelection) == DragSourceActionImage >- || (dragState().type & ~DragSourceActionSelection) == DragSourceActionAttachment >- || (dragState().type & ~DragSourceActionSelection) == DragSourceActionLink); >-#else > ASSERT((dragState().type & ~DragSourceActionSelection) == DragSourceActionDHTML > || (dragState().type & ~DragSourceActionSelection) == DragSourceActionImage >- || (dragState().type & ~DragSourceActionSelection) == DragSourceActionLink); >+#if ENABLE(ATTACHMENT_ELEMENT) >+ || (dragState().type & ~DragSourceActionSelection) == DragSourceActionAttachment >+#endif >+#if ENABLE(INPUT_TYPE_COLOR) >+ || (dragState().type & ~DragSourceActionSelection) == DragSourceActionColor > #endif >+ || (dragState().type & ~DragSourceActionSelection) == DragSourceActionLink); >+ > dragState().type = DragSourceActionSelection; > } > >diff --git a/Source/WebCore/page/EventHandler.h b/Source/WebCore/page/EventHandler.h >index 3ebe56f9b413de0bf3b292e998af86a8dcc2aba4..75ad2681445c52b97508b59ce1ba9a11e0682fe9 100644 >--- a/Source/WebCore/page/EventHandler.h >+++ b/Source/WebCore/page/EventHandler.h >@@ -100,6 +100,7 @@ struct DragState; > extern const int LinkDragHysteresis; > extern const int ImageDragHysteresis; > extern const int TextDragHysteresis; >+extern const int ColorDragHystersis; > extern const int GeneralDragHysteresis; > #endif > >diff --git a/Source/WebCore/page/mac/DragControllerMac.mm b/Source/WebCore/page/mac/DragControllerMac.mm >index 55f2134065c854c06dcbccbf9376f8461626e876..0e3dc5f08156abb154bdda6d6ae297eee21286bb 100644 >--- a/Source/WebCore/page/mac/DragControllerMac.mm >+++ b/Source/WebCore/page/mac/DragControllerMac.mm >@@ -144,6 +144,9 @@ void DragController::updateSupportedTypeIdentifiersForDragHandlingMethod(DragHan > supportedTypes.append(type); > } > break; >+ case DragHandlingMethod::SetColor: >+ supportedTypes.append(UIColorPboardType); >+ break; > default: > for (NSString *type in Pasteboard::supportedFileUploadPasteboardTypes()) > supportedTypes.append(type); >diff --git a/Source/WebCore/platform/DragData.h b/Source/WebCore/platform/DragData.h >index 0da8bc35e725d1e8967ea8f425f3646e4c048e46..1a4a45f805cc506ab9f191f8061578704ff49206 100644 >--- a/Source/WebCore/platform/DragData.h >+++ b/Source/WebCore/platform/DragData.h >@@ -73,7 +73,7 @@ typedef HashMap<unsigned, Vector<String>> DragDataMap; > class DragData { > public: > enum FilenameConversionPolicy { DoNotConvertFilenames, ConvertFilenames }; >- enum class DraggingPurpose { ForEditing, ForFileUpload }; >+ enum class DraggingPurpose { ForEditing, ForFileUpload, ForColorControl }; > > // clientPosition is taken to be the position of the drag event within the target window, with (0,0) at the top left > WEBCORE_EXPORT DragData(DragDataRef, const IntPoint& clientPosition, const IntPoint& globalPosition, DragOperation, DragApplicationFlags = DragApplicationNone, DragDestinationAction actions = DragDestinationActionAny); >diff --git a/Source/WebCore/platform/DragImage.cpp b/Source/WebCore/platform/DragImage.cpp >index c8a94e093e77229c4a611729ea9dedb2d9e8fdc7..ca4036b2b734c5f7931bec376d888276c4aed7f9 100644 >--- a/Source/WebCore/platform/DragImage.cpp >+++ b/Source/WebCore/platform/DragImage.cpp >@@ -38,6 +38,12 @@ > > namespace WebCore { > >+#if PLATFORM(COCOA) >+const float ColorSwatchCornerRadius = 4; >+const float ColorSwatchStrokeSize = 4; >+const float ColorSwatchWidth = 24; >+#endif >+ > DragImageRef fitDragImageToMaxSize(DragImageRef image, const IntSize& layoutSize, const IntSize& maxSize) > { > float heightResizeRatio = 0.0f; >@@ -259,6 +265,7 @@ DragImage::DragImage(DragImage&& other) > : m_dragImageRef { std::exchange(other.m_dragImageRef, nullptr) } > { > m_indicatorData = other.m_indicatorData; >+ m_visiblePath = other.m_visiblePath; > } > > DragImage& DragImage::operator=(DragImage&& other) >@@ -268,6 +275,7 @@ DragImage& DragImage::operator=(DragImage&& other) > > m_dragImageRef = std::exchange(other.m_dragImageRef, nullptr); > m_indicatorData = other.m_indicatorData; >+ m_visiblePath = other.m_visiblePath; > > return *this; > } >diff --git a/Source/WebCore/platform/DragImage.h b/Source/WebCore/platform/DragImage.h >index aa1699e568cb102e79021f08579ecb4b4057d9dd..be5b4c9c2a4704a1db9112c4ce94eac43f15d6f9 100644 >--- a/Source/WebCore/platform/DragImage.h >+++ b/Source/WebCore/platform/DragImage.h >@@ -28,6 +28,7 @@ > #include "FloatSize.h" > #include "ImageOrientation.h" > #include "IntSize.h" >+#include "Path.h" > #include "TextFlags.h" > #include "TextIndicator.h" > #include <wtf/Forward.h> >@@ -69,7 +70,9 @@ typedef RefPtr<cairo_surface_t> DragImageRef; > #endif > > #if PLATFORM(COCOA) >-static const float SelectionDragImagePadding = 15; >+extern const float ColorSwatchCornerRadius; >+extern const float ColorSwatchStrokeSize; >+extern const float ColorSwatchWidth; > #endif > > IntSize dragImageSize(DragImageRef); >@@ -88,6 +91,7 @@ DragImageRef createDragImageIconForCachedImageFilename(const String&); > WEBCORE_EXPORT DragImageRef createDragImageForNode(Frame&, Node&); > WEBCORE_EXPORT DragImageRef createDragImageForSelection(Frame&, TextIndicatorData&, bool forceBlackText = false); > WEBCORE_EXPORT DragImageRef createDragImageForRange(Frame&, Range&, bool forceBlackText = false); >+DragImageRef createDragImageForColor(const Color&, const FloatRect&, float, Path&); > DragImageRef createDragImageForImage(Frame&, Node&, IntRect& imageRect, IntRect& elementRect); > DragImageRef createDragImageForLink(Element&, URL&, const String& label, TextIndicatorData&, FontRenderingMode, float deviceScaleFactor); > void deleteDragImage(DragImageRef); >@@ -108,12 +112,17 @@ public: > bool hasIndicatorData() const { return !!m_indicatorData; } > std::optional<TextIndicatorData> indicatorData() const { return m_indicatorData; } > >+ void setVisiblePath(const Path& path) { m_visiblePath = path; } >+ bool hasVisiblePath() const { return !!m_visiblePath; } >+ std::optional<Path> visiblePath() const { return m_visiblePath; } >+ > explicit operator bool() const { return !!m_dragImageRef; } > DragImageRef get() const { return m_dragImageRef; } > > private: > DragImageRef m_dragImageRef; > std::optional<TextIndicatorData> m_indicatorData; >+ std::optional<Path> m_visiblePath; > }; > > } >diff --git a/Source/WebCore/platform/DragItem.h b/Source/WebCore/platform/DragItem.h >index 97680cd1560c01716ff52e3d7302761cf98069cf..3eae743754289ad1573d5309c9fb144bda8f71b9 100644 >--- a/Source/WebCore/platform/DragItem.h >+++ b/Source/WebCore/platform/DragItem.h >@@ -67,6 +67,10 @@ void DragItem::encode(Encoder& encoder) const > encoder << hasIndicatorData; > if (hasIndicatorData) > encoder << image.indicatorData().value(); >+ bool hasVisiblePath = image.hasVisiblePath(); >+ encoder << hasVisiblePath; >+ if (hasVisiblePath) >+ encoder << image.visiblePath().value(); > encoder << promisedBlob; > } > >@@ -99,6 +103,16 @@ bool DragItem::decode(Decoder& decoder, DragItem& result) > return false; > result.image.setIndicatorData(*indicatorData); > } >+ bool hasVisiblePath; >+ if (!decoder.decode(hasVisiblePath)) >+ return false; >+ if (hasVisiblePath) { >+ std::optional<Path> visiblePath; >+ decoder >> visiblePath; >+ if (!visiblePath) >+ return false; >+ result.image.setVisiblePath(*visiblePath); >+ } > if (!decoder.decode(result.promisedBlob)) > return false; > return true; >diff --git a/Source/WebCore/platform/Pasteboard.h b/Source/WebCore/platform/Pasteboard.h >index e88e28b38ea223edef70c7671b9bc5fb4c811a47..111f3afceaa7856bd71283a5b8e7a05348364063 100644 >--- a/Source/WebCore/platform/Pasteboard.h >+++ b/Source/WebCore/platform/Pasteboard.h >@@ -213,6 +213,7 @@ public: > virtual WEBCORE_EXPORT void read(PasteboardWebContentReader&, WebContentReadingPolicy = WebContentReadingPolicy::AnyType); > virtual WEBCORE_EXPORT void read(PasteboardFileReader&); > >+ virtual WEBCORE_EXPORT void write(const Color&); > virtual WEBCORE_EXPORT void write(const PasteboardURL&); > virtual WEBCORE_EXPORT void writeTrustworthyWebURLsPboardType(const PasteboardURL&); > virtual WEBCORE_EXPORT void write(const PasteboardImage&); >@@ -331,6 +332,7 @@ private: > > #if PLATFORM(IOS) > extern NSString *WebArchivePboardType; >+extern NSString *UIColorPboardType; > #endif > > #if PLATFORM(MAC) >diff --git a/Source/WebCore/platform/PasteboardStrategy.h b/Source/WebCore/platform/PasteboardStrategy.h >index be58bcfaf665b824e65b5a1760f4fcab32333a02..5ea4c6972ecaaf89d7068a6907ad68e50caf58d3 100644 >--- a/Source/WebCore/platform/PasteboardStrategy.h >+++ b/Source/WebCore/platform/PasteboardStrategy.h >@@ -71,6 +71,7 @@ public: > virtual long setTypes(const Vector<String>& pasteboardTypes, const String& pasteboardName) = 0; > virtual long setBufferForType(SharedBuffer*, const String& pasteboardType, const String& pasteboardName) = 0; > virtual long setURL(const PasteboardURL&, const String& pasteboardName) = 0; >+ virtual long setColor(const Color&, const String& pasteboardName) = 0; > virtual long setStringForType(const String&, const String& pasteboardType, const String& pasteboardName) = 0; > #endif > >diff --git a/Source/WebCore/platform/PlatformPasteboard.h b/Source/WebCore/platform/PlatformPasteboard.h >index f10bb5590fb777224c87b0f2fbda876b5afe5342..ec93df08161cede48e12058f596f711837a15214 100644 >--- a/Source/WebCore/platform/PlatformPasteboard.h >+++ b/Source/WebCore/platform/PlatformPasteboard.h >@@ -85,6 +85,7 @@ public: > WEBCORE_EXPORT long copy(const String& fromPasteboard); > WEBCORE_EXPORT long setBufferForType(SharedBuffer*, const String& pasteboardType); > WEBCORE_EXPORT long setURL(const PasteboardURL&); >+ WEBCORE_EXPORT long setColor(const Color&); > WEBCORE_EXPORT long setStringForType(const String&, const String& pasteboardType); > WEBCORE_EXPORT void write(const PasteboardWebContent&); > WEBCORE_EXPORT void write(const PasteboardImage&); >diff --git a/Source/WebCore/platform/gtk/DragImageGtk.cpp b/Source/WebCore/platform/gtk/DragImageGtk.cpp >index d41a4e569235f4d822ae82cb8b8785916ddd9376..33f4fe3a42f05f2d6b93db0fada87843e9b70268 100644 >--- a/Source/WebCore/platform/gtk/DragImageGtk.cpp >+++ b/Source/WebCore/platform/gtk/DragImageGtk.cpp >@@ -97,4 +97,9 @@ DragImageRef createDragImageForLink(Element&, URL&, const String&, TextIndicator > return nullptr; > } > >+DragImageRef createDragImageForColor(const Color&, const FloatRect&, float, Path&) >+{ >+ return nullptr; >+} >+ > } >diff --git a/Source/WebCore/platform/gtk/PasteboardGtk.cpp b/Source/WebCore/platform/gtk/PasteboardGtk.cpp >index d5baa1c9b6fe507dd1288de74b18b52508cfb983..a4ab610a73ff1ac91490ddc2008c488d42c900f0 100644 >--- a/Source/WebCore/platform/gtk/PasteboardGtk.cpp >+++ b/Source/WebCore/platform/gtk/PasteboardGtk.cpp >@@ -20,6 +20,7 @@ > #include "config.h" > #include "Pasteboard.h" > >+#include "Color.h" > #include "DragData.h" > #include "Image.h" > #include "NotImplemented.h" >@@ -332,4 +333,8 @@ void Pasteboard::writeCustomData(const PasteboardCustomData&) > { > } > >+void Pasteboard::write(const Color&) >+{ >+} >+ > } >diff --git a/Source/WebCore/platform/ios/DragImageIOS.mm b/Source/WebCore/platform/ios/DragImageIOS.mm >index a7996fd0db1d22de68794c4ac3c8f9cbe24020b5..5fb215a2970dd962aa0bdca983a9104ed4d43e10 100644 >--- a/Source/WebCore/platform/ios/DragImageIOS.mm >+++ b/Source/WebCore/platform/ios/DragImageIOS.mm >@@ -251,6 +251,23 @@ DragImageRef createDragImageForRange(Frame& frame, Range& range, bool forceBlack > return finalImage.CGImage; > } > >+DragImageRef createDragImageForColor(const Color& color, const FloatRect& elementRect, float pageScaleFactor, Path& visiblePath) >+{ >+ FloatRect imageRect { 0, 0, elementRect.width() * pageScaleFactor, elementRect.height() * pageScaleFactor }; >+ FloatRoundedRect swatch { imageRect, FloatRoundedRect::Radii(ColorSwatchCornerRadius * pageScaleFactor) }; >+ >+ auto render = adoptNS([allocUIGraphicsImageRendererInstance() initWithSize:imageRect.size()]); >+ UIImage *image = [render imageWithActions:^(UIGraphicsImageRendererContext *rendererContext) { >+ GraphicsContext context { rendererContext.CGContext }; >+ context.translate(0, CGRectGetHeight(imageRect)); >+ context.scale({ 1, -1 }); >+ context.fillRoundedRect(swatch, color); >+ }]; >+ >+ visiblePath.addRoundedRect(swatch); >+ return image.CGImage; >+} >+ > #else > > void deleteDragImage(RetainPtr<CGImageRef>) >diff --git a/Source/WebCore/platform/ios/PasteboardIOS.mm b/Source/WebCore/platform/ios/PasteboardIOS.mm >index 7d82c093903cc4b2fc8b6ade18368cf2d98403f0..3c709708b1221589877ba35f9a4b3cea0f1ec614 100644 >--- a/Source/WebCore/platform/ios/PasteboardIOS.mm >+++ b/Source/WebCore/platform/ios/PasteboardIOS.mm >@@ -83,6 +83,7 @@ static long changeCountForPasteboard(const String& pasteboardName = { }) > > // FIXME: Does this need to be declared in the header file? > WEBCORE_EXPORT NSString *WebArchivePboardType = @"Apple Web Archive pasteboard type"; >+NSString *UIColorPboardType = @"com.apple.uikit.color"; > > Pasteboard::Pasteboard() > : m_changeCount(0) >@@ -139,6 +140,11 @@ void Pasteboard::writeTrustworthyWebURLsPboardType(const PasteboardURL&) > ASSERT_NOT_REACHED(); > } > >+void Pasteboard::write(const Color& color) >+{ >+ platformStrategies()->pasteboardStrategy()->setColor(color, m_pasteboardName); >+} >+ > bool Pasteboard::canSmartReplace() > { > return false; >diff --git a/Source/WebCore/platform/ios/PlatformPasteboardIOS.mm b/Source/WebCore/platform/ios/PlatformPasteboardIOS.mm >index a5ca0372f4583900c2674e32f8ee4a68d2d5aa94..f1fea077afab4abb5d5f2377f9684ff21effd178 100644 >--- a/Source/WebCore/platform/ios/PlatformPasteboardIOS.mm >+++ b/Source/WebCore/platform/ios/PlatformPasteboardIOS.mm >@@ -37,6 +37,7 @@ > #import "WebCoreNSURLExtras.h" > #import "WebItemProviderPasteboard.h" > #import <MobileCoreServices/MobileCoreServices.h> >+#import <UIKit/UIColor.h> > #import <UIKit/UIImage.h> > #import <UIKit/UIPasteboard.h> > #import <pal/spi/cocoa/NSKeyedArchiverSPI.h> >@@ -49,6 +50,7 @@ > #define NSURL_SUPPORTS_TITLE (!PLATFORM(IOSMAC)) > > SOFT_LINK_FRAMEWORK(UIKit) >+SOFT_LINK_CLASS(UIKit, UIColor) > SOFT_LINK_CLASS(UIKit, UIImage) > SOFT_LINK_CLASS(UIKit, UIPasteboard) > >@@ -221,7 +223,9 @@ String PlatformPasteboard::stringForType(const String& type) const > > Color PlatformPasteboard::color() > { >- return Color(); >+ NSData *data = [m_pasteboard dataForPasteboardType:UIColorPboardType]; >+ UIColor *uiColor = [NSKeyedUnarchiver unarchivedObjectOfClass:getUIColorClass() fromData:data error:nil]; >+ return Color(uiColor.CGColor); > } > > URL PlatformPasteboard::url() >@@ -308,6 +312,15 @@ static void registerItemToPasteboard(WebItemProviderRegistrationInfoList *repres > > } > >+long PlatformPasteboard::setColor(const Color& color) >+{ >+ auto representationsToRegister = adoptNS([[WebItemProviderRegistrationInfoList alloc] init]); >+ UIColor *uiColor = [getUIColorClass() colorWithCGColor:cachedCGColor(color)]; >+ [representationsToRegister addData:[NSKeyedArchiver archivedDataWithRootObject:uiColor requiringSecureCoding:NO error:nil] forType:UIColorPboardType]; >+ registerItemToPasteboard(representationsToRegister.get(), m_pasteboard.get()); >+ return 0; >+} >+ > static void addRepresentationsForPlainText(WebItemProviderRegistrationInfoList *itemsToRegister, const String& plainText) > { > if (plainText.isEmpty()) >diff --git a/Source/WebCore/platform/mac/DragDataMac.mm b/Source/WebCore/platform/mac/DragDataMac.mm >index 76545e23a7acfcd66797ee1d76d9018eb3fb1351..dce73331e77a87468b67117c434b4b0b8232a9eb 100644 >--- a/Source/WebCore/platform/mac/DragDataMac.mm >+++ b/Source/WebCore/platform/mac/DragDataMac.mm >@@ -91,7 +91,7 @@ static inline String htmlPasteboardType() > static inline String colorPasteboardType() > { > #if PLATFORM(IOS) >- return "com.apple.uikit.color"; >+ return String { UIColorPboardType }; > #else > return String(legacyColorPasteboardType()); > #endif >@@ -226,6 +226,9 @@ bool DragData::containsCompatibleContent(DraggingPurpose purpose) const > if (purpose == DraggingPurpose::ForFileUpload) > return containsFiles(); > >+ if (purpose == DraggingPurpose::ForColorControl) >+ return containsColor(); >+ > if (purpose == DraggingPurpose::ForEditing && RuntimeEnabledFeatures::sharedFeatures().attachmentElementEnabled() && containsFiles()) > return true; > >diff --git a/Source/WebCore/platform/mac/DragImageMac.mm b/Source/WebCore/platform/mac/DragImageMac.mm >index 31b32a130baadcbdd2ab470f243830d980fe3a90..56102fa2907af84fe133021f08e4ef43b27dc992 100644 >--- a/Source/WebCore/platform/mac/DragImageMac.mm >+++ b/Source/WebCore/platform/mac/DragImageMac.mm >@@ -336,6 +336,26 @@ DragImageRef createDragImageForLink(Element& element, URL& url, const String& ti > > return dragImage; > } >+ >+DragImageRef createDragImageForColor(const Color& color, const FloatRect&, float, Path&) >+{ >+ auto dragImage = adoptNS([[NSImage alloc] initWithSize:NSMakeSize(ColorSwatchWidth, ColorSwatchWidth)]); >+ >+ [dragImage lockFocus]; >+ >+ NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:NSMakeRect(0, 0, ColorSwatchWidth, ColorSwatchWidth) xRadius:ColorSwatchCornerRadius yRadius:ColorSwatchCornerRadius]; >+ [path setLineWidth:ColorSwatchStrokeSize]; >+ >+ [nsColor(color) setFill]; >+ [path fill]; >+ >+ [[NSColor quaternaryLabelColor] setStroke]; >+ [path stroke]; >+ >+ [dragImage unlockFocus]; >+ >+ return dragImage; >+} > > } // namespace WebCore > >diff --git a/Source/WebCore/platform/mac/PasteboardMac.mm b/Source/WebCore/platform/mac/PasteboardMac.mm >index 0130bfde2e43710b3163dab09834e22ba0dc63d7..cb504cf543eb7e80d7665cd1e57e3089affb1a70 100644 >--- a/Source/WebCore/platform/mac/PasteboardMac.mm >+++ b/Source/WebCore/platform/mac/PasteboardMac.mm >@@ -223,6 +223,13 @@ void Pasteboard::writeTrustworthyWebURLsPboardType(const PasteboardURL& pasteboa > m_changeCount = platformStrategies()->pasteboardStrategy()->setURL(url, m_pasteboardName); > } > >+void Pasteboard::write(const Color& color) >+{ >+ Vector<String> types = { legacyColorPasteboardType() }; >+ platformStrategies()->pasteboardStrategy()->setTypes(types, m_pasteboardName); >+ m_changeCount = platformStrategies()->pasteboardStrategy()->setColor(color, m_pasteboardName); >+} >+ > static NSFileWrapper* fileWrapper(const PasteboardImage& pasteboardImage) > { > NSFileWrapper *wrapper = [[[NSFileWrapper alloc] initRegularFileWithContents:pasteboardImage.resourceData->createNSData().get()] autorelease]; >diff --git a/Source/WebCore/platform/mac/PlatformPasteboardMac.mm b/Source/WebCore/platform/mac/PlatformPasteboardMac.mm >index 535ce4e309b7cd3454df8a34192c7be97d78b55e..a1925badc93b6c71931ec9549d8cd72e622d1d7e 100644 >--- a/Source/WebCore/platform/mac/PlatformPasteboardMac.mm >+++ b/Source/WebCore/platform/mac/PlatformPasteboardMac.mm >@@ -274,6 +274,13 @@ long PlatformPasteboard::setURL(const PasteboardURL& pasteboardURL) > return changeCount(); > } > >+long PlatformPasteboard::setColor(const Color& color) >+{ >+ NSColor *pasteboardColor = nsColor(color); >+ [pasteboardColor writeToPasteboard:m_pasteboard.get()]; >+ return changeCount(); >+} >+ > long PlatformPasteboard::setStringForType(const String& string, const String& pasteboardType) > { > BOOL didWriteData; >diff --git a/Source/WebCore/platform/win/PasteboardWin.cpp b/Source/WebCore/platform/win/PasteboardWin.cpp >index 0c5e173cbcaf34ed9893e59b16cabbed4df25aea..66abe451e372d524b1cc1330cf00d9d84cba1a5f 100644 >--- a/Source/WebCore/platform/win/PasteboardWin.cpp >+++ b/Source/WebCore/platform/win/PasteboardWin.cpp >@@ -30,6 +30,7 @@ > #include "BitmapInfo.h" > #include "CachedImage.h" > #include "ClipboardUtilitiesWin.h" >+#include "Color.h" > #include "Document.h" > #include "DocumentFragment.h" > #include "Editor.h" >@@ -1085,4 +1086,8 @@ void Pasteboard::writeCustomData(const PasteboardCustomData&) > { > } > >+void Pasteboard::write(const Color&) >+{ >+} >+ > } // namespace WebCore >diff --git a/Source/WebCore/platform/wpe/PasteboardWPE.cpp b/Source/WebCore/platform/wpe/PasteboardWPE.cpp >index 8a1513e71ef4d7478cd6f898fa9a90b8fae387a0..14b48ab56c494bd712e05a00dcafa7ce6ff03bef 100644 >--- a/Source/WebCore/platform/wpe/PasteboardWPE.cpp >+++ b/Source/WebCore/platform/wpe/PasteboardWPE.cpp >@@ -149,4 +149,8 @@ void Pasteboard::writeCustomData(const PasteboardCustomData&) > { > } > >+void Pasteboard::write(const Color&) >+{ >+} >+ > } // namespace WebCore >diff --git a/Source/WebKit/Shared/WebCoreArgumentCoders.cpp b/Source/WebKit/Shared/WebCoreArgumentCoders.cpp >index 92d324ca7a9e2c62bbbe9c44eb329d68af0c411e..baa2fcf03e9ab2c9cff6a8adb9ff330bb03d896e 100644 >--- a/Source/WebKit/Shared/WebCoreArgumentCoders.cpp >+++ b/Source/WebKit/Shared/WebCoreArgumentCoders.cpp >@@ -852,6 +852,15 @@ bool ArgumentCoder<Path>::decode(Decoder& decoder, Path& path) > return true; > } > >+std::optional<Path> ArgumentCoder<Path>::decode(Decoder& decoder) >+{ >+ Path path; >+ if (!decode(decoder, path)) >+ return std::nullopt; >+ >+ return path; >+} >+ > void ArgumentCoder<RecentSearch>::encode(Encoder& encoder, const RecentSearch& recentSearch) > { > encoder << recentSearch.string << recentSearch.time; >diff --git a/Source/WebKit/Shared/WebCoreArgumentCoders.h b/Source/WebKit/Shared/WebCoreArgumentCoders.h >index 3a5cc681c1f29717d784aa4d1047e0883f8fb8cc..f2afcad596033940f1b49ad0623a089a8c539a75 100644 >--- a/Source/WebKit/Shared/WebCoreArgumentCoders.h >+++ b/Source/WebKit/Shared/WebCoreArgumentCoders.h >@@ -306,6 +306,7 @@ template<> struct ArgumentCoder<WebCore::LayoutPoint> { > template<> struct ArgumentCoder<WebCore::Path> { > static void encode(Encoder&, const WebCore::Path&); > static bool decode(Decoder&, WebCore::Path&); >+ static std::optional<WebCore::Path> decode(Decoder&); > }; > > template<> struct ArgumentCoder<WebCore::Region> { >diff --git a/Source/WebKit/UIProcess/Cocoa/WebPasteboardProxyCocoa.mm b/Source/WebKit/UIProcess/Cocoa/WebPasteboardProxyCocoa.mm >index 5dbdab8ca5cc46b28ed1540d0af42231d99e3fac..8f5a2f9f35a3fa00079c86be21dd6a2d92d8f7a4 100644 >--- a/Source/WebKit/UIProcess/Cocoa/WebPasteboardProxyCocoa.mm >+++ b/Source/WebKit/UIProcess/Cocoa/WebPasteboardProxyCocoa.mm >@@ -138,6 +138,11 @@ void WebPasteboardProxy::setPasteboardURL(IPC::Connection& connection, const Pas > newChangeCount = 0; > } > >+void WebPasteboardProxy::setPasteboardColor(const String& pasteboardName, const WebCore::Color& color, uint64_t& newChangeCount) >+{ >+ newChangeCount = PlatformPasteboard(pasteboardName).setColor(color); >+} >+ > void WebPasteboardProxy::setPasteboardStringForType(const String& pasteboardName, const String& pasteboardType, const String& string, uint64_t& newChangeCount) > { > newChangeCount = PlatformPasteboard(pasteboardName).setStringForType(string, pasteboardType); >diff --git a/Source/WebKit/UIProcess/WebPasteboardProxy.h b/Source/WebKit/UIProcess/WebPasteboardProxy.h >index 257ea3dc15f1890af150a189d5369b56803b7b43..58bdfed57d44e705326ff6c3a68b8f24478f2254 100644 >--- a/Source/WebKit/UIProcess/WebPasteboardProxy.h >+++ b/Source/WebKit/UIProcess/WebPasteboardProxy.h >@@ -96,6 +96,7 @@ private: > void addPasteboardTypes(const String& pasteboardName, const Vector<String>& pasteboardTypes, uint64_t& newChangeCount); > void setPasteboardTypes(const String& pasteboardName, const Vector<String>& pasteboardTypes, uint64_t& newChangeCount); > void setPasteboardURL(IPC::Connection&, const WebCore::PasteboardURL&, const String& pasteboardName, uint64_t& newChangeCount); >+ void setPasteboardColor(const String&, const WebCore::Color&, uint64_t&); > void setPasteboardStringForType(const String& pasteboardName, const String& pasteboardType, const String&, uint64_t& newChangeCount); > void setPasteboardBufferForType(const String& pasteboardName, const String& pasteboardType, const SharedMemory::Handle&, uint64_t size, uint64_t& newChangeCount); > #endif >diff --git a/Source/WebKit/UIProcess/WebPasteboardProxy.messages.in b/Source/WebKit/UIProcess/WebPasteboardProxy.messages.in >index 50866872e0293ab7a25ee5694fba7d6ff61d4454..21749f97f6c94c98d5f09436024779fc0f81929e 100644 >--- a/Source/WebKit/UIProcess/WebPasteboardProxy.messages.in >+++ b/Source/WebKit/UIProcess/WebPasteboardProxy.messages.in >@@ -54,6 +54,7 @@ messages -> WebPasteboardProxy { > AddPasteboardTypes(String pasteboardName, Vector<String> pasteboardTypes) -> (uint64_t changeCount) > SetPasteboardTypes(String pasteboardName, Vector<String> pasteboardTypes) -> (uint64_t changeCount) > SetPasteboardURL(struct WebCore::PasteboardURL pasteboardURL, String pasteboardName) -> (uint64_t changeCount) WantsConnection >+ SetPasteboardColor(String pasteboardName, WebCore::Color color) -> (uint64_t changeCount) > SetPasteboardStringForType(String pasteboardName, String pasteboardType, String string) -> (uint64_t changeCount) > SetPasteboardBufferForType(String pasteboardName, String pasteboardType, WebKit::SharedMemory::Handle handle, uint64_t size) -> (uint64_t changeCount) > #endif >diff --git a/Source/WebKit/UIProcess/ios/DragDropInteractionState.h b/Source/WebKit/UIProcess/ios/DragDropInteractionState.h >index 3b784f75ae69f9c60796adfad8fdc1aa78b1989b..799263eac4a2c2882464d9efaea46a843149da5f 100644 >--- a/Source/WebKit/UIProcess/ios/DragDropInteractionState.h >+++ b/Source/WebKit/UIProcess/ios/DragDropInteractionState.h >@@ -30,6 +30,7 @@ > #import "UIKitSPI.h" > #import <WebCore/DragActions.h> > #import <WebCore/DragData.h> >+#import <WebCore/Path.h> > #import <WebCore/TextIndicator.h> > #import <WebCore/URL.h> > #import <WebCore/WebItemProviderPasteboard.h> >@@ -49,6 +50,7 @@ struct DragSourceState { > CGRect dragPreviewFrameInRootViewCoordinates { CGRectZero }; > RetainPtr<UIImage> image; > std::optional<WebCore::TextIndicatorData> indicatorData; >+ std::optional<WebCore::Path> visiblePath; > String linkTitle; > WebCore::URL linkURL; > bool possiblyNeedsDragPreviewUpdate { true }; >diff --git a/Source/WebKit/UIProcess/ios/DragDropInteractionState.mm b/Source/WebKit/UIProcess/ios/DragDropInteractionState.mm >index 64c8f06dadfe11621b7134ae709b012ecef9efce..f685bd11d1339367bb7287df5ff22269161b8418 100644 >--- a/Source/WebKit/UIProcess/ios/DragDropInteractionState.mm >+++ b/Source/WebKit/UIProcess/ios/DragDropInteractionState.mm >@@ -46,7 +46,7 @@ static UIDragItem *dragItemMatchingIdentifier(id <UIDragSession> session, NSInte > return nil; > } > >-static UITargetedDragPreview *createTargetedDragPreview(UIImage *image, UIView *rootView, UIView *previewContainer, const FloatRect& frameInRootViewCoordinates, const Vector<FloatRect>& clippingRectsInFrameCoordinates, UIColor *backgroundColor) >+static UITargetedDragPreview *createTargetedDragPreview(UIImage *image, UIView *rootView, UIView *previewContainer, const FloatRect& frameInRootViewCoordinates, const Vector<FloatRect>& clippingRectsInFrameCoordinates, UIColor *backgroundColor, UIBezierPath *visiblePath) > { > if (frameInRootViewCoordinates.isEmpty() || !image) > return nullptr; >@@ -75,6 +75,9 @@ static UITargetedDragPreview *createTargetedDragPreview(UIImage *image, UIView * > if (backgroundColor) > [parameters setBackgroundColor:backgroundColor]; > >+ if (visiblePath) >+ [parameters setVisiblePath:visiblePath]; >+ > CGPoint centerInContainerCoordinates = { CGRectGetMidX(frameInContainerCoordinates), CGRectGetMidY(frameInContainerCoordinates) }; > auto target = adoptNS([[UIDragPreviewTarget alloc] initWithContainer:previewContainer center:centerInContainerCoordinates]); > auto dragPreview = adoptNS([[UITargetedDragPreview alloc] initWithView:imageView.get() parameters:parameters.get() target:target.get()]); >@@ -98,9 +101,27 @@ static bool shouldUseDragImageToCreatePreviewForDragSource(const DragSourceState > if (!source.image) > return false; > >+#if ENABLE(INPUT_TYPE_COLOR) >+ if (source.action & DragSourceActionColor) >+ return true; >+#endif >+ > return source.action & (DragSourceActionDHTML | DragSourceActionImage); > } > >+static bool shouldUseVisiblePathToCreatePreviewForDragSource(const DragSourceState& source) >+{ >+ if (!source.visiblePath) >+ return false; >+ >+#if ENABLE(INPUT_TYPE_COLOR) >+ if (source.action & DragSourceActionColor) >+ return true; >+#endif >+ >+ return false; >+} >+ > static bool shouldUseTextIndicatorToCreatePreviewForDragSource(const DragSourceState& source) > { > if (!source.indicatorData) >@@ -117,6 +138,22 @@ static bool shouldUseTextIndicatorToCreatePreviewForDragSource(const DragSourceS > return false; > } > >+static bool canUpdatePreviewForActiveDragSource(const DragSourceState& source) >+{ >+ if (!source.possiblyNeedsDragPreviewUpdate) >+ return false; >+ >+#if ENABLE(INPUT_TYPE_COLOR) >+ if (source.action & DragSourceActionColor) >+ return true; >+#endif >+ >+ if (source.action & DragSourceActionLink && !(source.action & DragSourceActionImage)) >+ return true; >+ >+ return false; >+} >+ > std::optional<DragSourceState> DragDropInteractionState::activeDragSourceForItem(UIDragItem *item) const > { > if (![item.privateLocalContext isKindOfClass:[NSNumber class]]) >@@ -158,13 +195,19 @@ UITargetedDragPreview *DragDropInteractionState::previewForDragItem(UIDragItem * > return nil; > > auto& source = foundSource.value(); >- if (shouldUseDragImageToCreatePreviewForDragSource(source)) >- return createTargetedDragPreview(source.image.get(), contentView, previewContainer, source.dragPreviewFrameInRootViewCoordinates, { }, nil); >+ if (shouldUseDragImageToCreatePreviewForDragSource(source)) { >+ if (shouldUseVisiblePathToCreatePreviewForDragSource(source)) { >+ auto path = source.visiblePath.value(); >+ UIBezierPath *visiblePath = [UIBezierPath bezierPathWithCGPath:path.ensurePlatformPath()]; >+ return createTargetedDragPreview(source.image.get(), contentView, previewContainer, source.dragPreviewFrameInRootViewCoordinates, { }, nil, visiblePath); >+ } >+ return createTargetedDragPreview(source.image.get(), contentView, previewContainer, source.dragPreviewFrameInRootViewCoordinates, { }, nil, nil); >+ } > > if (shouldUseTextIndicatorToCreatePreviewForDragSource(source)) { > auto indicator = source.indicatorData.value(); > auto textIndicatorImage = uiImageForImage(indicator.contentImage.get()); >- return createTargetedDragPreview(textIndicatorImage.get(), contentView, previewContainer, indicator.textBoundingRectInRootViewCoordinates, indicator.textRectsInBoundingRectCoordinates, [UIColor colorWithCGColor:cachedCGColor(indicator.estimatedBackgroundColor)]); >+ return createTargetedDragPreview(textIndicatorImage.get(), contentView, previewContainer, indicator.textBoundingRectInRootViewCoordinates, indicator.textRectsInBoundingRectCoordinates, [UIColor colorWithCGColor:cachedCGColor(indicator.estimatedBackgroundColor)], nil); > } > > return nil; >@@ -203,6 +246,7 @@ void DragDropInteractionState::stageDragItem(const DragItem& item, UIImage *drag > item.dragPreviewFrameInRootViewCoordinates, > dragImage, > item.image.indicatorData(), >+ item.image.visiblePath(), > item.title.isEmpty() ? nil : (NSString *)item.title, > item.url.isEmpty() ? nil : (NSURL *)item.url, > true, // We assume here that drag previews need to be updated until proven otherwise in updatePreviewsForActiveDragSources(). >@@ -239,29 +283,30 @@ void DragDropInteractionState::dragAndDropSessionsDidEnd() > void DragDropInteractionState::updatePreviewsForActiveDragSources() > { > for (auto& source : m_activeDragSources) { >- if (!source.possiblyNeedsDragPreviewUpdate) >- continue; >- >- if (source.action & DragSourceActionImage || !(source.action & DragSourceActionLink)) { >- // Currently, non-image links are the only type of source for which we need to update >- // drag preview providers after the initial lift. All other dragged content should maintain >- // the same targeted drag preview used during the lift animation. >+ if (!canUpdatePreviewForActiveDragSource(source)) > continue; >- } > > UIDragItem *dragItem = dragItemMatchingIdentifier(m_dragSession.get(), source.itemIdentifier); > if (!dragItem) > continue; > >- auto linkDraggingCenter = source.adjustedOrigin; >- RetainPtr<NSString> title = (NSString *)source.linkTitle; >- RetainPtr<NSURL> url = (NSURL *)source.linkURL; >- dragItem.previewProvider = [title, url, linkDraggingCenter] () -> UIDragPreview * { >- UIURLDragPreviewView *previewView = [UIURLDragPreviewView viewWithTitle:title.get() URL:url.get()]; >- previewView.center = linkDraggingCenter; >- UIDragPreviewParameters *parameters = [[[UIDragPreviewParameters alloc] initWithTextLineRects:@[ [NSValue valueWithCGRect:previewView.bounds] ]] autorelease]; >- return [[[UIDragPreview alloc] initWithView:previewView parameters:parameters] autorelease]; >- }; >+ if (source.action & DragSourceActionLink) { >+ dragItem.previewProvider = [title = retainPtr((NSString *)source.linkTitle), url = retainPtr((NSURL *)source.linkURL), center = source.adjustedOrigin] () -> UIDragPreview * { >+ UIURLDragPreviewView *previewView = [UIURLDragPreviewView viewWithTitle:title.get() URL:url.get()]; >+ previewView.center = center; >+ UIDragPreviewParameters *parameters = [[[UIDragPreviewParameters alloc] initWithTextLineRects:@[ [NSValue valueWithCGRect:previewView.bounds] ]] autorelease]; >+ return [[[UIDragPreview alloc] initWithView:previewView parameters:parameters] autorelease]; >+ }; >+ } >+#if ENABLE(INPUT_TYPE_COLOR) >+ else if (source.action & DragSourceActionColor) { >+ dragItem.previewProvider = [image = source.image] () -> UIDragPreview * { >+ UIImageView *imageView = [[[UIImageView alloc] initWithImage:image.get()] autorelease]; >+ UIDragPreviewParameters *parameters = [[[UIDragPreviewParameters alloc] initWithTextLineRects:@[ [NSValue valueWithCGRect:[imageView bounds]] ]] autorelease]; >+ return [[[UIDragPreview alloc] initWithView:imageView parameters:parameters] autorelease]; >+ }; >+ } >+#endif > > source.possiblyNeedsDragPreviewUpdate = false; > } >diff --git a/Source/WebKit/UIProcess/ios/forms/WKFormColorPicker.mm b/Source/WebKit/UIProcess/ios/forms/WKFormColorPicker.mm >index f3af8b62da5720f59b5fe4035510b90aa4803958..53fc009b5d4b7fa6e88fc13b656022567f076ed0 100644 >--- a/Source/WebKit/UIProcess/ios/forms/WKFormColorPicker.mm >+++ b/Source/WebKit/UIProcess/ios/forms/WKFormColorPicker.mm >@@ -180,7 +180,7 @@ using namespace WebKit; > colorPickerSize = CGSizeMake(keyboardSize.width, keyboardSize.height + additionalKeyboardAffordance); > } > >- _colorPicker = adoptNS([[UIView alloc] initWithSize:colorPickerSize]); >+ _colorPicker = adoptNS([[UIView alloc] initWithFrame:CGRectMake(0, 0, colorPickerSize.width, colorPickerSize.height)]); > > CGFloat totalRows = [[getPKColorMatrixViewClass() defaultColorMatrix] count] + 1; > CGFloat swatchHeight = (colorPickerSize.height - topColorMatrixPadding) / totalRows; >diff --git a/Source/WebKit/UIProcess/mac/WebColorPickerMac.h b/Source/WebKit/UIProcess/mac/WebColorPickerMac.h >index ae5e7b9fa62e33dc8f76e418adb1f3b572072d68..54af0637e60fcffed6ef3f11ee41c8982996f71e 100644 >--- a/Source/WebKit/UIProcess/mac/WebColorPickerMac.h >+++ b/Source/WebKit/UIProcess/mac/WebColorPickerMac.h >@@ -38,6 +38,7 @@ > #import "WebColorPicker.h" > #import <WebCore/IntRect.h> > #include <wtf/RetainPtr.h> >+#include <wtf/Vector.h> > > namespace WebCore { > class Color; >diff --git a/Source/WebKit/WebProcess/WebCoreSupport/WebPlatformStrategies.cpp b/Source/WebKit/WebProcess/WebCoreSupport/WebPlatformStrategies.cpp >index ae7388f9a49c30fcc6c86c851fa065821733bf50..4c8fd441798d45c633ae803ae7c9eff65cdb9b60 100644 >--- a/Source/WebKit/WebProcess/WebCoreSupport/WebPlatformStrategies.cpp >+++ b/Source/WebKit/WebProcess/WebCoreSupport/WebPlatformStrategies.cpp >@@ -274,6 +274,13 @@ long WebPlatformStrategies::setURL(const PasteboardURL& pasteboardURL, const Str > return newChangeCount; > } > >+long WebPlatformStrategies::setColor(const Color& color, const String& pasteboardName) >+{ >+ uint64_t newChangeCount { 0 }; >+ WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::SetPasteboardColor(pasteboardName, color), Messages::WebPasteboardProxy::SetPasteboardColor::Reply(newChangeCount), 0); >+ return newChangeCount; >+} >+ > long WebPlatformStrategies::setStringForType(const String& string, const String& pasteboardType, const String& pasteboardName) > { > uint64_t newChangeCount { 0 }; >diff --git a/Source/WebKit/WebProcess/WebCoreSupport/WebPlatformStrategies.h b/Source/WebKit/WebProcess/WebCoreSupport/WebPlatformStrategies.h >index b59842b4e4ebc859d3f786c6d3e68ee56de34467..b88fcab576be4ee9a09343f2bee1f67b15e2a28e 100644 >--- a/Source/WebKit/WebProcess/WebCoreSupport/WebPlatformStrategies.h >+++ b/Source/WebKit/WebProcess/WebCoreSupport/WebPlatformStrategies.h >@@ -85,6 +85,7 @@ private: > long setTypes(const Vector<String>& pasteboardTypes, const String& pasteboardName) override; > long setBufferForType(WebCore::SharedBuffer*, const String& pasteboardType, const String& pasteboardName) override; > long setURL(const WebCore::PasteboardURL&, const String& pasteboardName) override; >+ long setColor(const WebCore::Color&, const String& pasteboardName) override; > long setStringForType(const String&, const String& pasteboardType, const String& pasteboardName) override; > #endif > #if PLATFORM(GTK) >diff --git a/Source/WebKitLegacy/mac/WebCoreSupport/WebPlatformStrategies.h b/Source/WebKitLegacy/mac/WebCoreSupport/WebPlatformStrategies.h >index 565c3f4273dcb85f2e0a9bd5245d068d90ff36ac..debb0332b12cad54e7409c7a6064fd59e7d80be0 100644 >--- a/Source/WebKitLegacy/mac/WebCoreSupport/WebPlatformStrategies.h >+++ b/Source/WebKitLegacy/mac/WebCoreSupport/WebPlatformStrategies.h >@@ -88,6 +88,7 @@ private: > long setTypes(const Vector<String>& pasteboardTypes, const String& pasteboardName) override; > long setBufferForType(WebCore::SharedBuffer*, const String& pasteboardType, const String& pasteboardName) override; > long setURL(const WebCore::PasteboardURL&, const String& pasteboardName) override; >+ long setColor(const WebCore::Color&, const String& pasteboardName) override; > long setStringForType(const String&, const String& pasteboardType, const String& pasteboardName) override; > }; > >diff --git a/Source/WebKitLegacy/mac/WebCoreSupport/WebPlatformStrategies.mm b/Source/WebKitLegacy/mac/WebCoreSupport/WebPlatformStrategies.mm >index b53188ebfcdf5a74133185198ec3d24fe39ad855..0b16dcd0925dcc441df88e7ed6432a6e435839af 100644 >--- a/Source/WebKitLegacy/mac/WebCoreSupport/WebPlatformStrategies.mm >+++ b/Source/WebKitLegacy/mac/WebCoreSupport/WebPlatformStrategies.mm >@@ -168,6 +168,11 @@ long WebPlatformStrategies::setURL(const PasteboardURL& pasteboardURL, const Str > return PlatformPasteboard(pasteboardName).setURL(pasteboardURL); > } > >+long WebPlatformStrategies::setColor(const Color& color, const String& pasteboardName) >+{ >+ return PlatformPasteboard(pasteboardName).setColor(color); >+} >+ > long WebPlatformStrategies::setStringForType(const String& string, const String& pasteboardType, const String& pasteboardName) > { > return PlatformPasteboard(pasteboardName).setStringForType(string, pasteboardType); >diff --git a/Tools/ChangeLog b/Tools/ChangeLog >index f73d3a88e8877cddc68ce86eea3dac88fe8c98e5..651b5a281aba3115dc93c8789a77e0927fc9661a 100644 >--- a/Tools/ChangeLog >+++ b/Tools/ChangeLog >@@ -1,3 +1,25 @@ >+2018-08-15 Aditya Keerthi <akeerthi@apple.com> >+ >+ Support drag-and-drop for input[type=color] >+ https://bugs.webkit.org/show_bug.cgi?id=188464 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Added five cross-platform API tests, to verify that dragging and dropping with >+ color inputs changes the value of the drop target if and only if both inputs are >+ enabled. Also tests that the change and input events are fired when changing the >+ value of a color input through drag and drop. >+ >+ Additionally, added a macOS-specific test to verify that dropping an item with >+ NSColorPboardType changes the value of the color input. >+ >+ * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: >+ * TestWebKitAPI/Tests/WebKitCocoa/DragAndDropTests.mm: >+ (TestWebKitAPI::TEST): >+ * TestWebKitAPI/Tests/WebKitCocoa/color-drop.html: Added. >+ * TestWebKitAPI/Tests/mac/DragAndDropTestsMac.mm: >+ (TestWebKitAPI::TEST): >+ > 2018-08-13 Wenson Hsieh <wenson_hsieh@apple.com> > > [WK2] [macOS] Implement a mechanism to test drag and drop >diff --git a/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj b/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj >index 766bfb2b9f12132b0666863cdcaa56bfb8043326..9772148d451f0cce1790d3be32859e833a3ef1bc 100644 >--- a/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj >+++ b/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj >@@ -772,6 +772,7 @@ > E373D7911F2CF35200C6FAAF /* Signals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3953F951F2CF32100A76A2E /* Signals.cpp */; }; > E38A0D351FD50CC300E98C8B /* Threading.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38A0D341FD50CBC00E98C8B /* Threading.cpp */; }; > E3DEA8111F0A589000CBC2E8 /* ThreadGroup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3DEA8101F0A588000CBC2E8 /* ThreadGroup.cpp */; }; >+ E5036F78211BC25400BFDBE2 /* color-drop.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = E5036F77211BC22800BFDBE2 /* color-drop.html */; }; > ECA680CE1E68CC0900731D20 /* StringUtilities.mm in Sources */ = {isa = PBXBuildFile; fileRef = ECA680CD1E68CC0900731D20 /* StringUtilities.mm */; }; > F407FE391F1D0DFC0017CF25 /* enormous.svg in Copy Resources */ = {isa = PBXBuildFile; fileRef = F407FE381F1D0DE60017CF25 /* enormous.svg */; }; > F415086D1DA040C50044BE9B /* play-audio-on-click.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F415086C1DA040C10044BE9B /* play-audio-on-click.html */; }; >@@ -963,6 +964,7 @@ > 9BD4239C1E04C01C00200395 /* chinese-character-with-image.html in Copy Resources */, > 1A50AA201A2A51FC00F4C345 /* close-from-within-create-page.html in Copy Resources */, > 9B270FEE1DDC2C0B002D53F3 /* closed-shadow-tree-test.html in Copy Resources */, >+ E5036F78211BC25400BFDBE2 /* color-drop.html in Copy Resources */, > F4B825D81EF4DBFB006E417F /* compressed-files.zip in Copy Resources */, > 5C9E56871DF914AE00C9EE33 /* contentBlockerCheck.html in Copy Resources */, > F469FB241F01804B00401539 /* contenteditable-and-target.html in Copy Resources */, >@@ -2004,6 +2006,7 @@ > E490296714E2E3A4002BEDD1 /* TypingStyleCrash.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TypingStyleCrash.mm; sourceTree = "<group>"; }; > E4A757D3178AEA5B00B5D7A4 /* Deque.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Deque.cpp; sourceTree = "<group>"; }; > E4C9ABC71B3DB1710040A987 /* RunLoop.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RunLoop.cpp; sourceTree = "<group>"; }; >+ E5036F77211BC22800BFDBE2 /* color-drop.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "color-drop.html"; sourceTree = "<group>"; }; > ECA680CD1E68CC0900731D20 /* StringUtilities.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = StringUtilities.mm; sourceTree = "<group>"; }; > F3FC3EE213678B7300126A65 /* libgtest.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgtest.a; sourceTree = BUILT_PRODUCTS_DIR; }; > F407FE381F1D0DE60017CF25 /* enormous.svg */ = {isa = PBXFileReference; lastKnownFileType = text; path = enormous.svg; sourceTree = "<group>"; }; >@@ -2607,6 +2610,7 @@ > 2DE71AFF1D49C2F000904094 /* blinking-div.html */, > 2EFF06C41D8867700004BB30 /* change-video-source-on-click.html */, > 2EFF06C61D886A560004BB30 /* change-video-source-on-end.html */, >+ E5036F77211BC22800BFDBE2 /* color-drop.html */, > F4B825D61EF4DBD4006E417F /* compressed-files.zip */, > F469FB231F01803500401539 /* contenteditable-and-target.html */, > F41AB99C1EF4692C0083FA08 /* contenteditable-and-textarea.html */, >diff --git a/Tools/TestWebKitAPI/Tests/WebKitCocoa/DragAndDropTests.mm b/Tools/TestWebKitAPI/Tests/WebKitCocoa/DragAndDropTests.mm >index b4f6745bfb0733f2922a2b82974fe0c6814d97e2..ddda230de49145cb834361f59839cc76dca0b007 100644 >--- a/Tools/TestWebKitAPI/Tests/WebKitCocoa/DragAndDropTests.mm >+++ b/Tools/TestWebKitAPI/Tests/WebKitCocoa/DragAndDropTests.mm >@@ -43,4 +43,78 @@ TEST(DragAndDropTests, DragImageLocationForLinkInSubframe) > #endif > } > >+#if ENABLE(INPUT_TYPE_COLOR) >+ >+TEST(DragAndDropTests, ColorInputToColorInput) >+{ >+ auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebViewFrame:CGRectMake(0, 0, 320, 500)]); >+ auto webView = [simulator webView]; >+ >+ [webView synchronouslyLoadTestPageNamed:@"color-drop"]; >+ [simulator runFrom:CGPointMake(50, 50) to:CGPointMake(150, 50)]; >+ EXPECT_WK_STREQ(@"#000000", [webView stringByEvaluatingJavaScript:@"document.getElementById(\"drag-target\").value"]); >+ EXPECT_WK_STREQ(@"#000000", [webView stringByEvaluatingJavaScript:@"document.getElementById(\"drop-target\").value"]); >+} >+ >+TEST(DragAndDropTests, ColorInputToDisabledColorInput) >+{ >+ auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebViewFrame:CGRectMake(0, 0, 320, 500)]); >+ auto webView = [simulator webView]; >+ >+ [webView synchronouslyLoadTestPageNamed:@"color-drop"]; >+ [webView stringByEvaluatingJavaScript:@"document.getElementById(\"drop-target\").disabled = true"]; >+ [simulator runFrom:CGPointMake(50, 50) to:CGPointMake(150, 50)]; >+ EXPECT_WK_STREQ(@"#000000", [webView stringByEvaluatingJavaScript:@"document.getElementById(\"drag-target\").value"]); >+ EXPECT_WK_STREQ(@"#ff0000", [webView stringByEvaluatingJavaScript:@"document.getElementById(\"drop-target\").value"]); >+} >+ >+TEST(DragAndDropTests, DisabledColorInputToColorInput) >+{ >+ auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebViewFrame:CGRectMake(0, 0, 320, 500)]); >+ auto webView = [simulator webView]; >+ >+ [webView synchronouslyLoadTestPageNamed:@"color-drop"]; >+ [webView stringByEvaluatingJavaScript:@"document.getElementById(\"drag-target\").disabled = true"]; >+ [simulator runFrom:CGPointMake(50, 50) to:CGPointMake(150, 50)]; >+ EXPECT_WK_STREQ(@"#000000", [webView stringByEvaluatingJavaScript:@"document.getElementById(\"drag-target\").value"]); >+ EXPECT_WK_STREQ(@"#ff0000", [webView stringByEvaluatingJavaScript:@"document.getElementById(\"drop-target\").value"]); >+} >+ >+TEST(DragAndDropTests, ReadOnlyColorInputToReadOnlyColorInput) >+{ >+ auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebViewFrame:CGRectMake(0, 0, 320, 500)]); >+ auto webView = [simulator webView]; >+ >+ [webView synchronouslyLoadTestPageNamed:@"color-drop"]; >+ [webView stringByEvaluatingJavaScript:@"document.getElementById(\"drag-target\").readOnly = true"]; >+ [webView stringByEvaluatingJavaScript:@"document.getElementById(\"drop-target\").readOnly = true"]; >+ [simulator runFrom:CGPointMake(50, 50) to:CGPointMake(150, 50)]; >+ EXPECT_WK_STREQ(@"#000000", [webView stringByEvaluatingJavaScript:@"document.getElementById(\"drag-target\").value"]); >+ EXPECT_WK_STREQ(@"#000000", [webView stringByEvaluatingJavaScript:@"document.getElementById(\"drop-target\").value"]); >+} >+ >+TEST(DragAndDropTests, ColorInputEvents) >+{ >+ auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebViewFrame:CGRectMake(0, 0, 320, 500)]); >+ auto webView = [simulator webView]; >+ >+ [webView synchronouslyLoadTestPageNamed:@"color-drop"]; >+ >+ __block bool changeEventFired = false; >+ [webView performAfterReceivingMessage:@"change" action:^() { >+ changeEventFired = true; >+ }]; >+ >+ __block bool inputEventFired = false; >+ [webView performAfterReceivingMessage:@"input" action:^() { >+ inputEventFired = true; >+ }]; >+ >+ [simulator runFrom:CGPointMake(50, 50) to:CGPointMake(150, 50)]; >+ TestWebKitAPI::Util::run(&inputEventFired); >+ TestWebKitAPI::Util::run(&changeEventFired); >+} >+ >+#endif >+ > #endif // WK_API_ENABLED && ENABLE(DRAG_SUPPORT) >diff --git a/Tools/TestWebKitAPI/Tests/WebKitCocoa/color-drop.html b/Tools/TestWebKitAPI/Tests/WebKitCocoa/color-drop.html >new file mode 100644 >index 0000000000000000000000000000000000000000..e0e6ace96f95ebaa0439ac8bc6243b367d61cde5 >--- /dev/null >+++ b/Tools/TestWebKitAPI/Tests/WebKitCocoa/color-drop.html >@@ -0,0 +1,15 @@ >+<!DOCTYPE html> >+<meta name="viewport" content="width=device-width, initial-scale=1"> >+<body style="width: 100vw; height: 100vh; margin: 0;"> >+ <input type=color id="drag-target" style="width: 100px; height: 100px"> >+ <input type=color id="drop-target" style="width: 100px; height: 100px;" value="#ff0000"> >+</body> >+<script> >+let dropTarget = document.getElementById("drop-target"); >+dropTarget.addEventListener("change", () => { >+ window.webkit.messageHandlers.testHandler.postMessage("change"); >+}); >+dropTarget.addEventListener("input", () => { >+ window.webkit.messageHandlers.testHandler.postMessage("input"); >+}); >+</script> >diff --git a/Tools/TestWebKitAPI/Tests/mac/DragAndDropTestsMac.mm b/Tools/TestWebKitAPI/Tests/mac/DragAndDropTestsMac.mm >index 41c4cb3f0441ac96db96839eda329bc130f36f0f..0d136017bf6a6e366109e6d754dd07fea5a1945c 100644 >--- a/Tools/TestWebKitAPI/Tests/mac/DragAndDropTestsMac.mm >+++ b/Tools/TestWebKitAPI/Tests/mac/DragAndDropTestsMac.mm >@@ -58,4 +58,21 @@ TEST(DragAndDropTests, NumberOfValidItemsForDrop) > EXPECT_EQ(1U, numberOfValidItemsForDrop); > } > >+#if ENABLE(INPUT_TYPE_COLOR) >+TEST(DragAndDropTests, DropColor) >+{ >+ NSPasteboard *pasteboard = [NSPasteboard pasteboardWithUniqueName]; >+ [pasteboard declareTypes:@[NSColorPboardType] owner:nil]; >+ [[NSColor redColor] writeToPasteboard:pasteboard]; >+ >+ auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebViewFrame:NSMakeRect(0, 0, 400, 400)]); >+ TestWKWebView *webView = [simulator webView]; >+ [simulator setExternalDragPasteboard:pasteboard]; >+ >+ [webView synchronouslyLoadTestPageNamed:@"color-drop"]; >+ [simulator runFrom:NSMakePoint(0, 0) to:NSMakePoint(50, 50)]; >+ EXPECT_WK_STREQ(@"#ff0000", [webView stringByEvaluatingJavaScript:@"document.querySelector(\"input\").value"]); >+} >+#endif // ENABLE(INPUT_TYPE_COLOR) >+ > #endif // WK_API_ENABLED && ENABLE(DRAG_SUPPORT) && PLATFORM(MAC) >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index f3803878c68c128690f1a31963711b6a5962ab29..74c78c506b3b6dbdecae7d1b1b206e38ebeadb36 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,22 @@ >+2018-08-15 Aditya Keerthi <akeerthi@apple.com> >+ >+ Support drag-and-drop for input[type=color] >+ https://bugs.webkit.org/show_bug.cgi?id=188464 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Added tests to verify that dragging from one color input to another behaves as >+ expected in WK1. The tests consider disabled and read-only inputs in addition to >+ default color inputs. The WK2 implementation is tested through API tests. >+ >+ * editing/pasteboard/drag-and-drop-color-input-events-expected.txt: Added. >+ * editing/pasteboard/drag-and-drop-color-input-events.html: Added. >+ * editing/pasteboard/drag-and-drop-color-input-expected.txt: Added. >+ * editing/pasteboard/drag-and-drop-color-input.html: Added. >+ * platform/ios/TestExpectations: >+ * platform/mac/TestExpectations: >+ * platform/wk2/TestExpectations: >+ > 2018-08-13 Ali Juma <ajuma@chromium.org> > > [IntersectionObserver] Validate threshold values >diff --git a/LayoutTests/editing/pasteboard/drag-and-drop-color-input-events-expected.txt b/LayoutTests/editing/pasteboard/drag-and-drop-color-input-events-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..5203989bb591af69bc7884796505b67048459950 >--- /dev/null >+++ b/LayoutTests/editing/pasteboard/drag-and-drop-color-input-events-expected.txt >@@ -0,0 +1,12 @@ >+This test verifies that the input and change events fire when changing the value of a color input via drag and drop. To test manually, drag the color input on the left onto the color input on the right. >+ >+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". >+ >+ >+ >+PASS src.value is "#ff0000" >+PASS dest.value is "#ff0000" >+PASS successfullyParsed is true >+ >+TEST COMPLETE >+ >diff --git a/LayoutTests/editing/pasteboard/drag-and-drop-color-input-events.html b/LayoutTests/editing/pasteboard/drag-and-drop-color-input-events.html >new file mode 100644 >index 0000000000000000000000000000000000000000..b775c8fbe6bfad9727ca62fb8174b2bc07a84b6d >--- /dev/null >+++ b/LayoutTests/editing/pasteboard/drag-and-drop-color-input-events.html >@@ -0,0 +1,55 @@ >+<!DOCTYPE html> >+<html> >+<head> >+ <script src="../../resources/js-test.js"></script> >+</head> >+<body onload="runTest()"> >+ <p id="description"></p> >+ <input type=color id="src" value="#ff0000"> >+ <input type=color id="dest" value="#000000"> >+ <div id="console"></div> >+</body> >+<script> >+description('This test verifies that the input and change events fire when changing the value of a color input via drag and drop. To test manually, drag the color input on the left onto the color input on the right.'); >+ >+jsTestIsAsync = true; >+ >+var src = document.getElementById('src'); >+var dest = document.getElementById('dest'); >+ >+var changeFired = false; >+var inputFired = false; >+ >+function tryFinishTest() { >+ if (!changeFired || !inputFired) { >+ return; >+ } >+ >+ shouldBeEqualToString("src.value", "#ff0000"); >+ shouldBeEqualToString("dest.value", "#ff0000"); >+ finishJSTest(); >+} >+ >+function runTest() { >+ if (!window.testRunner) >+ return; >+ >+ dest.addEventListener("change", function(e) { >+ changeFired = true; >+ tryFinishTest(); >+ }); >+ >+ dest.addEventListener("input", function(e) { >+ inputFired = true; >+ tryFinishTest(); >+ }); >+ >+ eventSender.mouseMoveTo(src.offsetLeft + src.offsetWidth / 2, src.offsetTop + src.offsetHeight / 2); >+ eventSender.mouseDown(); >+ eventSender.leapForward(200); >+ eventSender.mouseMoveTo(dest.offsetLeft + dest.offsetWidth / 2, dest.offsetTop + dest.offsetHeight / 2); >+ eventSender.mouseUp(); >+ eventSender.leapForward(200); >+} >+</script> >+</html> >diff --git a/LayoutTests/editing/pasteboard/drag-and-drop-color-input-expected.txt b/LayoutTests/editing/pasteboard/drag-and-drop-color-input-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..103762418c2c63620cbc41620a3b21922d23aad6 >--- /dev/null >+++ b/LayoutTests/editing/pasteboard/drag-and-drop-color-input-expected.txt >@@ -0,0 +1,29 @@ >+This test verifies that dragging a color from one input to another changes the color of the second input. To test manually, drag from inputs on the left and drop into inputs on the right. >+ >+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". >+ >+ >+Drag and drop should work between two color inputs. >+ >+ >+Disabled color inputs should not be draggable. >+ >+ >+Disabled color inputs should not change color when a color is dropped. >+ >+ >+Read-only color inputs should behave like default color inputs. >+ >+ >+PASS element('src').value is "#ff0000" >+PASS element('dest').value is "#ff0000" >+PASS element('disabled-src').value is "#9a9a9a" >+PASS element('dest-disabled-src').value is "#ff0000" >+PASS element('src-disabled-dest').value is "#ff0000" >+PASS element('disabled-dest').value is "#9a9a9a" >+PASS element('readonly-src').value is "#ff0000" >+PASS element('readonly-dest').value is "#ff0000" >+PASS successfullyParsed is true >+ >+TEST COMPLETE >+ >diff --git a/LayoutTests/editing/pasteboard/drag-and-drop-color-input.html b/LayoutTests/editing/pasteboard/drag-and-drop-color-input.html >new file mode 100644 >index 0000000000000000000000000000000000000000..b3d85cf459d00d606b8801a67bf4814730ffd872 >--- /dev/null >+++ b/LayoutTests/editing/pasteboard/drag-and-drop-color-input.html >@@ -0,0 +1,67 @@ >+<!DOCTYPE html> >+<html> >+<head> >+ <script src="../../resources/js-test.js"></script> >+</head> >+<body onload="runTest()"> >+ <p id="description"></p> >+ <p>Drag and drop should work between two color inputs.</p> >+ <div> >+ <input type=color id="src" value="#ff0000"> >+ <input type=color id="dest" value="#000000"> >+ </div> >+ <p>Disabled color inputs should not be draggable.</p> >+ <div> >+ <input type=color id="disabled-src" value="#9A9A9A" disabled> >+ <input type=color id="dest-disabled-src" value="#ff0000"> >+ </div> >+ <p>Disabled color inputs should not change color when a color is dropped.</p> >+ <div> >+ <input type=color id="src-disabled-dest" value="#ff0000"> >+ <input type=color id="disabled-dest" value="#9A9A9A" disabled> >+ </div> >+ <p>Read-only color inputs should behave like default color inputs.</p> >+ <div> >+ <input type=color id="readonly-src" value="#ff0000" readonly> >+ <input type=color id="readonly-dest" value="#000000" readonly> >+ </div> >+ <div id="console"></div> >+</body> >+<script> >+description('This test verifies that dragging a color from one input to another changes the color of the second input. To test manually, drag from inputs on the left and drop into inputs on the right.'); >+ >+function element(id) { >+ return document.getElementById(id); >+} >+ >+function performDrag(src, dest) { >+ eventSender.mouseMoveTo(src.offsetLeft + src.offsetWidth / 2, src.offsetTop + src.offsetHeight / 2); >+ eventSender.mouseDown(); >+ eventSender.leapForward(200); >+ eventSender.mouseMoveTo(dest.offsetLeft + dest.offsetWidth / 2, dest.offsetTop + dest.offsetHeight / 2); >+ eventSender.mouseUp(); >+ eventSender.leapForward(200); >+} >+ >+function runTest() { >+ if (!window.testRunner) >+ return; >+ >+ performDrag(element("src"), element("dest")); >+ shouldBeEqualToString("element('src').value", "#ff0000"); >+ shouldBeEqualToString("element('dest').value", "#ff0000"); >+ >+ performDrag(element("disabled-src"), element("dest-disabled-src")); >+ shouldBeEqualToString("element('disabled-src').value", "#9a9a9a"); >+ shouldBeEqualToString("element('dest-disabled-src').value", "#ff0000"); >+ >+ performDrag(element("src-disabled-dest"), element("disabled-dest")); >+ shouldBeEqualToString("element('src-disabled-dest').value", "#ff0000"); >+ shouldBeEqualToString("element('disabled-dest').value", "#9a9a9a"); >+ >+ performDrag(element("readonly-src"), element("readonly-dest")); >+ shouldBeEqualToString("element('readonly-src').value", "#ff0000"); >+ shouldBeEqualToString("element('readonly-dest').value", "#ff0000"); >+} >+</script> >+</html> >diff --git a/LayoutTests/platform/ios/TestExpectations b/LayoutTests/platform/ios/TestExpectations >index 64355157b2ebf087dc075d41e669c835ecdbeccf..3eb7c716d53016e1fea43d50a3562cf14b828981 100644 >--- a/LayoutTests/platform/ios/TestExpectations >+++ b/LayoutTests/platform/ios/TestExpectations >@@ -1008,6 +1008,8 @@ editing/pasteboard/drop-file-svg.html [ Skip ] > editing/pasteboard/drop-inputtext-acquires-style.html [ Skip ] > editing/pasteboard/drop-link.html [ Skip ] > editing/pasteboard/drop-text-events.html [ Skip ] >+editing/pasteboard/drag-and-drop-color-input.html [ Skip ] >+editing/pasteboard/drag-and-drop-color-input-events.html [ Skip ] > editing/pasteboard/drag-and-drop-image-contenteditable.html [ Skip ] > editing/pasteboard/drag-and-drop-inputimage-contenteditable.html [ Skip ] > editing/pasteboard/drag-and-drop-objectimage-contenteditable.html [ Skip ] >diff --git a/LayoutTests/platform/mac/TestExpectations b/LayoutTests/platform/mac/TestExpectations >index 9cb6a5dd3c2babd20f4f5db00a1267043b3664d5..15eaeee2619df3eab77fa3a82e6419ce3a1aaf65 100644 >--- a/LayoutTests/platform/mac/TestExpectations >+++ b/LayoutTests/platform/mac/TestExpectations >@@ -1728,6 +1728,8 @@ webkit.org/b/183258 imported/w3c/web-platform-tests/css/css-text/word-break/word > # Color Well is turned off > accessibility/color-well.html [ Skip ] > fast/forms/color [ Skip ] >+editing/pasteboard/drag-and-drop-color-input.html [ Skip ] >+editing/pasteboard/drag-and-drop-color-input-events.html [ Skip ] > imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/color.html [ Skip ] > fast/css/read-only-read-write-input-basics.html [ ImageOnlyFailure ] > fast/css/pseudo-visited-background-color-on-input.html [ ImageOnlyFailure ] >diff --git a/LayoutTests/platform/wk2/TestExpectations b/LayoutTests/platform/wk2/TestExpectations >index cd053c194663d24765dfe09f37621ad116c48cab..9195b41c6f66ac379cedc71c05f360b9ad2ceca9 100644 >--- a/LayoutTests/platform/wk2/TestExpectations >+++ b/LayoutTests/platform/wk2/TestExpectations >@@ -570,6 +570,8 @@ platform/mac/fast/events/objc-event-api.html > # https://bugs.webkit.org/show_bug.cgi?id=64285 > editing/pasteboard/datatransfer-items-drop-plaintext-file.html > editing/pasteboard/datatransfer-types-dropping-text-file.html >+editing/pasteboard/drag-and-drop-color-input.html >+editing/pasteboard/drag-and-drop-color-input-events.html > editing/pasteboard/drag-and-drop-image-contenteditable.html > editing/pasteboard/drag-and-drop-inputimage-contenteditable.html > editing/pasteboard/drag-and-drop-objectimage-contenteditable.html
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 188464
:
346886
|
346889
|
346898
|
346911
|
346915
|
346917
|
346918
|
346927
|
346928
|
346938
|
346943
|
346947
|
346961
|
346994
|
347088
|
347168
|
347173
| 347225