Changeset 211227 in webkit
- Timestamp:
- Jan 26, 2017 12:58:08 PM (7 years ago)
- Location:
- trunk/Source
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r211226 r211227 1 2017-01-26 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 Add support for recognizing data interaction gestures in WebKit2 4 https://bugs.webkit.org/show_bug.cgi?id=167444 5 6 Reviewed by Beth Dakin. 7 8 Minor tweaks to pasteboard code to support data interaction. 9 10 * WebCore.xcodeproj/project.pbxproj: 11 * platform/PlatformPasteboard.h: 12 * platform/ios/PasteboardIOS.mm: 13 (WebCore::Pasteboard::read): 14 * platform/ios/PlatformPasteboardIOS.mm: 15 (WebCore::PlatformPasteboard::PlatformPasteboard): 16 17 If the pasteboard is the special data interaction type, use the shared item provider pasteboard; otherwise, 18 fall back to the general pasteboard. 19 20 (WebCore::PlatformPasteboard::getTypes): 21 22 Actually populate the list of available types using available pasteboardTypes. 23 24 (WebCore::PlatformPasteboard::write): 25 26 Add UTF8 plaintext type (kUTTypeUTF8PlainText) when vending data representations of rich text. 27 28 * platform/ios/WebItemProviderPasteboard.mm: 29 (-[WebItemProviderPasteboard setItems:]): 30 (-[WebItemProviderPasteboard dataForPasteboardType:inItemSet:]): 31 (-[WebItemProviderPasteboard valuesForPasteboardType:inItemSet:]): 32 33 Move off of deprecated methods when retrieving and supplying data to the item provider pasteboard. 34 35 * platform/spi/ios/UIKitSPI.h: 36 1 37 2017-01-26 Matt Rajca <mrajca@apple.com> 2 38 -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r211191 r211227 6512 6512 F47A5E3F195B8E4800483100 /* StyleScrollSnapPoints.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F47A5E3A195B8C8A00483100 /* StyleScrollSnapPoints.cpp */; }; 6513 6513 F48223101E3869B80066FC79 /* WebItemProviderPasteboard.mm in Sources */ = {isa = PBXBuildFile; fileRef = F482230E1E3869B80066FC79 /* WebItemProviderPasteboard.mm */; }; 6514 F48223111E3869B80066FC79 /* WebItemProviderPasteboard.h in Headers */ = {isa = PBXBuildFile; fileRef = F482230F1E3869B80066FC79 /* WebItemProviderPasteboard.h */; };6515 F48223131E386E240066FC79 /* AbstractPasteboard.h in Headers */ = {isa = PBXBuildFile; fileRef = F48223121E386E240066FC79 /* AbstractPasteboard.h */; };6514 F48223111E3869B80066FC79 /* WebItemProviderPasteboard.h in Headers */ = {isa = PBXBuildFile; fileRef = F482230F1E3869B80066FC79 /* WebItemProviderPasteboard.h */; settings = {ATTRIBUTES = (Private, ); }; }; 6515 F48223131E386E240066FC79 /* AbstractPasteboard.h in Headers */ = {isa = PBXBuildFile; fileRef = F48223121E386E240066FC79 /* AbstractPasteboard.h */; settings = {ATTRIBUTES = (Private, ); }; }; 6516 6516 F4BFB9851E1DDF9B00862C24 /* DumpEditingHistory.js in Copy Scripts */ = {isa = PBXBuildFile; fileRef = F48389831E1DDF2B0076B7EA /* DumpEditingHistory.js */; }; 6517 6517 F4BFB9861E1DDF9B00862C24 /* EditingHistoryUtil.js in Copy Scripts */ = {isa = PBXBuildFile; fileRef = F48389841E1DDF2B0076B7EA /* EditingHistoryUtil.js */; }; -
trunk/Source/WebCore/platform/PlatformPasteboard.h
r211158 r211227 93 93 #endif 94 94 #if PLATFORM(IOS) 95 RetainPtr< UIPasteboard> m_pasteboard;95 RetainPtr<id> m_pasteboard; 96 96 #endif 97 97 #if PLATFORM(GTK) -
trunk/Source/WebCore/platform/ios/PasteboardIOS.mm
r211192 r211227 151 151 { 152 152 PasteboardStrategy& strategy = *platformStrategies()->pasteboardStrategy(); 153 text.text = strategy.readStringFromPasteboard(0, kUTTypeURL, m_pasteboardName); 154 if (!text.text.isNull() && !text.text.isEmpty()) { 155 text.isURL = true; 156 return; 157 } 158 153 159 text.text = strategy.readStringFromPasteboard(0, kUTTypeText, m_pasteboardName); 154 if (text.text.isEmpty()) 155 text.text = strategy.readStringFromPasteboard(0, kUTTypeURL, m_pasteboardName); 160 text.isURL = false; 156 161 } 157 162 -
trunk/Source/WebCore/platform/ios/PlatformPasteboardIOS.mm
r209307 r211227 33 33 #import "SharedBuffer.h" 34 34 #import "SoftLinking.h" 35 #import "WebItemProviderPasteboard.h" 35 36 #import <MobileCoreServices/MobileCoreServices.h> 36 37 … … 54 55 } 55 56 57 #if ENABLE(DATA_INTERACTION) 58 PlatformPasteboard::PlatformPasteboard(const String& name) 59 { 60 if (name == "data interaction pasteboard") 61 m_pasteboard = [WebItemProviderPasteboard sharedInstance]; 62 else 63 m_pasteboard = [getUIPasteboardClass() generalPasteboard]; 64 } 65 #else 56 66 PlatformPasteboard::PlatformPasteboard(const String&) 57 67 : m_pasteboard([getUIPasteboardClass() generalPasteboard]) 58 68 { 59 69 } 60 61 void PlatformPasteboard::getTypes(Vector<String>&) 62 { 70 #endif 71 72 void PlatformPasteboard::getTypes(Vector<String>& types) 73 { 74 for (NSString *pasteboardType in [m_pasteboard pasteboardTypes]) 75 types.append(pasteboardType); 63 76 } 64 77 … … 146 159 if (content.dataInRTFFormat) 147 160 [representations setValue:content.dataInRTFFormat->createNSData().get() forKey:(NSString *)kUTTypeRTF]; 161 148 162 [representations setValue:content.dataInStringFormat forKey:(NSString *)kUTTypeText]; 163 [representations setValue:[(NSString *)content.dataInStringFormat dataUsingEncoding:NSUTF8StringEncoding] forKey:(NSString *)kUTTypeUTF8PlainText]; 149 164 [m_pasteboard setItems:@[representations.get()]]; 150 165 } -
trunk/Source/WebCore/platform/ios/WebItemProviderPasteboard.mm
r211175 r211227 31 31 #import "SoftLinking.h" 32 32 #import "UIKitSPI.h" 33 #import <Foundation/NSProgress.h> 33 34 #import <MobileCoreServices/MobileCoreServices.h> 34 35 #import <UIKit/UIColor.h> … … 132 133 UIItemProvider *itemProvider = [[getUIItemProviderClass() alloc] init]; 133 134 for (NSString *typeIdentifier in item) { 134 [itemProvider registerDataRepresentationForTypeIdentifier:typeIdentifier loadHandler:^(UIItemProviderDataLoadCompletionBlock completionBlock, NSDictionary *) { 135 [itemProvider registerDataRepresentationForTypeIdentifier:typeIdentifier options:nil loadHandler:^NSProgress *(UIItemProviderDataLoadCompletionBlock completionBlock) 136 { 135 137 completionBlock(item[typeIdentifier], nil); 138 return [NSProgress discreteProgressWithTotalUnitCount:100]; 136 139 }]; 137 140 } … … 150 153 return; 151 154 152 NSData *data = [provider copyDataRepresentationForTypeIdentifier:pasteboardType options:nilerror:nil];155 NSData *data = [provider copyDataRepresentationForTypeIdentifier:pasteboardType error:nil]; 153 156 if (data) 154 157 [values addObject:data]; … … 166 169 return; 167 170 168 if (isRichTextType(pasteboardType) && [provider canInstantiateObjectOfClass:[NSAttributedString class]]) { 169 [values addObject:[provider instantiateObjectOfClass:[NSAttributedString class] options:nil error:nil]]; 170 return; 171 } 172 173 if (isStringType(pasteboardType) && [provider canInstantiateObjectOfClass:[NSString class]]) { 174 [values addObject:[provider instantiateObjectOfClass:[NSString class] options:nil error:nil]]; 175 return; 176 } 177 178 if (isColorType(pasteboardType) && [provider canInstantiateObjectOfClass:[getUIColorClass() class]]) { 179 [values addObject:[provider instantiateObjectOfClass:[getUIColorClass() class] options:nil error:nil]]; 180 return; 181 } 182 183 if (isURLType(pasteboardType) && [provider canInstantiateObjectOfClass:[NSURL class]]) { 184 [values addObject:[provider instantiateObjectOfClass:[NSURL class] options:nil error:nil]]; 185 return; 186 } 187 188 if (isImageType(pasteboardType) && [provider canInstantiateObjectOfClass:[getUIImageClass() class]]) { 189 [values addObject:[provider instantiateObjectOfClass:[getUIImageClass() class] options:nil error:nil]]; 171 // FIXME: These should be refactored to use asynchronous calls. 172 if (isColorType(pasteboardType) && [provider canCreateObjectOfClass:[getUIColorClass() class]]) { 173 [values addObject:[provider createObjectOfClass:[getUIColorClass() class] error:nil]]; 174 return; 175 } 176 177 if (isImageType(pasteboardType) && [provider canCreateObjectOfClass:[getUIImageClass() class]]) { 178 [values addObject:[provider createObjectOfClass:[getUIImageClass() class] error:nil]]; 179 return; 180 } 181 182 if (isURLType(pasteboardType) && [provider canCreateObjectOfClass:[NSURL class]]) { 183 [values addObject:[provider createObjectOfClass:[NSURL class] error:nil]]; 184 return; 185 } 186 187 if (isRichTextType(pasteboardType) && [provider canCreateObjectOfClass:[NSAttributedString class]]) { 188 [values addObject:[provider createObjectOfClass:[NSAttributedString class] error:nil]]; 189 return; 190 } 191 192 if (isStringType(pasteboardType) && [provider canCreateObjectOfClass:[NSString class]]) { 193 [values addObject:[provider createObjectOfClass:[NSString class] error:nil]]; 190 194 return; 191 195 } -
trunk/Source/WebKit2/ChangeLog
r211226 r211227 1 2017-01-26 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 Add support for recognizing data interaction gestures in WebKit2 4 https://bugs.webkit.org/show_bug.cgi?id=167444 5 6 Reviewed by Beth Dakin. 7 8 Adds a new data interaction gesture recognizer, responsible for determining when to begin data interaction. This 9 is a new long press gesture recognizer that fires simultaneously with the existing long press gesture 10 recognizers (for performing long-press actions, and for showing the tap highlight). 11 12 Also tweaks logic for determining whether selection gesture recognizers should fire to account for data 13 interaction -- in particular, we don't want selection gesture recognizers to cause the current selection to 14 change while data interaction is possible. See -hasSelectablePositionAtPoint and -pointIsInAssistedNode for 15 more details. 16 17 * UIProcess/ios/PageClientImplIOS.mm: 18 (WebKit::PageClientImpl::didPerformDataInteractionControllerOperation): 19 (WebKit::PageClientImpl::startDataInteractionWithImage): 20 * UIProcess/ios/WKContentViewInteraction.h: 21 * UIProcess/ios/WKContentViewInteraction.mm: 22 (-[WKContentView _createAndConfigureLongPressGestureRecognizer]): 23 (-[WKContentView setupInteraction]): 24 (-[WKContentView cleanupInteraction]): 25 (-[WKContentView _removeDefaultGestureRecognizers]): 26 (-[WKContentView _addDefaultGestureRecognizers]): 27 (-[WKContentView resignFirstResponder]): 28 (-[WKContentView gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:]): 29 (-[WKContentView gestureRecognizerShouldBegin:]): 30 (-[WKContentView hasSelectablePositionAtPoint:]): 31 (-[WKContentView pointIsInDataInteractionContent:]): 32 (-[WKContentView pointIsInAssistedNode:]): 33 1 34 2017-01-26 Matt Rajca <mrajca@apple.com> 2 35 -
trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.mm
r211199 r211227 766 766 void PageClientImpl::didPerformDataInteractionControllerOperation() 767 767 { 768 } 769 770 void PageClientImpl::startDataInteractionWithImage(const WebCore::IntPoint& clientPosition, const ShareableBitmap::Handle& image, bool isLink) 771 { 768 [m_contentView _didPerformDataInteractionControllerOperation]; 769 } 770 771 void PageClientImpl::startDataInteractionWithImage(const IntPoint& clientPosition, const ShareableBitmap::Handle& image, bool isLink) 772 { 773 [m_contentView _startDataInteractionWithImage:ShareableBitmap::create(image)->makeCGImageCopy() atClientPosition:CGPointMake(clientPosition.x(), clientPosition.y()) isLink:isLink]; 772 774 } 773 775 #endif -
trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.h
r211095 r211227 45 45 #import <wtf/text/WTFString.h> 46 46 47 #if USE(APPLE_INTERNAL_SDK) && __has_include(<WebKitAdditions/WKContentViewInteractionAdditions.h>) 48 #import <WebKitAdditions/WKContentViewInteractionAdditions.h> 49 #endif 50 47 51 namespace API { 48 52 class OpenPanelParameters; … … 180 184 BOOL _resigningFirstResponder; 181 185 BOOL _needsDeferredEndScrollingSelectionUpdate; 182 } 183 184 @end 185 186 @interface WKContentView (WKInteraction) <UIGestureRecognizerDelegate, UIWebTouchEventsGestureRecognizerDelegate, UITextInputPrivate, UIWebFormAccessoryDelegate, UIWKInteractionViewProtocol, WKFileUploadPanelDelegate, WKActionSheetAssistantDelegate> 186 187 #if ENABLE(DATA_INTERACTION) 188 RetainPtr<UILongPressGestureRecognizer> _dataInteractionGestureRecognizer; 189 RetainPtr<UIImage> _currentDataInteractionImage; 190 CGPoint _currentDataInteractionOrigin; 191 BOOL _shouldHandleLongPressActionAfterDataInteraction; 192 #endif 193 } 194 195 @end 196 197 @interface WKContentView (WKInteraction) <UIGestureRecognizerDelegate, UIWebTouchEventsGestureRecognizerDelegate, UITextInputPrivate, UIWebFormAccessoryDelegate, UIWKInteractionViewProtocol, WKFileUploadPanelDelegate, WKActionSheetAssistantDelegate 198 #if ENABLE(DATA_INTERACTION) 199 , WKViewDataInteractionSourceDelegate, WKDataInteractionSessionDelegate, WKViewDataInteractionDestinationDelegate, WKDataInteractionItemVisualTarget 200 #endif 201 > 187 202 188 203 @property (nonatomic, readonly) CGPoint lastInteractionLocation; … … 233 248 - (NSArray<NSValue *> *)_uiTextSelectionRects; 234 249 - (void)accessibilityRetrieveSpeakSelectionContent; 250 251 #if ENABLE(DATA_INTERACTION) 252 - (void)_didPerformDataInteractionControllerOperation; 253 - (void)_startDataInteractionWithImage:(RetainPtr<CGImageRef>)image atClientPosition:(CGPoint)clientPosition isLink:(BOOL)isLink; 254 #endif 255 235 256 @end 236 257 -
trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm
r211121 r211227 68 68 #import <WebCore/DataDetectorsUISPI.h> 69 69 #import <WebCore/FloatQuad.h> 70 #import <WebCore/NotImplemented.h> 70 71 #import <WebCore/Pasteboard.h> 71 72 #import <WebCore/Path.h> … … 80 81 #import <WebKit/WebSelectionRect.h> // FIXME: WK2 should not include WebKit headers! 81 82 #import <wtf/RetainPtr.h> 83 84 #if ENABLE(DATA_INTERACTION) 85 #import <WebCore/PlatformPasteboard.h> 86 #import <WebCore/WebItemProviderPasteboard.h> 87 #endif 82 88 83 89 @interface UIEvent(UIEventInternal) … … 494 500 @implementation WKContentView (WKInteraction) 495 501 502 #if USE(APPLE_INTERNAL_SDK) && __has_include(<WebKitAdditions/WKContentViewInteractionAdditions.mm>) 503 #import <WebKitAdditions/WKContentViewInteractionAdditions.mm> 504 #endif 505 496 506 static UIWebSelectionMode toUIWebSelectionMode(WKSelectionGranularity granularity) 497 507 { … … 516 526 } 517 527 528 - (void)_createAndConfigureLongPressGestureRecognizer 529 { 530 _longPressGestureRecognizer = adoptNS([[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(_longPressRecognized:)]); 531 [_longPressGestureRecognizer setDelay:tapAndHoldDelay]; 532 [_longPressGestureRecognizer setDelegate:self]; 533 [_longPressGestureRecognizer _setRequiresQuietImpulse:YES]; 534 [self addGestureRecognizer:_longPressGestureRecognizer.get()]; 535 } 536 518 537 - (void)setupInteraction 519 538 { … … 558 577 [self addGestureRecognizer:_highlightLongPressGestureRecognizer.get()]; 559 578 560 _longPressGestureRecognizer = adoptNS([[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(_longPressRecognized:)]); 561 [_longPressGestureRecognizer setDelay:tapAndHoldDelay]; 562 [_longPressGestureRecognizer setDelegate:self]; 563 [_longPressGestureRecognizer _setRequiresQuietImpulse:YES]; 564 [self addGestureRecognizer:_longPressGestureRecognizer.get()]; 579 [self _createAndConfigureLongPressGestureRecognizer]; 580 581 #if ENABLE(DATA_INTERACTION) 582 _dataInteractionGestureRecognizer = adoptNS([[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(_dataInteractionGestureRecognizer:)]); 583 [_dataInteractionGestureRecognizer setDelay:0.25]; 584 [_dataInteractionGestureRecognizer setDelegate:self]; 585 [_dataInteractionGestureRecognizer _setRequiresQuietImpulse:YES]; 586 [self addGestureRecognizer:_dataInteractionGestureRecognizer.get()]; 587 [self setupDataInteractionDelegates]; 588 #endif 565 589 566 590 _twoFingerSingleTapGestureRecognizer = adoptNS([[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(_twoFingerSingleTapGestureRecognized:)]); … … 638 662 [self removeGestureRecognizer:_twoFingerSingleTapGestureRecognizer.get()]; 639 663 664 #if ENABLE(DATA_INTERACTION) 665 [_dataInteractionGestureRecognizer setDelegate:nil]; 666 [self removeGestureRecognizer:_dataInteractionGestureRecognizer.get()]; 667 [self teardownDataInteractionDelegates]; 668 #endif 669 640 670 _inspectorNodeSearchEnabled = NO; 641 671 if (_inspectorNodeSearchGestureRecognizer) { … … 665 695 [self removeGestureRecognizer:_twoFingerDoubleTapGestureRecognizer.get()]; 666 696 [self removeGestureRecognizer:_twoFingerSingleTapGestureRecognizer.get()]; 697 #if ENABLE(DATA_INTERACTION) 698 [self removeGestureRecognizer:_dataInteractionGestureRecognizer.get()]; 699 #endif 667 700 } 668 701 … … 676 709 [self addGestureRecognizer:_twoFingerDoubleTapGestureRecognizer.get()]; 677 710 [self addGestureRecognizer:_twoFingerSingleTapGestureRecognizer.get()]; 711 #if ENABLE(DATA_INTERACTION) 712 [self addGestureRecognizer:_dataInteractionGestureRecognizer.get()]; 713 #endif 678 714 } 679 715 … … 813 849 - (BOOL)resignFirstResponder 814 850 { 851 #if ENABLE(DATA_INTERACTION) 852 _shouldHandleLongPressActionAfterDataInteraction = NO; 853 #endif 815 854 // FIXME: Maybe we should call resignFirstResponder on the superclass 816 855 // and do nothing if the return value is NO. … … 1191 1230 return YES; 1192 1231 1232 #if ENABLE(DATA_INTERACTION) 1233 if (isSamePair(gestureRecognizer, otherGestureRecognizer, _highlightLongPressGestureRecognizer.get(), _dataInteractionGestureRecognizer.get())) 1234 return YES; 1235 1236 if (isSamePair(gestureRecognizer, otherGestureRecognizer, _longPressGestureRecognizer.get(), _dataInteractionGestureRecognizer.get())) 1237 return YES; 1238 #endif 1239 1193 1240 return NO; 1194 1241 } … … 1361 1408 } 1362 1409 1410 #if ENABLE(DATA_INTERACTION) 1411 if (gestureRecognizer == _dataInteractionGestureRecognizer) 1412 return [self pointIsInDataInteractionContent:point]; 1413 #endif 1414 1363 1415 return YES; 1364 1416 } … … 1391 1443 InteractionInformationRequest request(roundedIntPoint(point)); 1392 1444 [self ensurePositionInformationIsUpToDate:request]; 1445 1446 #if ENABLE(DATA_INTERACTION) 1447 if (_positionInformation.hasDataInteractionAtPosition) { 1448 // If the position might initiate a data interaction, we don't want to consider the content at this position to be selectable. 1449 // FIXME: This should be renamed to something more precise, such as textSelectionShouldRecognizeGestureAtPoint: 1450 return NO; 1451 } 1452 #endif 1453 1393 1454 return _positionInformation.isSelectable; 1394 1455 } 1456 1457 #if ENABLE(DATA_INTERACTION) 1458 1459 - (BOOL)pointIsInDataInteractionContent:(CGPoint)point 1460 { 1461 InteractionInformationRequest request(roundedIntPoint(point)); 1462 [self ensurePositionInformationIsUpToDate:request]; 1463 1464 if (_positionInformation.isImage) 1465 return YES; 1466 1467 // FIXME: Add support for links. 1468 if (_positionInformation.isLink) 1469 return NO; 1470 1471 return _positionInformation.hasDataInteractionAtPosition; 1472 } 1473 1474 #endif 1395 1475 1396 1476 - (BOOL)pointIsNearMarkedText:(CGPoint)point … … 1405 1485 InteractionInformationRequest request(roundedIntPoint(point)); 1406 1486 [self ensurePositionInformationIsUpToDate:request]; 1487 1488 #if ENABLE(DATA_INTERACTION) 1489 if (_positionInformation.hasDataInteractionAtPosition) { 1490 // If the position might initiate data interaction, we don't want to change the selection. 1491 // FIXME: This should be renamed to something more precise, such as textInteractionShouldRecognizeGestureAtPoint: 1492 return NO; 1493 } 1494 #endif 1495 1407 1496 return _positionInformation.nodeAtPositionIsAssistedNode; 1408 1497 }
Note: See TracChangeset
for help on using the changeset viewer.