[iOS] Expose SPI to access the current sentence boundary and selection state
[WebKit-https.git] / Tools / TestWebKitAPI / EditingTestHarness.mm
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
27 #include "config.h"
28 #include "EditingTestHarness.h"
29
30 #if WK_API_ENABLED
31
32 #import "PlatformUtilities.h"
33 #import <WebKit/WKWebViewPrivate.h>
34
35 @implementation EditingTestHarness
36
37 - (instancetype)initWithWebView:(TestWKWebView *)webView
38 {
39     if (self = [super init]) {
40         _webView = webView;
41         [_webView setUIDelegate:self];
42         _editorStateHistory = adoptNS([[NSMutableArray alloc] init]);
43     }
44     return self;
45 }
46
47 - (void)dealloc
48 {
49     if ([_webView UIDelegate] == self)
50         [_webView setUIDelegate:nil];
51
52     [super dealloc];
53 }
54
55 - (TestWKWebView *)webView
56 {
57     return _webView.get();
58 }
59
60 - (NSDictionary *)latestEditorState
61 {
62     return self.editorStateHistory.lastObject;
63 }
64
65 - (NSArray<NSDictionary *> *)editorStateHistory
66 {
67     return _editorStateHistory.get();
68 }
69
70 - (void)insertParagraph
71 {
72     [self insertParagraphAndExpectEditorStateWith:nil];
73 }
74
75 - (void)insertText:(NSString *)text
76 {
77     [self insertText:text andExpectEditorStateWith:nil];
78 }
79
80 - (void)insertHTML:(NSString *)html
81 {
82     [self insertHTML:html andExpectEditorStateWith:nil];
83 }
84
85 - (void)selectAll
86 {
87     [self selectAllAndExpectEditorStateWith:nil];
88 }
89
90 - (void)deleteBackwards
91 {
92     [self deleteBackwardAndExpectEditorStateWith:nil];
93 }
94
95 - (void)moveBackward
96 {
97     [self moveBackwardAndExpectEditorStateWith:nil];
98 }
99
100 - (void)moveForward
101 {
102     [self moveForwardAndExpectEditorStateWith:nil];
103 }
104
105 - (void)insertText:(NSString *)text andExpectEditorStateWith:(NSDictionary<NSString *, id> *)entries
106 {
107     [self _execCommand:@"InsertText" argument:text expectEntries:entries];
108 }
109
110 - (void)insertHTML:(NSString *)html andExpectEditorStateWith:(NSDictionary<NSString *, id> *)entries
111 {
112     [self _execCommand:@"InsertHTML" argument:html expectEntries:entries];
113 }
114
115 - (void)selectAllAndExpectEditorStateWith:(NSDictionary<NSString *, id> *)entries
116 {
117     [self _execCommand:@"SelectAll" argument:nil expectEntries:entries];
118 }
119
120 - (void)moveBackwardAndExpectEditorStateWith:(NSDictionary<NSString *, id> *)entries
121 {
122     [self _execCommand:@"MoveBackward" argument:nil expectEntries:entries];
123 }
124
125 - (void)moveWordBackwardAndExpectEditorStateWith:(NSDictionary<NSString *, id> *)entries
126 {
127     [self _execCommand:@"MoveWordBackward" argument:nil expectEntries:entries];
128 }
129
130 - (void)moveForwardAndExpectEditorStateWith:(NSDictionary<NSString *, id> *)entries
131 {
132     [self _execCommand:@"MoveForward" argument:nil expectEntries:entries];
133 }
134
135 - (void)toggleBold
136 {
137     [self _execCommand:@"ToggleBold" argument:nil expectEntries:nil];
138 }
139
140 - (void)toggleItalic
141 {
142     [self _execCommand:@"ToggleItalic" argument:nil expectEntries:nil];
143 }
144
145 - (void)toggleUnderline
146 {
147     [self _execCommand:@"ToggleUnderline" argument:nil expectEntries:nil];
148 }
149
150 - (void)setForegroundColor:(NSString *)colorAsString
151 {
152     [self _execCommand:@"ForeColor" argument:colorAsString expectEntries:nil];
153 }
154
155 - (void)alignJustifiedAndExpectEditorStateWith:(NSDictionary<NSString *, id> *)entries
156 {
157     [self _execCommand:@"AlignJustified" argument:nil expectEntries:entries];
158 }
159
160 - (void)alignLeftAndExpectEditorStateWith:(NSDictionary<NSString *, id> *)entries
161 {
162     [self _execCommand:@"AlignLeft" argument:nil expectEntries:entries];
163 }
164
165 - (void)alignCenterAndExpectEditorStateWith:(NSDictionary<NSString *, id> *)entries
166 {
167     [self _execCommand:@"AlignCenter" argument:nil expectEntries:entries];
168 }
169
170 - (void)alignRightAndExpectEditorStateWith:(NSDictionary<NSString *, id> *)entries
171 {
172     [self _execCommand:@"AlignRight" argument:nil expectEntries:entries];
173 }
174
175 - (void)insertParagraphAndExpectEditorStateWith:(NSDictionary<NSString *, id> *)entries
176 {
177     [self _execCommand:@"InsertParagraph" argument:nil expectEntries:entries];
178 }
179
180 - (void)deleteBackwardAndExpectEditorStateWith:(NSDictionary<NSString *, id> *)entries
181 {
182     [self _execCommand:@"DeleteBackward" argument:nil expectEntries:entries];
183 }
184
185 - (void)_execCommand:(NSString *)command argument:(NSString *)argument expectEntries:(NSDictionary<NSString *, id> *)entries
186 {
187     __block BOOL result = false;
188     __block bool done = false;
189     [_webView _executeEditCommand:command argument:argument completion:^(BOOL success) {
190         result = success;
191         done = true;
192     }];
193     TestWebKitAPI::Util::run(&done);
194
195     [_webView waitForNextPresentationUpdate];
196
197     EXPECT_TRUE(result);
198     if (!result)
199         NSLog(@"Failed to execute editing command: ('%@', '%@')", command, argument ?: @"");
200
201     BOOL containsEntries = [self latestEditorStateContains:entries];
202     EXPECT_TRUE(containsEntries);
203     if (!containsEntries)
204         NSLog(@"Expected %@ to contain %@", self.latestEditorState, entries);
205 }
206
207 - (BOOL)latestEditorStateContains:(NSDictionary<NSString *, id> *)entries
208 {
209     NSDictionary *latestEditorState = self.latestEditorState;
210     for (NSString *key in entries) {
211         if (![latestEditorState[key] isEqual:entries[key]])
212             return NO;
213     }
214     return latestEditorState.count || !entries.count;
215 }
216
217 #pragma mark - WKUIDelegatePrivate
218
219 - (void)_webView:(WKWebView *)webView editorStateDidChange:(NSDictionary *)editorState
220 {
221     if (![editorState[@"post-layout-data"] boolValue])
222         return;
223
224     if (![self.latestEditorState isEqualToDictionary:editorState])
225         [_editorStateHistory addObject:editorState];
226 }
227
228 @end
229
230 #endif // WK_API_ENABLED