[iOS WK2] Add plumbing for WKContentView to ask the web process for additional drag...
[WebKit-https.git] / Source / WebKit / UIProcess / ios / DragDropInteractionState.h
1 /*
2  * Copyright (C) 2017 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #pragma once
27
28 #if ENABLE(DRAG_SUPPORT) && PLATFORM(IOS)
29
30 #import "UIKitSPI.h"
31 #import <WebCore/DragActions.h>
32 #import <WebCore/DragData.h>
33 #import <WebCore/TextIndicator.h>
34 #import <WebCore/URL.h>
35 #import <WebCore/WebItemProviderPasteboard.h>
36 #import <wtf/BlockPtr.h>
37 #import <wtf/RetainPtr.h>
38 #import <wtf/Vector.h>
39
40 namespace WebCore {
41 struct DragItem;
42 }
43
44 namespace WebKit {
45
46 struct DragSourceState {
47     WebCore::DragSourceAction action { WebCore::DragSourceActionNone };
48     CGPoint adjustedOrigin { CGPointZero };
49     CGRect elementBounds { CGRectZero };
50     RetainPtr<UIImage> image;
51     std::optional<WebCore::TextIndicatorData> indicatorData;
52     String linkTitle;
53     WebCore::URL linkURL;
54     bool possiblyNeedsDragPreviewUpdate { true };
55
56     NSInteger itemIdentifier { 0 };
57 };
58
59 class DragDropInteractionState {
60 public:
61     bool anyActiveDragSourceIs(WebCore::DragSourceAction) const;
62
63     // These helper methods are unique to UIDragInteraction.
64     void prepareForDragSession(id <UIDragSession>, dispatch_block_t completionHandler);
65     void dragSessionWillBegin();
66     void stageDragItem(const WebCore::DragItem&, UIImage *);
67     bool hasStagedDragSource() const;
68     const DragSourceState& stagedDragSource() const { return m_stagedDragSource.value(); }
69     enum class DidBecomeActive { No, Yes };
70     void clearStagedDragSource(DidBecomeActive = DidBecomeActive::No);
71     UITargetedDragPreview *previewForDragItem(UIDragItem *, UIView *contentView, UIView *previewContainer) const;
72     void dragSessionWillDelaySetDownAnimation(dispatch_block_t completion);
73     bool shouldRequestAdditionalItemForDragSession(id <UIDragSession>) const;
74     void dragSessionWillRequestAdditionalItem(void (^completion)(NSArray <UIDragItem *> *));
75
76     // These helper methods are unique to UIDropInteraction.
77     void dropSessionDidEnterOrUpdate(id <UIDropSession>, const WebCore::DragData&);
78     void dropSessionDidExit() { m_dropSession = nil; }
79     void dropSessionWillPerformDrop() { m_isPerformingDrop = true; }
80
81     // This is invoked when both drag and drop interactions are no longer active.
82     void dragAndDropSessionsDidEnd();
83
84     CGPoint adjustedPositionForDragEnd() const { return m_adjustedPositionForDragEnd; }
85     bool didBeginDragging() const { return m_didBeginDragging; }
86     bool isPerformingDrop() const { return m_isPerformingDrop; }
87     id<UIDragSession> dragSession() const { return m_dragSession.get(); }
88     id<UIDropSession> dropSession() const { return m_dropSession.get(); }
89     BlockPtr<void()> takeDragStartCompletionBlock() { return WTFMove(m_dragStartCompletionBlock); }
90     BlockPtr<void()> takeDragCancelSetDownBlock() { return WTFMove(m_dragCancelSetDownBlock); }
91     BlockPtr<void(NSArray<UIDragItem *> *)> takeAddDragItemCompletionBlock() { return WTFMove(m_addDragItemCompletionBlock); }
92
93 private:
94     void updatePreviewsForActiveDragSources();
95     std::optional<DragSourceState> activeDragSourceForItem(UIDragItem *) const;
96
97     CGPoint m_lastGlobalPosition { CGPointZero };
98     CGPoint m_adjustedPositionForDragEnd { CGPointZero };
99     bool m_didBeginDragging { false };
100     bool m_isPerformingDrop { false };
101     RetainPtr<id <UIDragSession>> m_dragSession;
102     RetainPtr<id <UIDropSession>> m_dropSession;
103     BlockPtr<void()> m_dragStartCompletionBlock;
104     BlockPtr<void()> m_dragCancelSetDownBlock;
105     BlockPtr<void(NSArray<UIDragItem *> *)> m_addDragItemCompletionBlock;
106
107     std::optional<DragSourceState> m_stagedDragSource;
108     Vector<DragSourceState> m_activeDragSources;
109 };
110
111 } // namespace WebKit
112
113 #endif // ENABLE(DRAG_SUPPORT) && PLATFORM(IOS)