Changeset 235011 in webkit
- Timestamp:
- Aug 18, 2018 3:59:20 PM (6 years ago)
- Location:
- trunk
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r235009 r235011 1 2018-08-18 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 [iOS] Paste is missing from callout bar when pasteboard only contains custom data 4 https://bugs.webkit.org/show_bug.cgi?id=184271 5 <rdar://problem/39256708> 6 7 Reviewed by Ryosuke Niwa. 8 9 Export a couple of WebCore functions for use in WebKit. 10 11 * dom/Document.h: 12 * platform/Pasteboard.h: 13 1 14 2018-08-17 Ryosuke Niwa <rniwa@webkit.org> 2 15 -
trunk/Source/WebCore/dom/Document.h
r234680 r235011 1007 1007 uint64_t domTreeVersion() const { return m_domTreeVersion; } 1008 1008 1009 String originIdentifierForPasteboard();1009 WEBCORE_EXPORT String originIdentifierForPasteboard(); 1010 1010 1011 1011 // XPathEvaluator methods -
trunk/Source/WebCore/platform/Pasteboard.h
r234930 r235011 171 171 172 172 #if PLATFORM(COCOA) 173 static const char* cocoaType();173 WEBCORE_EXPORT static const char* cocoaType(); 174 174 #endif 175 175 }; -
trunk/Source/WebKit/ChangeLog
r235006 r235011 1 2018-08-18 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 [iOS] Paste is missing from callout bar when pasteboard only contains custom data 4 https://bugs.webkit.org/show_bug.cgi?id=184271 5 <rdar://problem/39256708> 6 7 Reviewed by Ryosuke Niwa. 8 9 Currently, the "paste:" selector action cannot be performed during editing if the pasteboard only contains 10 custom pasteboard data. This is because logic in -[WKContentView canPerformActionForWebView:withSender:] only 11 checks against a list of pasteboard types which does not include the type identifier for custom pasteboard data. 12 To fix this, we allow pasting only in the case where none of the other type identifiers exist in the pasteboard, 13 as long as the custom pasteboard data type identifier is present, and the custom pasteboard data's origin 14 matches the origin of the focused frame's document. 15 16 Test: PasteMixedContent.CopyAndPasteWithCustomPasteboardDataOnly 17 18 * Shared/EditorState.cpp: 19 (WebKit::EditorState::encode const): 20 (WebKit::EditorState::decode): 21 * Shared/EditorState.h: 22 23 Add a originIdentifierForPasteboard field, and add support for encoding it when propagating EditorState via IPC. 24 25 * UIProcess/ios/WKContentViewInteraction.mm: 26 (-[WKContentView canPerformActionForWebView:withSender:]): 27 28 If none of the conventional pasteboard type identifiers for rich or plain text editing are present, check to see 29 if we have custom pasteboard data; if so, only allow pasting if the custom pasteboard data's origin matches that 30 of the focused frame's document origin. 31 32 Additionally refactor a bit of logic by pulling out `_page->editorState()` into a separate local variable, used 33 throughout the rest of the method. 34 35 * WebProcess/WebPage/WebPage.cpp: 36 (WebKit::WebPage::editorState const): 37 38 Send the focused frame's document origin to the UI process via EditorState. 39 1 40 2018-08-17 Tim Horton <timothy_horton@apple.com> 2 41 -
trunk/Source/WebKit/Shared/EditorState.cpp
r225651 r235011 54 54 encoder << markedText; 55 55 #endif 56 57 encoder << originIdentifierForPasteboard; 56 58 } 57 59 … … 98 100 return false; 99 101 #endif 102 103 if (!decoder.decode(result.originIdentifierForPasteboard)) 104 return false; 100 105 101 106 return true; -
trunk/Source/WebKit/Shared/EditorState.h
r225651 r235011 81 81 #endif 82 82 83 String originIdentifierForPasteboard; 84 83 85 struct PostLayoutData { 84 86 uint32_t typingAttributes { AttributeNone }; -
trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm
r234808 r235011 2277 2277 return [self isFirstResponder]; 2278 2278 2279 auto editorState = _page->editorState(); 2279 2280 if (action == @selector(_showTextStyleOptions:)) 2280 return _page->editorState().isContentRichlyEditable && _page->editorState().selectionIsRange && !_showingTextStyleOptions;2281 return editorState.isContentRichlyEditable && editorState.selectionIsRange && !_showingTextStyleOptions; 2281 2282 if (_showingTextStyleOptions) 2282 2283 return (action == @selector(toggleBoldface:) || action == @selector(toggleItalics:) || action == @selector(toggleUnderline:)); 2283 2284 if (action == @selector(toggleBoldface:) || action == @selector(toggleItalics:) || action == @selector(toggleUnderline:)) 2284 return _page->editorState().isContentRichlyEditable;2285 return editorState.isContentRichlyEditable; 2285 2286 if (action == @selector(cut:)) 2286 return ! _page->editorState().isInPasswordField && _page->editorState().isContentEditable && _page->editorState().selectionIsRange;2287 return !editorState.isInPasswordField && editorState.isContentEditable && editorState.selectionIsRange; 2287 2288 2288 2289 if (action == @selector(paste:)) { 2289 if ( _page->editorState().selectionIsNone || !_page->editorState().isContentEditable)2290 if (editorState.selectionIsNone || !editorState.isContentEditable) 2290 2291 return NO; 2291 2292 UIPasteboard *pasteboard = [UIPasteboard generalPasteboard]; 2292 2293 NSArray *types = [self supportedPasteboardTypesForCurrentSelection]; 2293 2294 NSIndexSet *indices = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [pasteboard numberOfItems])]; 2294 return [pasteboard containsPasteboardTypes:types inItemSet:indices]; 2295 if ([pasteboard containsPasteboardTypes:types inItemSet:indices]) 2296 return YES; 2297 2298 auto focusedDocumentOrigin = editorState.originIdentifierForPasteboard; 2299 if (focusedDocumentOrigin.isEmpty()) 2300 return NO; 2301 2302 NSArray *allCustomPasteboardData = [pasteboard dataForPasteboardType:@(PasteboardCustomData::cocoaType()) inItemSet:indices]; 2303 for (NSData *data in allCustomPasteboardData) { 2304 auto buffer = SharedBuffer::create(data); 2305 if (PasteboardCustomData::fromSharedBuffer(buffer.get()).origin == focusedDocumentOrigin) 2306 return YES; 2307 } 2308 return NO; 2295 2309 } 2296 2310 2297 2311 if (action == @selector(copy:)) { 2298 if ( _page->editorState().isInPasswordField)2312 if (editorState.isInPasswordField) 2299 2313 return NO; 2300 return _page->editorState().selectionIsRange;2314 return editorState.selectionIsRange; 2301 2315 } 2302 2316 2303 2317 if (action == @selector(_define:)) { 2304 if ( _page->editorState().isInPasswordField || !_page->editorState().selectionIsRange)2318 if (editorState.isInPasswordField || !editorState.selectionIsRange) 2305 2319 return NO; 2306 2320 2307 NSUInteger textLength = _page->editorState().postLayoutData().selectedTextLength;2321 NSUInteger textLength = editorState.postLayoutData().selectedTextLength; 2308 2322 // FIXME: We should be calling UIReferenceLibraryViewController to check if the length is 2309 2323 // acceptable, but the interface takes a string. … … 2321 2335 2322 2336 if (action == @selector(_lookup:)) { 2323 if ( _page->editorState().isInPasswordField)2337 if (editorState.isInPasswordField) 2324 2338 return NO; 2325 2339 … … 2329 2343 #endif 2330 2344 2331 return _page->editorState().selectionIsRange;2345 return editorState.selectionIsRange; 2332 2346 } 2333 2347 2334 2348 if (action == @selector(_share:)) { 2335 if ( _page->editorState().isInPasswordField || !_page->editorState().selectionIsRange)2349 if (editorState.isInPasswordField || !editorState.selectionIsRange) 2336 2350 return NO; 2337 2351 2338 return _page->editorState().postLayoutData().selectedTextLength > 0;2352 return editorState.postLayoutData().selectedTextLength > 0; 2339 2353 } 2340 2354 2341 2355 if (action == @selector(_addShortcut:)) { 2342 if ( _page->editorState().isInPasswordField || !_page->editorState().selectionIsRange)2356 if (editorState.isInPasswordField || !editorState.selectionIsRange) 2343 2357 return NO; 2344 2358 … … 2355 2369 2356 2370 if (action == @selector(_promptForReplace:)) { 2357 if (! _page->editorState().selectionIsRange || !_page->editorState().postLayoutData().isReplaceAllowed || ![[UIKeyboardImpl activeInstance] autocorrectSpellingEnabled])2371 if (!editorState.selectionIsRange || !editorState.postLayoutData().isReplaceAllowed || ![[UIKeyboardImpl activeInstance] autocorrectSpellingEnabled]) 2358 2372 return NO; 2359 2373 if ([[self selectedText] _containsCJScriptsOnly]) … … 2363 2377 2364 2378 if (action == @selector(_transliterateChinese:)) { 2365 if (! _page->editorState().selectionIsRange || !_page->editorState().postLayoutData().isReplaceAllowed || ![[UIKeyboardImpl activeInstance] autocorrectSpellingEnabled])2379 if (!editorState.selectionIsRange || !editorState.postLayoutData().isReplaceAllowed || ![[UIKeyboardImpl activeInstance] autocorrectSpellingEnabled]) 2366 2380 return NO; 2367 2381 return UIKeyboardEnabledInputModesAllowChineseTransliterationForText([self selectedText]); … … 2370 2384 if (action == @selector(select:)) { 2371 2385 // Disable select in password fields so that you can't see word boundaries. 2372 return ! _page->editorState().isInPasswordField && [self hasContent] && !_page->editorState().selectionIsNone && !_page->editorState().selectionIsRange;2386 return !editorState.isInPasswordField && [self hasContent] && !editorState.selectionIsNone && !editorState.selectionIsRange; 2373 2387 } 2374 2388 2375 2389 if (action == @selector(selectAll:)) { 2376 if (! _page->editorState().selectionIsNone && !_page->editorState().selectionIsRange)2390 if (!editorState.selectionIsNone && !editorState.selectionIsRange) 2377 2391 return YES; 2378 2392 return NO; … … 2380 2394 2381 2395 if (action == @selector(replace:)) 2382 return _page->editorState().isContentEditable && !_page->editorState().isInPasswordField;2396 return editorState.isContentEditable && !editorState.isInPasswordField; 2383 2397 2384 2398 return [super canPerformAction:action withSender:sender]; -
trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp
r234995 r235011 922 922 result.shouldIgnoreSelectionChanges = editor.ignoreSelectionChanges(); 923 923 924 if (auto* document = frame.document()) 925 result.originIdentifierForPasteboard = document->originIdentifierForPasteboard(); 926 924 927 bool canIncludePostLayoutData = frame.view() && !frame.view()->needsLayout(); 925 928 if (shouldIncludePostLayoutData == IncludePostLayoutDataHint::Yes && canIncludePostLayoutData) { -
trunk/Tools/ChangeLog
r234997 r235011 1 2018-08-18 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 [iOS] Paste is missing from callout bar when pasteboard only contains custom data 4 https://bugs.webkit.org/show_bug.cgi?id=184271 5 <rdar://problem/39256708> 6 7 Reviewed by Ryosuke Niwa. 8 9 Add a new API test to verify that on both iOS and macOS, copied custom pasteboard data can only be pasted in a 10 matching origin. Additionally verify that on iOS, the web view is capable of performing the "paste:" selector. 11 12 * TestWebKitAPI/Tests/WebKitCocoa/PasteMixedContent.mm: 13 (TestWebKitAPI::TEST): 14 (imagePath): Deleted. 15 (writeTypesAndDataToPasteboard): Deleted. 16 (setUpWebView): Deleted. 17 (markupString): Deleted. 18 19 Make this test file no longer exclusive to macOS. 20 21 * TestWebKitAPI/cocoa/TestWKWebView.h: 22 * TestWebKitAPI/cocoa/TestWKWebView.mm: 23 (-[TestWKWebView synchronouslyLoadHTMLString:baseURL:]): 24 25 Tweak this helper to also take in a `baseURL`. Defaults to using the TestWebKitAPI bundle resource URL. 26 27 (-[TestWKWebView synchronouslyLoadHTMLString:]): 28 1 29 2018-08-17 Jonathan Bedard <jbedard@apple.com> 2 30 -
trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/PasteMixedContent.mm
r231531 r235011 26 26 #include "config.h" 27 27 28 #if PLATFORM(MAC) &&WK_API_ENABLED28 #if WK_API_ENABLED 29 29 30 30 #import "PlatformUtilities.h" 31 #import "TestURLSchemeHandler.h" 31 32 #import "TestWKWebView.h" 32 33 #import <WebKit/WKPreferencesRef.h> 33 34 #import <WebKit/WKPreferencesRefPrivate.h> 35 #import <WebKit/WKWebViewPrivate.h> 34 36 #import <wtf/RetainPtr.h> 35 37 #import <wtf/text/WTFString.h> 38 39 namespace TestWebKitAPI { 40 41 #if PLATFORM(MAC) 36 42 37 43 static NSString *imagePath() … … 97 103 } 98 104 99 namespace TestWebKitAPI {100 101 105 TEST(PasteMixedContent, ImageFileAndPlainText) 102 106 { … … 252 256 } 253 257 258 #endif // PLATFORM(MAC) 259 260 TEST(PasteMixedContent, CopyAndPasteWithCustomPasteboardDataOnly) 261 { 262 NSString *markupForSource = @"<body oncopy=\"event.preventDefault(); event.clipboardData.setData('foo', 'bar')\">hello</body>"; 263 NSString *markupForDestination = @"<input autofocus onpaste=\"event.preventDefault(); this.value = event.clipboardData.getData('foo')\">"; 264 265 auto schemeHandler = adoptNS([[TestURLSchemeHandler alloc] init]); 266 auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]); 267 [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"same"]; 268 [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"different"]; 269 270 auto source = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 400, 400) configuration:configuration.get()]); 271 [source synchronouslyLoadHTMLString:markupForSource baseURL:[NSURL URLWithString:@"same://"]]; 272 [source selectAll:nil]; 273 [source _executeEditCommand:@"copy" argument:nil completion:nil]; 274 275 auto destination = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 400, 400) configuration:configuration.get()]); 276 [destination synchronouslyLoadHTMLString:markupForDestination baseURL:[NSURL URLWithString:@"same://"]]; 277 [destination paste:nil]; 278 EXPECT_WK_STREQ("bar", [destination stringByEvaluatingJavaScript:@"document.querySelector('input').value"]); 279 #if PLATFORM(IOS) 280 EXPECT_TRUE([destination canPerformAction:@selector(paste:) withSender:nil]); 281 #endif 282 283 [destination synchronouslyLoadHTMLString:markupForDestination baseURL:[NSURL URLWithString:@"different://"]]; 284 [destination paste:nil]; 285 EXPECT_WK_STREQ("", [destination stringByEvaluatingJavaScript:@"document.querySelector('input').value"]); 286 #if PLATFORM(IOS) 287 EXPECT_FALSE([destination canPerformAction:@selector(paste:) withSender:nil]); 288 #endif 289 } 290 254 291 } // namespace TestWebKitAPI 255 292 256 #endif // PLATFORM(MAC) &&WK_API_ENABLED293 #endif // WK_API_ENABLED -
trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.h
r234816 r235011 52 52 - (void)loadTestPageNamed:(NSString *)pageName; 53 53 - (void)synchronouslyLoadHTMLString:(NSString *)html; 54 - (void)synchronouslyLoadHTMLString:(NSString *)html baseURL:(NSURL *)url; 54 55 - (void)synchronouslyLoadTestPageNamed:(NSString *)pageName; 55 56 - (id)objectByEvaluatingJavaScript:(NSString *)script; -
trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.mm
r234816 r235011 247 247 } 248 248 249 - (void)synchronouslyLoadHTMLString:(NSString *)html baseURL:(NSURL *)url 250 { 251 [self loadHTMLString:html baseURL:url]; 252 [self _test_waitForDidFinishNavigation]; 253 } 254 249 255 - (void)synchronouslyLoadHTMLString:(NSString *)html 250 256 { 251 NSURL *testResourceURL = [[[NSBundle mainBundle] bundleURL] URLByAppendingPathComponent:@"TestWebKitAPI.resources"]; 252 [self loadHTMLString:html baseURL:testResourceURL]; 253 [self _test_waitForDidFinishNavigation]; 257 [self synchronouslyLoadHTMLString:html baseURL:[[[NSBundle mainBundle] bundleURL] URLByAppendingPathComponent:@"TestWebKitAPI.resources"]]; 254 258 } 255 259
Note: See TracChangeset
for help on using the changeset viewer.