[Cocoa] Web Automation: non-sticky virtual keys like 'left arrow' don't work properly
[WebKit-https.git] / Source / WebKit2 / UIProcess / Automation / cocoa / WebAutomationSessionCocoa.mm
1 /*
2  * Copyright (C) 2016, 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 #import "config.h"
27 #import "WebAutomationSession.h"
28
29 #if PLATFORM(COCOA)
30
31 #if PLATFORM(IOS)
32 #include <ImageIO/CGImageDestination.h>
33 #include <MobileCoreServices/UTCoreTypes.h>
34 #include <WebCore/KeyEventCodesIOS.h>
35 #endif
36
37 using namespace WebCore;
38
39 namespace WebKit {
40
41 std::optional<String> WebAutomationSession::platformGetBase64EncodedPNGData(const ShareableBitmap::Handle& imageDataHandle)
42 {
43     RefPtr<ShareableBitmap> bitmap = ShareableBitmap::create(imageDataHandle, SharedMemory::Protection::ReadOnly);
44     if (!bitmap)
45         return std::nullopt;
46
47     RetainPtr<CGImageRef> cgImage = bitmap->makeCGImage();
48     RetainPtr<NSMutableData> imageData = adoptNS([[NSMutableData alloc] init]);
49     RetainPtr<CGImageDestinationRef> destination = adoptCF(CGImageDestinationCreateWithData((CFMutableDataRef)imageData.get(), kUTTypePNG, 1, 0));
50     if (!destination)
51         return std::nullopt;
52
53     CGImageDestinationAddImage(destination.get(), cgImage.get(), 0);
54     CGImageDestinationFinalize(destination.get());
55
56     return String([imageData base64EncodedStringWithOptions:0]);
57 }
58
59 std::optional<unichar> WebAutomationSession::charCodeForVirtualKey(Inspector::Protocol::Automation::VirtualKey key) const
60 {
61     switch (key) {
62     case Inspector::Protocol::Automation::VirtualKey::Shift:
63     case Inspector::Protocol::Automation::VirtualKey::Control:
64     case Inspector::Protocol::Automation::VirtualKey::Alternate:
65     case Inspector::Protocol::Automation::VirtualKey::Meta:
66     case Inspector::Protocol::Automation::VirtualKey::Command:
67         return std::nullopt;
68     case Inspector::Protocol::Automation::VirtualKey::Help:
69         return NSHelpFunctionKey;
70     case Inspector::Protocol::Automation::VirtualKey::Backspace:
71         return NSBackspaceCharacter;
72     case Inspector::Protocol::Automation::VirtualKey::Tab:
73         return NSTabCharacter;
74     case Inspector::Protocol::Automation::VirtualKey::Clear:
75         return NSClearLineFunctionKey;
76     case Inspector::Protocol::Automation::VirtualKey::Enter:
77         return NSEnterCharacter;
78     case Inspector::Protocol::Automation::VirtualKey::Pause:
79         return NSPauseFunctionKey;
80     case Inspector::Protocol::Automation::VirtualKey::Cancel:
81         // The 'cancel' key does not exist on Apple keyboards and has no keycode.
82         // According to the internet its functionality is similar to 'Escape'.
83     case Inspector::Protocol::Automation::VirtualKey::Escape:
84         return 0x1B;
85     case Inspector::Protocol::Automation::VirtualKey::PageUp:
86         return NSPageUpFunctionKey;
87     case Inspector::Protocol::Automation::VirtualKey::PageDown:
88         return NSPageDownFunctionKey;
89     case Inspector::Protocol::Automation::VirtualKey::End:
90         return NSEndFunctionKey;
91     case Inspector::Protocol::Automation::VirtualKey::Home:
92         return NSHomeFunctionKey;
93     case Inspector::Protocol::Automation::VirtualKey::LeftArrow:
94         return NSLeftArrowFunctionKey;
95     case Inspector::Protocol::Automation::VirtualKey::UpArrow:
96         return NSUpArrowFunctionKey;
97     case Inspector::Protocol::Automation::VirtualKey::RightArrow:
98         return NSRightArrowFunctionKey;
99     case Inspector::Protocol::Automation::VirtualKey::DownArrow:
100         return NSDownArrowFunctionKey;
101     case Inspector::Protocol::Automation::VirtualKey::Insert:
102         return NSInsertFunctionKey;
103     case Inspector::Protocol::Automation::VirtualKey::Delete:
104         return NSDeleteFunctionKey;
105     case Inspector::Protocol::Automation::VirtualKey::Space:
106         return ' ';
107     case Inspector::Protocol::Automation::VirtualKey::Semicolon:
108         return ';';
109     case Inspector::Protocol::Automation::VirtualKey::Equals:
110         return '=';
111     case Inspector::Protocol::Automation::VirtualKey::Return:
112         return NSCarriageReturnCharacter;
113     case Inspector::Protocol::Automation::VirtualKey::NumberPad0:
114         return '0';
115     case Inspector::Protocol::Automation::VirtualKey::NumberPad1:
116         return '1';
117     case Inspector::Protocol::Automation::VirtualKey::NumberPad2:
118         return '2';
119     case Inspector::Protocol::Automation::VirtualKey::NumberPad3:
120         return '3';
121     case Inspector::Protocol::Automation::VirtualKey::NumberPad4:
122         return '4';
123     case Inspector::Protocol::Automation::VirtualKey::NumberPad5:
124         return '5';
125     case Inspector::Protocol::Automation::VirtualKey::NumberPad6:
126         return '6';
127     case Inspector::Protocol::Automation::VirtualKey::NumberPad7:
128         return '7';
129     case Inspector::Protocol::Automation::VirtualKey::NumberPad8:
130         return '8';
131     case Inspector::Protocol::Automation::VirtualKey::NumberPad9:
132         return '9';
133     case Inspector::Protocol::Automation::VirtualKey::NumberPadMultiply:
134         return '*';
135     case Inspector::Protocol::Automation::VirtualKey::NumberPadAdd:
136         return '+';
137     case Inspector::Protocol::Automation::VirtualKey::NumberPadSubtract:
138         return '-';
139     case Inspector::Protocol::Automation::VirtualKey::NumberPadSeparator:
140         // The 'Separator' key is only present on a few international keyboards.
141         // It is usually mapped to the same character as Decimal ('.' or ',').
142     case Inspector::Protocol::Automation::VirtualKey::NumberPadDecimal:
143         return '.';
144     case Inspector::Protocol::Automation::VirtualKey::NumberPadDivide:
145         return '/';
146     case Inspector::Protocol::Automation::VirtualKey::Function1:
147         return NSF1FunctionKey;
148     case Inspector::Protocol::Automation::VirtualKey::Function2:
149         return NSF2FunctionKey;
150     case Inspector::Protocol::Automation::VirtualKey::Function3:
151         return NSF3FunctionKey;
152     case Inspector::Protocol::Automation::VirtualKey::Function4:
153         return NSF4FunctionKey;
154     case Inspector::Protocol::Automation::VirtualKey::Function5:
155         return NSF5FunctionKey;
156     case Inspector::Protocol::Automation::VirtualKey::Function6:
157         return NSF6FunctionKey;
158     case Inspector::Protocol::Automation::VirtualKey::Function7:
159         return NSF7FunctionKey;
160     case Inspector::Protocol::Automation::VirtualKey::Function8:
161         return NSF8FunctionKey;
162     case Inspector::Protocol::Automation::VirtualKey::Function9:
163         return NSF9FunctionKey;
164     case Inspector::Protocol::Automation::VirtualKey::Function10:
165         return NSF10FunctionKey;
166     case Inspector::Protocol::Automation::VirtualKey::Function11:
167         return NSF11FunctionKey;
168     case Inspector::Protocol::Automation::VirtualKey::Function12:
169         return NSF12FunctionKey;
170     default:
171         return std::nullopt;
172     }
173 }
174
175 std::optional<unichar> WebAutomationSession::charCodeIgnoringModifiersForVirtualKey(Inspector::Protocol::Automation::VirtualKey key) const
176 {
177     switch (key) {
178     case Inspector::Protocol::Automation::VirtualKey::NumberPadMultiply:
179         return '8';
180     case Inspector::Protocol::Automation::VirtualKey::NumberPadAdd:
181         return '=';
182     default:
183         return charCodeForVirtualKey(key);
184     }
185 }
186
187 } // namespace WebKit
188
189 #endif // PLATFORM(COCOA)